opencode-skills-doctor 0.6.0 → 0.6.2

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/README.md CHANGED
@@ -1,546 +1,138 @@
1
- # skills-doctor
1
+ <p align="center">
2
+ <img src="https://raw.githubusercontent.com/wangyuchen5110/opencodeplugginprogram/main/docs/assets/banner.svg" alt="skills-doctor — audit the hidden token cost of agent skills" width="100%">
3
+ </p>
2
4
 
3
- [![npm](https://img.shields.io/npm/v/opencode-skills-doctor)](https://www.npmjs.com/package/opencode-skills-doctor)
4
- [![downloads](https://img.shields.io/npm/dw/opencode-skills-doctor)](https://www.npmjs.com/package/opencode-skills-doctor)
5
- [![node](https://img.shields.io/node/v/opencode-skills-doctor)](https://www.npmjs.com/package/opencode-skills-doctor)
6
- [![license](https://img.shields.io/npm/l/opencode-skills-doctor)](LICENSE)
7
- [![test](https://github.com/wangyuchen5110/opencodeplugginprogram/actions/workflows/test.yml/badge.svg)](https://github.com/wangyuchen5110/opencodeplugginprogram/actions/workflows/test.yml)
5
+ <p align="center">
6
+ <a href="https://www.npmjs.com/package/opencode-skills-doctor"><img src="https://img.shields.io/npm/v/opencode-skills-doctor?style=flat-square&color=3fb950" alt="npm version"></a>
7
+ <a href="https://www.npmjs.com/package/opencode-skills-doctor"><img src="https://img.shields.io/npm/dw/opencode-skills-doctor?style=flat-square" alt="npm downloads"></a>
8
+ <a href="https://github.com/wangyuchen5110/opencodeplugginprogram/stargazers"><img src="https://img.shields.io/github/stars/wangyuchen5110/opencodeplugginprogram?style=flat-square&color=58a6ff" alt="GitHub stars"></a>
9
+ <img src="https://img.shields.io/badge/node-%E2%89%A520-3fb950?style=flat-square" alt="Node ≥ 20">
10
+ <a href="LICENSE"><img src="https://img.shields.io/npm/l/opencode-skills-doctor?style=flat-square" alt="MIT license"></a>
11
+ <a href="https://github.com/wangyuchen5110/opencodeplugginprogram/actions/workflows/test.yml"><img src="https://github.com/wangyuchen5110/opencodeplugginprogram/actions/workflows/test.yml/badge.svg?style=flat-square" alt="tests"></a>
12
+ </p>
8
13
 
9
- Local scanner, linter, fixer, updater and **OpenCode plugin** for agent skills — zero dependencies, Node ≥ 20.
14
+ <p align="center">
15
+ <b>Audit, fix and update the skills your coding agent loads.</b><br>
16
+ Measure the per-step token tax, find shadowed duplicates and broken references — then fix them safely.
17
+ </p>
10
18
 
11
- **English** | [简体中文](docs/README.zh-CN.md) · [Changelog](CHANGELOG.md) · [Security](SECURITY.md)
19
+ <p align="center">
20
+ English · <a href="docs/README.zh-CN.md">简体中文</a> · <a href="CHANGELOG.md">Changelog</a> · <a href="SECURITY.md">Security</a> · <a href="docs/REFERENCE.md">Full reference</a>
21
+ </p>
12
22
 
13
- ## At a glance
23
+ ---
14
24
 
15
- | | |
16
- |---|---|
17
- | **What it is** | Audit, fix and update the skills your coding agent loads |
18
- | **Interfaces** | CLI · OpenCode plugin (1.x / 2.x) · MCP server (Claude Code, Codex, DSH, …) · Grok CLI compatible |
19
- | **Skill sources** | `.opencode/skills`, `.claude/skills`, `.agents/skills`, `.grok/skills`, `.cursor/skills`, `opencode.json(c)` entries, HTTP catalogs |
20
- | **What it finds** | shadowed IDs, duplicates, long descriptions, oversized bodies, per-step token budget, broken file references, invalid frontmatter, empty bodies, stale skills |
21
- | **What it fixes** | archives shadowed definitions (reversible), hides low-frequency skills, syncs catalogs with drift detection |
22
- | **Reports** | terminal, JSON, or a self-contained HTML report (`--html [file] --open`) |
23
- | **Plan** | exact token savings: trim descriptions and/or hide skills, projected over N steps |
24
- | **Cost** | CLI: 0 tokens. Plugin: ~191 tokens/step for the tool definition, plus a one-time warning per session |
25
- | **Requirements** | Node ≥ 20, zero runtime dependencies |
26
- | **Quality** | 57 tests, CI on ubuntu/macos/windows × Node 20/22/24 |
27
-
28
- ## Why
25
+ ## The 30-second version
29
26
 
30
- On every model step, OpenCode advertises every skill that has a `description` — the model sees `ID + name + description` for each of them. Skills are not free: they are a permanent context tax on every request.
27
+ Every agent skill with a `description` is advertised to the model on **every single step**. On a machine with 29 skills that is **~3,074 tokens per step** — before the model reads a line of your code. Duplicates silently shadow each other, descriptions drift, and references to files that no longer exist go unnoticed.
31
28
 
32
- **What this costs.** 29 skills with long descriptions ≈ **3,000+ tokens every step**. Over a 100-step session that is ~300k tokens of pure overhead — spent before the model reads a single line of your code. And that is only 29 skills: many users have far more they downloaded without noticing, some already out of date. This tool helps you understand your skill repository much better.
29
+ `skills-doctor` measures that cost, shows which definition actually wins, and fixes it:
33
30
 
34
- **What can go wrong.** As skills pile up:
35
- - duplicate IDs silently shadow each other — you may be editing a file that never loads;
36
- - descriptions drift until the model picks the wrong skill;
37
- - half the catalog is dead weight nobody noticed.
31
+ | | |
32
+ |---|---|
33
+ | **Find** | token budget, shadowed duplicates, flat/dir collisions, long descriptions, oversized bodies, broken references, invalid frontmatter, stale skills |
34
+ | **Fix** | archive shadowed definitions (reversible), hide low-frequency skills, trim descriptions with a measured plan |
35
+ | **Update** | sync skills from HTTP catalogs with a lockfile, drift detection and `--prune` |
36
+ | **Report** | terminal, JSON, or a self-contained HTML report |
37
+ | **Run it** | CLI · OpenCode plugin (1.x/2.x/Desktop) · MCP server · DeepSeek Harness skill |
38
38
 
39
- **What `skills-doctor` does.** It measures the cost, shows which definition actually wins, and fixes it:
39
+ ## See it
40
40
 
41
- - `check` — report duplicates/shadowing, long descriptions, oversized bodies and the per-step token budget, with fix hints;
42
- - `scan` — list every skill with its source, precedence and cost;
43
- - `fix` — archive shadowed duplicates (reversible) or hide low-frequency skills (`autoinvoke: false`, still loadable with `@id`);
44
- - `update` — sync skills from HTTP catalogs by version, with a lockfile and drift detection;
45
- - plugin — expose the audit as a `skills_doctor` tool / `/skills-doctor` command inside OpenCode.
41
+ <p align="center">
42
+ <img src="https://raw.githubusercontent.com/wangyuchen5110/opencodeplugginprogram/main/docs/assets/report.png" alt="skills-doctor HTML report" width="82%">
43
+ </p>
46
44
 
47
- Works as a CLI and a plugin on **OpenCode 1.x and 2.x**.
45
+ A real `check --html` run: summary cards, the context-budget bar, filterable findings, and the exact potential savings.
48
46
 
49
47
  ## Quick start
50
48
 
51
49
  ```powershell
52
- # Run straight from the repo (no install)
53
- node bin/skills-doctor.mjs check
54
-
55
- # Or install it locally
56
- npm link
57
- skills-doctor check
58
- ```
59
-
60
- What a run looks like:
61
-
62
- ```text
63
- skills-doctor 0.4.1
64
- sources: 5 (2 exist) definitions: 29 unique IDs: 29 advertised: 29 description budget: ~3074 tokens
65
-
66
- [E] token-budget Advertised skill descriptions cost about 3074 tokens per model step, over 2x the 1200 budget
67
- [W] long-description "deep-research" description is 917 chars; it is paid on every model step
68
- [W] large-body "academic-paper" body is about 9980 tokens; invoking it pastes the whole body into context
69
- ...
70
-
71
- 1 error, 18 warn, 0 info
72
-
73
- Hints:
74
- - Trim descriptions, or hide low-frequency skills with metadata.opencode/autoinvoke: false.
75
- - Move details into references/ and keep SKILL.md to the workflow.
76
- ```
77
-
78
- ## Commands
79
-
80
- All commands accept `--lang en|zh` (default: auto from the system locale) and `--json`.
81
-
82
- ### `check` (default)
83
-
84
- Scans every skill source, reports problems, the context budget and fix hints.
85
-
86
- ```powershell
87
- skills-doctor check
88
- skills-doctor check --json
89
- skills-doctor check --budget 800 --strict # for CI
90
- skills-doctor check --root .\some-project --no-global
91
- skills-doctor check --html report.html # self-contained HTML report
92
- skills-doctor check --html report.html --open
93
- ```
94
-
95
- ### HTML report
96
-
97
- `--html [file]` writes a single self-contained HTML file (no external assets):
98
-
99
- - summary cards and a context-budget bar;
100
- - findings filterable by severity and text;
101
- - a skill table with scope, token cost, description preview and file path;
102
- - default path `./skills-report.html` when `--html` is given without a value; `--open` launches the browser.
103
-
104
- The plugin and MCP tool accept the same thing as an `html` argument, so the agent can ask you where to save it — for example: *"save the report to D:\reports\skills.html"*.
105
-
106
- ### `plan` (how many tokens can I actually save?)
107
-
108
- ```powershell
109
- skills-doctor plan
110
- skills-doctor plan --budget 800 --desc-target 160 --steps 200
111
- skills-doctor plan --json
112
- ```
113
-
114
- It answers "how much can I cut, exactly?":
115
-
116
- - only **advertised** definitions cost tokens — archiving shadowed duplicates saves 0, and the plan says so instead of pretending;
117
- - **Option A** trims every description longer than `--desc-target` (default 160 chars, cut at sentence boundaries) and computes the exact saving;
118
- - **Option B** hides the fewest skills needed to reach the budget (still loadable with `@id`; picking the largest savings first is optimal for "minimal hides");
119
- - **Recommended** trims first, then hides, with no double counting, and projects the saving over `--steps` model steps (default 100).
120
-
121
- `check` prints a one-line pointer when you are over budget, and the HTML report shows the same potential-savings card.
122
-
123
- ### `scan`
124
-
125
- Lists every skill with its source, precedence, whether the model can see it, and token cost.
126
-
127
- ```powershell
128
- skills-doctor scan
129
- ```
130
-
131
- `*` marks the definition that actually wins (later registration = higher precedence).
132
-
133
- ### `fix`
134
-
135
- Archives definitions that are shadowed — files that never load because another source defines the same ID. The move is reversible: files go into `.skills-doctor-archive/<timestamp>/` inside the same source, which OpenCode ignores (dot-directory).
136
-
137
- ```powershell
138
- skills-doctor fix --dry-run # preview what would be archived
139
- skills-doctor fix
140
- skills-doctor fix --hide academic-paper,deep-research --dry-run # hide low-frequency skills
141
- ```
142
-
143
- - Only shadowed duplicates are touched; the effective definition is never moved;
144
- - Files installed by `update` are skipped — use `update` to bring them back;
145
- - Default scope is project-only; pass `--all` to also archive global sources;
146
- - After fixing, `check` should report no `shadowed` findings.
147
-
148
- ### `update` (updater)
149
-
150
- Reads HTTP catalogs from the `skills` array in `opencode.json(c)`, compares `version`, and downloads whatever changed.
151
-
152
- ```powershell
153
- skills-doctor update # installs into .opencode/skills by default (where opencode reads)
154
- skills-doctor update --check-only # only report available updates
155
- skills-doctor update --into .\team-skills
156
- ```
157
-
158
- - The output directory is a real OpenCode skill directory, so **`check` picks the update up immediately**;
159
- - Overwrites files in place and **deletes files that the new version no longer lists** (no stale leftovers from the old version);
160
- - Writes `.skills-doctor.lock.json` (schema v2: a sha1 for every file);
161
- - `check` reads that lock: shows managed versions, detects hand edits (`managed-drift`) and missing files (`managed-missing`);
162
- - Running `update` again re-downloads drifted files (self-healing);
163
- - Use `--prune` to delete skills that disappeared from the catalog (by default they are reported but kept).
164
-
165
- ## Does the plugin cost tokens?
166
-
167
- Local execution is free, but any tool registered with the model is visible on every request. Measured on this repo:
168
-
169
- | Component | Tokens | When |
170
- |---|---|---|
171
- | Scan / lint / fix / update (local work) | **0** | always |
172
- | `skills_doctor` tool definition | **~191** | every request |
173
- | Budget warning injected into the system prompt | **~60–80** | once per session, only when over budget |
174
- | Audit report returned by the tool | **~940** | only when the tool is actually called |
175
-
176
- So the plugin trades a small fixed overhead for the agent being able to audit by itself. In the example above the skill descriptions cost 3,074 tokens per step; dropping that to the 1,200 budget saves more than 10× the plugin overhead. If you want **zero** context cost, don't install the plugin — run `npx opencode-skills-doctor check` from the terminal or CI instead.
177
-
178
- ## Self-update
179
-
180
- `skills-doctor` checks npm for a newer version of itself at most once per 24 hours (skipped in CI, non-TTY and `--json` runs):
181
-
182
- ```powershell
183
- skills-doctor upgrade # check now
184
- skills-doctor upgrade --open # check and open the GitHub release page
185
- skills-doctor upgrade --apply # npm install -g opencode-skills-doctor@latest
186
- ```
187
-
188
- Opt out permanently in `.skills-doctor.json`:
189
-
190
- ```json
191
- { "checkUpdates": "off" }
192
- ```
193
-
194
- | Value | Behavior |
195
- |---|---|
196
- | `"notify"` (default) | print a one-line notice when a newer version exists |
197
- | `"open"` | same, plus opens the release page in the browser |
198
- | `"off"` | never check |
199
-
200
- Per run: `--no-update-check`. Per environment: `SKILLS_DOCTOR_UPDATE_CHECK=0`. The plugin injects the same notice into the system prompt once per session when an update exists. Cached state lives in `~/.skills-doctor/self-update.json`.
201
-
202
- ## Configuration
203
-
204
- Optional `.skills-doctor.json` in the working directory (or pass `--config <file>`):
205
-
206
- ```json
207
- {
208
- "budget": 1200,
209
- "staleDays": 180,
210
- "lang": "en",
211
- "checkUpdates": "notify",
212
- "rules": { "long-description": "off", "hidden-skill": "info" },
213
- "ignore": ["legacy-skill"]
214
- }
215
- ```
216
-
217
- `rules` accepts `off`, `info`, `warn` or `error`; `ignore` drops findings that only involve those IDs; `checkUpdates` is `notify` / `open` / `off`. CLI flags override the file.
218
-
219
- ## OpenCode plugin
220
-
221
- The package also exports an OpenCode 2.x plugin:
222
-
223
- ```jsonc
224
- // opencode.jsonc
225
- {
226
- "plugins": ["opencode-skills-doctor"]
227
- }
228
- ```
229
-
230
- It registers:
231
-
232
- - the `skills_doctor` tool (namespace `skills`) — the agent can audit with `{ directory?, budget?, html? }` and gets a markdown report;
233
- - the `/skills-doctor` command — asks the agent to run the audit and summarize fixes;
234
- - `/skills-report` — asks where to save an HTML report, then writes it;
235
- - `/skills-upgrade` — checks whether skills-doctor itself has a newer version.
236
-
237
- `@opencode/plugin` is an optional peer dependency; OpenCode provides it at runtime.
238
-
239
- ### OpenCode 1.x
50
+ # terminal report
51
+ npx -y opencode-skills-doctor check
240
52
 
241
- 1.x uses a different plugin API: it resolves the `./server` export for npm plugins and needs `@opencode-ai/plugin` at runtime. The reliable setup is a one-line local plugin file.
53
+ # how many tokens can I actually cut?
54
+ npx -y opencode-skills-doctor plan
242
55
 
243
- 1. Install the package where OpenCode resolves plugins:
244
-
245
- ```powershell
246
- npm i --prefix ~/.config/opencode opencode-skills-doctor
56
+ # shareable HTML report
57
+ npx -y opencode-skills-doctor check --html report.html --open
247
58
  ```
248
59
 
249
- 2. Create `~/.config/opencode/plugins/skills-doctor.js`:
250
-
251
- ```js
252
- export { SkillsDoctorPlugin } from "opencode-skills-doctor/v1"
253
- ```
60
+ Example `plan` output on a real setup:
254
61
 
255
- 3. Reference it from `opencode.json` (1.x uses `plugin`, not `plugins`):
62
+ ```text
63
+ current: ~3,124 tokens/step (30 advertised) budget: 1,200
256
64
 
257
- ```jsonc
258
- {
259
- "plugin": ["C:\\Users\\<you>\\.config\\opencode\\plugins\\skills-doctor.js"]
260
- }
65
+ Option A — trim descriptions 26 skills → 1,606 (−1,518)
66
+ Option B — hide skills 11 skills → 1,200 (−1,924)
67
+ Recommended trim 26 + hide 2 → 1,184 (−1,940)
68
+ over 100 steps that saves ~194,000 tokens
261
69
  ```
262
70
 
263
- It registers the same `skills_doctor` tool. 1.x plugins cannot register commands, so `skills-doctor install` writes a `/skills-doctor` markdown command.
264
-
265
- > The package root entry is the V2 plugin and requires OpenCode 2.x. The CLI works on both lines.
266
-
267
- ### OpenCode Desktop
268
-
269
- The desktop app bundles the same OpenCode core and reads the **same config directory** as the CLI (`~/.config/opencode`; its UI settings live elsewhere), so one install covers both:
71
+ ## Install
270
72
 
271
73
  ```powershell
272
- npx opencode-skills-doctor install --client desktop
273
- ```
274
-
275
- - detects the app in the standard install locations and reads its bundled core version from `resources/app.asar` (e.g. 1.17.11), then uses the matching plugin API;
276
- - writes the same plugin entry and `/skills-doctor`, `/skills-report`, `/skills-upgrade` commands as the CLI install — restart the desktop app afterwards;
277
- - `--client auto` (default) prefers the CLI version when both are installed; `--client opencode` skips desktop detection;
278
- - `uninstall --client desktop` reverses it.
279
-
280
- Verified on Windows: app at `%LOCALAPPDATA%\Programs\@opencode-aidesktop\OpenCode.exe`, sharing config with the `opencode` CLI.
74
+ # OpenCode — plugin + /skills-doctor, /skills-report, /skills-upgrade commands
75
+ npx -y opencode-skills-doctor install # auto-detects 1.x / 2.x / Desktop
76
+ npx -y opencode-skills-doctor install --client desktop
281
77
 
282
- ### Deep integration (one command)
283
-
284
- ```powershell
285
- npx opencode-skills-doctor install
78
+ # DeepSeek Harness — MCP tool + audit skill, one command
79
+ npx -y opencode-skills-doctor install --client dsh
286
80
  ```
287
81
 
288
- The installer detects your OpenCode version and wires everything up:
289
-
290
- - **2.x** — adds `"plugins": ["opencode-skills-doctor"]` to `opencode.json(c)`;
291
- - **1.x** — installs the package into `~/.config/opencode`, writes the local plugin entry, generates `/skills-doctor`, `/skills-report` and `/skills-upgrade` markdown commands, sets `"type": "module"`;
292
- - backs up the config file as `<config>.bak-<timestamp>` before editing.
293
-
294
- Use `--dry-run` to preview, `--config-dir <dir>` for a custom config location, and `--no-npm` to skip the package install.
295
-
296
- Once installed you get:
297
-
298
- - the `skills_doctor` tool (with an optional `html` argument to write a report to a path you choose);
299
- - the `/skills-doctor` command (1.x: generated markdown command; 2.x: plugin command);
300
- - the `/skills-report` command (2.x) that asks where to save the HTML report;
301
- - the `/skills-upgrade` command (2.x) that checks for a newer skills-doctor;
302
- - a one-time system-prompt warning when the skill description budget is exceeded.
303
-
304
- ### Uninstall
82
+ **Claude Code, Codex, Grok or any MCP client** — register the server once:
305
83
 
306
84
  ```powershell
307
- npx opencode-skills-doctor uninstall
85
+ npx -y opencode-skills-doctor mcp
308
86
  ```
309
87
 
310
- - **2.x** — removes `opencode-skills-doctor` from `plugins`;
311
- - **1.x** — removes the config entry, deletes the generated plugin entry and `/skills-doctor` command, and uninstalls the package (`--no-npm` skips that);
312
- - only files generated by the installer are deleted — anything you edited is kept and reported;
313
- - config files are backed up before editing; `--dry-run` previews, `--config-dir` targets a custom location.
314
-
315
- Your data is never touched: `.skills-doctor.json`, `.skills-doctor.lock.json` and `.skills-doctor-archive/` stay until you delete them. MCP entries in other clients (Claude Code, Codex, DSH) are per-client configs and must be removed there.
316
-
317
- ## MCP server (Claude Code, Codex, Kimi Code, any MCP client)
318
-
319
- `skills-doctor mcp` speaks the Model Context Protocol over stdio and exposes one tool: `skills_doctor` with arguments `directory?`, `budget?`, `lang?` and `global?`. It does not need OpenCode installed.
320
-
321
- Claude Code (`.mcp.json` in the project, or your MCP config):
322
-
323
88
  ```json
324
- {
325
- "mcpServers": {
326
- "skills-doctor": { "command": "npx", "args": ["-y", "opencode-skills-doctor", "mcp"] }
327
- }
328
- }
329
- ```
330
-
331
- Codex (`~/.codex/config.toml`):
332
-
333
- ```toml
334
- [mcp_servers.skills-doctor]
335
- command = "npx"
336
- args = ["-y", "opencode-skills-doctor", "mcp"]
337
- ```
338
-
339
- Any other MCP client: run `npx -y opencode-skills-doctor mcp` and allow the `skills_doctor` tool.
340
-
341
- It scans `.opencode/skills`, `.claude/skills` and `.agents/skills` (project and global), so it can audit skills used by other agents too.
342
-
343
- ### DeepSeek Harness (DSH)
344
-
345
- One command installs both the MCP tool and a skill that tells the model when to audit:
346
-
347
- ```powershell
348
- npx -y opencode-skills-doctor install --client dsh
349
- ```
350
-
351
- It locates `~/.dsh/profiles/<profile>/cordis.patch.yml` (default `desktop`; otherwise `--profile <name>`), appends the `mcp-skills-doctor` entry idempotently, and copies the `skills-doctor-audit` skill into `~/.dsh/skills/`. Restart DSH to load the MCP tool; the skill is watched and appears without a restart.
352
-
353
- - tool name `mcp__skills_doctor__skills_doctor`, arguments `directory`, `budget`, `lang`, `global`, `html`;
354
- - `uninstall --client dsh` removes both the patch entry and the skill;
355
- - `--dsh-home <dir>` for a non-standard DSH home.
356
-
357
- Manual fallback — add this to the profile patch yourself:
358
-
359
- ```yaml
360
- - id: mcp-skills-doctor
361
- name: "@deepseek-ai/dsh-mcp-client"
362
- config:
363
- serverName: skills_doctor
364
- transport: stdio
365
- command: npx
366
- args: ["-y", "opencode-skills-doctor", "mcp"]
89
+ { "mcpServers": { "skills-doctor": { "command": "npx", "args": ["-y", "opencode-skills-doctor", "mcp"] } } }
367
90
  ```
368
91
 
369
- On Windows, if the stdio spawn cannot resolve `npx`, use `command: cmd` and `args: ["/c", "npx", "-y", "opencode-skills-doctor", "mcp"]`.
370
-
371
- ## How it works
92
+ Nothing to configure for **skills discovery**: it reads `.opencode/skills`, `.claude/skills`, `.agents/skills`, `.grok/skills`, `.cursor/skills` and their user-level equivalents. See the [full reference](docs/REFERENCE.md) for OpenCode 1.x, DSH YAML, Codex TOML and Claude Code details.
372
93
 
373
- **Audit pipeline**
374
-
375
- 1. Discover every skill source (see the precedence list below).
376
- 2. Parse each `SKILL.md` / flat `.md` frontmatter and estimate its description/body cost.
377
- 3. Resolve which definition wins for each ID (later registration wins; `SKILL.md` directory form wins ties).
378
- 4. Run the rules, compute the per-step token budget, and emit findings with fix hints.
379
-
380
- **Fix pipeline**
381
-
382
- `fix` only touches definitions that are shadowed (never loaded): it moves them into `.skills-doctor-archive/<timestamp>/` inside the same source. The effective definition is never moved, and files managed by `update` are skipped. Scope defaults to the project; `--all` extends it to global sources.
383
-
384
- **Update pipeline**
385
-
386
- 1. Fetch `<catalog>/index.json` (3 attempts with backoff on 5xx/network errors).
387
- 2. Compare each skill's `version` with the lockfile.
388
- 3. Download changed files (same-origin only, path traversal blocked) and write them atomically.
389
- 4. Delete files the new version no longer lists, and clean empty directories.
390
- 5. Verify hashes, write the lockfile, and — with `--prune` — delete skills removed from the catalog.
391
-
392
- `check` reads the lockfile and reports drift (`managed-drift`), missing files (`managed-missing`) and unknown lock versions (`lock-version-unsupported`). Re-running `update` re-downloads drifted files.
393
-
394
- ### Grok CLI
395
-
396
- Grok discovers skills from `.grok/skills` (project, repo and `~/.grok/skills`), plus `.claude/skills`, `.cursor/skills` and `.agents/skills`. `skills-doctor` scans exactly the same locations, so:
397
-
398
- ```powershell
399
- skills-doctor check --root . # covers your Grok project skills
400
- skills-doctor check --root $HOME # covers ~/.grok/skills and other user-level skills
401
- ```
402
-
403
- No install step is needed — Grok loads `SKILL.md` packages natively. If your Grok build has MCP enabled, you can additionally register the MCP server above to let the model call `skills_doctor` itself.
404
-
405
- ## Rules
406
-
407
- | Rule | Level | Meaning |
408
- |---|---|---|
409
- | `shadowed` | warn | Same ID defined in multiple sources; only one wins, the rest is dead weight and easy to edit by mistake |
410
- | `flat-dir-collision` | warn | Both `<id>.md` and `<id>/SKILL.md` exist in the same source |
411
- | `duplicate-content` | warn | Two skills share identical body text |
412
- | `near-duplicate-description` | warn | Descriptions are ≥ 75% similar; the model may pick the wrong one |
413
- | `missing-description` | info | No description, so the model never discovers it |
414
- | `long-description` | warn | Description > 240 chars (paid on every model step) |
415
- | `large-body` | warn | Body > 4000 tokens (pasted into context when invoked) |
416
- | `token-budget` | warn/error | Total advertised description tokens exceed the budget (default 1200) |
417
- | `too-many-skills` | warn/error | More than 60 / 100 skills are advertised |
418
- | `invalid-id` | info | ID is not kebab-case |
419
- | `hidden-skill` | info | Hidden via `opencode/autoinvoke: false` or `disable-model-invocation: true` |
420
- | `stale-skill` | info | Not updated within `--stale-days` |
421
- | `broken-reference` | warn | `references/`, `scripts/`, `assets/`, `templates/` or `examples/` path does not exist |
422
- | `reference-outside-skill` | info | A referenced file lives outside the skill directory (hurts portability) |
423
- | `invalid-frontmatter` | warn | Unclosed `---` fence, or non-string name/description / non-object metadata |
424
- | `empty-body` | info | Body is nearly empty, so the skill carries no instructions |
425
- | `managed-drift` | warn | A file installed by `update` was modified afterwards |
426
- | `managed-missing` | warn | Recorded in the lock, but the local file is gone |
427
- | `managed-unsafe` | warn | Path traversal or another unsafe path in the lock |
428
- | `lock-version-unsupported` | info | Lock is newer than this tool; parsed in compatibility mode |
429
-
430
- ## Forward compatibility
431
-
432
- - **Lock**: supports v1 (string versions, no hashes) and v2 (per-file sha1). A newer lock version is parsed in compatibility mode, unknown fields are ignored, and a single `lock-version-unsupported` notice is emitted.
433
- - **Catalog `index.json`**: only `skills[].name/version/files` is read; any future fields are ignored.
434
- - **Skill frontmatter**: only `name`, `description`, `metadata.opencode/autoinvoke` and `disable-model-invocation` are read; everything else is ignored.
435
- - **Paths**: both OpenCode 2.0 locations (`.opencode/skills`, `~/.config/opencode/skills`) and compatibility locations (`.claude/skills`, `.agents/skills`, searched upward level by level).
436
- - The updater always writes the highest lock version this tool supports, so older readers never break on new fields.
437
-
438
- ## Discovery sources (low → high precedence)
439
-
440
- 1. `~/.claude/skills`
441
- 2. project `.claude/skills` (from the project root up to the current directory)
442
- 3. `~/.agents/skills`
443
- 4. project `.agents/skills`
444
- 5. `~/.cursor/skills`
445
- 6. project `.cursor/skills`
446
- 7. `~/.grok/skills`
447
- 8. project `.grok/skills`
448
- 9. `~/.config/opencode/skills`
449
- 10. project `.opencode/skills`
450
- 11. the `skills` array in `opencode.json(c)` (2.x) or `skills.paths` (1.x); relative paths resolve from the working directory; supports `~/`, absolute paths and HTTP catalogs
451
-
452
- ## JSON output
453
-
454
- `check --json`, `scan --json` and `update --json` all print structured JSON, ready for CI or a web report. Fields include `summary`, `findings[]` and `skills[]` (with `managed: { version, url, root }`).
455
-
456
- ## Security
457
-
458
- This tool reads and writes skill files. Before using it against a real setup:
459
-
460
- - `update` downloads catalog content **without signature verification** — treat catalogs as code;
461
- - `fix` / `--prune` move or delete files — preview with `--dry-run` first;
462
- - it is **not a sandbox** and does not constrain what an agent can do.
463
-
464
- See [SECURITY.md](SECURITY.md) for the full threat model, hardening checklist and private vulnerability reporting.
465
-
466
- ## Caveats and known limitations
467
-
468
- **Install / plugin**
469
-
470
- - OpenCode **2.x**: add `"plugins": ["opencode-skills-doctor"]` to `opencode.jsonc` — done.
471
- - OpenCode **1.x**: needs `npm i --prefix ~/.config/opencode opencode-skills-doctor` plus a one-line local plugin file (`export { SkillsDoctorPlugin } from "opencode-skills-doctor/v1"`), because 1.x resolves plugins differently and `@opencode-ai/plugin` is an optional peer.
472
- - 1.x has no plugin-registered `/skills-doctor` command; `skills-doctor install` writes a markdown command file instead.
473
-
474
- **Safety / behavior**
475
-
476
- - `fix` defaults to **project-only**; pass `--all` to touch global sources. Archived files go to `.skills-doctor-archive/<timestamp>/` (reversible; originals are moved, not deleted).
477
- - `fix` only touches **shadowed** definitions. It never edits the effective skill and never rewrites descriptions or bodies.
478
- - `fix --hide` only adds `metadata.opencode/autoinvoke: false`; the skill stays loadable with `@id`.
479
- - Shadowing follows OpenCode's precedence: later registration wins; on a tie, the `SKILL.md` directory form wins. If the runtime disagrees, trust the runtime.
480
- - This is **not** a security sandbox: it audits configuration and files, it does not constrain what the agent can do.
481
-
482
- **Measurement**
483
-
484
- - The default `budget` (1200 tokens) is a recommendation, not a hard limit. Tune it with `.skills-doctor.json` or `--budget`.
485
- - Token counts are heuristic (CJK ≈ 1.7 chars/token, the rest ≈ 4 chars/token) — good for comparisons, not for billing.
486
- - `check` is offline; ask a catalog for new versions with `update --check-only`.
487
- - Config precedence is assumed: global config < project config < `skills` array order.
488
-
489
- ## FAQ and troubleshooting
490
-
491
- **A skill I created does not appear.**
492
- Check: does the file have a `description`? Is it hidden via `opencode/autoinvoke: false` or `disable-model-invocation`? Is the ID derived from the path (directory name for `SKILL.md`, filename for flat `.md`)? Is an earlier/later source shadowing it? `skills-doctor scan` shows the winning definition for each ID.
493
-
494
- **`fix` did nothing.**
495
- `fix` only archives **shadowed** duplicates and defaults to project-only. Run `skills-doctor fix --dry-run` to see what it would do, and `--all` to include global sources. Content issues (long descriptions, large bodies) are reported, not rewritten.
496
-
497
- **`check` says the budget is exceeded but the agent feels fine.**
498
- The token numbers are heuristics, and the 1,200-token budget is a recommendation. Tune it with `--budget` or `.skills-doctor.json`; treat the report as a relative comparison, not billing.
94
+ ## Commands
499
95
 
500
- **Where did `fix` move my files?**
501
- Into `.skills-doctor-archive/<timestamp>/` inside the same skill source. Move them back to restore.
96
+ | Command | What it does |
97
+ |---|---|
98
+ | `check` | audit sources, conflicts, budget and broken references (default) |
99
+ | `plan` | exact token savings: what to trim, what to hide, projected over N steps |
100
+ | `scan` | every skill with its source, precedence and cost |
101
+ | `fix` | archive shadowed definitions (reversible) or hide low-frequency skills |
102
+ | `update` | sync skills from HTTP catalogs, verify hashes, detect drift |
103
+ | `install` / `uninstall` | wire into OpenCode (1.x/2.x/Desktop) or DeepSeek Harness |
104
+ | `upgrade` | check for / apply a newer skills-doctor itself |
105
+ | `mcp` | run as an MCP server |
502
106
 
503
- **Does it update skills automatically in the background?**
504
- No daemon. Run `skills-doctor update` when you want to sync; use `--check-only` to just list available updates.
107
+ All commands accept `--json`, `--lang en|zh`, `--budget`, `--root` and `--no-global`. Full flags, rules and configuration live in the [reference](docs/REFERENCE.md).
505
108
 
506
- **Does it work on OpenCode 1.x?**
507
- Yes — the CLI works on both lines, and `skills-doctor install` wires up the 1.x plugin (local plugin entry + generated command). 1.x has no `/skills-doctor` command registration from plugins, so the installer writes a command file instead.
109
+ ## Works where you work
508
110
 
509
- **Why does the plugin cost tokens if it runs locally?**
510
- Executing code is free, but the tool definition is part of the model's context. That is why the CLI mode exists: zero context cost.
111
+ | Agent | How |
112
+ |---|---|
113
+ | **OpenCode 2.x** | `plugins: ["opencode-skills-doctor"]` → tool + commands + budget warning |
114
+ | **OpenCode 1.x** | `install` writes the local plugin entry and markdown commands |
115
+ | **OpenCode Desktop** | shares the CLI config; `--client desktop` detects the app and its bundled core |
116
+ | **DeepSeek Harness** | `install --client dsh` adds the MCP entry and the `skills-doctor-audit` skill |
117
+ | **Claude Code / Codex** | MCP server (`npx -y opencode-skills-doctor mcp`) |
118
+ | **Grok CLI / Cursor** | their skill roots are scanned natively |
511
119
 
512
- ## Roadmap
120
+ ## Why it is safe
513
121
 
514
- - v0.6: CI governance (baseline that only reports new issues, official GitHub Action), content-aware suggestions (which skills are never used), catalog signature verification
515
- - Later: V1/Claude skill migration report
122
+ - `fix` only archives **shadowed** definitions, moving them into `.skills-doctor-archive/<timestamp>/` — reversible, and the effective skill is never touched.
123
+ - `plan` is pure math: no LLM calls, no network, no file changes.
124
+ - `update` blocks path traversal, writes atomically, verifies sha1 and detects drift.
125
+ - It is **not** a sandbox; read [SECURITY.md](SECURITY.md) before pointing it at a real setup.
516
126
 
517
- ## Development and contributing
127
+ ## Development
518
128
 
519
129
  ```powershell
520
- npm test # 57 tests (node test/doctor.test.mjs)
130
+ npm test # 58 tests (node test/doctor.test.mjs)
521
131
  npm run bench # lint timing for 100/500/1000 skills
522
132
  ```
523
133
 
524
- - CI runs on ubuntu/macos/windows × Node 20/22/24; `prepublishOnly` re-runs the tests before every publish.
525
- - Issues and PRs are welcome: for behavior changes, open an issue first with the scenario and expected output. Link the issue in the PR.
526
- - Keep the CLI dependency-free and the output bilingual (`--lang en|zh`) — both are project invariants.
527
- - Security reports: see [SECURITY.md](SECURITY.md); do not open a public issue for vulnerabilities.
528
- - Release notes live in [CHANGELOG.md](CHANGELOG.md).
134
+ CI runs ubuntu/macos/windows × Node 20/22/24; `prepublishOnly` re-runs the tests. Issues and PRs are welcome — see the [reference](docs/REFERENCE.md).
529
135
 
530
- ### Project layout
531
-
532
- | Path | Purpose |
533
- |---|---|
534
- | `src/audit.mjs` | one-call audit used by CLI, plugin and MCP |
535
- | `src/discover.mjs` | source discovery, precedence, JSONC parsing |
536
- | `src/lint.mjs` | rules, token budget, near-duplicate detection |
537
- | `src/fix.mjs` | archive / hide |
538
- | `src/catalog.mjs` | updater, lockfile, retries, atomic writes |
539
- | `src/managed.mjs` | lock verification and drift detection |
540
- | `src/cli.mjs` | command dispatch and output |
541
- | `src/i18n.mjs` | English/Chinese strings |
542
- | `src/mcp.mjs` | MCP stdio server |
543
- | `src/plugin.mjs` / `src/plugin-v1.mjs` | OpenCode 2.x / 1.x entries |
544
- | `src/install.mjs` | one-command OpenCode integration |
136
+ [Full reference](docs/REFERENCE.md) · [中文 README](docs/README.zh-CN.md) · [Changelog](CHANGELOG.md) · [Security](SECURITY.md)
545
137
 
546
138
  MIT