dsh-pm
dsh-pm(pm = project management)由 春笋(ChunSun) 驱动 —— 把「春笋」AI 原生项目交付平台的能力,作为 DeepSeek Harness(DSH)的一等插件深度接入。
dsh-pm 让 DSH Agent 以「需求」为工作对象自主交付:开 Run、上报 Step、维护验收场景/用例、读写工作记忆、过 completed 硬门禁,并在 GUI 的会话级交付面板(composer 上方状态条 + 「项目管理」视图)实时看交付进度。工作记忆与状态以春笋自部署实例为 SSOT。
结构
src/index.ts——ChunsunService(TypertRemoteService,@Remote方法)src/tools.ts—— 28 个chunsun_*模型工具src/typert.ts/src/remote.ts—— Host./typert与 Client./remote(仓库外需自备;dsh-api-remotes不会替你 mount)src/client/index.ts—— 会话级交付 GUI(lazy-CJS):conversation.input.dock状态条(实时当前需求/Run 轮次/Step)+conversation.view「项目管理」视图(总览页);apply内$mount(./remote)后再用ctx.remote.chunsuncordis.patch.yml—— 组合包 patch(service + tools 两行)lib/——npm run build的产物(被 .gitignore 忽略)
已提供(Host 工具)
需求(list/show)· Run(start/takeover/status/list/remind)· Step(add/list)· 场景(list/upsert/status)· 用例(upsert/status)· 工作记忆(context_get/put)· 环境变量(env_list/env_get,secret 走审批栈)· reset · status
快速开始:安装到 DSH
前置条件
- Node.js ≥ 20 + npm(本仓库构建用);pnpm(DSH profile 管理插件用)
- 一个可启动的 DSH(下文以
webprofile 为例) - 可选:春笋自部署实例(否则只能看到「未连接」状态)
1. 构建插件(在 dsh-pm 目录内)
npm install
npm run build # tsc 转译,产物输出到 lib/(与 package.json exports 对齐)
构建必须用
tsc(不能用 tsdown):@Remote是 Stage 3 装饰器,DSH 用原生 Node ESM 加载组合包入口,需要tsc降级成__esDecorate。tsdown/oxc 目前不支持 Stage 3 装饰器,会把@Remote原样留在.js里导致Invalid or unexpected token。
2. 装进 DSH profile
dsh plugin --profile web add ./dsh-pm # 在 dsh-pm checkout 目录执行
这条命令等价于:在 ~/.dsh/profiles/web/ 里执行 pnpm add <checkout 绝对路径>,成功后自动把声明了 dsh.bundle 的 dsh-pm 追加到 package.json 的 dsh.profile.bundles。
pnpm 对本地路径依赖创建符号链接(node_modules/dsh-pm -> 你的 checkout),因此之后每次改动只需重新构建,无需重新 add。
如果
dsh不在 PATH(如从 monorepo checkout 直接跑),用完整路径:node <dsh-checkout>/apps/cli/lib/bin.js plugin --profile web add ./dsh-pm
手动方式(效果相同):编辑
~/.dsh/profiles/web/package.json,在dependencies加"dsh-pm": "file:/绝对路径/dsh-pm",在dsh.profile.bundles加"dsh-pm",然后在 profile 目录pnpm install。
3. 启动并接入
dsh web # 或 dsh --profile web
首次接入:把 CHUNSUN_API_URL + CHUNSUN_SECRET_KEY 写进工作区 .env(与 chunsun CLI 同源)。也可以在 GUI 的「项目管理」视图(conversation.view)里填写并「保存并测试连接」——composer 上方状态条仅作实时状态展示,不含「配置」入口。
开发调试
迭代循环
改 src/*.ts → npm run build → 生效
├─ Host 侧(服务/工具):重启 DSH
└─ Client 侧(面板):刷新浏览器页面
- Host 侧改动(
src/index.ts、src/tools.ts):DSH 启动时加载lib/index.js/lib/tools.js,必须重启 DSH 才生效。 - Client 侧改动(
src/client/index.ts):webServer 直接服务lib/client.js(lazy-CJS /__ModuleLoader__.load),重新构建 + 刷新浏览器即可;若同时跑着 DSH 的dev:web监视构建,会自动广播重载。 - 依赖变更(package.json):
npm install后再构建。
提交前快速校验
npx tsc --noEmit # 必须 0 错误
npm run build # 必须无 UNRESOLVED_IMPORT 之类警告
ls lib/ # index.js / tools.js / client.js(+ 对应 .d.ts)
调试手段
| 层 | 手段 |
|---|---|
| 构建/类型 | npx tsc --noEmit;检查 lib/ 产物是否更新、路径/扩展名是否与 package.json exports 一致;lib/client.js 必须以 window.__ModuleLoader__.load({ 开头 |
| Host 服务/工具 | 看 DSH 启动日志;在 DSH 会话里直接让 Agent 调用 chunsun_* 工具,观察返回 JSON;需要时在源码里加日志 |
| Client 面板 | 浏览器 DevTools:Console 看报错、Network 看 remote.chunsun.* RPC 请求与响应 |
| 接线自检 | 面板「保存并测试连接」→ 依次触发 config-read / config-save / status;curl 春笋实例 /health 可区分是插件问题还是实例问题 |
注意事项与常见坑
- 构建后用
node --check lib/index.js校验 Host:产物里不应再出现@Remote;应看到__esDecorate/Remote('status')这类降级代码。若仍有裸@,说明没用tsc构建。 - Client 必须是 lazy-CJS:
exports["./client"]指向的lib/client.js必须调用window.__ModuleLoader__.load({ id: "dsh-pm", factory });普通 ESM(import/export)会报loaded without registering ... via __ModuleLoader__.load。 remote.chunsun不会自动出现:仓库外插件必须导出./remote,并在 Clientapply里await ctx.remote.$mount(...);不要inject: ['remote.chunsun']却无人 mount(会一直 pending)。react保持 external:客户端 factory 里通过require("react")取壳层播种的 React,不要试图打包它。- 工具参数是 DSL 不是 JSON Schema:
defineTool的parameters是「属性名 → 值 schema」映射,必填以逐属性required: true标注(src/tools.ts的regTool已封装)。 - npm 缓存 EPERM:若报
Your cache folder contains root-owned files,执行sudo chown -R 501:20 ~/.npm,或临时用npm install --cache <本地目录>。 - git 安装插件:
dsh plugin ... add github:mengqinghe/dsh-pm会跑prepare构建脚本,pnpm 会拦截,需把报错里给出的 key 加进 profile 的pnpm-workspace.yaml的allowBuilds后重试。 - profile 位置:默认
~/.dsh/profiles/<name>/(可用DSH_HOME环境变量改)。
设计文档
详见本仓库 docs/design.md、docs/p5-promotion.md 与 docs/prototype/(动态插件原型源码)。
还没有评论,来写第一条。