@njuptlzf/dsh-ponytail 1.1.0 → 1.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 (3) hide show
  1. package/README.md +4 -4
  2. package/index.js +23 -3
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -13,7 +13,7 @@ A [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) plugin tha
13
13
  ### What it does
14
14
 
15
15
  1. **Always-on section (lean)** — the compact ruleset (`.agents/rules/ponytail.md`, ~2.5 KB) as a system-prompt section, cached at `~/.dsh/ponytail-cache/compact.md`. Switch the level per session with `/ponytail lite|full|ultra|off`; `off` empties the section so the tokens are actually saved. Default `full`.
16
- 2. **On-demand skills** — the full ruleset (`ponytail`) and the 5 companions (`ponytail-help` / `ponytail-audit` / `ponytail-debt` / `ponytail-gain` / `ponytail-review`) written once to `~/.dsh/skills/<name>/SKILL.md`, invocable from the `/` palette.
16
+ 2. **On-demand skills (user-only)** — the full ruleset (`ponytail`) and the 5 companions (`ponytail-help` / `ponytail-audit` / `ponytail-debt` / `ponytail-gain` / `ponytail-review`) written once to `~/.dsh/skills/<name>/SKILL.md`, invocable from the `/` palette. Each file's frontmatter carries `disable-model-invocation: true`, so these skills stay **user-invocable** (shown in `/` with a "user only" tag) but are **not advertised to the model** — no `available_skills` catalog cost, no auto-load on "ANY coding task". The always-on compact section is the only model-facing copy.
17
17
 
18
18
  ### Install
19
19
 
@@ -29,7 +29,7 @@ Restart `dsh web` after install. The first boot fetches once and caches, so late
29
29
  ### Usage
30
30
 
31
31
  - `/ponytail` — report the current level; `/ponytail lite|full|ultra|off` — switch it. Mode is per-session (`agent.id`), so one conversation's `off` does not affect another.
32
- - The 6 skills stay in the `/` palette; name them (e.g. "audit for over-engineering") and the model loads them on its own.
32
+ - The 6 skills stay in the `/` palette, tagged "user only"; type `/` and pick one (e.g. `/ponytail-review`) to trigger it manually — the model never pulls them in unprompted.
33
33
 
34
34
  ### dsh-ponytail vs codex-ponytail
35
35
 
@@ -77,7 +77,7 @@ Skill content comes from [DietrichGebert/ponytail](https://github.com/DietrichGe
77
77
  ### 它做什么
78
78
 
79
79
  1. **常驻 section(精简)** — 精简规则(`.agents/rules/ponytail.md`,~2.5 KB)作为 system-prompt section,缓存于 `~/.dsh/ponytail-cache/compact.md`。用 `/ponytail lite|full|ultra|off` 按会话切档;`off` 会让 section 渲染为空、真的省回 token。默认 `full`。
80
- 2. **按需 skills** — 全文规则(`ponytail`)和 5 个同伴(`ponytail-help` / `ponytail-audit` / `ponytail-debt` / `ponytail-gain` / `ponytail-review`)写入 `~/.dsh/skills/<name>/SKILL.md`,`/` 面板可调。
80
+ 2. **按需 skills(仅用户可用)** — 全文规则(`ponytail`)和 5 个同伴(`ponytail-help` / `ponytail-audit` / `ponytail-debt` / `ponytail-gain` / `ponytail-review`)写入 `~/.dsh/skills/<name>/SKILL.md`,`/` 面板可调。每个 skill 的 frontmatter 都带 `disable-model-invocation: true`:技能保持**仅用户可调用**(在 `/` 里显示、带「仅用户可用」标签),但**不对模型公开**——不进 `available_skills` catalog、不会因描述写着 "ANY coding task" 被自动加载。常驻精简 section 是唯一面向模型的那一份。
81
81
 
82
82
  ### 安装
83
83
 
@@ -93,7 +93,7 @@ npx @deepseek-ai/dsh plugin --profile web add @njuptlzf/dsh-ponytail
93
93
  ### 使用
94
94
 
95
95
  - `/ponytail` — 报告当前档;`/ponytail lite|full|ultra|off` — 切档。档位按会话(`agent.id`)隔离,一个会话的 `off` 不影响其它会话。
96
- - 6 个技能常驻 `/` 面板;直接说「audit for over-engineering」等关键词,模型会按描述自行加载。
96
+ - 6 个技能常驻 `/` 面板、标「仅用户可用」;打 `/` 看候选、手工选一个(如 `/ponytail-review`)触发——模型不会未经请求就自动加载它们。
97
97
 
98
98
  ### dsh-ponytail vs codex-ponytail
99
99
 
package/index.js CHANGED
@@ -13,7 +13,10 @@
13
13
  *
14
14
  * Layer 2 — on-demand skills: the FULL ruleset
15
15
  * (skills/ponytail/SKILL.md) and the five companions, fetched once directly
16
- * into ~/.dsh/skills/<name>/SKILL.md, invocable from the "/" palette.
16
+ * into ~/.dsh/skills/<name>/SKILL.md. Manually triggered only: each file's
17
+ * frontmatter is marked user-only (disable-model-invocation), so it stays in
18
+ * the "/" palette but is never advertised to the model — no catalog cost,
19
+ * no auto-load. The always-on compact section is the sole model-facing copy.
17
20
  *
18
21
  * "只抓一次": fetch only when a disk copy is missing; a present copy is reused
19
22
  * forever. Delete a copy to force a refetch.
@@ -72,6 +75,14 @@ function saveFile(target, content) {
72
75
  }
73
76
  }
74
77
 
78
+ function disableModelInvocation(content) {
79
+ // Keep fetched skills user-only: present in the "/" palette (userInvocable)
80
+ // but absent from the model catalog / auto-load. Only touches skill files,
81
+ // which begin with a YAML frontmatter. Idempotent on repeated runs.
82
+ if (!/^---\r?\n/.test(content) || content.includes('disable-model-invocation:')) return content;
83
+ return content.replace(/^---\r?\n/, '---\ndisable-model-invocation: true\n');
84
+ }
85
+
75
86
  async function fetchUrl(rel) {
76
87
  try {
77
88
  var res = await fetch(RAW_BASE + rel);
@@ -129,9 +140,18 @@ export function apply(ctx) {
129
140
  var skills = [MAIN].concat(COMPANIONS);
130
141
  for (var i = 0; i < skills.length; i++) {
131
142
  var name = skills[i];
132
- if (existsSync(skillFile(name))) continue;
143
+ var file = skillFile(name);
144
+ if (existsSync(file)) {
145
+ // Idempotent policy normalize: existing files may predate the user-only
146
+ // flag — add it without re-fetching (keeps the offline, fetch-once promise).
147
+ var existing = readFileOrNull(file);
148
+ if (existing !== null && !existing.includes('disable-model-invocation:')) {
149
+ saveFile(file, disableModelInvocation(existing));
150
+ }
151
+ continue;
152
+ }
133
153
  var content = await fetchUrl('skills/' + name + '/SKILL.md');
134
- if (content !== null) { saveFile(skillFile(name), content); fetched += 1; }
154
+ if (content !== null) { saveFile(file, disableModelInvocation(content)); fetched += 1; }
135
155
  }
136
156
 
137
157
  console.log('[dsh-ponytail] ready: compact=' + (compactSpec !== '' ? 'ok' : 'MISSING') + ', skills fetched=' + fetched + ' (rest cached)');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@njuptlzf/dsh-ponytail",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "Ponytail (lazy-senior-dev) as a mode-switchable, always-on DSH plugin: injects the COMPACT ruleset every step (off empties it) and mirrors the full ruleset + five companions into ~/.dsh/skills. Attribution: github.com/DietrichGebert/ponytail (MIT).",
5
5
  "type": "module",
6
6
  "main": "index.js",