docs(skills): recommend the per-agent install that lands the bundle once - #16806
Conversation
The catalog front page recommended `--all`, which the skills CLI expands to `--skill '*' --agent '*' -y`. Measured against skills@1.5.23 with this catalog in an empty directory, that writes the bundle to THREE destinations: a full real copy in `.agents/` (46 files) AND in `agent/` (46 files, re-serialized frontmatter, same bodies), plus 11 `.claude/` symlinks into `.agents/`. The per-agent form lands 46 real files in `.claude/` and nothing else. Line 9 now recommends the per-agent form — the same command the scaffolder already runs (`packages/create-objectstack/src/skills-install.ts`), so the front page and the scaffolder no longer disagree. `--all` is retained as an explicitly-labelled multi-runtime opt-in with its three-destination cost stated rather than merely mentioned. The `/skills` subpath is preserved in the one catalog spelling the file carries: it is the boundary that keeps `metadata.internal` skills out, and `packages/create-objectstack/src/template-consistency.test.ts` ratchets it across `skills/**`. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01P58euzUXCVJNwmhuPC9DXY
维护者速读(终稿)席位复核记录:#16768 上的 ACCEPT 评论(skills 席,hotlong,session 改了什么技能包目录首页 为什么改
风险与代价(含回滚)风险低:纯文档,不进任何 npm 包的发布产物(实测:70 个已发布 manifest 无一 席位意见同意合并。席位对照 GitHub 与树逐项核过: dev 留给你的那个取舍——首页只写「两份完整副本 + 一组符号链接」、不写死 46/11——席位意见是对的:那两个数随目录增删漂移、没有门禁读它们,写死就是下一次静默过期;承重的事实(三处、其中两处是实体副本)不漂。带日期的数字留在 PR 正文,合适。 你要做的受管面( 是 Generated by Claude Code |
Fixes #16768
skills/README.md:9recommendednpx skills add objectstack-ai/objectstack/skills --all. The skills CLI's own help spells--allas "Shorthand for--skill '*' --agent '*' -y", and the--agent '*'half is what makes a single copy-paste land the bundle three times. Line 9 now recommends the per-agent form — byte-for-byte the commandpackages/create-objectstackalready runs — and--allstays on the page as an explicitly-labelled multi-runtime opt-in whose three-destination cost is stated rather than merely mentioned.The catalog front page and the scaffolder had drifted apart: the scaffolder moved to the per-agent form and recorded why in
packages/create-objectstack/src/skills-install.ts, while the front page kept recommending the form that scaffolder comment exists to warn about.The measurement — re-run in this container, not cited
skills@1.5.23, this catalog (11 skills), two empty directories:npx skills add objectstack-ai/objectstack/skills --all.agents/46 real files (602,278 B) ·agent/46 real files (600,858 B) ·.claude/11 symlinks into.agents/npx skills add objectstack-ai/objectstack/skills --skill '*' --agent claude-code -y.claude/46 real files (602,278 B) — and nothing elseBoth also write
skills-lock.json. The shape reproduces the reading recorded on the card exactly (46 / 46 / 11). The byte totals differ from the ones inskills-install.ts(604,102 / 602,682) only because the catalog's own content has moved since that reading was taken — the file counts, which are what the cost statement rests on, are identical.Why the README states the cost without the numbers. The prose says "a full real copy in both
.agents/andagent/, plus.claude/symlinks pointing into.agents/" rather than pinning46and11. Those two counts are a function of how many files the catalog currently has; they would go stale the next time a skill is added, and no gate reads them. The load-bearing facts — three destinations, two of them full real copies — do not drift. The dated numbers live in this PR body instead, which is where a reading with a date on it belongs.The
/skillssubpath, and proof the guard is liveThe card's ruling requires the subpath in every spelling. The file carries exactly one catalog spelling and it has the subpath:
That is ratcheted by
packages/create-objectstack/src/template-consistency.test.ts("no customer-facing surface advertises a repo-root skills install"), whose scan surface includesskills/**. A one-shot ablation proved the guard actually reads this file rather than passing vacuously — the subpath was removed from line 9 on disk, the removal was confirmed by anchoredgrep -c(removed text 1 to 0, injected text 0 to 1), and the test was re-run:Restore was proven by artefact, not by an exit code:
git checkout HEAD -- (absolute path), then the post-restoregit hash-objectmatched the HEAD blob hashe274f0d5bb1178b72daf644f91ccd6914d08f3d3andgit diff HEADcame back empty. No test file was left behind.Published-surface readings (
skills/**)Line counts are the unit; the sibling gate defines a token count, so both are reported.
skills/README.mdSKILL.md, summed)No ratchet applies to this file, and that is a measured fact rather than an assumption:
scripts/check-skills-token-ratchet.mjsplacesskills/README.mdin population 3 (OUTSIDE — "not inside any published skill directory"), pinned by its own self-test caseskills/README.md is outside the population (population 3). Running the gate prints no row for the file:36 authored bundle file(s) within their ceilings.scripts/pm/check-skill-line-ratchet.mjsexcludes the published catalog by design. So the +8 lines are unbudgeted — no ceiling was raised and none needed to be.Verification
Gate families derived in the worktree and reconciled, not taken from a list:
All 21 exited 0, at
290c258ef. Named verdict lines:pnpm --filter @objectstack/spec run check:skill-docs—✓ skills/README.md/✅ Skill docs in sync(the generated index block is untouched and still in sync).node scripts/check-skills-token-ratchet.mjs—✓ … 36 authored bundle file(s) within their ceilings(run beyond the derived union; the reconciliation names it as the one extra).pnpm --filter @objectstack/lint run check:doc-formula-expressions— first returned exit 3PREREQUISITE NOT MET, which is not a reading; afterturbo run build --filter=@objectstack/formula --filter=@objectstack/lintunderscripts/pm/os-verify-lock.sh(VERDICT command-exit 0) it returned✓ check:doc-formula-expressions: 22 record-scoped formula example(s) across 434 files / 1372 TS blocks judged clean.pnpm --filter create-objectstack testunder the same lock —Test Files 16 passed (16) · Tests 203 passed (203).node scripts/pm/check-governed-merges.mjs --test skills/README.md— exit 3:⛔ GOVERNED — a human merge is the review record for this PR (#9495 regime).Repo-scale lint is CI's run, and this diff is outside its population — measured, not assumed. (1) Population read from eslint's own configuration: for this path it answers
File ignored because no matching configuration was supplied.(2) Count read from--format json: 1 result object, 0 errors, and the single warning is that ignore notice, not a finding. (3) Invariance: the diff is one Markdown file eslint's config does not match and no TS/JS file is touched, so no untouched file's verdict can move.Changeset
skip-changeset, measured rather than fast-tracked (skills/**is not on the fast path). Across 70 published manifests,files[]entries escaping their package directory: 0; entries naming askillspath segment: 0; build steps copying askills/tree into a package: none. Symbol grep over the 130 enumerated published payload paths with a positive control — markermulti-runtime opt-in0 hits, controlobjectstack-ai/objectstack/skills2 hits. Nothing this PR moves is inside any package's published payload.验收备注
Observations found in passing, deliberately not acted on and not filed:
content/docs/tree still recommends--allin six places —content/docs/ai/skills-reference.mdx:27and:30,content/docs/ai/skills.mdx:35,content/docs/getting-started/build-with-claude-code.mdx:57and:381,content/docs/getting-started/your-first-project.mdx:45and:286. Out of scope here: that surface belongs to docs: five surfaces tell readers to install the skills bundle with--all, which writes it to three directories — and two of them describe a scaffolder command that is changing #16400, and this dispatch names it as another seat's. One detail worth handing over: theskills-reference.mdxsites are hand-authored prose, not generator output — the generated block in that file starts at line 38, andpackages/spec/scripts/build-skill-docs.tscontains no install command at all. Whoever takes that card edits the.mdxdirectly; there is no generator to re-run. Successor: the seat holding docs: five surfaces tell readers to install the skills bundle with--all, which writes it to three directories — and two of them describe a scaffolder command that is changing #16400.skills/objectstack-pm-dispatch/SKILL.md:53spellsnpx skills add objectstack-ai/objectstack/skills --skill objectstack-pm-dispatch— one named skill, no--agentand no-y, so the CLI prompts for the runtime interactively. That is a different shape from the--alldefect and is not obviously wrong, but it is the one other install spelling left insideskills/**. Out of scope for this one-file card; noted so a reviewer sees the whole set. Successor: none currently holds it.packages/create-objectstack/README.md:60,src/templates/AGENTS.md:82,src/templates/blank/README.md:148) already carry the per-agent form, so after this change the only remaining--allrecommendations in the repo are thecontent/docs/**ones above. Out of scope: scaffold:skills add --allwrites the bundle three times (~1.6 MB, byte-identical) and the template_gitignoreexcludes none of it, so every new project's FIRST commit vendors it in triplicate #16331 covered the scaffolder side and has already landed.维护者速读(草稿)
改了什么 — 技能包目录首页
skills/README.md第 9 行的安装命令,从--all改成按单一 agent 安装的形式;--all仍然留在页面上,但改成明确标注的「多运行时可选项」,并写清它的代价。只动这一个文件,9 行增、1 行删。为什么改 —
--all是 skills CLI 的简写,展开后是--skill '*' --agent '*' -y。实测:一个照抄首页命令的客户,会在项目里得到同一份技能包的两份完整实体副本(.agents/与agent/,各 46 个文件、约 600 KB)外加一组.claude/符号链接 —— 一次安装落三处。按单一 agent 安装则只落一处 46 个文件。这个代价此前在脚手架代码的注释里被完整记录过,首页却仍在推荐那条被注释警告的命令:客户读到的第一份文档,和我们自己的脚手架实际执行的命令,是矛盾的。本次改动把首页对齐到脚手架已经在用的那条命令。风险与代价(含回滚) — 风险低:纯文档,不进任何 npm 包的发布产物(已实测,故
skip-changeset)。真实代价有两点。其一,首页多了 8 行(2,079 到 2,215 tokens);该文件不在任何 ratchet 的管辖内,所以没有抬任何天花板,但客户上下文窗口确实多付这一点。其二,新推荐的命令更长、并且默认只为 Claude Code 一种运行时装好 —— 用别的运行时的客户需要自己把--agent换掉,页面已经写明这一点。回滚成本极低:单文件单 commit,git revert即可,没有任何生成物或下游依赖跟着动。席位意见 — (留空,待席位填)
你要做的 — 这是受管面(
skills/**,Prime Directive 14),PR 保持 draft,不进合并队列、不开自动合并。请判断一件事:首页把--all的代价写成「两份完整副本 + 一组符号链接」而不写死 46/11 这两个数字,这个取舍是否合你的意 —— 写死更具体,但会随目录增删而悄悄过期且无门禁兜底。确认后由你手工合并。Generated by Claude Code