@mengyuly/dsh-ponytail 0.1.3 → 0.1.5
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 +138 -0
- package/README.md +21 -2
- package/dist-provenance.json +10 -0
- package/lib/index.js +4 -4
- package/lib/invariant.js +3 -3
- package/lib/types/content.d.ts +2 -3
- package/lib/types/index.d.ts +1 -2
- package/lib/types/instructions.d.ts +1 -2
- package/lib/types/invariant.d.ts +2 -3
- package/lib/types/modes.d.ts +42 -6
- package/package.json +11 -2
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@mengyuly/dsh-ponytail` are documented here.
|
|
4
|
+
Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
5
|
+
|
|
6
|
+
## [0.1.5] - 2026-08-24
|
|
7
|
+
|
|
8
|
+
### Fixed
|
|
9
|
+
|
|
10
|
+
- Windows 下验证脚本无法启动 `npm.cmd`:`spawnSync('npm', …)` 在 Windows 上对
|
|
11
|
+
`.cmd` 无效(`status === null`)。现在统一走 `process.execPath + npm_execpath`
|
|
12
|
+
(npm script 环境内为 npm 自身 CLI,跨平台可靠),并在 `npm_execpath` 缺失或
|
|
13
|
+
指向其他包管理器(pnpm/yarn/bun shim)时回退到 `npm`/`npm.cmd`。
|
|
14
|
+
- `spawnSync` 启动失败时错误信息丢失:统一 `formatSpawnFailure` 输出 command、
|
|
15
|
+
args、cwd、status、signal、`result.error.message`、stdout/stderr 尾部
|
|
16
|
+
(各 4KB 上限);`status === null` 明确判为启动失败或被信号终止,不再显示为
|
|
17
|
+
普通退出码。
|
|
18
|
+
- `verify-dist` 不再有未定义 `existsSync` 的潜伏分支:改为**直接拒绝**任何
|
|
19
|
+
`sourceMappingURL`(与 v0.1.4 起 `declarationMap: false` 的发布策略一致),
|
|
20
|
+
并新增回归测试证明声明文件重现 source map 时验证会明确失败。
|
|
21
|
+
- 删除 CI 中 checkout 后立即执行的无效 `git diff --exit-code -- lib` 步骤
|
|
22
|
+
(工作区天然干净,证明不了任何事);防漂移表述与真实能力对齐。
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
|
|
26
|
+
- `verify-pack` / `test-consumer` 共用 `scripts/lib/run-command.mjs` 跨平台进程
|
|
27
|
+
工具,不再各自维护一套 `spawnSync('npm', …)`。
|
|
28
|
+
- `verify-pack` 如实报告实际安装的依赖(npm 会解析全部声明 peers,包括宿主
|
|
29
|
+
契约 peers;bundle 运行时只 import `@deepseek-ai/cordis` 由独立外链检查证明)。
|
|
30
|
+
- CI 增加 Windows Runner(`windows-latest` + `ubuntu-latest` 矩阵,Node 24,
|
|
31
|
+
不允许跳过或 continue-on-error)。
|
|
32
|
+
- `sync:dist` 生成 `dist-provenance.json`:`sourceCommit` 来自权威 checkout 的
|
|
33
|
+
`git rev-parse HEAD`(真实 SHA,不手工填写),工具链版本取自 checkout 的
|
|
34
|
+
node_modules,不含本机绝对路径;`verify:dist` 校验其格式。
|
|
35
|
+
- tarball 现在包含 `dist-provenance.json`。
|
|
36
|
+
- 产物一致性检查命名与真实能力一致:`verify:dist` 是静态一致性检查(src/d.ts
|
|
37
|
+
导出、关键签名、主入口运行时导出、无 source map、provenance),不是与权威
|
|
38
|
+
构建的字节级等价证明。
|
|
39
|
+
|
|
40
|
+
### Tests
|
|
41
|
+
|
|
42
|
+
- Ubuntu:verify:dist / verify:pack / test:consumer / test:regressions 全部通过。
|
|
43
|
+
- Windows:CI 矩阵真实执行 verify:dist / verify:pack / test:consumer。
|
|
44
|
+
- npm tarball smoke(仅声明依赖安装后加载)。
|
|
45
|
+
- NodeNext + skipLibCheck:false consumer。
|
|
46
|
+
- 子进程启动失败诊断回归测试。
|
|
47
|
+
- declaration source map 回归测试。
|
|
48
|
+
|
|
49
|
+
## [0.1.4] - 2026-08-24
|
|
50
|
+
|
|
51
|
+
### Fixed
|
|
52
|
+
|
|
53
|
+
- 修复运行时 JS 与 TypeScript declarations 不一致:v0.1.3 只同步了
|
|
54
|
+
`lib/index.js`/`lib/invariant.js`,声明文件停留在旧版本。
|
|
55
|
+
- `compileSubagentMatcher` 声明恢复正确(`{ matcher, invalid }`),与运行时一致。
|
|
56
|
+
- 补齐 `readDefaultModeInfo`、`sessionKey` 及诊断类型
|
|
57
|
+
(`DefaultModeIssueKind` / `DefaultModeIssue` / `DefaultModeResolution`)的声明。
|
|
58
|
+
- `writeDefaultMode` 声明注释补充「写入失败会抛出异常」。
|
|
59
|
+
- 移除失效的 declaration source map 引用:声明生成关闭 `declarationMap`,
|
|
60
|
+
发布的 `.d.ts` 不再携带指向不存在 `.d.ts.map` 的 `sourceMappingURL`。
|
|
61
|
+
|
|
62
|
+
### Changed
|
|
63
|
+
|
|
64
|
+
- 发布流程改为同步**完整** `lib/`(两个运行时 bundle + 全部 `.d.ts`):
|
|
65
|
+
`npm run sync:dist`(要求 `DSH_CHECKOUT`,在权威 checkout 中重建后整体同步)。
|
|
66
|
+
- CI 增加防漂移检查:src 导出 ↔ 声明导出、运行时导出 ↔ 声明导出、
|
|
67
|
+
`modes.d.ts` 关键签名、无悬空 source map、tarball 内容/版本/安装后 smoke、
|
|
68
|
+
NodeNext + `skipLibCheck:false` 的声明消费测试。
|
|
69
|
+
- tarball 现在包含 `CHANGELOG.md`。
|
|
70
|
+
|
|
71
|
+
### Tests
|
|
72
|
+
|
|
73
|
+
- npm tarball smoke test(仅声明 peer 安装后加载)。
|
|
74
|
+
- TypeScript consumer test(打包安装后编译,非相对路径读 src)。
|
|
75
|
+
- 运行时/声明导出一致性验证。
|
|
76
|
+
- src↔d.ts 漂移检查(CI 与 `verify:dist` 双保险)。
|
|
77
|
+
|
|
78
|
+
## [0.1.3] - 2026-08-23
|
|
79
|
+
|
|
80
|
+
### Fixed
|
|
81
|
+
|
|
82
|
+
- Bare `/ponytail` on an `off` session now re-enables at the effective default
|
|
83
|
+
(or `full` when that default is `off` too), matching the documented "resume
|
|
84
|
+
anytime with `/ponytail`" behavior. It still only reports when already enabled.
|
|
85
|
+
- `/ponytail default <mode>` no longer bypasses `PONYTAIL_DEFAULT_MODE`: the
|
|
86
|
+
effective default is recomputed after the write, so the env var keeps its
|
|
87
|
+
documented highest priority; the result distinguishes saved vs effective.
|
|
88
|
+
- Typo: `Ponyytail default set` → `Ponytail default set`.
|
|
89
|
+
- Deactivation phrases now also strip CJK sentence enders (`。?!`), so
|
|
90
|
+
`normal mode?` and `stop ponytail。` deactivate as expected.
|
|
91
|
+
- Config writes are now atomic (temp file + rename); a failed write returns an
|
|
92
|
+
error instead of a false success.
|
|
93
|
+
- A temporarily invalid config during hot-reload keeps the last known good
|
|
94
|
+
default instead of snapping back to `full`.
|
|
95
|
+
|
|
96
|
+
### Changed
|
|
97
|
+
|
|
98
|
+
- `/ponytail status` added as a pure query (never modifies the session).
|
|
99
|
+
- Command hints and error text updated to the new surface
|
|
100
|
+
(`[status|default <mode>|lite|full|ultra|off]`).
|
|
101
|
+
- Invalid config JSON / `defaultMode` / read failures and invalid
|
|
102
|
+
`PONYTAIL_SUBAGENT_MATCHER` now warn exactly once (fail-open preserved,
|
|
103
|
+
missing config file stays silent).
|
|
104
|
+
- Session identity is centralized in one `sessionKey(agent)` helper; mode
|
|
105
|
+
overrides are released on `agent/disposed`, so long-running hosts do not
|
|
106
|
+
accumulate stale per-session entries.
|
|
107
|
+
|
|
108
|
+
### Tests
|
|
109
|
+
|
|
110
|
+
- 47 unit/integration tests (was 24): command semantics (bare `/ponytail`
|
|
111
|
+
restore paths, `status`, `default` saved-vs-effective, write failure),
|
|
112
|
+
priority (env > config > full, invalid env falls back to config),
|
|
113
|
+
session isolation and disposal cleanup, CJK/ASCII deactivation punctuation,
|
|
114
|
+
config file edge cases (BOM, empty, invalid JSON, array root, unknown-field
|
|
115
|
+
preservation, atomic write), hot-reload keep-last-good, and a headless
|
|
116
|
+
(no command plane) mount.
|
|
117
|
+
|
|
118
|
+
## [0.1.2] - 2026-08-23
|
|
119
|
+
|
|
120
|
+
### Changed
|
|
121
|
+
|
|
122
|
+
- Self-contained bundle: `dsh-llm` / `dsh-skill` are inlined, so the runtime
|
|
123
|
+
only depends on the `@deepseek-ai/cordis` peer — installable from GitHub,
|
|
124
|
+
tarball, or npm without a dsh source tree.
|
|
125
|
+
- npm scope renamed to `@mengyuly/dsh-ponytail` (matches the npm account).
|
|
126
|
+
|
|
127
|
+
### Tests
|
|
128
|
+
|
|
129
|
+
- CI smoke verifies the bundle leaves no dsh core external and loads with only
|
|
130
|
+
cordis installed.
|
|
131
|
+
|
|
132
|
+
## [0.1.0] - 2026-08-23
|
|
133
|
+
|
|
134
|
+
### Added
|
|
135
|
+
|
|
136
|
+
- Initial release: always-on lazy-senior-developer ruleset, lite/full/ultra/off
|
|
137
|
+
intensities, six skills and slash commands, deactivation phrases,
|
|
138
|
+
`PONYTAIL_DEFAULT_MODE` / config-file defaults, subagent matcher.
|
package/README.md
CHANGED
|
@@ -62,8 +62,27 @@ dsh plugin --profile web add @mengyuly/dsh-ponytail
|
|
|
62
62
|
|
|
63
63
|
## 测试环境与权威关系
|
|
64
64
|
|
|
65
|
-
-
|
|
66
|
-
- 权威源码在 deepseek-harness monorepo 的 `packages/community/ponytail`(`@deepseek-ai/dsh-ponytail`);本仓库(`@mengyuly/dsh-ponytail
|
|
65
|
+
- 本机(Linux,Node.js **v24.16.0**,deepseek-harness checkout 构建)与 CI 矩阵(**ubuntu-latest + windows-latest**,Node 24)上验证通过。与之精确匹配的已发布 DSH/Cordis 版本**待确认**——checkout 是预发布工作树,非发布 tag。
|
|
66
|
+
- 权威源码在 deepseek-harness monorepo 的 `packages/community/ponytail`(`@deepseek-ai/dsh-ponytail`);本仓库(`@mengyuly/dsh-ponytail`)是**发行镜像**:随包附构建产物,不是独立真源。
|
|
67
|
+
|
|
68
|
+
## 发行维护
|
|
69
|
+
|
|
70
|
+
- **权威源码**:deepseek-harness monorepo 的 `packages/community/ponytail`(本仓库是发行镜像,只随包发布构建产物)。
|
|
71
|
+
- **完整重新生成并同步 `lib/`**(JS 与声明必须作为同一产物同步,禁止只复制单个 JS 文件):
|
|
72
|
+
```bash
|
|
73
|
+
DSH_CHECKOUT=/path/to/deepseek-harness npm run sync:dist
|
|
74
|
+
```
|
|
75
|
+
该命令在权威 checkout 中重建(`tsc` 生成声明 + `tsdown` 打包运行时),同步 `lib/index.js`、`lib/invariant.js`、`lib/types/*.d.ts`,生成 `dist-provenance.json`(记录权威 checkout 的真实 commit SHA 与工具链版本),并自动执行一致性校验;产物有变化时会提示提交。**完整构建一致性由本命令在发布流程中完成——发行镜像 CI 不会重新构建权威 monorepo。**
|
|
76
|
+
- **验证命令**(Linux / Windows 通用,跨平台进程调用见 `scripts/lib/run-command.mjs`):
|
|
77
|
+
```bash
|
|
78
|
+
npm run verify:dist # 静态一致性:src/d.ts 导出一致、关键签名、主入口运行时导出、无 source map、provenance 合法
|
|
79
|
+
npm run verify:pack # tarball 内容/版本、安装后 smoke(如实报告实际安装的依赖)
|
|
80
|
+
npm run test:consumer # NodeNext + skipLibCheck:false 的声明消费测试(对打包产物)
|
|
81
|
+
npm run test:regressions # 验证工具自身的回归测试(source map 策略、provenance、spawn 诊断)
|
|
82
|
+
```
|
|
83
|
+
- **CI 能力边界(如实)**:CI(ubuntu + windows 矩阵)执行上述静态验证与打包/消费测试,但**不重新构建权威 monorepo**;`verify:dist` 是导出表面/签名/运行时导出的一致性检查,**不是**与权威构建的字节级等价证明——后者由 `sync:dist` 在发布流程中保证。
|
|
84
|
+
- `dist-provenance.json` 随 npm 包发布,便于审计构建来源。
|
|
85
|
+
- 本机验证时若 `npm_execpath` 指向其他包管理器(如 pnpm/yarn shim),脚本会自动回退到 PATH 上的 `npm`;临时目录失败时保留需设 `PONYTAIL_VERIFY_KEEP_TEMP=1`。
|
|
67
86
|
|
|
68
87
|
## 许可
|
|
69
88
|
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"sourceRepository": "https://github.com/deepseek-ai/deepseek-harness.git",
|
|
3
|
+
"sourceCommit": "b150a551b8d465e31e418e1b2eaf5e79bbb7d28e",
|
|
4
|
+
"sourcePackage": "packages/community/ponytail",
|
|
5
|
+
"generatedBy": {
|
|
6
|
+
"node": "v24.16.0",
|
|
7
|
+
"typescript": "6.0.3",
|
|
8
|
+
"tsdown": "0.22.2"
|
|
9
|
+
}
|
|
10
|
+
}
|
package/lib/index.js
CHANGED
|
@@ -1713,7 +1713,7 @@ function errorMessage(error) {
|
|
|
1713
1713
|
* `skill` tool). `ponytail` is the source the system-prompt ruleset is
|
|
1714
1714
|
* filtered from; the other five ship verbatim as runtime skills.
|
|
1715
1715
|
*
|
|
1716
|
-
* @module @
|
|
1716
|
+
* @module @deepseek-ai/dsh-ponytail
|
|
1717
1717
|
*/
|
|
1718
1718
|
/** The always-on lazy-senior-dev ruleset: also registered as a loadable skill. */
|
|
1719
1719
|
const PONYTAIL_SKILL_BODY = `
|
|
@@ -2114,7 +2114,7 @@ function ponytailSkills() {
|
|
|
2114
2114
|
* level via the `/ponytail` command is session-scoped and lives in an
|
|
2115
2115
|
* in-memory, per-agent {@link ModeStore}.
|
|
2116
2116
|
*
|
|
2117
|
-
* @module @
|
|
2117
|
+
* @module @deepseek-ai/dsh-ponytail
|
|
2118
2118
|
*/
|
|
2119
2119
|
const DEFAULT_MODE = "full";
|
|
2120
2120
|
const RUNTIME_MODES = [
|
|
@@ -2309,7 +2309,7 @@ function isSubagentSession(header) {
|
|
|
2309
2309
|
* `hooks/ponytail-instructions.js`, so the injected text is byte-for-byte the
|
|
2310
2310
|
* same ruleset every other host emits, filtered to the active intensity.
|
|
2311
2311
|
*
|
|
2312
|
-
* @module @
|
|
2312
|
+
* @module @deepseek-ai/dsh-ponytail
|
|
2313
2313
|
*/
|
|
2314
2314
|
/**
|
|
2315
2315
|
* Keep a line of the skill body only when it belongs to every mode or to the
|
|
@@ -2373,7 +2373,7 @@ const instructionCache = /* @__PURE__ */ new Map();
|
|
|
2373
2373
|
* from `PONYTAIL_DEFAULT_MODE` then `~/.config/ponytail/config.json` (see
|
|
2374
2374
|
* {@link readDefaultMode}).
|
|
2375
2375
|
*
|
|
2376
|
-
* @module @
|
|
2376
|
+
* @module @deepseek-ai/dsh-ponytail
|
|
2377
2377
|
*/
|
|
2378
2378
|
const name = "ponytail";
|
|
2379
2379
|
const inject = ["systemPrompt", "skills"];
|
package/lib/invariant.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
//#region lib/types/invariant.js
|
|
2
2
|
/**
|
|
3
|
-
* Package-owned invariant companion for `@
|
|
4
|
-
* @module @
|
|
3
|
+
* Package-owned invariant companion for `@deepseek-ai/dsh-ponytail`.
|
|
4
|
+
* @module @deepseek-ai/dsh-ponytail/invariant
|
|
5
5
|
*/
|
|
6
|
-
const PACKAGE_NAME = "@
|
|
6
|
+
const PACKAGE_NAME = "@deepseek-ai/dsh-ponytail";
|
|
7
7
|
/** Cordis companion plugin name. */
|
|
8
8
|
const name = "ponytail-invariant";
|
|
9
9
|
/** Service required before the companion can reserve package ownership. */
|
package/lib/types/content.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* `skill` tool). `ponytail` is the source the system-prompt ruleset is
|
|
5
5
|
* filtered from; the other five ship verbatim as runtime skills.
|
|
6
6
|
*
|
|
7
|
-
* @module @
|
|
7
|
+
* @module @deepseek-ai/dsh-ponytail
|
|
8
8
|
*/
|
|
9
9
|
import type { SkillRegistration } from '@deepseek-ai/dsh-skill';
|
|
10
10
|
/** The always-on lazy-senior-dev ruleset: also registered as a loadable skill. */
|
|
@@ -18,8 +18,7 @@ export declare const DEBT_SKILL_BODY = "\nEvery deliberate ponytail shortcut is
|
|
|
18
18
|
export declare const DEBT_DESCRIPTION: string;
|
|
19
19
|
export declare const GAIN_SKILL_BODY = "\nDisplay this scoreboard when invoked. One-shot: do NOT change mode, write flag\nfiles, or persist anything.\n\nThe figures are the published benchmark medians (5 everyday tasks: email\nvalidator, debounce, CSV sum, countdown timer, rate limiter; three models:\nHaiku, Sonnet, Opus). They are measured, not computed from the current repo.\nSource: the upstream `benchmarks/` directory and README.\n\n## Scoreboard\n\nRender plain ASCII bars. The bar length shows the measured range; the label\ncarries the exact figure:\n\n```\n ponytail gain benchmark median \u00B7 5 tasks \u00B7 3 models\n\n Lines of code no-skill \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 100%\n ponytail \u2588\u2588\u258C\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7 6\u201320% \u25BC 80\u201394%\n Cost no-skill \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 100%\n ponytail \u2588\u2588\u2588\u2588\u2588\u258C\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7 23\u201353% \u25BC 47\u201377%\n Speed ponytail \u25B8 3\u20136\u00D7 faster\n\n This repo: /ponytail-debt (shortcuts you deferred)\n /ponytail-audit (what's still cuttable)\n```\n\n## Honesty boundary\n\nThese are benchmark medians, not this repo. NEVER print a per-repo savings\nnumber (\"you saved X lines/tokens here\"): the unbuilt version was never\nwritten, so there is no real baseline to subtract from in a live repo. The\nonly real per-repo figures come from `/ponytail-debt` (a counted ledger), and\nthis card points there instead of inventing one.\n\n## Boundaries\n\nOne-shot display. Edits nothing, changes no mode.\n\"stop ponytail\" or \"normal mode\": revert.\n";
|
|
20
20
|
export declare const GAIN_DESCRIPTION: string;
|
|
21
|
-
export declare const HELP_SKILL_BODY = "\nDisplay this reference card when invoked. One-shot, do NOT change mode,\nwrite flag files, or persist anything.\n\n## Levels\n\n| Level | Trigger | What change |\n|-------|---------|-------------|\n| **Lite** | `/ponytail lite` | Build what's asked, name the lazier alternative in one line. |\n| **Full** | `/ponytail` | The ladder enforced: YAGNI \u2192 stdlib \u2192 native \u2192 one line \u2192 minimum. Default. |\n| **Ultra** | `/ponytail ultra` | YAGNI extremist. Deletion before addition. Challenges requirements before building. |\n| **Off** | `/ponytail off` | Ponytail stops injecting its ruleset for this session. |\n\nLevel is session-scoped until changed.\n\n## Skills\n\n| Skill | Trigger | What it does |\n|-------|---------|--------------|\n| **ponytail** | `/ponytail` | Lazy mode itself. Simplest solution that works. |\n| **ponytail-review** | `/ponytail-review` | Over-engineering review: `L42: yagni: factory, one product. Inline.` |\n| **ponytail-audit** | `/ponytail-audit` | Whole-repo over-engineering audit: ranked list of what to delete. |\n| **ponytail-debt** | `/ponytail-debt` | Harvest `ponytail:` shortcut comments into a tracked ledger. |\n| **ponytail-gain** | `/ponytail-gain` | Measured-impact scoreboard: less code, less cost, more speed. |\n| **ponytail-help** | `/ponytail-help` | This card. |\n\nYou can also load any of these with the `skill` tool.\n\n## Deactivate\n\nSay \"stop ponytail\" or \"normal mode\". Resume anytime with `/ponytail
|
|
21
|
+
export declare const HELP_SKILL_BODY = "\nDisplay this reference card when invoked. One-shot, do NOT change mode,\nwrite flag files, or persist anything.\n\n## Levels\n\n| Level | Trigger | What change |\n|-------|---------|-------------|\n| **Lite** | `/ponytail lite` | Build what's asked, name the lazier alternative in one line. |\n| **Full** | `/ponytail` | The ladder enforced: YAGNI \u2192 stdlib \u2192 native \u2192 one line \u2192 minimum. Default. |\n| **Ultra** | `/ponytail ultra` | YAGNI extremist. Deletion before addition. Challenges requirements before building. |\n| **Off** | `/ponytail off` | Ponytail stops injecting its ruleset for this session. |\n\nLevel is session-scoped until changed.\n\n## Skills\n\n| Skill | Trigger | What it does |\n|-------|---------|--------------|\n| **ponytail** | `/ponytail` | Lazy mode itself. Simplest solution that works. |\n| **ponytail-review** | `/ponytail-review` | Over-engineering review: `L42: yagni: factory, one product. Inline.` |\n| **ponytail-audit** | `/ponytail-audit` | Whole-repo over-engineering audit: ranked list of what to delete. |\n| **ponytail-debt** | `/ponytail-debt` | Harvest `ponytail:` shortcut comments into a tracked ledger. |\n| **ponytail-gain** | `/ponytail-gain` | Measured-impact scoreboard: less code, less cost, more speed. |\n| **ponytail-help** | `/ponytail-help` | This card. |\n\nYou can also load any of these with the `skill` tool.\n\n## Deactivate\n\nSay \"stop ponytail\" or \"normal mode\". Resume anytime with `/ponytail` \u2014\nit re-enables at the effective default (or `full` when that is off too).\n`/ponytail status` only shows the current level, never changes it.\n`/ponytail off` also works. Level is session-scoped; a new session starts\nfrom the configured default.\n\n## Configure Default Mode\n\nDefault mode = `full`, auto-active every session. Change it:\n\n**Environment variable** (highest priority):\n```bash\nexport PONYTAIL_DEFAULT_MODE=ultra\n```\n\n**Config file** (`~/.config/ponytail/config.json`, Windows: `%APPDATA%\\ponytail\\config.json`):\n```json\n{ \"defaultMode\": \"lite\" }\n```\n\nSet `\"off\"` to disable auto-activation on session start, activate manually\nwith `/ponytail` when wanted. `/ponytail default <mode>` persists a new\ndefault to the config file; an exported `PONYTAIL_DEFAULT_MODE` still\noutranks the saved value for new sessions.\n\nResolution: env var > config file > `full`.\n\n## More\n\nFull docs + examples: https://github.com/DietrichGebert/ponytail\n";
|
|
22
22
|
export declare const HELP_DESCRIPTION: string;
|
|
23
23
|
/** Ordered set of runtime skills surfaced to the model catalog and `/` menu. */
|
|
24
24
|
export declare function ponytailSkills(): readonly SkillRegistration[];
|
|
25
|
-
//# sourceMappingURL=content.d.ts.map
|
package/lib/types/index.d.ts
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* from `PONYTAIL_DEFAULT_MODE` then `~/.config/ponytail/config.json` (see
|
|
11
11
|
* {@link readDefaultMode}).
|
|
12
12
|
*
|
|
13
|
-
* @module @
|
|
13
|
+
* @module @deepseek-ai/dsh-ponytail
|
|
14
14
|
*/
|
|
15
15
|
import type { Context } from '@deepseek-ai/cordis';
|
|
16
16
|
export declare const name = "ponytail";
|
|
@@ -34,4 +34,3 @@ export declare function containsDeactivation(messages: readonly {
|
|
|
34
34
|
* commands, and the plain-text deactivation listener.
|
|
35
35
|
*/
|
|
36
36
|
export declare function apply(ctx: Context): void;
|
|
37
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* `hooks/ponytail-instructions.js`, so the injected text is byte-for-byte the
|
|
4
4
|
* same ruleset every other host emits, filtered to the active intensity.
|
|
5
5
|
*
|
|
6
|
-
* @module @
|
|
6
|
+
* @module @deepseek-ai/dsh-ponytail
|
|
7
7
|
*/
|
|
8
8
|
import { type PonytailRuntimeMode } from './modes.ts';
|
|
9
9
|
/**
|
|
@@ -21,4 +21,3 @@ export declare function fallbackInstructions(mode: PonytailRuntimeMode): string;
|
|
|
21
21
|
* Returns an empty string for `off` (ponytail contributes nothing).
|
|
22
22
|
*/
|
|
23
23
|
export declare function getPonytailInstructions(mode: PonytailRuntimeMode | null | undefined): string;
|
|
24
|
-
//# sourceMappingURL=instructions.d.ts.map
|
package/lib/types/invariant.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Package-owned invariant companion for `@
|
|
3
|
-
* @module @
|
|
2
|
+
* Package-owned invariant companion for `@deepseek-ai/dsh-ponytail`.
|
|
3
|
+
* @module @deepseek-ai/dsh-ponytail/invariant
|
|
4
4
|
*/
|
|
5
5
|
import type { Context } from '@deepseek-ai/cordis';
|
|
6
6
|
/** Cordis companion plugin name. */
|
|
@@ -13,4 +13,3 @@ export declare const inject: string[];
|
|
|
13
13
|
* @returns the installed registration's disposer after setup succeeds.
|
|
14
14
|
*/
|
|
15
15
|
export declare const apply: (ctx: Context) => Promise<() => void>;
|
|
16
|
-
//# sourceMappingURL=invariant.d.ts.map
|
package/lib/types/modes.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* level via the `/ponytail` command is session-scoped and lives in an
|
|
6
6
|
* in-memory, per-agent {@link ModeStore}.
|
|
7
7
|
*
|
|
8
|
-
* @module @
|
|
8
|
+
* @module @deepseek-ai/dsh-ponytail
|
|
9
9
|
*/
|
|
10
10
|
/** One settable runtime intensity. `review` is command-only and never a default. */
|
|
11
11
|
export type PonytailRuntimeMode = 'off' | 'lite' | 'full' | 'ultra';
|
|
@@ -31,6 +31,28 @@ export declare function configPath(env?: NodeJS.ProcessEnv): string;
|
|
|
31
31
|
* then {@link DEFAULT_MODE}. Pure so callers can supply fixtures.
|
|
32
32
|
*/
|
|
33
33
|
export declare function resolveDefaultMode(envMode: unknown, configText: string | undefined): PonytailRuntimeMode;
|
|
34
|
+
/**
|
|
35
|
+
* One configuration problem worth surfacing exactly once. `read` covers
|
|
36
|
+
* permission/IO failures, `json` malformed documents, `shape` a root that is
|
|
37
|
+
* not an object, and `value` a `defaultMode` that is not a runtime level.
|
|
38
|
+
*/
|
|
39
|
+
export type DefaultModeIssueKind = 'read' | 'json' | 'shape' | 'value';
|
|
40
|
+
export interface DefaultModeIssue {
|
|
41
|
+
readonly kind: DefaultModeIssueKind;
|
|
42
|
+
readonly detail: string;
|
|
43
|
+
}
|
|
44
|
+
/** The resolved default plus the first config problem found, if any. */
|
|
45
|
+
export interface DefaultModeResolution {
|
|
46
|
+
readonly mode: PonytailRuntimeMode;
|
|
47
|
+
readonly issue?: DefaultModeIssue;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Read the configured default with diagnostics: environment variable first,
|
|
51
|
+
* then the config file, then `full`. A missing config file is normal and
|
|
52
|
+
* yields no issue; a broken one yields the fallback mode plus one issue for
|
|
53
|
+
* the caller to warn about once.
|
|
54
|
+
*/
|
|
55
|
+
export declare function readDefaultModeInfo(env?: NodeJS.ProcessEnv): DefaultModeResolution;
|
|
34
56
|
/**
|
|
35
57
|
* Read the configured default for this host: environment variable first, then
|
|
36
58
|
* the config file, then `full`.
|
|
@@ -39,6 +61,8 @@ export declare function readDefaultMode(env?: NodeJS.ProcessEnv): PonytailRuntim
|
|
|
39
61
|
/**
|
|
40
62
|
* Persist a new default level to the config file, preserving other fields.
|
|
41
63
|
* Returns the normalized mode, or `null` when the value is not a runtime mode.
|
|
64
|
+
* Throws when the write itself fails, so callers never report success for a
|
|
65
|
+
* file that was not written.
|
|
42
66
|
*/
|
|
43
67
|
export declare function writeDefaultMode(mode: unknown, env?: NodeJS.ProcessEnv): PonytailRuntimeMode | null;
|
|
44
68
|
/**
|
|
@@ -56,14 +80,26 @@ export declare class ModeStore {
|
|
|
56
80
|
clear(agentId: string): void;
|
|
57
81
|
}
|
|
58
82
|
/**
|
|
59
|
-
* Compile `PONYTAIL_SUBAGENT_MATCHER` into a case-insensitive regex
|
|
60
|
-
*
|
|
61
|
-
*
|
|
83
|
+
* Compile `PONYTAIL_SUBAGENT_MATCHER` into a case-insensitive regex. An unset
|
|
84
|
+
* matcher yields `null`; an invalid pattern stays fail-open (every agent gets
|
|
85
|
+
* the ruleset) but is reported so the caller can warn exactly once.
|
|
86
|
+
*/
|
|
87
|
+
export declare function compileSubagentMatcher(raw: string | undefined): {
|
|
88
|
+
matcher: RegExp | null;
|
|
89
|
+
invalid: boolean;
|
|
90
|
+
};
|
|
91
|
+
/**
|
|
92
|
+
* The stable per-session identity backing every mode override. DSH's `Agent`
|
|
93
|
+
* type documents `id` as "the single identity shared with session", so the
|
|
94
|
+
* agent id IS the SessionId: one entry per live session, never shared between
|
|
95
|
+
* two sessions, and stable across the session's lifetime. Centralized so the
|
|
96
|
+
* key choice lives in exactly one place.
|
|
62
97
|
*/
|
|
63
|
-
export declare function
|
|
98
|
+
export declare function sessionKey(agent: {
|
|
99
|
+
readonly id: string;
|
|
100
|
+
}): string;
|
|
64
101
|
/** Whether a session is a subagent child (origin, or any delegation depth with no origin). */
|
|
65
102
|
export declare function isSubagentSession(header: {
|
|
66
103
|
origin?: 'subagent';
|
|
67
104
|
delegationDepth?: number;
|
|
68
105
|
}): boolean;
|
|
69
|
-
//# sourceMappingURL=modes.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mengyuly/dsh-ponytail",
|
|
3
3
|
"description": "Lazy senior dev mode for DeepSeek Harness: always-on minimal-code ruleset, intensity switching, and short review/audit/debt/gain/help skills",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.5",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -25,6 +25,8 @@
|
|
|
25
25
|
"./package.json": "./package.json"
|
|
26
26
|
},
|
|
27
27
|
"files": [
|
|
28
|
+
"dist-provenance.json",
|
|
29
|
+
"CHANGELOG.md",
|
|
28
30
|
"lib/index.js",
|
|
29
31
|
"lib/invariant.js",
|
|
30
32
|
"lib/types/**/*.d.ts",
|
|
@@ -43,5 +45,12 @@
|
|
|
43
45
|
"@deepseek-ai/dsh-llm": ">=0.0.1-rc <2",
|
|
44
46
|
"@deepseek-ai/dsh-skill": ">=0.0.1-rc <2",
|
|
45
47
|
"@deepseek-ai/dsh-system-prompt": ">=0.0.1-rc <2"
|
|
48
|
+
},
|
|
49
|
+
"scripts": {
|
|
50
|
+
"sync:dist": "node scripts/sync-dist.mjs",
|
|
51
|
+
"verify:dist": "node scripts/verify-dist.mjs",
|
|
52
|
+
"verify:pack": "node scripts/verify-pack.mjs",
|
|
53
|
+
"test:consumer": "node scripts/test-consumer.mjs",
|
|
54
|
+
"test:regressions": "node scripts/test-regressions.mjs"
|
|
46
55
|
}
|
|
47
|
-
}
|
|
56
|
+
}
|