skills-manager-cli 2026.10.26 → 2026.10.27
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 +41 -1
- package/README.zh-CN.md +41 -1
- package/dist/cli/bootstrap.js +5 -0
- package/dist/cli/bootstrap.js.map +1 -1
- package/dist/cli/cost-output.js +3 -2
- package/dist/cli/cost-output.js.map +1 -1
- package/dist/cli/doctor-output.js +29 -0
- package/dist/cli/doctor-output.js.map +1 -0
- package/dist/cli/main.js +207 -17
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/sync-output.js +31 -0
- package/dist/cli/sync-output.js.map +1 -0
- package/dist/core/services/description-lint.js +68 -0
- package/dist/core/services/description-lint.js.map +1 -0
- package/dist/core/services/description-overlap.js +87 -0
- package/dist/core/services/description-overlap.js.map +1 -0
- package/dist/core/services/doctor-service.js +12 -1
- package/dist/core/services/doctor-service.js.map +1 -1
- package/dist/core/services/index.js +5 -3
- package/dist/core/services/index.js.map +1 -1
- package/dist/core/services/security-scan.js +61 -0
- package/dist/core/services/security-scan.js.map +1 -1
- package/dist/core/services/sync-service.js +1 -1
- package/dist/core/services/sync-service.js.map +1 -1
- package/docs/CLI.md +84 -7
- package/package.json +1 -1
- package/skills/skills-manager/SKILL.md +23 -10
package/README.md
CHANGED
|
@@ -46,7 +46,7 @@ npx skills-manager-cli
|
|
|
46
46
|
|
|
47
47
|

|
|
48
48
|
|
|
49
|
-
*`--help` and the resident context-cost ledger (`cost`) in action.*
|
|
49
|
+
*`--help` and the resident context-cost ledger (`cost`) in action. After bootstrap, try `cost --share` and `doctor` — both are printed as pasteable demos.*
|
|
50
50
|
|
|
51
51
|
That is the whole setup. Bootstrap creates the skill hub (`~/.skills-manager`), installs the **manager skill** into it from the bundled copy, and mounts it (symlink) into the agents it detects on your machine — you confirm the list in the one prompt it shows.
|
|
52
52
|
|
|
@@ -70,8 +70,41 @@ npx skills-manager-cli # bootstrap the hub + manager skill
|
|
|
70
70
|
skills-manager init --dry-run # preview importing existing runtime skills
|
|
71
71
|
# or ask your agent: Import my existing skills into skills-manager
|
|
72
72
|
skills-manager cost --share # privacy-safe paste card of your resident skill tax
|
|
73
|
+
skills-manager doctor --share # privacy-safe hub health card (counts only)
|
|
74
|
+
skills-manager update --check # freshness vs skill subtree tree-SHA (git) — no cry-wolf
|
|
75
|
+
skills-manager audit security --strict # CI gate: fail only on high-severity findings
|
|
76
|
+
skills-manager audit overlap # which skills compete for the same request (wrong-skill triggers)
|
|
77
|
+
skills-manager audit descriptions # descriptions that will never trigger (no "use when", vague, too long)
|
|
78
|
+
skills-manager sync init --remote <url> # multi-machine hub git sync (unique vs installers)
|
|
79
|
+
skills-manager sync status --share # privacy-safe paste card of sync posture
|
|
73
80
|
```
|
|
74
81
|
|
|
82
|
+
`cost --share` prints a paste-ready card (no absolute paths). Example shape:
|
|
83
|
+
|
|
84
|
+
```text
|
|
85
|
+
Resident skill tax · char-approx · skills-manager
|
|
86
|
+
≈1.2k tokens / message · 12 skill(s) · 2 path(s)
|
|
87
|
+
Paths: user/claude-code+zed · project/cursor
|
|
88
|
+
Heaviest: big-skill ≈400 · mid ≈200 · small ≈80
|
|
89
|
+
Try: npx skills-manager-cli
|
|
90
|
+
Reproduce: skills-manager cost --share
|
|
91
|
+
https://github.com/shenysun/skills-manager
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**CI?** Drop [`examples/github-actions/audit-security.yml`](examples/github-actions/audit-security.yml) into `.github/workflows/` on a hub repo (`skills/` + `registry.yaml`). It runs `audit security --strict --format github` on PR/push — fails only on high-severity findings, and annotates the PR Files tab.
|
|
95
|
+
|
|
96
|
+
Every gate exits 1 on failure and writes its verdict to stderr, so stdout (text/JSON) stays stable:
|
|
97
|
+
|
|
98
|
+
| Gate | Command | Fails when | Network |
|
|
99
|
+
| --- | --- | --- | --- |
|
|
100
|
+
| Security | `audit security --strict` | any high-severity finding | no |
|
|
101
|
+
| Provenance | `provenance list --fail-on-imported` | an imported skill has no usable source (can't get updates) | no |
|
|
102
|
+
| Resident cost | `cost --budget <tokens>` | total resident tokens exceed the budget | no |
|
|
103
|
+
| Freshness | `update --check --fail-on-stale` | any skill is stale, or a check fails | yes (`GH_TOKEN` helps) |
|
|
104
|
+
| **All of the above** | `check [--budget <tokens>] [--freshness]` | any enabled gate fails (security + provenance always; budget/freshness opt-in) — copy [`examples/github-actions/hub-check.yml`](examples/github-actions/hub-check.yml) | only with `--freshness` |
|
|
105
|
+
|
|
106
|
+
Details: [docs/CLI.md](docs/CLI.md).
|
|
107
|
+
|
|
75
108
|
Runtime copies become hub-backed; originals are backed up first.
|
|
76
109
|
|
|
77
110
|
## How it works
|
|
@@ -132,10 +165,12 @@ Skill home resolution priority:
|
|
|
132
165
|
npx skills-manager-cli # bootstrap (default when no subcommand)
|
|
133
166
|
skills-manager bootstrap --agent claude-code # scripted bootstrap / mount later
|
|
134
167
|
skills-manager doctor
|
|
168
|
+
skills-manager doctor --share # privacy-safe hub health paste card
|
|
135
169
|
skills-manager list
|
|
136
170
|
skills-manager add owner/repo --all --yes
|
|
137
171
|
skills-manager distribute --to user --skill my-skill --agent claude-code
|
|
138
172
|
skills-manager update --plan
|
|
173
|
+
skills-manager update --check # tree-SHA freshness (git/marketplace)
|
|
139
174
|
skills-manager update --skill my-skill
|
|
140
175
|
skills-manager init --dry-run # preview runtime-skill import
|
|
141
176
|
skills-manager init --prefer claude-code hub # this-run conflict priority
|
|
@@ -144,11 +179,16 @@ skills-manager backup list # inspect init backups
|
|
|
144
179
|
skills-manager backup restore my-skill # roll one import back
|
|
145
180
|
skills-manager edit my-skill --source-git owner/repo --subpath skills/my-skill
|
|
146
181
|
skills-manager provenance list # skills still missing a source
|
|
182
|
+
skills-manager provenance list --fail-on-imported # fail (exit 1) when any imported skill still lacks a source
|
|
147
183
|
skills-manager provenance adopt # backfill lockfile evidence
|
|
148
184
|
skills-manager categories set my-skill frontend # tag with a domain category
|
|
149
185
|
skills-manager categories apply frontend -a claude-code # load only that domain
|
|
150
186
|
skills-manager categories status # applied sets + drift
|
|
151
187
|
skills-manager cost # resident context-cost ledger (report-only recall suggestions)
|
|
188
|
+
skills-manager cost --budget 2000 # fail (exit 1) when resident context tax exceeds a token budget
|
|
189
|
+
skills-manager sync init --remote <url> # multi-machine hub git sync
|
|
190
|
+
skills-manager sync status --share # privacy-safe paste card of sync posture
|
|
191
|
+
skills-manager update --check --fail-on-stale # fail (exit 1) when any hub skill is stale vs upstream tree-SHA
|
|
152
192
|
skills-manager archive old-skill
|
|
153
193
|
```
|
|
154
194
|
|
package/README.zh-CN.md
CHANGED
|
@@ -46,7 +46,7 @@ npx skills-manager-cli
|
|
|
46
46
|
|
|
47
47
|

|
|
48
48
|
|
|
49
|
-
*演示:`--help` 与常驻上下文成本账本(`cost
|
|
49
|
+
*演示:`--help` 与常驻上下文成本账本(`cost`)。bootstrap 结束后还会打印可粘贴的 `cost --share` 与 `doctor` demo。*
|
|
50
50
|
|
|
51
51
|
这就是全部的安装步骤。bootstrap 会创建技能库(`~/.skills-manager`),从包内副本把 **manager skill** 种进库,并(以软链接)挂载到它检测到的 agent——展示一次多选让你确认清单。
|
|
52
52
|
|
|
@@ -70,8 +70,41 @@ npx skills-manager-cli # 引导创建 hub + manager skill
|
|
|
70
70
|
skills-manager init --dry-run # 预览导入现有运行时 skill
|
|
71
71
|
# 或对 agent 说:把我现有的 skills 导入 skills-manager
|
|
72
72
|
skills-manager cost --share # 可粘贴分享的常驻 skill 税卡片(无绝对路径)
|
|
73
|
+
skills-manager doctor --share # 可粘贴的 hub 健康卡片(仅计数,无路径/技能名)
|
|
74
|
+
skills-manager update --check # 新鲜度:skill 子目录 tree-SHA(git)——不上游无关提交的狼来了
|
|
75
|
+
skills-manager audit security --strict # CI 闸:仅 high 严重度发现时失败
|
|
76
|
+
skills-manager audit overlap # 哪些 skill 在抢同一个请求(误触发错的 skill)
|
|
77
|
+
skills-manager audit descriptions # 永远不会被触发的 description(缺「何时用」、太含糊、太长)
|
|
78
|
+
skills-manager sync init --remote <url> # 多机 hub git 同步(相对安装器的差异化)
|
|
79
|
+
skills-manager sync status --share # 可粘贴分享的同步姿态卡片(无 hub 路径 / remote URL)
|
|
73
80
|
```
|
|
74
81
|
|
|
82
|
+
`cost --share` 输出可直接粘贴的卡片(不含绝对路径)。示例形状:
|
|
83
|
+
|
|
84
|
+
```text
|
|
85
|
+
Resident skill tax · char-approx · skills-manager
|
|
86
|
+
≈1.2k tokens / message · 12 skill(s) · 2 path(s)
|
|
87
|
+
Paths: user/claude-code+zed · project/cursor
|
|
88
|
+
Heaviest: big-skill ≈400 · mid ≈200 · small ≈80
|
|
89
|
+
Try: npx skills-manager-cli
|
|
90
|
+
Reproduce: skills-manager cost --share
|
|
91
|
+
https://github.com/shenysun/skills-manager
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**上 CI?** 把 [`examples/github-actions/audit-security.yml`](examples/github-actions/audit-security.yml) 拷进 hub 仓库的 `.github/workflows/`(仓库根需是 `skills/` + `registry.yaml`)。PR/push 时跑 `audit security --strict --format github`——仅 high 严重度发现会失败,并在 PR Files 页打注解。
|
|
95
|
+
|
|
96
|
+
每个闸失败即退出 1,结论写 stderr,stdout(文本/JSON)保持稳定:
|
|
97
|
+
|
|
98
|
+
| 闸 | 命令 | 何时失败 | 联网 |
|
|
99
|
+
| --- | --- | --- | --- |
|
|
100
|
+
| 安全 | `audit security --strict` | 存在 high 严重度发现 | 否 |
|
|
101
|
+
| 来源 | `provenance list --fail-on-imported` | 有导入 skill 缺可用来源(拿不到更新) | 否 |
|
|
102
|
+
| 常驻成本 | `cost --budget <tokens>` | 常驻总 token 超出预算 | 否 |
|
|
103
|
+
| 新鲜度 | `update --check --fail-on-stale` | 任一 skill 过期,或检测失败 | 是(建议设 `GH_TOKEN`) |
|
|
104
|
+
| **以上全部** | `check [--budget <tokens>] [--freshness]` | 任一启用的闸失败(安全 + 来源必跑;预算/新鲜度按需开启)——可直接拷贝 [`examples/github-actions/hub-check.yml`](examples/github-actions/hub-check.yml) | 仅 `--freshness` 时 |
|
|
105
|
+
|
|
106
|
+
详见 [docs/CLI.zh-CN.md](docs/CLI.zh-CN.md)。
|
|
107
|
+
|
|
75
108
|
运行时副本改为由 hub 托管;原文件会先备份。
|
|
76
109
|
|
|
77
110
|
## 工作原理
|
|
@@ -132,10 +165,12 @@ apply 是显式的、可逆的快照:缺的分发、集合外(含未打标
|
|
|
132
165
|
npx skills-manager-cli # bootstrap(不带子命令时的默认行为)
|
|
133
166
|
skills-manager bootstrap --agent claude-code # 脚本化 bootstrap / 之后再挂载
|
|
134
167
|
skills-manager doctor
|
|
168
|
+
skills-manager doctor --share # 可粘贴的 hub 健康卡片(仅计数)
|
|
135
169
|
skills-manager list
|
|
136
170
|
skills-manager add owner/repo --all --yes
|
|
137
171
|
skills-manager distribute --to user --skill my-skill --agent claude-code
|
|
138
172
|
skills-manager update --plan
|
|
173
|
+
skills-manager update --check # tree-SHA 新鲜度(git/marketplace)
|
|
139
174
|
skills-manager update --skill my-skill
|
|
140
175
|
skills-manager init --dry-run # 预览运行时技能导入
|
|
141
176
|
skills-manager init --prefer claude-code hub # 本次导入的冲突优先级
|
|
@@ -144,11 +179,16 @@ skills-manager backup list # 查看 init 备份
|
|
|
144
179
|
skills-manager backup restore my-skill # 回滚某次导入
|
|
145
180
|
skills-manager edit my-skill --source-git owner/repo --subpath skills/my-skill
|
|
146
181
|
skills-manager provenance list # 仍缺来源的技能清单
|
|
182
|
+
skills-manager provenance list --fail-on-imported # 仍有「导入却无来源」的 skill 时失败(exit 1)
|
|
147
183
|
skills-manager provenance adopt # 补采锁文件证据
|
|
148
184
|
skills-manager categories set my-skill 前端 # 打领域类别标签
|
|
149
185
|
skills-manager categories apply 前端 -a claude-code # 只加载该领域
|
|
150
186
|
skills-manager categories status # 已应用集合 + 漂移
|
|
151
187
|
skills-manager cost # 常驻上下文成本账本(只报告不执行的收回建议)
|
|
188
|
+
skills-manager cost --budget 2000 # 常驻上下文税超出 token 预算时失败(exit 1)
|
|
189
|
+
skills-manager sync init --remote <url> # 多机 hub git 同步
|
|
190
|
+
skills-manager sync status --share # 可粘贴分享的同步姿态卡片
|
|
191
|
+
skills-manager update --check --fail-on-stale # 任一 hub skill 相对上游树 SHA 过期时失败(exit 1)
|
|
152
192
|
skills-manager archive old-skill
|
|
153
193
|
```
|
|
154
194
|
|
package/dist/cli/bootstrap.js
CHANGED
|
@@ -67,6 +67,11 @@ export async function runBootstrap(opts, cmd) {
|
|
|
67
67
|
console.log('\nAll set. Go back to your agent and say:');
|
|
68
68
|
console.log(` “${STARTER_PROMPT_ZH}”`);
|
|
69
69
|
console.log(` (“${STARTER_PROMPT_EN}”)`);
|
|
70
|
+
// Growth wedge: surface the pasteable demos that land after the next npm cut
|
|
71
|
+
// (cost --share + doctor already ships security.high / residentCost rollups).
|
|
72
|
+
console.log('\nAlso try (CLI demos — paste anywhere):');
|
|
73
|
+
console.log(' skills-manager cost --share # privacy-safe resident skill tax card');
|
|
74
|
+
console.log(' skills-manager doctor # health + security.high + residentCost');
|
|
70
75
|
}
|
|
71
76
|
/** `--agent` wins; one detected agent needs no question; several get the picker in a TTY, all of them otherwise. */
|
|
72
77
|
async function chooseAgents(opts, detected, resolveGlobalDir) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../../src/cli/bootstrap.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../../src/cli/bootstrap.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/cost-output.js
CHANGED
|
@@ -68,7 +68,7 @@ export function renderPresetCostLine(cost) {
|
|
|
68
68
|
/**
|
|
69
69
|
* Privacy-safe paste card for `skills-manager cost --share` (growth wedge):
|
|
70
70
|
* no absolute paths, agent-family labels only, top skills by total tokens,
|
|
71
|
-
*
|
|
71
|
+
* Try/Reproduce CTA + repo URL (not a circular "Share: cost --share"). Same ledger, thinner surface.
|
|
72
72
|
*/
|
|
73
73
|
export function renderCostShare(ledger) {
|
|
74
74
|
const skillTotals = new Map();
|
|
@@ -105,7 +105,8 @@ export function renderCostShare(ledger) {
|
|
|
105
105
|
}
|
|
106
106
|
if (ledger.unmanaged > 0)
|
|
107
107
|
lines.push(`${ledger.unmanaged} unmanaged skill(s) not counted`);
|
|
108
|
-
lines.push('
|
|
108
|
+
lines.push('Try: npx skills-manager-cli');
|
|
109
|
+
lines.push('Reproduce: skills-manager cost --share');
|
|
109
110
|
lines.push('https://github.com/shenysun/skills-manager');
|
|
110
111
|
return `${lines.join('\n')}\n`;
|
|
111
112
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cost-output.js","sourceRoot":"","sources":["../../src/cli/cost-output.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"cost-output.js","sourceRoot":"","sources":["../../src/cli/cost-output.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAwC,MAAM,yCAAyC,CAAC;AAEnH;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAkB;IACjD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,0BAA0B,MAAM,CAAC,MAAM,aAAa,kBAAkB,CAAC,MAAM,CAAC,WAAW,CAAC,kBAAkB,MAAM,CAAC,KAAK,CAAC,MAAM,kBAAkB,CAAC,CAAC;IAC9J,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;QAC1E,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,UAAU,KAAK,KAAK,CAAC,IAAI,aAAa,MAAM,OAAO,kBAAkB,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC3G,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;QAC5E,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;YAChC,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACrH,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC9G,CAAC;IACH,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,SAAS,iCAAiC,CAAC,CAAC;IACjE,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7B,KAAK,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;QACrC,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM;YAAE,KAAK,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,KAAK,MAAM,KAAK,CAAC,WAAW,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IAC5G,CAAC;IAED,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;IACvC,MAAM,KAAK,GAAG,WAAW,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,IAAI,WAAW,CAAC,eAAe,CAAC,MAAM,KAAK,CAAC,IAAI,WAAW,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,CAAC;IAClI,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,kDAAkD,CAAC,CAAC;IAC/D,IAAI,KAAK,EAAE,CAAC;QACV,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACrB,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;IACjC,CAAC;IACD,IAAI,WAAW,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpC,KAAK,CAAC,IAAI,CAAC,4DAA4D,CAAC,CAAC;QACzE,KAAK,MAAM,IAAI,IAAI,WAAW,CAAC,QAAQ,EAAE,CAAC;YACxC,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,eAAe,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;YACjG,KAAK,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IACD,IAAI,WAAW,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3C,MAAM,KAAK,GAAG,WAAW,CAAC,eAAe,CAAC,MAAM,CAAC;QACjD,KAAK,CAAC,IAAI,CAAC,OAAO,KAAK,8BAA8B,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;QAChF,KAAK,MAAM,IAAI,IAAI,WAAW,CAAC,eAAe,EAAE,CAAC;YAC/C,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,IAAI,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;YACtF,KAAK,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IACD,IAAI,WAAW,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrC,KAAK,CAAC,IAAI,CAAC,+FAA+F,CAAC,CAAC;QAC5G,KAAK,MAAM,IAAI,IAAI,WAAW,CAAC,SAAS,EAAE,CAAC;YACzC,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,WAAW,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAClG,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ;gBAAE,KAAK,CAAC,IAAI,CAAC,OAAO,OAAO,EAAE,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;IACD,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;AACjC,CAAC;AAED;;oBAEoB;AACpB,MAAM,UAAU,oBAAoB,CAAC,IAAoB;IACvD,OAAO,kBAAkB,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,wBAAwB,IAAI,CAAC,MAAM,GAAG,CAAC;AACjG,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,MAAkB;IAChD,MAAM,WAAW,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC9C,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjC,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;YAChC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;QAChF,CAAC;IACH,CAAC;IACD,MAAM,UAAU,GAAG,WAAW,CAAC,IAAI,CAAC;IACpC,MAAM,QAAQ,GAAG,CAAC,GAAG,WAAW,CAAC,OAAO,EAAE,CAAC;SACxC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;SACvD,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;SACX,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,IAAI,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAEtE,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QAC1C,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;QACzE,OAAO,GAAG,KAAK,CAAC,IAAI,IAAI,MAAM,EAAE,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,wBAAwB,MAAM,CAAC,MAAM,mBAAmB,CAAC,CAAC;IACrE,KAAK,CAAC,IAAI,CAAC,GAAG,kBAAkB,CAAC,MAAM,CAAC,WAAW,CAAC,uBAAuB,UAAU,eAAe,MAAM,CAAC,KAAK,CAAC,MAAM,UAAU,CAAC,CAAC;IACnI,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,UAAU,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACtE,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,aAAa,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACzE,MAAM,QAAQ,GAAG,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC;IACpD,MAAM,SAAS,GAAG,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,MAAM,CAAC;IACtD,IAAI,QAAQ,GAAG,CAAC,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;QAClC,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,IAAI,QAAQ,GAAG,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,GAAG,QAAQ,6BAA6B,CAAC,CAAC;QACvE,IAAI,SAAS,GAAG,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,GAAG,SAAS,YAAY,CAAC,CAAC;QACxD,KAAK,CAAC,IAAI,CAAC,UAAU,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC5C,CAAC;IACD,IAAI,MAAM,CAAC,SAAS,GAAG,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,SAAS,iCAAiC,CAAC,CAAC;IAC3F,KAAK,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;IAC1C,KAAK,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC;IACrD,KAAK,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAC;IACzD,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;AACjC,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { formatApproxTokens } from '../core/services/cost-ledger-service.js';
|
|
2
|
+
/**
|
|
3
|
+
* Privacy-safe paste card for `skills-manager doctor --share` (growth wedge):
|
|
4
|
+
* counts and magnitudes only — never skillHome, broken-link paths, skill names,
|
|
5
|
+
* or warning text that may embed absolute paths. Try/Reproduce CTA + repo URL.
|
|
6
|
+
*/
|
|
7
|
+
export function renderDoctorShare(report) {
|
|
8
|
+
const cost = report.residentCost;
|
|
9
|
+
const dist = report.distribution;
|
|
10
|
+
const lines = [];
|
|
11
|
+
lines.push('Hub health · skills-manager');
|
|
12
|
+
lines.push(`${report.skillCount} skill(s) · managed ${dist.managedEntries} · outdated ${dist.outdated} · foreign ${dist.foreign}`);
|
|
13
|
+
lines.push(`Resident: ${formatApproxTokens(cost.totalTokens)} tokens / message · ${cost.method}`);
|
|
14
|
+
const scattered = cost.suggestions.scattered.length;
|
|
15
|
+
if (scattered > 0)
|
|
16
|
+
lines.push(`Watch: ${scattered} scattered`);
|
|
17
|
+
lines.push(`Security: ${report.security.high} high · ${report.security.scanner} · scanned ${report.security.scanned}`);
|
|
18
|
+
lines.push(report.warnings.length === 0 ? 'Warnings: none' : `Warnings: ${report.warnings.length}`);
|
|
19
|
+
if (report.brokenLinks.length > 0)
|
|
20
|
+
lines.push(`Broken links: ${report.brokenLinks.length}`);
|
|
21
|
+
if (report.importedWithoutSource.length > 0) {
|
|
22
|
+
lines.push(`Imported without source: ${report.importedWithoutSource.length}`);
|
|
23
|
+
}
|
|
24
|
+
lines.push('Try: npx skills-manager-cli');
|
|
25
|
+
lines.push('Reproduce: skills-manager doctor --share');
|
|
26
|
+
lines.push('https://github.com/shenysun/skills-manager');
|
|
27
|
+
return `${lines.join('\n')}\n`;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=doctor-output.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor-output.js","sourceRoot":"","sources":["../../src/cli/doctor-output.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAG7E;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAoB;IACpD,MAAM,IAAI,GAAG,MAAM,CAAC,YAAY,CAAC;IACjC,MAAM,IAAI,GAAG,MAAM,CAAC,YAAY,CAAC;IACjC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;IAC1C,KAAK,CAAC,IAAI,CACR,GAAG,MAAM,CAAC,UAAU,uBAAuB,IAAI,CAAC,cAAc,eAAe,IAAI,CAAC,QAAQ,cAAc,IAAI,CAAC,OAAO,EAAE,CACvH,CAAC;IACF,KAAK,CAAC,IAAI,CAAC,aAAa,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,uBAAuB,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IAClG,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,MAAM,CAAC;IACpD,IAAI,SAAS,GAAG,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,UAAU,SAAS,YAAY,CAAC,CAAC;IAC/D,KAAK,CAAC,IAAI,CACR,aAAa,MAAM,CAAC,QAAQ,CAAC,IAAI,WAAW,MAAM,CAAC,QAAQ,CAAC,OAAO,cAAc,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,CAC3G,CAAC;IACF,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,aAAa,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IACpG,IAAI,MAAM,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,iBAAiB,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC;IAC5F,IAAI,MAAM,CAAC,qBAAqB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5C,KAAK,CAAC,IAAI,CAAC,4BAA4B,MAAM,CAAC,qBAAqB,CAAC,MAAM,EAAE,CAAC,CAAC;IAChF,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;IAC1C,KAAK,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAC;IACvD,KAAK,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAC;IACzD,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;AACjC,CAAC"}
|
package/dist/cli/main.js
CHANGED
|
@@ -5,6 +5,8 @@ import { createRuntimeServices, projectRootFromImportMeta } from '../infra/runti
|
|
|
5
5
|
import { isInsecureHttpSource, normalizeGitSourceUrl } from '../core/services/source-service.js';
|
|
6
6
|
import { isUpdatableSourceType } from '../core/services/update-service.js';
|
|
7
7
|
import { parseFormatFlag } from '../core/services/url-payload.js';
|
|
8
|
+
import { findDescriptionOverlaps, renderOverlapReport } from '../core/services/description-overlap.js';
|
|
9
|
+
import { lintDescriptions, renderDescriptionLint } from '../core/services/description-lint.js';
|
|
8
10
|
import { confirmInsecureHttp } from './insecure-http-confirm.js';
|
|
9
11
|
import { SkillsManagerError } from '../shared/errors.js';
|
|
10
12
|
import { redactCheckout, redactDiscovered } from '../shared/redact.js';
|
|
@@ -14,6 +16,9 @@ import { HttpDownloadClient } from '../infra/http-download-client.js';
|
|
|
14
16
|
import { DetectionService, detectionLogPath } from '../core/services/detection-service.js';
|
|
15
17
|
import { runBootstrap, managerSkillBundle } from './bootstrap.js';
|
|
16
18
|
import { renderCostLedger, renderCostShare, renderPresetCostLine } from './cost-output.js';
|
|
19
|
+
import { renderDoctorShare } from './doctor-output.js';
|
|
20
|
+
import { renderSyncShare } from './sync-output.js';
|
|
21
|
+
import { formatGithubAnnotations } from '../core/services/security-scan.js';
|
|
17
22
|
const pkg = createRequire(import.meta.url)('../../package.json');
|
|
18
23
|
const projectRoot = projectRootFromImportMeta(import.meta.url);
|
|
19
24
|
function services(cmd, options = {}) {
|
|
@@ -82,6 +87,9 @@ const webCommand = (cmd, description) => cmd
|
|
|
82
87
|
.option('--host <host>', 'host', '127.0.0.1')
|
|
83
88
|
.option('--no-open', 'do not open a browser')
|
|
84
89
|
.action(async (opts, self) => {
|
|
90
|
+
const port = Number(opts.port);
|
|
91
|
+
if (!/^\d+$/.test(String(opts.port)) || port > 65535)
|
|
92
|
+
throw new Error(`--port expects an integer from 0 to 65535, got "${opts.port}"`);
|
|
85
93
|
const globalOpts = self.optsWithGlobals();
|
|
86
94
|
// Single entry point (ADR-0014): the dashboard never creates the hub — bootstrap does.
|
|
87
95
|
const probe = createRuntimeServices({ home: globalOpts.home }, projectRoot);
|
|
@@ -91,23 +99,31 @@ const webCommand = (cmd, description) => cmd
|
|
|
91
99
|
selfCheckManagerSkill(probe);
|
|
92
100
|
// Lazy: fastify/shiki/markdown load only for the dashboard command, not on every CLI invocation.
|
|
93
101
|
const { startDashboardServer } = await import('../dashboard/server/main.js');
|
|
94
|
-
return startDashboardServer({ home: globalOpts.home, port
|
|
102
|
+
return startDashboardServer({ home: globalOpts.home, port, host: opts.host, open: opts.open, projectRoot });
|
|
95
103
|
});
|
|
96
104
|
webCommand(program.command('web'), 'Start the local web dashboard');
|
|
97
105
|
webCommand(program.command('dashboard', { hidden: true }), 'Deprecated alias for web');
|
|
98
106
|
program.command('doctor')
|
|
99
107
|
.description('Run health checks')
|
|
108
|
+
.option('--share', 'privacy-safe paste card (counts only — no paths / skill names) for X / HN / chat')
|
|
100
109
|
.option('--migrate-views', 'distribute leftover hub views to user runtimes')
|
|
101
110
|
.option('--delete-views', 'with --migrate-views, remove generated view symlinks')
|
|
102
111
|
.option('--force', 'with --migrate-views, overwrite unmanaged runtime paths')
|
|
103
112
|
.action((opts, cmd) => {
|
|
104
113
|
const s = services(cmd);
|
|
114
|
+
if (opts.share && opts.migrateViews)
|
|
115
|
+
throw new Error('use either --share or --migrate-views, not both');
|
|
105
116
|
if (opts.migrateViews) {
|
|
106
117
|
const migrated = s.distribute.migrateViews({ deleteViews: Boolean(opts.deleteViews), force: Boolean(opts.force) });
|
|
107
118
|
s.activity.record({ action: 'cli-migrate-views', summary: 'Migrated leftover hub views', details: migrated });
|
|
108
119
|
return print({ migrated, doctor: s.doctor.check() });
|
|
109
120
|
}
|
|
110
|
-
|
|
121
|
+
const report = s.doctor.check();
|
|
122
|
+
if (opts.share) {
|
|
123
|
+
process.stdout.write(renderDoctorShare(report));
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
print(report);
|
|
111
127
|
});
|
|
112
128
|
program.command('status')
|
|
113
129
|
.description('Summarize managed distribution health (managed/foreign/outdated/stale)')
|
|
@@ -393,16 +409,31 @@ provenance.command('adopt')
|
|
|
393
409
|
provenance.command('list')
|
|
394
410
|
.description('List skills still missing a source: imported-without-source vs locally authored')
|
|
395
411
|
.option('--json', 'machine-readable output for agents')
|
|
412
|
+
.option('--fail-on-imported', 'exit 1 when any imported-without-source skill remains (CI / hub-hygiene gate; locally authored never fails)')
|
|
396
413
|
.action((opts, cmd) => {
|
|
397
414
|
const pending = services(cmd).provenance.pending();
|
|
398
415
|
if (opts.json)
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
416
|
+
print(pending);
|
|
417
|
+
else {
|
|
418
|
+
console.log(`Imported without source (${pending.importedWithoutSource.length}):`);
|
|
419
|
+
for (const item of pending.importedWithoutSource)
|
|
420
|
+
console.log(` ${item.skill}${item.importedAt ? ` (imported ${item.importedAt})` : ''}`);
|
|
421
|
+
console.log(`Locally authored, no upstream recorded (${pending.locallyAuthored.length}):`);
|
|
422
|
+
for (const skill of pending.locallyAuthored)
|
|
423
|
+
console.log(` ${skill}`);
|
|
424
|
+
}
|
|
425
|
+
// Hygiene gate: imported skills without a source cannot get tree-SHA updates.
|
|
426
|
+
// Locally authored skills are intentional and never trip this flag.
|
|
427
|
+
if (opts.failOnImported) {
|
|
428
|
+
const n = pending.importedWithoutSource.length;
|
|
429
|
+
if (n > 0) {
|
|
430
|
+
process.stderr.write(`Provenance: ${n} imported skill(s) still missing a source — FAIL (--fail-on-imported); run \`skills-manager provenance adopt\` or \`edit --source-*\`\n`);
|
|
431
|
+
process.exitCode = 1;
|
|
432
|
+
}
|
|
433
|
+
else {
|
|
434
|
+
process.stderr.write('Provenance: no imported-without-source skills — within hygiene gate\n');
|
|
435
|
+
}
|
|
436
|
+
}
|
|
406
437
|
});
|
|
407
438
|
// Hub git-ification for multi-machine sync (ADR-0020): each command thin, git
|
|
408
439
|
// stays the merge tool, and the operator keeps every git decision.
|
|
@@ -429,10 +460,17 @@ sync.command('init')
|
|
|
429
460
|
sync.command('status')
|
|
430
461
|
.description('Read-only sync status: git-ification, remote, dirty files, ahead/behind (last fetch), last sync commit — zero network')
|
|
431
462
|
.option('--json', 'machine-readable output for agents')
|
|
463
|
+
.option('--share', 'privacy-safe paste card (no hub path / remote URL) for X / HN / chat')
|
|
432
464
|
.action((opts, cmd) => {
|
|
433
465
|
const result = services(cmd).sync.status();
|
|
466
|
+
if (opts.json && opts.share)
|
|
467
|
+
throw new Error('use either --json or --share, not both');
|
|
434
468
|
if (opts.json)
|
|
435
469
|
return print(result);
|
|
470
|
+
if (opts.share) {
|
|
471
|
+
process.stdout.write(renderSyncShare(result));
|
|
472
|
+
return;
|
|
473
|
+
}
|
|
436
474
|
// Read-only probe: no activity record — status itself must not dirty the hub.
|
|
437
475
|
console.log(`hub: ${result.home}`);
|
|
438
476
|
if (!result.gitified) {
|
|
@@ -588,17 +626,29 @@ program.command('cost')
|
|
|
588
626
|
.option('--json', 'machine-readable output for agents')
|
|
589
627
|
.option('--share', 'privacy-safe paste card (no absolute paths) for X / HN / chat')
|
|
590
628
|
.option('--top <n>', 'how many of the most expensive descriptions to list', '5')
|
|
629
|
+
.option('--budget <tokens>', 'exit 1 when total resident tokens exceed this budget (CI / pre-commit gate)')
|
|
591
630
|
.action((opts, cmd) => {
|
|
592
|
-
const s = services(cmd);
|
|
593
631
|
const top = Number.parseInt(opts.top, 10);
|
|
594
632
|
if (!Number.isInteger(top) || top < 0)
|
|
595
633
|
throw new Error(`--top expects a non-negative integer, got "${opts.top}"`);
|
|
596
634
|
if (opts.json && opts.share)
|
|
597
635
|
throw new Error('use either --json or --share, not both');
|
|
636
|
+
const budget = opts.budget === undefined ? null : Number(opts.budget);
|
|
637
|
+
if (budget !== null && (!Number.isInteger(budget) || budget < 0))
|
|
638
|
+
throw new Error(`--budget expects a non-negative integer token count, got "${opts.budget}"`);
|
|
639
|
+
const s = services(cmd);
|
|
598
640
|
const ledger = s.cost.ledger(top);
|
|
599
641
|
if (opts.json)
|
|
600
|
-
|
|
601
|
-
|
|
642
|
+
print(ledger);
|
|
643
|
+
else
|
|
644
|
+
process.stdout.write(opts.share ? renderCostShare(ledger) : renderCostLedger(ledger));
|
|
645
|
+
// Budget gate on stderr so stdout (JSON / card) stays script-stable.
|
|
646
|
+
if (budget !== null) {
|
|
647
|
+
const over = ledger.totalTokens > budget;
|
|
648
|
+
process.stderr.write(`Resident budget: ${ledger.totalTokens} / ${budget} tokens — ${over ? 'OVER (exit 1); see Suggestions or run `skills-manager cost` for recalls' : 'within budget'}\n`);
|
|
649
|
+
if (over)
|
|
650
|
+
process.exitCode = 1;
|
|
651
|
+
}
|
|
602
652
|
});
|
|
603
653
|
program.command('add')
|
|
604
654
|
.description('Discover from a source, then install selected skills')
|
|
@@ -646,8 +696,11 @@ program.command('update')
|
|
|
646
696
|
.option('-s, --skill <skill...>', 'skill(s) to update')
|
|
647
697
|
.option('--source <key>', 'source group key from updates plan')
|
|
648
698
|
.option('--plan', 'print update plan (candidates only)')
|
|
649
|
-
.option('--check', 'run upstream freshness detection: stale / upToDate / failed / skipped per skill (uncalibrated entries adopt their observed anchor, ADR-0013)')
|
|
699
|
+
.option('--check', 'run upstream freshness detection: stale / upToDate / failed / skipped per skill (git/marketplace: skill subdirectory tree SHA, not whole-repo HEAD; uncalibrated entries adopt their observed anchor, ADR-0013)')
|
|
700
|
+
.option('--fail-on-stale', 'with --check: also exit 1 when any skill is stale (failed checks already exit 1; CI / hub-freshness gate)')
|
|
650
701
|
.action(async (opts, cmd) => {
|
|
702
|
+
if (opts.failOnStale && !opts.check)
|
|
703
|
+
throw new Error('--fail-on-stale requires --check');
|
|
651
704
|
const s = services(cmd);
|
|
652
705
|
if (opts.check) {
|
|
653
706
|
const detection = new DetectionService({ githubApi: new GitHubApiClient(), http: new HttpDownloadClient(), fs: new NodeFileSystem() });
|
|
@@ -675,9 +728,22 @@ program.command('update')
|
|
|
675
728
|
upToDate.push(skill.name);
|
|
676
729
|
}
|
|
677
730
|
print({ checked: stale.length + failed.length + upToDate.length + skipped.length, stale, upToDate, failed, skipped });
|
|
731
|
+
// Growth tip (stderr): JSON stdout stays script-stable; the differentiator is the git/marketplace tree-SHA anchor.
|
|
732
|
+
console.error('Update signal (git/marketplace): skill subdirectory tree SHA — upstream noise outside the skill never lights an update.');
|
|
678
733
|
// A failed check is a failed check — scripts read the exit code (adversary M6).
|
|
679
734
|
if (failed.length > 0)
|
|
680
735
|
process.exitCode = 1;
|
|
736
|
+
// Optional CI gate: stale skills are informational by default; --fail-on-stale
|
|
737
|
+
// turns the tree-SHA freshness signal into a nonzero exit (stdout JSON unchanged).
|
|
738
|
+
if (opts.failOnStale) {
|
|
739
|
+
if (stale.length > 0) {
|
|
740
|
+
process.stderr.write(`Update check: ${stale.length} stale skill(s) — FAIL (--fail-on-stale); run \`skills-manager update --plan\` then update\n`);
|
|
741
|
+
process.exitCode = 1;
|
|
742
|
+
}
|
|
743
|
+
else if (failed.length === 0) {
|
|
744
|
+
process.stderr.write('Update check: no stale skills — within freshness gate\n');
|
|
745
|
+
}
|
|
746
|
+
}
|
|
681
747
|
return;
|
|
682
748
|
}
|
|
683
749
|
if (opts.plan || (!opts.skill && !opts.source))
|
|
@@ -688,15 +754,139 @@ program.command('update')
|
|
|
688
754
|
remindSecurityScan(s, result.updated);
|
|
689
755
|
remindStaleTargets(s);
|
|
690
756
|
});
|
|
691
|
-
|
|
757
|
+
// One exit code for CI: the offline hub gates (security high, imported-without-source)
|
|
758
|
+
// always run; the resident budget and the networked freshness check are opt-in.
|
|
759
|
+
program.command('check')
|
|
760
|
+
.description('Run the hub CI gates in one go: audit security (high) + provenance (imported-without-source), plus optional --budget, --freshness, --overlap and --descriptions; exit 1 if any gate fails')
|
|
761
|
+
.option('--budget <tokens>', 'also fail when total resident tokens exceed this budget (same as cost --budget)')
|
|
762
|
+
.option('--freshness', 'also run update --check (network) and fail on stale or failed detection')
|
|
763
|
+
.option('--overlap', 'also fail when any two skill descriptions compete (same as audit overlap --strict, threshold 0.3)')
|
|
764
|
+
.option('--descriptions', 'also fail on error-level description lint findings (same as audit descriptions --strict; warnings never fail)')
|
|
765
|
+
.option('--json', 'machine-readable gate results')
|
|
766
|
+
.action(async (opts, cmd) => {
|
|
767
|
+
const budget = opts.budget === undefined ? null : Number(opts.budget);
|
|
768
|
+
if (budget !== null && (!Number.isInteger(budget) || budget < 0))
|
|
769
|
+
throw new Error(`--budget expects a non-negative integer token count, got "${opts.budget}"`);
|
|
770
|
+
const s = services(cmd);
|
|
771
|
+
const gates = [];
|
|
772
|
+
const names = s.registry.listSkills().map((skill) => skill.name);
|
|
773
|
+
const high = s.security.countHighFindings(s.security.scanSkills(names));
|
|
774
|
+
gates.push({ gate: 'security', ok: high === 0, detail: `${high} high finding(s) across ${names.length} skill(s)${high ? ' — run `skills-manager audit security --strict`' : ''}` });
|
|
775
|
+
const imported = s.provenance.pending().importedWithoutSource.length;
|
|
776
|
+
gates.push({ gate: 'provenance', ok: imported === 0, detail: `${imported} imported skill(s) missing a source${imported ? ' — run `skills-manager provenance adopt`' : ''}` });
|
|
777
|
+
if (budget !== null) {
|
|
778
|
+
const total = s.cost.ledger(0).totalTokens;
|
|
779
|
+
gates.push({ gate: 'budget', ok: total <= budget, detail: `${total} / ${budget} resident tokens${total > budget ? ' — run `skills-manager cost` for recalls' : ''}` });
|
|
780
|
+
}
|
|
781
|
+
if (opts.overlap || opts.descriptions) {
|
|
782
|
+
const inputs = s.registry.listSkills().map((skill) => ({ name: skill.name, description: skill.description }));
|
|
783
|
+
if (opts.overlap) {
|
|
784
|
+
const pairs = findDescriptionOverlaps(inputs, 0.3).pairs.length;
|
|
785
|
+
gates.push({ gate: 'overlap', ok: pairs === 0, detail: `${pairs} competing description pair(s)${pairs ? ' — run `skills-manager audit overlap`' : ''}` });
|
|
786
|
+
}
|
|
787
|
+
if (opts.descriptions) {
|
|
788
|
+
const lint = lintDescriptions(inputs);
|
|
789
|
+
gates.push({ gate: 'descriptions', ok: lint.errors === 0, detail: `${lint.errors} error(s), ${lint.warnings} warning(s) in skill descriptions${lint.errors ? ' — run `skills-manager audit descriptions`' : ''}` });
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
if (opts.freshness) {
|
|
793
|
+
const detection = new DetectionService({ githubApi: new GitHubApiClient(), http: new HttpDownloadClient(), fs: new NodeFileSystem() });
|
|
794
|
+
const listed = s.registry.listSkills({ includeArchived: false });
|
|
795
|
+
const outcomes = await detection.detect(s, listed);
|
|
796
|
+
let stale = 0;
|
|
797
|
+
let failed = 0;
|
|
798
|
+
for (const outcome of outcomes.values()) {
|
|
799
|
+
if (outcome.detection === 'failed')
|
|
800
|
+
failed += 1;
|
|
801
|
+
else if (outcome.detection !== 'skipped' && outcome.hasUpdate)
|
|
802
|
+
stale += 1;
|
|
803
|
+
}
|
|
804
|
+
gates.push({ gate: 'freshness', ok: stale === 0 && failed === 0, detail: `${stale} stale, ${failed} failed (tree-SHA)${stale || failed ? ' — run `skills-manager update --check`' : ''}` });
|
|
805
|
+
}
|
|
806
|
+
const ok = gates.every((g) => g.ok);
|
|
807
|
+
if (opts.json)
|
|
808
|
+
print({ ok, gates });
|
|
809
|
+
else {
|
|
810
|
+
for (const g of gates)
|
|
811
|
+
console.log(`${g.ok ? 'PASS' : 'FAIL'} ${g.gate}: ${g.detail}`);
|
|
812
|
+
console.log(`check: ${ok ? 'PASS' : 'FAIL'} (${gates.filter((g) => g.ok).length}/${gates.length} gates)`);
|
|
813
|
+
}
|
|
814
|
+
if (!ok)
|
|
815
|
+
process.exitCode = 1;
|
|
816
|
+
});
|
|
817
|
+
const audit = program.command('audit').description('Report-only audits over hub skills (security, description overlap, description lint)');
|
|
692
818
|
audit.command('security')
|
|
693
|
-
.description('Scan skill tree(s) for high-signal risks: shell exec, network calls, credential paths, secret-like strings (
|
|
819
|
+
.description('Scan skill tree(s) for high-signal risks: shell exec, network calls, credential paths, secret-like strings (report-only by default)')
|
|
694
820
|
.argument('[skills...]', 'canonical skill names; omit to scan every non-archived hub skill')
|
|
695
|
-
.
|
|
821
|
+
.option('--strict', 'exit 1 when any high-severity finding is present (warn/info never fail; default stays report-only)')
|
|
822
|
+
.option('--format <format>', 'json (default) or github (Actions ::error/::warning/::notice annotations for the PR file UI)', 'json')
|
|
823
|
+
.action((skills, opts, cmd) => {
|
|
824
|
+
const format = opts.format ?? 'json';
|
|
825
|
+
if (format !== 'json' && format !== 'github') {
|
|
826
|
+
throw new SkillsManagerError('invalid_format_flag', `--format must be json or github (got ${JSON.stringify(format)})`);
|
|
827
|
+
}
|
|
696
828
|
const s = services(cmd);
|
|
697
829
|
const names = skills.length > 0 ? skills : s.registry.listSkills().map((skill) => skill.name);
|
|
698
830
|
const reports = s.security.scanSkills(names);
|
|
699
|
-
|
|
831
|
+
if (format === 'github') {
|
|
832
|
+
const annotations = formatGithubAnnotations(reports);
|
|
833
|
+
if (annotations)
|
|
834
|
+
console.log(annotations);
|
|
835
|
+
}
|
|
836
|
+
else {
|
|
837
|
+
print(reports.length === 1 ? reports[0] : reports);
|
|
838
|
+
}
|
|
839
|
+
if (opts.strict && s.security.failsStrict(reports))
|
|
840
|
+
process.exitCode = 1;
|
|
841
|
+
});
|
|
842
|
+
audit.command('overlap')
|
|
843
|
+
.description('Find skills whose descriptions compete for the same trigger words (the agent may pick the wrong one); offline, report-only')
|
|
844
|
+
.argument('[skills...]', 'canonical skill names; omit to compare every non-archived hub skill')
|
|
845
|
+
.option('--threshold <score>', 'minimum overlap score from 0 to 1 to report', '0.3')
|
|
846
|
+
.option('--strict', 'exit 1 when any pair is reported (CI gate)')
|
|
847
|
+
.option('--json', 'machine-readable report')
|
|
848
|
+
.action((skills, opts, cmd) => {
|
|
849
|
+
const threshold = Number(opts.threshold);
|
|
850
|
+
if (!/^(0(\.\d+)?|1(\.0+)?|\.\d+)$/.test(opts.threshold) || !(threshold >= 0 && threshold <= 1)) {
|
|
851
|
+
throw new Error(`--threshold expects a number from 0 to 1, got "${opts.threshold}"`);
|
|
852
|
+
}
|
|
853
|
+
const s = services(cmd);
|
|
854
|
+
const all = s.registry.listSkills();
|
|
855
|
+
const missing = skills.filter((name) => !all.some((skill) => skill.name === name));
|
|
856
|
+
if (missing.length > 0)
|
|
857
|
+
throw new Error(`Skill not found: ${missing.join(', ')}. Run \`skills-manager list\` to see hub skills.`);
|
|
858
|
+
const picked = skills.length > 0 ? all.filter((skill) => skills.includes(skill.name)) : all;
|
|
859
|
+
const report = findDescriptionOverlaps(picked.map((skill) => ({ name: skill.name, description: skill.description })), threshold);
|
|
860
|
+
if (opts.json)
|
|
861
|
+
print(report);
|
|
862
|
+
else
|
|
863
|
+
process.stdout.write(renderOverlapReport(report));
|
|
864
|
+
if (opts.strict && report.pairs.length > 0) {
|
|
865
|
+
process.stderr.write(`Overlap: ${report.pairs.length} competing pair(s) — FAIL (--strict); sharpen the descriptions above\n`);
|
|
866
|
+
process.exitCode = 1;
|
|
867
|
+
}
|
|
868
|
+
});
|
|
869
|
+
audit.command('descriptions')
|
|
870
|
+
.description('Lint skill descriptions for what makes them fail to trigger: missing, too long, no "use when", wrong point of view, vague; offline, report-only')
|
|
871
|
+
.argument('[skills...]', 'canonical skill names; omit to lint every non-archived hub skill')
|
|
872
|
+
.option('--strict', 'exit 1 when any error-level finding is present (warnings never fail)')
|
|
873
|
+
.option('--json', 'machine-readable report')
|
|
874
|
+
.action((skills, opts, cmd) => {
|
|
875
|
+
const s = services(cmd);
|
|
876
|
+
const all = s.registry.listSkills();
|
|
877
|
+
const missing = skills.filter((name) => !all.some((skill) => skill.name === name));
|
|
878
|
+
if (missing.length > 0)
|
|
879
|
+
throw new Error(`Skill not found: ${missing.join(', ')}. Run \`skills-manager list\` to see hub skills.`);
|
|
880
|
+
const picked = skills.length > 0 ? all.filter((skill) => skills.includes(skill.name)) : all;
|
|
881
|
+
const report = lintDescriptions(picked.map((skill) => ({ name: skill.name, description: skill.description })));
|
|
882
|
+
if (opts.json)
|
|
883
|
+
print(report);
|
|
884
|
+
else
|
|
885
|
+
process.stdout.write(renderDescriptionLint(report));
|
|
886
|
+
if (opts.strict && report.errors > 0) {
|
|
887
|
+
process.stderr.write(`Description lint: ${report.errors} error(s) — FAIL (--strict)\n`);
|
|
888
|
+
process.exitCode = 1;
|
|
889
|
+
}
|
|
700
890
|
});
|
|
701
891
|
const distribute = program.command('distribute')
|
|
702
892
|
.description('Distribute hub skills to user or project runtime directories')
|