Cluster B: bundled skills workspace, idempotent installer, CLAUDE.md sentinel injection#33
Open
spaceshipmike wants to merge 6 commits into
Open
Cluster B: bundled skills workspace, idempotent installer, CLAUDE.md sentinel injection#33spaceshipmike wants to merge 6 commits into
spaceshipmike wants to merge 6 commits into
Conversation
…0, S221) Add new private workspace packages/skills/ holding the bundled Claude Code and Codex skills (setlist-enroll-project, setlist-portfolio-graph) with parallel .claude-plugin/ and .codex-plugin/ manifests over a single skills/ tree. The skills walk an agent through the four-step onboarding workflow and render the area to project to capability portfolio graph using only the 58 shipped MCP tools. scripts/validate-skills-manifests.js cross-checks the dual manifests on: - version drift between claude plugin.json and codex plugin.json - version drift between marketplace.json (top + plugin entry) and plugin.json - skill listing drift between claude and codex manifests - orphan content on disk vs orphan listings in either manifest Silent on pass (S221 spec literal); exits 1 on drift with stderr diagnostics; exits 2 on config/IO error. Wired as npm run validate-skills-manifests at the root. Ten unit tests cover every drift case plus the real-repo passing case. Satisfies: S220, S221 Spec sections: #bundled-skills (2.17), #monorepo (5.1), #testing-discipline (4.5)
Add packages/skills/scripts/install.js — the installer that copies the bundled skills from packages/skills/skills/ into the host's skills directory ($CLAUDE_CONFIG_DIR/skills/ or ~/.claude/skills/) with placeholder-token substitution at copy time so installed files carry machine-specific paths. Contract highlights: - honors CLAUDE_CONFIG_DIR for both skills install dir and CLAUDE.md path - copies all skill files; .md files get placeholder substitution (__NODE_BIN__, __SETLIST_PACKAGE_ROOT__, __SETLIST_CLI_BIN__) - preserves user .local.md siblings byte-identical across re-runs and logs a one-line 'preserving local override' notice per preserved file - --no-skills skips the copy phase; previously-installed skills are NOT deleted (contract is 'do not overwrite', not 'uninstall') - --no-rule skips the CLAUDE.md sentinel-block injection (the injection itself lands in B3 — install.js calls into rule-injection.js which is a stub in this commit) - idempotent: re-running produces byte-identical files for any skill whose source content hasn't changed Wired as 'npm run install:skills' at the root. Seventeen unit tests cover copy + idempotency + .local.md preservation + flag combinations + path rewriting + CLAUDE_CONFIG_DIR routing. Satisfies: S210, S211 Spec sections: #bundled-skills (2.17)
Flesh out packages/skills/scripts/rule-injection.js — the four-state
idempotent injection of the setlist proactive-use rule between
<!-- setlist:rule:begin --> / <!-- setlist:rule:end --> sentinel markers
in CLAUDE.md (honoring $CLAUDE_CONFIG_DIR or falling back to
~/.claude/CLAUDE.md).
The four states (per spec §2.17 'Idempotency contract for the rule
injection'):
1. file missing → create with '# Claude Code instructions' header
plus the sentinel block (single trailing newline)
2. markers absent in existing file → append the block with a single
leading blank line; existing content stays byte-identical
3. markers present with matching content → no-op (no mtime bump,
no rewrite)
4. markers present with drifted content → replace ONLY the content
between the markers; everything outside stays byte-identical
4*. exactly one marker present (or end-before-begin) → REFUSE to
write; log one-line warning naming the file and the missing
marker. The user fixes the file and re-runs.
The rule body is the textual companion to the MCP server's
ONBOARDING_INSTRUCTIONS envelope — coordinated framing, distinct
surface. The MCP instructions reach sessions over MCP; the CLAUDE.md
rule reaches sessions in directories without setlist's MCP server
connected.
Eighteen tests cover each state, the orphan-refusal logger, idempotency
across consecutive runs, multi-line drift, end-before-begin marker
order, an empty file, and runInstaller integration (--no-rule opt-out,
CLAUDE_CONFIG_DIR routing, orphan refusal end-to-end).
Satisfies: S198
Spec sections: #bundled-skills (2.17)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Spec §2.17 "Bundled Claude Code Skills and CLAUDE.md Rule Injection" lands as code. Three chunks, six commits, three local tags (.19 → .20 → .21).
What's in this PR
B1 —
packages/skills/workspace + dual manifest + validator (S220, S221)New private workspace
packages/skills/holding the two bundled skills with parallel host manifests over oneskills/tree:skills/setlist-enroll-project/SKILL.md— walks the four-step onboarding (register_project→enrich_project→write_fields→refresh_project_digest) and post-enrollmentregister_capabilities. Callsvocab(field)before writing open-vocabulary values. Defers tosetlist://docs/onboardingfor full field semantics.skills/setlist-portfolio-graph/SKILL.md— renders the area → project → capability tree usingportfolio_brief,list_areas,list_projects,query_capabilities. Read-only by contract..claude-plugin/plugin.json+.claude-plugin/marketplace.json+.codex-plugin/plugin.json— same skills, two host manifests.scripts/validate-skills-manifests.jscross-checks the manifests for version drift, skill-list drift, and orphan content. Silent on pass (S221 spec literal). Wired asnpm run validate-skills-manifests. 10 unit tests.B2 — Idempotent skills installer (S210, S211)
packages/skills/scripts/install.js(wired asnpm run install:skills):\$CLAUDE_CONFIG_DIRfor both the skills install dir andCLAUDE.mdpath__NODE_BIN__,__SETLIST_PACKAGE_ROOT__,__SETLIST_CLI_BIN__).local.mdsiblings byte-identical across re-runs--no-skillsand--no-ruleflags compose17 unit tests cover copy + idempotency +
.local.mdpreservation + flag combinations + path rewriting +CLAUDE_CONFIG_DIRrouting.B3 — CLAUDE.md sentinel-block injection (S198)
packages/skills/scripts/rule-injection.jsimplements the four-state idempotency contract:The rule body is the textual companion to the MCP server's `ONBOARDING_INSTRUCTIONS` — coordinated framing, distinct surface. MCP instructions reach sessions over MCP; the CLAUDE.md rule reaches sessions where setlist's MCP isn't connected.
18 unit tests cover each state, end-before-begin marker order, an empty file, and `runInstaller` integration.
Versioning
`.fctry/config.json` `propagationTargets` extended with `packages/skills/package.json`, the two host plugin manifests, and the marketplace.json fields.
Scope guards
Test plan
🤖 Generated with Claude Code