@wenaixi/dsh-ponytail 5.0.0 → 5.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/CHANGELOG.md +140 -226
  2. package/README.md +102 -98
  3. package/lib/client.js +303 -140
  4. package/lib/ponytail-config.d.ts +47 -21
  5. package/lib/ponytail-config.d.ts.map +1 -1
  6. package/lib/ponytail-config.js +42 -36
  7. package/lib/ponytail-config.js.map +1 -1
  8. package/lib/ponytail-instructions.d.ts.map +1 -1
  9. package/lib/ponytail-instructions.js +31 -31
  10. package/lib/ponytail-instructions.js.map +1 -1
  11. package/lib/ponytail-priority.d.ts +10 -8
  12. package/lib/ponytail-priority.d.ts.map +1 -1
  13. package/lib/ponytail-priority.js +12 -11
  14. package/lib/ponytail-priority.js.map +1 -1
  15. package/lib/ponytail-remote.d.ts +65 -0
  16. package/lib/ponytail-remote.d.ts.map +1 -0
  17. package/lib/ponytail-remote.js +141 -0
  18. package/lib/ponytail-remote.js.map +1 -0
  19. package/lib/ponytail-settings.d.ts +96 -0
  20. package/lib/ponytail-settings.d.ts.map +1 -0
  21. package/lib/ponytail-settings.js +165 -0
  22. package/lib/ponytail-settings.js.map +1 -0
  23. package/lib/ponytail-skills.d.ts +10 -0
  24. package/lib/ponytail-skills.d.ts.map +1 -1
  25. package/lib/ponytail-skills.js +23 -5
  26. package/lib/ponytail-skills.js.map +1 -1
  27. package/lib/ponytail-state.d.ts +8 -4
  28. package/lib/ponytail-state.d.ts.map +1 -1
  29. package/lib/ponytail-state.js +40 -39
  30. package/lib/ponytail-state.js.map +1 -1
  31. package/lib/ponytail.d.ts +28 -4
  32. package/lib/ponytail.d.ts.map +1 -1
  33. package/lib/ponytail.js +181 -83
  34. package/lib/ponytail.js.map +1 -1
  35. package/locale/en.json +37 -27
  36. package/locale/zh.json +37 -27
  37. package/package.json +3 -1
  38. package/skills/descriptions.en.json +8 -0
  39. package/skills/descriptions.zh.json +8 -0
  40. package/skills/ponytail/SKILL.md +89 -46
  41. package/skills/ponytail-audit/SKILL.md +27 -17
  42. package/skills/ponytail-debt/SKILL.md +27 -14
  43. package/skills/ponytail-gain/SKILL.md +32 -19
  44. package/skills/ponytail-help/SKILL.md +53 -32
  45. package/skills/ponytail-review/SKILL.md +36 -24
  46. package/lib/ponytail-http.d.ts +0 -45
  47. package/lib/ponytail-http.d.ts.map +0 -1
  48. package/lib/ponytail-http.js +0 -162
  49. package/lib/ponytail-http.js.map +0 -1
package/README.md CHANGED
@@ -5,156 +5,160 @@
5
5
  </p>
6
6
 
7
7
  <p align="center">
8
- <strong>懒惰的资深工程师 · 移植到 DeepSeek Harness</strong><br/>
8
+ 懒惰的资深工程师,移植到 DeepSeek Harness。<br/>
9
9
  <em>The best code is the code you never wrote.</em>
10
10
  </p>
11
11
 
12
12
  <p align="center">
13
13
  <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-111111?style=flat-square" alt="MIT"/></a>
14
14
  <a href="https://www.npmjs.com/package/@wenaixi/dsh-ponytail"><img src="https://img.shields.io/npm/v/@wenaixi/dsh-ponytail?color=111111&style=flat-square" alt="npm"/></a>
15
- <img src="https://img.shields.io/badge/DSH-333333?style=flat-square" alt="DSH"/>
16
- <img src="https://img.shields.io/badge/skills-6-008080?style=flat-square" alt="skills"/>
17
15
  </p>
18
16
 
19
17
  <p align="center">
20
- <a href="CHANGELOG.md">Changelog</a> · <a href="https://github.com/DietrichGebert/ponytail">上游</a> · <a href="https://www.npmjs.com/package/@wenaixi/dsh-ponytail">npm</a>
18
+ <a href="CHANGELOG.md">Changelog</a> ·
19
+ <a href="https://github.com/DietrichGebert/ponytail">上游</a> ·
20
+ <a href="https://www.npmjs.com/package/@wenaixi/dsh-ponytail">npm</a>
21
21
  </p>
22
22
 
23
- ---
23
+ 面向 DeepSeek Harness 的常驻插件:把七阶梯子注入系统提示词,提供 6 个中文技能,不注册任何 tool。实现参考 [DietrichGebert/ponytail](https://github.com/DietrichGebert/ponytail),本地版本与上游参考版本独立维护。
24
24
 
25
- > 这是面向 DeepSeek Harness 的 Ponytail 适配插件:提供常驻懒人 senior 模式、七阶梯子、6 个中文原生技能和零 tool 注册。实现参考 [DietrichGebert/ponytail](https://github.com/DietrichGebert/ponytail),但本地版本、发布节奏和 DSH 兼容边界独立维护。
26
- >
27
- > **版本对照(2026-10-04 核验)**:本地发行版本为 `5.0.0`;上游参考版本为 `4.10.3`。上游参考版本不会自动决定本地版本号。
25
+ ## 安装
28
26
 
29
- ## 🚀 安装(默认装到 `web`)
30
-
31
- > `web` 即日常的 DSH Web UI(3080)。示例中的 `demo` 可换成任意 `--profile <name>`。
27
+ 装到任意 profile。示例里的 `web` 换成你的 `--profile <name>`。
32
28
 
33
29
  ```bash
34
- # 方式一:npm
35
30
  dsh plugin --profile web add @wenaixi/dsh-ponytail
31
+ dsh plugin --profile web remove @wenaixi/dsh-ponytail
32
+ dsh --profile web --dump-config | grep -A2 ponytail
33
+ ```
36
34
 
37
- # 方式二:GitHub 直装(lib 已提交,无需构建)
38
- dsh plugin --profile web add github:Wenaixi/dsh-ponytail
35
+ `WARN missing peer @deepseek-ai/...` 是正常的,peer 由 DSH 运行时提供。看到 `Packages: +2 Done` 就是装好了。
39
36
 
40
- # 方式三:本地 / tarball
41
- pnpm install && pnpm build && dsh plugin --profile web add ./
42
- pnpm pack && dsh plugin --profile web add ./wenaixi-dsh-ponytail-*.tgz
37
+ 若插件卡片只有包名、没有标题描述图标,说明包的 `exports` 没放行 `./package.json` 与 `./locale/*.json`。这是 DSH 读取展示元信息的硬约束,与安装本身无关。
43
38
 
44
- # 卸载
45
- dsh plugin --profile web remove @wenaixi/dsh-ponytail
39
+ ### 补丁条目要写在顶层
46
40
 
47
- # 验证
48
- dsh --profile web --dump-config | grep -A2 ponytail
41
+ 插件包自带的 `cordis.patch.yml` 用 `insert` 列表声明条目:
42
+
43
+ ```yaml
44
+ - insert:
45
+ - id: ponytail
46
+ name: "@wenaixi/dsh-ponytail"
49
47
  ```
50
48
 
51
- > `WARN missing peer @deepseek-ai/...` 属正常,peer 由 DSH 运行时提供;`Packages: +2 Done` 即成功。
49
+ **卡片能渲染不等于能写配置。** 宿主的配置编辑器只管理顶层条目的 `config` 块,`insert` 里的条目永远判为被覆盖,面板显示「本部署没有接受这次修改」。要能写,条目得是顶层:
52
50
 
53
- > **首次安装后若插件卡片只有包名、没有标题描述图标**,说明包的 `exports` 没放行 `./package.json` 与 `./locale/*.json`。这是 DSH 读展示元信息时的硬约束,与安装本身无关。
51
+ ```yaml
52
+ - id: ponytail
53
+ name: "@wenaixi/dsh-ponytail"
54
+ config:
55
+ defaultMode: full # off|lite|full|ultra
56
+ ```
57
+
58
+ 本插件的面板不显示只读横幅,所以那句拒绝提示是唯一判据。宿主的判定在 `dsh-config-editor` 的 `edit()`:写入前把新配置与继承层合成结果逐字段比对,不一致就报 `Configuration for "ponytail" is overridden by a home patch or command-line overlay`。
54
59
 
55
- ## ✨ 特性
60
+ ## 用法
56
61
 
57
- - **梯子 7 阶**:YAGNI → 复用 → 标准库 → 平台原生 → 已有依赖 → 一行 → 最小实现,`off` 时静默
58
- - **6 个中文 Skill**(`rank: 550`):`ponytail` / `ponytail-review` / `ponytail-audit` / `ponytail-debt` / `ponytail-gain` / `ponytail-help`
59
- - **四种运行模式**:`off` / `lite` / `full`(默认)/ `ultra`
60
- - **无 tool 注册**:全部能力经 `ctx.skills` 暴露
62
+ ```
63
+ /ponytail 切到 full(七阶梯子全开)
64
+ /ponytail lite 只做最低限度
65
+ /ponytail ultra 先挑战需求本身
66
+ /ponytail off 关闭注入
67
+ /ponytail default lite 跨会话持久化
68
+ stop ponytail 同 off,整句匹配
69
+ ```
61
70
 
62
- | 能力 | 说明 |
63
- |---|---|
64
- | `ponytail` | 7 阶梯子,触发词兼容中英文 |
65
- | `ponytail-review` | diff 评审,`delete/stdlib/native/yagni/shrink` |
66
- | `ponytail-audit` | 全仓审计,按可删收益排序 |
67
- | `ponytail-debt` | 收割 `ponytail:` 注释 |
68
- | `ponytail-gain` | 收益看板(benchmark 中位数) |
69
- | `ponytail-help` | 速查卡 |
71
+ 等级在每次会话启动时按 `env > Profile 补丁 > 内置兜底 full` 重置,所以 `/ponytail <档>` 只在本会话有效,跨会话要写 `/ponytail default <档>`。
70
72
 
71
- ## 🪝 Hook 注入
73
+ 六档之外的技能:
72
74
 
73
- > 上游 `hooks/` 的 6 个 Hook(config / instructions / runtime / activate / mode-tracker / subagent)已合并进单一 DSH 插件(runtime 的 flag 存取并入 state),无需宿主配置。
75
+ | 技能 | 作用 |
76
+ | --- | --- |
77
+ | `/ponytail-review` | 只看 diff,找能删的东西 |
78
+ | `/ponytail-audit` | 全仓审计,按可删收益排序 |
79
+ | `/ponytail-debt` | 收割 `ponytail:` 注释列成待办 |
80
+ | `/ponytail-gain` | 收益看板 |
81
+ | `/ponytail-help` | 速查卡 |
74
82
 
75
- | 上游 | DSH 侧 |
76
- |---|---|
77
- | `ponytail-config.js` | `src/ponytail-config.ts`(`env > 文件 > full`,`review` 不可默认) |
78
- | `ponytail-instructions.js` | `src/ponytail-instructions.ts`(唯一出口 `renderPromptSection(skillDir, state)`:review 短路 + 按档裁剪 + 中文 fallback 全部内聚) |
79
- | `ponytail-state.js` | `src/ponytail-state.ts`(`.ponytail-active` 物理存取内联于此——上游 runtime 的 flag 存取已并入 state,DSH 单一宿主无外部探针;技能禁用 reload 收敛同在此) |
80
- | `ponytail-activate.js` | `src/ponytail.ts` 的 `agent/created`(startup/resume 对齐 flag) |
81
- | `ponytail-mode-tracker.js` | `src/ponytail-commands.ts` 的 `createCommandDispatcher`(指令解析纯函数 + 状态机副作用) |
82
- | `ponytail-subagent.js` | `src/ponytail.ts` 的 `agent/created`(`PONYTAIL_SUBAGENT_MATCHER`) |
83
+ 命令行调试时任务文本不要写 `headless`,否则整句匹配不上 `/ponytail` 前缀:
83
84
 
85
+ ```bash
86
+ dsh --profile web '<任务>'
84
87
  ```
85
- 启动: env PONYTAIL_DEFAULT_MODE → cordis defaultMode → $DSH_HOME/ponytail/config.json → full
86
- → setMode(flag 文件) // 会话启动对齐语义,见下方说明
87
88
 
88
- 每轮请求前: agent/pre-step (waterfall, 必须 return next())
89
- → 解析 /ponytail 族 / stop ponytail → 切 currentMode + 写 flag → next()
89
+ ## 技能正文与描述语言
90
90
 
91
- 注入: systemPrompt:section { name: ponytail, order: 50 }
92
- order 50 在 persona(0) 之后、工具(100) 之前;回调收敛为单行 text: () => renderPromptSection(skillDir, state)
93
- off → 空,review → 指向技能,读盘失败 → 中文 fallback,assembly 前以 readMode() 对齐
91
+ 技能正文是上游 DietrichGebert/ponytail v4.10.3 的英文原文,按 tag 逐文件取回。两处内容对 DSH
92
+ 不适用,已就地改写为真实落点:`ponytail-gain` 的数据来源指向 `assets/*.svg`(本仓无上游的
93
+ `benchmarks/`),`ponytail-help` 的配置与更新章节改为 profile 补丁与 `dsh plugin`。
94
94
 
95
- 持久化: /ponytail default <mode> → 写入 config.json
96
- 子智能体: PONYTAIL_SUBAGENT_MATCHER 正则(非法 warn 回退),共享同一 section
97
- HMR: 全部走 ctx,热重载逆序自动清理
98
- ```
95
+ 模型目录与配置面板看到的是同一个描述字符串,语言由 `skillDescriptionLang` 决定(默认中文)。
96
+ 两套描述的真源是 `skills/descriptions.zh.json` 与 `skills/descriptions.en.json`,
97
+ 经 `ctx.remote.ponytail.snapshot()` 下发,因此切换后模型侧与界面同时改变。
99
98
 
100
- `systemPrompt` 而非 `agent.inject`:落入日志可重建,`order: 50` 优先级高,每次 `assemble` 动态求值,`off` 零成本。flag(`.ponytail-active`)与配置同源持久化于 DSH 用户数据根目录(`$DSH_HOME/ponytail`,默认 `~/.dsh/ponytail`),`/ponytail` 切换在 DSH 内闭环。
99
+ 描述长度上限来自官方 `dsh-tool-skill` 的 `catalogDescriptionMaxLength`(默认 500),
100
+ 超长会在模型目录里被截断,`verify.mjs` 对两册都断言。
101
+ ## 配置面板
101
102
 
102
- **会话启动对齐**:每次会话启动都会按默认档(env > patch > 配置文件 > full)重写 flag,这是对齐上游 SessionStart 语义。因此 `/ponytail <档>` **只在本会话生效**;要让某个等级跨会话持久化,必须用 `/ponytail default <档>` 写进配置文件。
103
+ 已安装插件的卡片详情内嵌配置面板:运行等级、6 个技能的独立开关、一键恢复默认,外加一条三级优先级诊断链,逐行显示环境变量、Profile 补丁、内置兜底各自的值与生效状态。
103
104
 
104
- ## ⚙️ 配置
105
+ 等级控件只显示补丁里真实配置的档。补丁没写 `defaultMode` 时选中末尾追加的「未设置」段,「当前生效」由诊断链顶部的文字给出。把兜底档显示成已配置档就是在骗人。
105
106
 
106
- ```yaml
107
- - insert:
108
- - id: ponytail
109
- name: "@wenaixi/dsh-ponytail"
110
- config:
111
- providerName: ponytail
112
- defaultMode: full # off|lite|full|ultra
113
- ```
107
+ 读写走两条官方通道:
108
+
109
+ | 通道 | 内容 | 落点 |
110
+ | --- | --- | --- |
111
+ | `ctx.configForms.get('ponytail')` | 默认档、技能启用列表,写入自带 revision 冲突检测 | `profiles/<name>/cordis.patch.yml` |
112
+ | `ctx.remote.ponytail.snapshot()` | 当前生效等级、三级诊断链,只读 | 不落盘,按需拉取 |
114
113
 
115
- 优先级(四级,取第一个有效值):`PONYTAIL_DEFAULT_MODE` env > `cordis.defaultMode` > `$DSH_HOME/ponytail/config.json`(默认 `~/.dsh/ponytail/config.json`) > `full`。持久化:`/ponytail default <mode>` 写入文件,`review` 不可作默认。
114
+ 无 Profile 上下文的组合(headless、CLI)没有 Settings 服务,配置读写回退到 `profiles/<name>/ponytail/config.json`。从旧版本升级时,全局的 `$DSH_HOME/ponytail/config.json` 首次启动时一次性导入 Profile 补丁,旧文件随后被改名 `.imported`;导入失败不影响启动。
116
115
 
117
- **注意**:`Config.defaultMode` 的 Schema 刻意不带默认值。Cordis 校验会把缺省 fill 成显式配置,一旦填上就会永久压过 `config.json` 里用户设置的档位,让 UI 上的改动看起来"不生效"。
116
+ ## 安装、更新、卸载的真实行为
118
117
 
119
- ### 界面配置
118
+ | 动作 | 需要重启宿主 | 原因 |
119
+ | --- | --- | --- |
120
+ | 新装 | 否,刷新浏览器即可 | 宿主检测到新增条目,投递新的产物指纹 |
121
+ | 更新 | 是 | 条目 `rev` 在进程启动时算好就冻结,运行中替换文件不触发重算 |
122
+ | 卸载 | 否,但补丁条目要手工删 | `dsh plugin remove` 清 `package.json`、bundles 与物理包,不删 `cordis.patch.yml` 的条目 |
120
123
 
121
- 插件在已安装插件卡片详情内嵌配置面板(`plugins.bundle.config` 插槽),支持四档运行等级、6 个技能的独立开关、一键恢复默认,并给出**四级优先级诊断链**——逐行显示环境变量、Profile 补丁、配置文件、内置兜底各自的值与生效状态,被更高优先级压制的那一级会显式标为"被覆盖",等级选择器同时禁用。面板读写均经 `/api/plugins/ponytail/config`,落盘位置同样是 `$DSH_HOME/ponytail/config.json`。
124
+ 卸载后的残留条目每次启动打印 `patch: entry "ponytail" not found`,是警告,不致命。宿主侧确实没有删除条目的能力,只能手工清。
122
125
 
123
- 若从旧位置升级,首次读取会兼容旧配置,但新写入一律落到 DSH 数据根;旧目录不删不改。
126
+ 更新后请重启宿主再验证界面。
124
127
 
125
- ## 🎮 使用
128
+ ## 上游映射
126
129
 
127
- - 自动生效,无需手动触发
128
- - `/ponytail [lite|full|ultra|off]` / `/ponytail default <mode>` / `/ponytail-review` / `/ponytail-audit` / `/ponytail-debt` / `/ponytail-gain` / `/ponytail-help`
129
- - 退出:`stop ponytail` / `normal mode`(整句)或 `/ponytail off`
130
- - 命令行调试:`dsh --profile <name> '<任务>'`——不要写 `headless` 字样,否则任务文本会被 CLI 前置成 `headless <任务>`,整句不再匹配 `/ponytail` 指令前缀(切换指令也就不会生效)。
130
+ 上游 `hooks/` 的六个 Hook 合并进单一 DSH 插件:
131
+
132
+ | 上游 | DSH 侧 |
133
+ | --- | --- |
134
+ | `ponytail-config.js` | `src/ponytail-config.ts` |
135
+ | `ponytail-instructions.js` | `src/ponytail-instructions.ts`,唯一出口 `renderPromptSection(skillDir, state)` |
136
+ | `ponytail-state.js` | `src/ponytail-state.ts`,flag 文件存取与技能禁用 reload 都在此 |
137
+ | `ponytail-activate.js` | `src/ponytail.ts` 的 `agent/created` |
138
+ | `ponytail-mode-tracker.js` | `src/ponytail-commands.ts` 的 `createCommandDispatcher` |
139
+ | `ponytail-subagent.js` | `src/ponytail.ts` 的 `agent/created`,`PONYTAIL_SUBAGENT_MATCHER` |
131
140
 
132
- ## 🛠️ 开发
141
+ 提示词经 `systemPrompt.section('ponytail')` 注入,`order: 50` 落在 persona(0) 与工具(100) 之间,每次 assemble 动态求值,`off` 时零成本。flag 与配置同源持久化在当前 profile 内,同机多实例互不干扰。
142
+
143
+ ## 开发
133
144
 
134
145
  ```bash
135
- # 四道门禁,改完必须全绿
136
- pnpm typecheck # tsc --noEmit
137
- pnpm build # tsc 出 lib/,再由 build-client.mjs 生成 lib/client.js
138
- node scripts/verify.mjs # 静态门禁:38 条断言(含 client.js Node API 残留反向断言)(产物/技能/零 tool/落点/元数据真源/locale)
139
- node scripts/behavior.test.mjs # 行为单测(64 项)
140
-
141
- # 0 侵入联调
142
- dsh --profile web --patch ./cordis.patch.yml --dump-config # 仅验证补丁解析,不替代真实启动验收
146
+ pnpm typecheck # tsc --noEmit
147
+ pnpm build # tsc 出 lib/,再由 build-client.mjs 生成 lib/client.js
148
+ node scripts/verify.mjs # 静态门禁:产物、技能、零 tool、UI 落点、locale 键集
149
+ node scripts/docs-verify.mjs # 版本策略文档一致性
150
+ node scripts/behavior.test.mjs # 行为测试
151
+
152
+ dsh --profile web --patch ./cordis.patch.yml --dump-config # 只验证补丁解析
143
153
  pnpm dsh web --patch ./cordis.patch.yml # 热重载
144
154
  ```
145
155
 
146
- - **版本策略**:本地发行版本使用独立的标准 SemVer,例如当前 `5.0.0`;使用 `pnpm version:bump` 递增 patch,或 `pnpm version:set -- 5.1.0` 设置明确版本。旧的 `-dsh.N` 仅属于历史版本策略,不再生成。
147
- - **上游参考**:README 记录上游参考版本和核验日期,但上游发布不会自动改变本地版本;是否升级参考实现由本地兼容性评估决定。
148
- - **发布铁律**:严禁本地 `npm publish` 和未经授权的 `git push`。本地完成门禁后,由授权的 CI tag 流程发布 npm 与 GitHub Release。
149
- - **客户端产物单一来源**:`lib/client.js` 只由 `scripts/build-client.mjs` 生成。`tsconfig.build.json` 不得把它列入编译输入,否则会出现同名双产物并静默漂移。
150
-
151
- ---
156
+ 本地版本用独立的标准 SemVer,`pnpm version:bump` 递增 patch,`pnpm version:set -- 5.2.0` 指定版本。旧的 `-dsh.N` 不再生成。上游发布不会改变本地版本号,是否吸收上游变化由本地兼容性评估决定。
152
157
 
153
- ## 🔗 上游
158
+ 发布只走 tag 触发的 CI。严禁本地 `npm publish`,push 与打 tag 都需要明确授权。
154
159
 
155
- 原仓 https://github.com/DietrichGebert/ponytail(MIT)
160
+ `lib/client.js` 只由 `scripts/build-client.mjs` 生成。`tsconfig.build.json` 不能把它列入编译输入,否则会出现同名双产物并静默漂移。
156
161
 
157
- ## 📄 许可
162
+ ## 许可
158
163
 
159
- [MIT](LICENSE)
160
- © DietrichGebert / Wenaixi
164
+ [MIT](LICENSE),原作 DietrichGebert,移植 Wenaixi。上游仓库 https://github.com/DietrichGebert/ponytail