Conversation
5e594f4 to
071cd15
Compare
071cd15 to
d181de6
Compare
d181de6 to
6206b47
Compare
6206b47 to
0206986
Compare
0604388 to
2db53d2
Compare
2db53d2 to
d76ec2f
Compare
d76ec2f to
31a06b0
Compare
f40b132 to
a133503
Compare
β¦ repo Project-scoped, marketplace-independent onboarding for the client's coding agent (Claude Code + Codex). Fetches the public ForestAdmin/ai-marketplace, drops all 8 skill bundles (forest/* + forest-code + forest-legacy) into .claude/skills/ and .agents/skills/, merges a Forest block into CLAUDE.md/AGENTS.md, and wires the forest-docs MCP (https://docs.forest.app/mcp, no secret) from the marketplace. Includes 11 unit tests (skills-manager) and conforms to repo conventions (array methods, declared `tar` dep, no jest hooks). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
a133503 to
6c0e6f3
Compare
On the no-force skip path, installSkills reported the bundle-derived file list as managed even though nothing was written. A user-authored skill dir that pre-existed the first skills:init (e.g. their own .claude/skills/layout/SKILL.md) was thus recorded in the manifest, and a later refresh β once the skill left the upstream bundle β would prune it, deleting user data. installSkills now takes the previous manifest's file list (null on a first run) and, on the skip path, only carries over the intersection of the bundle-derived list and that previous manifest: files a past run provably wrote. First run over a pre-existing dir claims nothing. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
β¦ write installDocsMcp runs last (after skill installs, CLAUDE.md/AGENTS.md merges and stale pruning), so its deliberate throw on an unparseable local .mcp.json β or a raw ENOENT on a bundle missing forest-docs/.mcp.json β left a half-applied install with no manifest rewrite. skills:init now fails fast: validateLocalMcp() runs before any disk mutation, and validateMarketplaceBundle() checks the fetched bundle right after the fetch, before the first write. Both are exported from skills-manager (and unit-tested) so skills:update can reuse them. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
| * write. The docs MCP config is read last by `installDocsMcp`; a bundle missing it would otherwise | ||
| * die on a raw ENOENT after everything else was already applied. | ||
| */ | ||
| export function validateMarketplaceBundle(srcRoot: string, ref: string): void { |
There was a problem hiding this comment.
π High skills/skills-manager.ts:287
validateMarketplaceBundle only checks that forest-docs/.mcp.json exists, so a custom ref with malformed MCP JSON (or a later curated skill missing from the bundle) passes the preflight. installSkills and mergeBlock then write skills and context files before installDocsMcp parses the JSON or the missing skill throws, aborting the command without writing a manifest β leaving the repo in a half-applied state. Parse the MCP JSON and verify every SKILL_SOURCES source path inside validateMarketplaceBundle so both failures surface before any writes begin.
π Reply "fix it for me" or copy this AI Prompt for your agent:
In file @src/services/skills/skills-manager.ts around line 287:
`validateMarketplaceBundle` only checks that `forest-docs/.mcp.json` exists, so a custom ref with malformed MCP JSON (or a later curated skill missing from the bundle) passes the preflight. `installSkills` and `mergeBlock` then write skills and context files before `installDocsMcp` parses the JSON or the missing skill throws, aborting the command without writing a manifest β leaving the repo in a half-applied state. Parse the MCP JSON and verify every `SKILL_SOURCES` source path inside `validateMarketplaceBundle` so both failures surface before any writes begin.
|
Superseded by #814, which carries these commits rebased on The design changed rather than the code: Claude Code and Codex both expose a non-interactive plugin CLI, and both read the same Closing here rather than force-pushing, so the new diff is readable on its own instead of mutating under the old description. Review continues in #814. |
What
forest skills:initβ install Forest's agent skills into the current repo, project-scoped (.claude/skills/+.agents/skills/), so a client's coding agent (Claude Code or Codex) knows Forest with no marketplace add.Fetches from
ForestAdmin/ai-marketplace(tarball at--ref, defaultmain), copies the curated dev-facing skills for both agents, merges a delimited Forest block intoCLAUDE.md/AGENTS.md(preserving user content), wires the Forest docs MCP into.mcp.json, and records the ref + file list in.forest/skills-manifest.json.Flags:
--ref(git ref, defaultmain),--force(overwrite existing skill files). Both agents are always set up β the unused one's files are inert.The distributed set is a curated list in
SKILL_SOURCES(explicit control over what ships; internal/test-only skills stay out).Tested
.mcp.json), manifest round-trip, missing-source fail-loud, and symlink-safe writes on both the destination and the source bundle.fetchMarketplacehas a timeout and maps a bad--ref(404) to a clear message.ai-marketplace@main: skills installed across.claude/+.agents/.Note
Add
forest skills:initcommand to install Forest skills into agent reposforest skills:initCLI command in init.ts that downloads a tar.gz bundle fromForestAdmin/ai-marketplaceat a given git ref and installs curated skills for Claude Code (.claude/skills) and Codex (.agents/skills).CLAUDE.md/AGENTS.mdand wires theforest-docsMCP server into.mcp.json, preserving existing user-defined servers..forest/skills-manifest.jsonto prune stale managed files on re-runs without deleting user-added content..mcp.jsonand the bundle.taras a new runtime dependency; command aborts early if the local.mcp.jsonis malformed or the bundle is missingforest-docs/.mcp.json.Macroscope summarized aea7046.