@mengyuly/dsh-ponytail 0.1.5 → 0.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.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,87 @@
3
3
  All notable changes to `@mengyuly/dsh-ponytail` are documented here.
4
4
  Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
5
5
 
6
+ ## [0.2.0] - 2026-08-24
7
+
8
+ ### Added
9
+
10
+ - 真正区分 lite/full/ultra 的 Prompt:从「Markdown 正则过滤同一份正文」改为
11
+ **结构化片段组合**(Common 规则 + 永不可删的 Safety 边界 + 各档独立规则)。
12
+ - `lite`:完整交付明确要求、可一句话提示更简方案、不挑战明确需求;
13
+ - `full`:完整七级阶梯、默认最短正确实现、修根因;
14
+ - `ultra`:先删后加、主动质疑投机性功能/缓存/抽象/配置/新依赖、先给最小
15
+ 正确版并说明完整版条件、不是无脑拒绝;
16
+ - 三档共享 Common + Safety(输入校验/数据丢失防护/安全/无障碍/明确验收项)。
17
+ - 常驻注入从 ~1.3k tokens 降到 **lite≈369 / full≈420 / ultra≈406** tokens。
18
+ - **Cordis Profile 级 `defaultMode` 配置**:`config: { defaultMode }` 按
19
+ profile 生效(`web → full`、`tui → lite` 等),优先级
20
+ `会话 override > env > Profile > 用户 config.json > full`;非法值告警一次
21
+ 并回退;Profile 配置初始化时读取(Cordis 无公开配置变更事件),重启生效;
22
+ `/ponytail default` 的 saved/effective 提示现在会点名覆盖来源
23
+ (`PONYTAIL_DEFAULT_MODE` / `profile configuration`)。
24
+ - 兼容矩阵:CI 扩展为 **Node 22 × Node 24 × ubuntu × windows**(4 组合);
25
+ `dist-provenance.json` 增加 `generatedBy.cordis`;README 记录实测矩阵
26
+ (含 web profile 本机验证、tui/headless 如实标注未验证)。
27
+ - 结构化 Prompt 的行为测试、快照测试、token 统计测试;Profile 优先级测试
28
+ (env>profile、会话 override>env、非法回退、双 profile 不同默认)。
29
+
30
+ ### Changed
31
+
32
+ - 默认模式解析加入 Profile 档(代码/测试/README 三处一致)。
33
+ - README:三档真实差异、Profile 配置示例、兼容矩阵、子代理边界表述。
34
+
35
+ ### Fixed
36
+
37
+ - 删除随旧实现遗留的 `filterSkillBodyForMode` 正则过滤路径及其测试
38
+ (被结构化组合取代)。
39
+
40
+ ### Security
41
+
42
+ - 无变化(0.1.6 的 eval-free 产物与 dev-tooling 边界保持)。
43
+
44
+ ## Unreleased
45
+
46
+ ### Security
47
+
48
+ - Documented the development-only `child_process` boundary (`SECURITY.md`):
49
+ `scripts/**` is excluded from the npm tarball, has no install lifecycle
50
+ hook, and is unreachable from the installed runtime entry.
51
+ - Added tarball checks preventing `scripts/` (and `src/`, `tests/`, `test/`,
52
+ `tools/`) from being published, plus a post-install assertion that the
53
+ installed package contains no `scripts/`.
54
+ - Added checks preventing `preinstall` / `install` / `postinstall` /
55
+ `prepare` lifecycle hooks from silently invoking development tooling.
56
+ - Classified repository-only `child_process` findings as accepted
57
+ development-tooling risk.
58
+
59
+ ## [0.1.6] - 2026-08-24
60
+
61
+ ### Fixed
62
+
63
+ - 移除发行产物中的动态代码执行:`new Function` 的调用点来自内联进 bundle 的
64
+ schemastery(其 schema DSL 会把字符串 `callback` 编译成函数)。已把
65
+ `@deepseek-ai/schemastery` 从 bundle **外置**为已发布的 peer(与 cordis
66
+ 同等对待),发行 `lib/index.js` 不再包含任何 `new Function` / `eval`
67
+ (CI 的 `check-bundle` 现在断言外链集合精确为
68
+ `cordis + schemastery`,且产物零动态执行)。该调用点在本插件运行时路径上
69
+ 本不可达(只构造、不解析),外置是消除扫描告警的根治,也是更诚实的依赖声明。
70
+
71
+ ### Changed
72
+
73
+ - 运行时依赖表述更新:bundle 现在 import `@deepseek-ai/cordis` +
74
+ `@deepseek-ai/schemastery`(两者都已发布);`dsh-llm` / `dsh-skill` 仍内联
75
+ (npm 无兼容版本)。
76
+ - `@deepseek-ai/schemastery` 加入 peerDependencies(宿主兼容声明)。
77
+ - `verify-dist` 的运行时导出检查改用链式可调用 stub 加载 bundle
78
+ (schemastery 在模块加载时被急切构建 schema,但本插件路径不解析它们)。
79
+ - 移除只做类型检查、职责与 `sync:dist` 重叠的 `scripts/build.sh`。
80
+
81
+ ### Tests
82
+
83
+ - Ubuntu + Windows(CI 矩阵):check-bundle(外链白名单 + 零动态执行)、
84
+ verify:dist、verify:pack、test:consumer、test:regressions。
85
+ - tarball 安装 smoke 现在显式安装 cordis + schemastery 两个运行时 peer。
86
+
6
87
  ## [0.1.5] - 2026-08-24
7
88
 
8
89
  ### Fixed
package/README.md CHANGED
@@ -1,6 +1,9 @@
1
1
  # dsh-ponytail
2
2
 
3
3
  ![CI](https://github.com/MengYuil/dsh-ponytail/actions/workflows/ci.yml/badge.svg)
4
+ ![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)
5
+ [![npm](https://img.shields.io/npm/v/@mengyuly/dsh-ponytail)](https://www.npmjs.com/package/@mengyuly/dsh-ponytail)
6
+ [![dsh.so security](https://www.dsh.so/badge/dsh-ponytail-4.svg)](https://www.dsh.so/artifact/dsh-ponytail-4/)
4
7
 
5
8
  把 [DietrichGebert/ponytail](https://github.com/DietrichGebert/ponytail)(「懒惰资深开发者」最少代码心智)移植成 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) 原生插件。功能与效率与上游一致:7 级阶梯规则集每轮注入、强度切换、`/ponytail-*` 斜杠命令。
6
9
 
@@ -24,18 +27,24 @@ dsh plugin --profile web add @mengyuly/dsh-ponytail
24
27
 
25
28
  装完重启 profile 生效(`dsh web` / `dsh tui`)。装载完成后,会话技能目录里会出现 6 个 `ponytail*` 技能,发 `/ponytail-help` 立即验证。
26
29
 
27
- > `lib/index.js` 是自包含 bundle(已内联 `dsh-llm` / `dsh-skill`),运行时只依赖 `@deepseek-ai/cordis` peer(registry 有 4.0.1),所以 GitHub / tgz / npm 三种安装方式都不需要 dsh 源码树。
30
+ > `lib/index.js` 是自包含 bundle(已内联 `dsh-llm` / `dsh-skill`——npm 无兼容版本),运行时依赖两个已发布的 peer:`@deepseek-ai/cordis`(4.0.1)与 `@deepseek-ai/schemastery`(3.18.x)。`schemastery` 刻意保持外置而非内联:其 schema DSL 用 `new Function` 编译 `callback` 字符串,外置后**发行产物不含任何动态代码执行**(CI 有专门检查)。GitHub / tgz / npm 三种安装方式都不需要 dsh 源码树。
28
31
 
29
- > 说明:`src/` 是源码、`lib/` 是预构建产物(开箱即可加载,无需编译)。源码主仓在 deepseek-harness 的 `packages/community/ponytail`,改源码后回主仓重建,再把 `lib/` 同步回本仓库即可发版。本地改 `src/` 想快速验证编译,可用 `DSH_CHECKOUT=/path/to/deepseek-harness ./scripts/build.sh`(只做类型检查)。
32
+ > 说明:`src/` 是源码、`lib/` 是预构建产物(开箱即可加载,无需编译)。源码主仓在 deepseek-harness 的 `packages/community/ponytail`;改源码后用 `DSH_CHECKOUT=/path/to/deepseek-harness npm run sync:dist` 重建并同步完整 `lib/`(见下「发行维护」)。
30
33
 
31
34
  ## 功能
32
35
 
33
- - **核心模式** `/ponytail` — 每轮注入「懒惰阶梯」:能不做就不做(YAGNI)→ 代码库已有 → 标准库 → 平台原生 → 已装依赖 → 一行能解决 → 才是最少代码。
34
- - `full`(默认)/ `lite` / `ultra` / `off` 四档,**会话级**(会话 A 的档位不影响会话 B,会话结束自动释放)。
35
- - `/ponytail`:已启用时只报告;会话为 `off` 时恢复到有效默认档(有效默认也是 `off` 则回 `full`)。
36
+ - **核心模式** `/ponytail` — 每轮注入结构化的懒惰开发者规则集,**三个档位是真实不同的 Prompt 片段**(不只是换一行):
37
+ - **Common(所有非 off 档共享)**:先理解问题、追踪真实调用流;优先复用/标准库/原生能力/已有依赖;非平凡改动留一个最小可运行检查;解释简短但不省略关键决策。
38
+ - **Safety(任何档位都不可删)**:输入校验、防数据丢失的错误处理、安全措施、无障碍、明确验收项、先理解问题、「最小 diff 正确修复」。
39
+ - **`lite`**:完整交付明确要求;可以一句话指出更简方案,但**不挑战明确需求**;输出可略完整。
40
+ - **`full`(默认)**:完整七级阶梯(YAGNI → 复用 → 标准库 → 原生 → 已装依赖 → 一行 → 最小实现),默认选最短正确实现,修根因而非症状。
41
+ - **`ultra`**:YAGNI 极端(先删后加);主动质疑投机性功能/缓存/抽象/配置/新依赖;复杂需求先给最小正确版并说明完整版条件;**不是无脑拒绝**。
42
+ - `off`:完全不注入。
43
+ - 档位**会话级**(会话 A 不影响会话 B,会话结束自动释放)。
44
+ - 裸 `/ponytail`:已启用时只报告;`off` 时恢复到有效默认档(默认也是 `off` 则回 `full`)。
36
45
  - `/ponytail status`:只查询、永不修改。
37
46
  - `/ponytail lite|full|ultra|off`:显式切换。
38
- - `/ponytail default <mode>`:持久化默认值到配置文件(环境变量仍优先)。
47
+ - `/ponytail default <mode>`:持久化默认值到**用户级配置文件**(env/Profile 仍优先,命令分别提示 saved 与 effective)。
39
48
  - **一次性技能**(用哪个载哪个,不进常驻 prompt):
40
49
  - `/ponytail-review` — 针对最近改动找过度工程,一行一条:位置 + 删什么 + 替代。
41
50
  - `/ponytail-audit` — 全仓库过度工程审计,排序清单。
@@ -43,23 +52,53 @@ dsh plugin --profile web add @mengyuly/dsh-ponytail
43
52
  - `/ponytail-gain` — 收益计分板(更少代码/更省成本/更快)。
44
53
  - `/ponytail-help` — 参考卡。
45
54
  - **停用**:说 `stop ponytail` 或 `normal mode`(兼容中英文句末标点);随时 `/ponytail` 恢复。
46
- - **默认值**:环境变量 `PONYTAIL_DEFAULT_MODE` > `~/.config/ponytail/config.json`(Windows:`%APPDATA%\ponytail\config.json`)的 `{"defaultMode": "lite"}` > `full`。`/ponytail default` 写入的是配置文件,**环境变量设置且合法时仍压过保存值**(命令会分别提示 saved 与 effective)。
47
- - **子代理**:常驻段作用于当前会话自身;DSH 内置 `subagent` 工具跑的是隔离的全新子代理、不继承本 persona。`PONYTAIL_SUBAGENT_MATCHER`(匹配子代理 `agentPreset` 的正则)用于在 harness 会下发给子代理的场景里排除指定子代理;缺省全部注入。
48
- - **配置错误**:非法 JSON / 非法 `defaultMode` / 读取失败 / 非法正则只告警一次(不刷屏);配置文件不存在属正常、不告警;热更新遇到临时非法内容保留上一个合法默认值。
55
+ - **默认值优先级**(代码/测试/文档一致):
56
+ ```
57
+ 会话 override > PONYTAIL_DEFAULT_MODE > Profile config.defaultMode > 用户 config.json > full
58
+ ```
59
+ - **Profile 级配置**(Cordis 官方插件配置 API,各 profile 可不同):
60
+ ```yaml
61
+ # ~/.dsh/profiles/tui/cordis.patch.yml 中给 ponytail 行补 config
62
+ - insert:
63
+ - id: ponytail
64
+ name: '@mengyuly/dsh-ponytail'
65
+ config:
66
+ defaultMode: lite
67
+ ```
68
+ 例:`web → full`、`tui → lite`、`automation → off`。Profile 配置在插件初始化时读取(Cordis 无公开配置变更事件),**改后需重启该 profile**;非法值只告警一次并回退,不影响启动。用户 `config.json` 仍保持热更新。
69
+ - **用户 config.json**(`~/.config/ponytail/config.json`,Windows `%APPDATA%\ponytail\config.json`):`{"defaultMode": "lite"}`,热更新(~1s 轮询),非法内容保留上次合法值。
70
+ - **子代理(如实边界)**:DSH 内置 `subagent` 工具是**隔离派生**,默认**不继承**本插件的 system-prompt;`PONYTAIL_SUBAGENT_MATCHER`(匹配子代理 `agentPreset` 的正则)**只用于筛选能进入本 Prompt 管线的子代理**,不是继承开关;DSH 当前没有公开的子代理派生/可继承 Prompt API,因此**未实现、也不宣称父子 Prompt 继承**(有官方 API 后再考虑只读快照传播)。非法正则告警一次并 fail-open。
71
+ - **配置错误**:非法 JSON / 非法 `defaultMode` / 读取失败 / 非法正则只告警一次(不刷屏);配置文件不存在属正常、不告警。
49
72
 
50
73
  ## 效率
51
74
 
52
- - 常驻注入 ≈ 1.3k tokens/请求,`off` 归零;同模式字节级稳定,KV-cache 前缀命中,切模式后才重算一次。
75
+ - 常驻注入:**lite369 / full ≈ 420 / ultra ≈ 406 tokens**(结构化片段,不再是 ~1.3k);`off` 归零;同模式字节级稳定,KV-cache 前缀命中。
53
76
  - 一次性技能 300–540 tokens 一个,零常驻开销。
54
77
  - 实测同任务 A/B:ponytail 臂 34 行 vs 完整实现臂 272 行,均标准库、均自测通过。
55
78
 
56
79
  ## 已知限制
57
80
 
58
- - 强度档位只切换阶梯表格/示例,阶梯正文恒定;lite/full/ultra 体积差异很小(行为倾向,非大小差异)。
81
+ - 档位差异在**规则语义**上(见上),三者体积相近(≤ 满档 ×1.25)。
59
82
  - 上游 Claude 专属的 statusline 徽标无 DSH 对应物,MCP 服务器因 DSH 有一等 system-prompt 注入点而弃用。
60
- - 配置文件的默认档位热更新(fs 轮询 ~1s,作用于无覆盖的会话);环境变量改动仍需重启。
83
+ - 用户 `config.json` 热更新;`PONYTAIL_DEFAULT_MODE` 与 Profile config 需重启生效。
61
84
  - 发行 `lib/` 是预编译产物;改源码请回主仓重建后同步。
62
85
 
86
+ ## 兼容矩阵(实测,不虚构)
87
+
88
+ | 组件 | 已验证环境 | 备注 |
89
+ |---|---|---|
90
+ | Node.js | 22.x / 24.x | CI 矩阵 4 组合全绿 |
91
+ | OS | ubuntu-latest / windows-latest | CI 矩阵 |
92
+ | DSH | commit `b150a551`(构建所用 checkout) | 与正式发布版本的精确对应关系**待确认** |
93
+ | Cordis | 4.0.1(构建所用 vendor) | 同上 |
94
+ | web profile | 已验证 | 本机真实 profile 长期运行 + 三路径隔离安装实测(npm / GitHub / tgz) |
95
+ | tui profile | 未验证 | 未在 tui profile 中启动测试 |
96
+ | headless profile | 未验证 | 未完整启动;插件单元测试运行于无 UI 环境 |
97
+ | npm tarball | 已验证 | 内容/版本/安装后 smoke/NodeNext consumer |
98
+
99
+ - `dist-provenance.json` 记录实际构建来源(checkout commit + node/typescript/tsdown/cordis 版本)。
100
+ - 不要用 `continue-on-error` 掩盖失败——矩阵全绿才是绿。
101
+
63
102
  ## 测试环境与权威关系
64
103
 
65
104
  - 本机(Linux,Node.js **v24.16.0**,deepseek-harness checkout 构建)与 CI 矩阵(**ubuntu-latest + windows-latest**,Node 24)上验证通过。与之精确匹配的已发布 DSH/Cordis 版本**待确认**——checkout 是预发布工作树,非发布 tag。
@@ -83,6 +122,7 @@ dsh plugin --profile web add @mengyuly/dsh-ponytail
83
122
  - **CI 能力边界(如实)**:CI(ubuntu + windows 矩阵)执行上述静态验证与打包/消费测试,但**不重新构建权威 monorepo**;`verify:dist` 是导出表面/签名/运行时导出的一致性检查,**不是**与权威构建的字节级等价证明——后者由 `sync:dist` 在发布流程中保证。
84
123
  - `dist-provenance.json` 随 npm 包发布,便于审计构建来源。
85
124
  - 本机验证时若 `npm_execpath` 指向其他包管理器(如 pnpm/yarn shim),脚本会自动回退到 PATH 上的 `npm`;临时目录失败时保留需设 `PONYTAIL_VERIFY_KEEP_TEMP=1`。
125
+ - **安全**:`scripts/**` 仅用于开发/构建/发行验证,**不进入 npm tarball**、无安装生命周期钩子、运行时入口不引用;`child_process` 告警属于可接受的开发工具风险。详见 [SECURITY.md](SECURITY.md)。
86
126
 
87
127
  ## 许可
88
128
 
@@ -5,6 +5,7 @@
5
5
  "generatedBy": {
6
6
  "node": "v24.16.0",
7
7
  "typescript": "6.0.3",
8
- "tsdown": "0.22.2"
8
+ "tsdown": "0.22.2",
9
+ "cordis": "4.0.1"
9
10
  }
10
11
  }