@wenaixi/dsh-ponytail 5.0.0 → 5.1.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.
package/CHANGELOG.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  所有重要变更记录于此,格式基于 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.0.0/)。本地版本与上游参考版本独立维护。
4
4
 
5
- > 当前本地版本:`5.0.0`。上游参考:`DietrichGebert/ponytail 4.10.3`(2026-10-04 核验)。历史 `-dsh.N` 记录仅用于追溯,不再作为现行版本规则。
5
+ > 当前本地版本:`5.1.0`。上游参考:`DietrichGebert/ponytail 4.10.3`(2026-10-04 核验)。历史 `-dsh.N` 记录仅用于追溯,不再作为现行版本规则。
6
6
 
7
7
  ## [5.0.0] - 2026-10-04
8
8
 
@@ -15,9 +15,34 @@
15
15
  - 客户端 locale 字典改为 DSH 要求的扁平键,避免界面显示 `panel.title`、`priority.title` 等裸 key。
16
16
  - 客户端产物继续禁止 `import.meta` 和 `process.`,避免浏览器导入失败。
17
17
 
18
- ## [Unreleased]
18
+ ## [5.1.0] - 2026-10-05
19
19
 
20
- (本段暂无待发布内容)
20
+ ### Breaking
21
+
22
+ - **配置与 flag 的落点从全局数据根改为 profile 目录**(`profiles/<name>/ponytail/`)。升级用户的当前档位会重置为 `full`:迁移读取的是 profile 内的新位置,全局共享的旧 `config.json` 只需一次性导入。
23
+ - **优先级链从四级降为三级**(`env > patch > fallback`),`config.json` 层退役。界面上的「用户配置文件」一行已移除。
24
+
25
+ ### Added
26
+ - 配置与 flag 的 profile 维度:全部配置文件读写函数与 `createDiskStorage` 接受 `profileDir`,目录来自宿主 `profileContext.dir`,落点改为 `profiles/<name>/ponytail/`。同机多实例不再共享 `$DSH_HOME/ponytail`,最后写者赢的串扰消失。`src/ponytail-settings.ts` 提供两条通道——`createSettingsSink` 经 `ctx.settings.mutate('ponytail', ops, revision)` 写入,由宿主落到 profile 补丁并自带 revision 冲突保护;`createFileSink` 在无 settings 服务的组合(headless / CLI)回退读写 profile 内 `config.json`;`migrateLegacyConfig` 把全局共享的旧 `config.json` 一次性导入 profile 补丁并改名使其幂等。
27
+ - `src/ponytail-remote.ts`:`PonytailRemote extends TypertRemoteService`,命名空间 `ponytail`,只暴露只读端点 `snapshot()`(当前生效等级 + 三级优先级诊断链)。宿主网关按服务上的 `typertRemote` 绑定自动发现端点,浏览器侧即 `ctx.remote.ponytail.snapshot()`。
28
+ - 客户端 Remote 贡献声明 `PONYTAIL_REMOTE`:`apply()` 先 `await ctx.remote.$mount(...)` 再建 store。此前客户端只读命名空间却从未挂载,而网关的命名空间不是按需自动开通的(`dsh-api-remotes` 只遍历编译期写死的 25 个官方贡献),`remote.ponytail` 永不出现,面板因此永久显示「诊断信息不可用」——宿主完全正常。`$mount` 返回即命名空间就绪,故 40 次 x 50ms 轮询一并删除,改为挂载失败直接降级。
29
+
30
+ ### Changed
31
+ - 配置卡改用 DSH 官方插件配置组合:`Config` 的 `defaultMode` 与 `disabledSkills` 声明为 `.volatile()` 字段,宿主 `volatileForm()` 投影成官方表单;客户端经 `ctx.configForms.get('ponytail')` 读写,插槽注册包在 `configForms.whileServed(['ponytail'])` 内。
32
+ - 优先级链从四级降为三级 `env > patch > fallback`:`config.json` 层随 1A 下沉退役。留在链里就是一层永远不生效的空壳,而「看着能改其实不生效」正是这套面板最初要解决的坑。`LEVELS` / `LABELS` / `PROBLEMS` 各删一项,`resolvePriority` 去掉 `configMode` 参数,locale 同步删除 `level.config` 与 `problem.config`。
33
+ - `patchMode` 改为实时读取 volatile 引用,不再缓存启动期快照。
34
+ - `PonytailConfig` 的两个可持久化字段类型为 `VolatileRef<T>`,新增 `readVolatile()` 兼容「引用 / 裸值 / 未配置」三态。
35
+ - 技能启用态的失效触发点从自制 HTTP 端点直调改为监听宿主 `loader/volatile-update`。
36
+
37
+ ### Removed
38
+ - 删除 `src/ponytail-http.ts` 与 `/api/plugins/ponytail/config` 端点,以及 `webServer` 注入。
39
+ - 删除 `apply()` 里对 `settings.register('ponytail', Config)` 的调用——`@deepseek-ai/dsh-settings@0.2.0-rc.2` 没有 `register` 方法(全文件零次出现),该调用此前被 `typeof` 守卫静默跳过,属于从未生效的死代码。命名空间改由「唯一 profile 条目 + 含 volatile 字段的 Config」自动产生。
40
+ - 删除平台位置兼容读取 `getLegacyConfigDir()` / `getLegacyConfigPath()`(`%APPDATA%` / `XDG_CONFIG_HOME` / `~/.config` 三条分支)。1A 下沉后它们不再有任何读取者,`scripts/verify.mjs` 的对应豁免同时移除——现在 `src/` 下出现任何平台路径字面量直接判失败。
41
+
42
+ ### Fixed
43
+ - 技能禁用状态此前只存在 `config.json` 且只能由 HTTP 端点修改;迁移后 UI 改开关后模型侧目录不收敛(写入链不经过本插件任何函数)。现由 loader 的 volatile 提交事件驱动失效。
44
+ - 客户端配置卡此前自建 `fetch` 状态机(含空配置兜底、加载态、错误态),现完全走官方表单控制器,不发起任何 HTTP 请求。
45
+ - 等级选择器的锁定判定原为「除 patch 与 config 外、只要有层级命中就锁」,而兜底层在没有 env 与 patch 时恒命中,于是按钮永久禁用、提示永远显示「当前有更高优先级的配置在生效」——但兜底不是更高优先级的配置,改补丁立刻生效,文案在说谎。改为只认 env 命中。
21
46
 
22
47
  ## [4.10.0-dsh.12] - 2026-10-04
23
48
 
package/README.md CHANGED
@@ -24,7 +24,7 @@
24
24
 
25
25
  > 这是面向 DeepSeek Harness 的 Ponytail 适配插件:提供常驻懒人 senior 模式、七阶梯子、6 个中文原生技能和零 tool 注册。实现参考 [DietrichGebert/ponytail](https://github.com/DietrichGebert/ponytail),但本地版本、发布节奏和 DSH 兼容边界独立维护。
26
26
  >
27
- > **版本对照(2026-10-04 核验)**:本地发行版本为 `5.0.0`;上游参考版本为 `4.10.3`。上游参考版本不会自动决定本地版本号。
27
+ > **版本对照(2026-10-05 核验)**:本地发行版本为 `5.1.0`;上游参考版本为 `4.10.3`。上游参考版本不会自动决定本地版本号。
28
28
 
29
29
  ## 🚀 安装(默认装到 `web`)
30
30
 
@@ -82,7 +82,7 @@ dsh --profile web --dump-config | grep -A2 ponytail
82
82
  | `ponytail-subagent.js` | `src/ponytail.ts` 的 `agent/created`(`PONYTAIL_SUBAGENT_MATCHER`) |
83
83
 
84
84
  ```
85
- 启动: env PONYTAIL_DEFAULT_MODE → cordis defaultMode → $DSH_HOME/ponytail/config.json → full
85
+ 启动: env PONYTAIL_DEFAULT_MODE → cordis defaultMode → full
86
86
  → setMode(flag 文件) // 会话启动对齐语义,见下方说明
87
87
 
88
88
  每轮请求前: agent/pre-step (waterfall, 必须 return next())
@@ -92,14 +92,14 @@ dsh --profile web --dump-config | grep -A2 ponytail
92
92
  order 50 在 persona(0) 之后、工具(100) 之前;回调收敛为单行 text: () => renderPromptSection(skillDir, state)
93
93
  off → 空,review → 指向技能,读盘失败 → 中文 fallback,assembly 前以 readMode() 对齐
94
94
 
95
- 持久化: /ponytail default <mode> → 写入 config.json
95
+ 持久化: /ponytail default <mode> → 写入 profile 补丁或 profile 内 config.json
96
96
  子智能体: PONYTAIL_SUBAGENT_MATCHER 正则(非法 warn 回退),共享同一 section
97
97
  HMR: 全部走 ctx,热重载逆序自动清理
98
98
  ```
99
99
 
100
- `systemPrompt` 而非 `agent.inject`:落入日志可重建,`order: 50` 优先级高,每次 `assemble` 动态求值,`off` 零成本。flag(`.ponytail-active`)与配置同源持久化于 DSH 用户数据根目录(`$DSH_HOME/ponytail`,默认 `~/.dsh/ponytail`),`/ponytail` 切换在 DSH 内闭环。
100
+ `systemPrompt` 而非 `agent.inject`:落入日志可重建,`order: 50` 优先级高,每次 `assemble` 动态求值,`off` 零成本。flag(`.ponytail-active`)与配置同源持久化在当前 profile 内(`profiles/<name>/ponytail/`),`/ponytail` 切换在 DSH 内闭环。作用域随 profile 隔离,同机多实例互不干扰。
101
101
 
102
- **会话启动对齐**:每次会话启动都会按默认档(env > patch > 配置文件 > full)重写 flag,这是对齐上游 SessionStart 语义。因此 `/ponytail <档>` **只在本会话生效**;要让某个等级跨会话持久化,必须用 `/ponytail default <档>` 写进配置文件。
102
+ **会话启动对齐**:每次会话启动都会按默认档(env > patch > full)重写 flag,这是对齐上游 SessionStart 语义。因此 `/ponytail <档>` **只在本会话生效**;要让某个等级跨会话持久化,必须用 `/ponytail default <档>` 写进配置文件。
103
103
 
104
104
  ## ⚙️ 配置
105
105
 
@@ -112,15 +112,24 @@ HMR: 全部走 ctx,热重载逆序自动清理
112
112
  defaultMode: full # off|lite|full|ultra
113
113
  ```
114
114
 
115
- 优先级(四级,取第一个有效值):`PONYTAIL_DEFAULT_MODE` env > `cordis.defaultMode` > `$DSH_HOME/ponytail/config.json`(默认 `~/.dsh/ponytail/config.json`) > `full`。持久化:`/ponytail default <mode>` 写入文件,`review` 不可作默认。
115
+ 优先级(三级,取第一个有效值):`PONYTAIL_DEFAULT_MODE` env > `cordis.defaultMode` > 内置兜底 `full`。持久化:`/ponytail default <mode>` 写入 profile 补丁,`review` 不可作默认。
116
116
 
117
- **注意**:`Config.defaultMode` 的 Schema 刻意不带默认值。Cordis 校验会把缺省 fill 成显式配置,一旦填上就会永久压过 `config.json` 里用户设置的档位,让 UI 上的改动看起来"不生效"。
117
+ **注意**:`Config.defaultMode` 的 Schema 刻意不带默认值。Cordis 校验会把缺省 fill 成显式配置——补丁里显式写 `full` 与什么都不写会读出同一个值,诊断面板就无法区分"用户配过"与"没配过",界面因此说谎。
118
118
 
119
119
  ### 界面配置
120
120
 
121
- 插件在已安装插件卡片详情内嵌配置面板(`plugins.bundle.config` 插槽),支持四档运行等级、6 个技能的独立开关、一键恢复默认,并给出**四级优先级诊断链**——逐行显示环境变量、Profile 补丁、配置文件、内置兜底各自的值与生效状态,被更高优先级压制的那一级会显式标为"被覆盖",等级选择器同时禁用。面板读写均经 `/api/plugins/ponytail/config`,落盘位置同样是 `$DSH_HOME/ponytail/config.json`。
121
+ 插件在已安装插件卡片详情内嵌配置面板(`plugins.bundle.config` 插槽),支持四档运行等级、6 个技能的独立开关、一键恢复默认,并给出**三级优先级诊断链**——逐行显示环境变量、Profile 补丁、内置兜底各自的值与生效状态,被更高优先级压制的那一级会显式标为"被覆盖"。只有环境变量命中时等级选择器才禁用(env 压过一切,此时改补丁确实无效);兜底命中属于"补丁与 env 都没写",不是更高优先级的配置,必须放行。
122
122
 
123
- 若从旧位置升级,首次读取会兼容旧配置,但新写入一律落到 DSH 数据根;旧目录不删不改。
123
+ 面板不使用自制 HTTP 端点,读写分两条官方通道:
124
+
125
+ | 通道 | 内容 | 落点 |
126
+ | --- | --- | --- |
127
+ | `ctx.configForms.get('ponytail')` | 默认档、技能启用列表(写入自带 revision 冲突检测) | Profile 补丁 `profiles/<name>/cordis.patch.yml` |
128
+ | `ctx.remote.ponytail.snapshot()` | 当前生效等级、三级优先级诊断链(只读) | 不落盘,按需拉取 |
129
+
130
+ 在无 Profile 上下文的组合(headless / CLI)里,宿主没有装配 Settings 服务,此时配置读写回退到 profile 内的 `ponytail/config.json`。从旧版本升级时,全局共享的 `$DSH_HOME/ponytail/config.json` 会在首次启动时一次性导入 Profile 补丁,随后旧文件被改名为 `config.json.imported`;导入失败不影响启动,可用 `/ponytail default <档>` 重新设置。
131
+
132
+ 旧的平台位置(`%APPDATA%` / `XDG_CONFIG_HOME` / `~/.config`)兼容读取已随 1A 下沉一并删除;`scripts/verify.mjs` 现在对 `src/` 下任何平台路径字面量直接判失败。
124
133
 
125
134
  ## 🎮 使用
126
135
 
@@ -143,7 +152,7 @@ dsh --profile web --patch ./cordis.patch.yml --dump-config # 仅验证补丁解
143
152
  pnpm dsh web --patch ./cordis.patch.yml # 热重载
144
153
  ```
145
154
 
146
- - **版本策略**:本地发行版本使用独立的标准 SemVer,例如当前 `5.0.0`;使用 `pnpm version:bump` 递增 patch,或 `pnpm version:set -- 5.1.0` 设置明确版本。旧的 `-dsh.N` 仅属于历史版本策略,不再生成。
155
+ - **版本策略**:本地发行版本使用独立的标准 SemVer,例如当前 `5.1.0`;使用 `pnpm version:bump` 递增 patch,或 `pnpm version:set -- 5.1.1` 设置明确版本。旧的 `-dsh.N` 仅属于历史版本策略,不再生成。
147
156
  - **上游参考**:README 记录上游参考版本和核验日期,但上游发布不会自动改变本地版本;是否升级参考实现由本地兼容性评估决定。
148
157
  - **发布铁律**:严禁本地 `npm publish` 和未经授权的 `git push`。本地完成门禁后,由授权的 CI tag 流程发布 npm 与 GitHub Release。
149
158
  - **客户端产物单一来源**:`lib/client.js` 只由 `scripts/build-client.mjs` 生成。`tsconfig.build.json` 不得把它列入编译输入,否则会出现同名双产物并静默漂移。