上一篇说,DSH 是一套积木,插件就是一块积木。这一篇我们亲手做一块。
现在做插件,代码大多交给 AI 来写,下一篇就会这么做。这一篇偏偏一个字一个字手写,所以叫"古法"。
为什么还要手写一遍?DSH 很新,AI 对它的插件写法并不熟,常常写错,甚至编出根本不存在的接口。你自己亲手搭过一遍骨架,知道每个文件是干什么的,以后才看得出 AI 哪里写错了、该怎么提醒它。

做法分两步。
第一步,只写四个小文件,不装任何工具,不用编译。做完以后,DSH 的终端里会打印出我们写的一句话,输入框下方会多出一行"你好,DSH"。

第二步,把它换成正式项目的写法:用 TypeScript 写,用工具自动生成 DSH 要的文件。后面几篇写功能,都在这个基础上进行。
为什么不一上来就用工具?工具会替你做很多事,一开始就用,你分不清哪些是 DSH 的要求,哪些是工具自己加的。先手写一遍,再看工具替你做了什么,心里就有底了。
AI 也是一样的道理。
学完你能做到:说出一个插件最少要哪几个文件、每个文件管什么;把插件装进一个试验用的 DSH 里看到效果;知道改了代码以后怎么让它生效。
一、准备:终端、Node.js 和 dsh 命令
这一篇的操作大多在终端里进行。终端是一个打字下命令的窗口,Mac 上在"启动台"里搜"终端"就能打开。下面凡是灰色框里写着 bash 的,都是要敲进终端的命令,敲完按回车。
这一章的命令都按 Mac 的终端写。用 Windows 的话,先装一个 Git(官网下载,一路默认安装),它会附带一个叫 Git Bash 的终端,在 Git Bash 里敲同样的命令就行。
先确认电脑上装了 Node.js,版本 22 或更高。DSH 的插件用 JavaScript 写,Node.js 就是在电脑上运行 JavaScript 的程序。在终端里运行:
node --version会打印类似 v24.22.0 的版本号,v 后面的数字不小于 22 就行。提示找不到命令,或者版本太旧,就去 Node.js 官网下载安装新版,装完关掉终端重新打开。
再准备 dsh 命令,后面装插件、启动 DSH 都靠它。DSH 桌面版里自带了一份:打开桌面版,在顶部应用菜单里找到「检查更新…」下面的「管理 dsh 命令…」,点「安装」。
装好后新开一个终端窗口,运行:
dsh --version会打印 DSH 的版本号,比如 0.2.2-rc.1。看到版本号,准备工作就完成了。
二、最小的插件:三个文件
先做后台那一半。还记得上一篇说的吗:DSH 启动时会读一张总清单,按清单一块块装积木。所以要让 DSH 装上我们的插件,得做三件事:
- 告诉 DSH"我是一块积木";
- 往总清单里加一行"把我装上";
- 写好 DSH 装上这块积木时要做的事。
正好对应三个文件。
先建一个文件夹放插件。在终端里进到你平时放代码的目录,运行:
mkdir dsh-branch-chip
cd dsh-branch-chip
git initmkdir 新建一个叫 dsh-branch-chip 的文件夹,cd 进到这个文件夹里。
git init 把它变成一个 Git 仓库(提示找不到 git 的话,先去 Git 官网装一个)。我们这一章要做的插件叫"分支徽章",用来显示 Git 分支,到时候正好拿这个项目自己来试。
第一个文件:package.json,插件的身份证。
用任意文本编辑器(比如 VS Code),在 dsh-branch-chip 文件夹里新建一个文件,名字叫 package.json,把下面的内容复制进去:
{
"name": "dsh-branch-chip",
"version": "0.1.0",
"type": "module",
"main": "index.js",
"dsh": {
"bundle": { "patch": "./cordis.patch.yml" }
}
}每个 JavaScript 项目都有一个 package.json,写着它叫什么、入口在哪。逐行看:
name:插件的名字,全世界不能重名,后面 DSH 就靠它找到你的插件。version:版本号,第一版写0.1.0。type:写module,表示代码用import、export这种新写法。main:入口文件。DSH 装这块积木时,从index.js开始读。dsh.bundle:最关键的一行。它告诉 DSH"我是一块 DSH 积木",要往总清单里加的那一行,写在cordis.patch.yml里。没有这一行,DSH 会把它当成一个普通的包,不会装上它。
第二个文件:cordis.patch.yml,往总清单里加的那一行。
在同一个文件夹里新建 cordis.patch.yml,写入:
- insert:
- id: branch-chip
name: dsh-branch-chip意思是:往总清单里插入(insert)一条。id 是这一条的编号,以后要改这个插件的设置,就按编号找到它;name 写包名,和 package.json 里的 name 一样,DSH 按它找到你的代码。
文件名里的 cordis 是 DSH 底层那套插件框架的名字,patch 是"补丁",合起来就是"给总清单打的补丁"。
第三个文件:index.js,装上时要做的事。
再新建 index.js,写入:
export const name = 'dsh-branch-chip'
export function apply() {
console.log('[branch-chip] 后台那一半加载好了')
}这个文件不用自己运行,DSH 会加载它。apply 是约定好的名字:DSH 把这块积木装上去的那一刻,就会调用 apply。我们先只让它打印一句话,证明它被装上了。
三个文件是这样连起来的:

三、装进一个试验用的 DSH
插件先别装进你平时用的 DSH。写错了,可能连 DSH 都打不开。
DSH 把装了哪些插件、聊过的会话、各种设置,都放在一个"主目录"里,默认是你电脑上的 ~/.dsh 文件夹。我们给它换一个新的主目录,就得到一个干干净净、和平时互不影响的 DSH,怎么折腾都没关系。

确认终端还在 dsh-branch-chip 文件夹里,运行:
export DSH_HOME="$HOME/dsh-dev-home"
dsh plugin --profile web add "$PWD"第一行把主目录换成 dsh-dev-home,只对这个终端窗口有效。
第二行把当前文件夹($PWD 就是"当前所在的文件夹")当作插件,装进名叫 web 的那套配置里。web 就是网页版 DSH 用的配置。