feat(init): configure Sanity MCP and install agent skill in one combined step#1124
feat(init): configure Sanity MCP and install agent skill in one combined step#1124jwoods02 wants to merge 9 commits into
Conversation
Co-authored-by: Jonah Snider <jonah@jonahsnider.com>
…t-out Skills install is now part of the default `sanity init` flow: no yes/no prompt, times it post-scaffold so the install lands in the new project dir, and runs project-wide for every detected editor with a `skillsCliAgent` mapping. - New `--no-skills` flag mirroring `--no-mcp`, with matching `skillsMode` plumbing alongside `mcpMode`. Both share env / non-interactive gating so e2e / UI tests don't shell out to `npx skills add`. - Editor detection is shared between MCP and skills and only runs when at least one of the two is active. - `installSkills()` in initAction wraps the call in a defensive try/catch so init never fails on a scaffolded project even if `setupSkills` violates its no-throw contract. - Dropped the `fs.mkdir` workaround from `setupSkills` — the scaffolded project directory always exists by the time we run. - `'prompt'` mode and `promptForSkillsSetup` helper are kept in `setupSkills` for a future `sanity skills add` command.
Adds `skills` to @sanity/cli dependencies and resolves the bundled bin via `import.meta.resolve` so init runs the version we ship rather than paying the `npx -y` registry lookup at runtime. Also passes `--project` to `skills add` explicitly instead of relying on the CLI's cwd-based scope auto-detect.
- `sanity skills add` installs Sanity agent skills into the current project for detected AI editors. Same code path as the post-init install: interactive prompt when TTY, auto when not. New `explicit` flag on `setupSkills` surfaces a hint when no eligible editors are detected so the command isn't silent. - `sanity skills update` refreshes any installed project skill whose `skills-lock.json` source points at a Sanity-owned GitHub org (currently `sanity-io` and `sanity-labs`), leaving foreign skills untouched. Runs the upstream `skills update` codepath rather than re-copying via `add`, so it's hash-checked and fast. Plumbed through oclif as a new `skills` topic; `check-topic-aliases.ts` updated to allowlist it.
|
Claude finished @mwritter's task in 2m 53s —— View job ReviewTwo real issues plus one description/code mismatch. 1. Typo in
|
📦 Bundle Stats —
|
| Metric | Value | vs main (7d2118d) |
|---|---|---|
| Internal (raw) | 2.1 KB | - |
| Internal (gzip) | 799 B | - |
| Bundled (raw) | 10.97 MB | - |
| Bundled (gzip) | 2.06 MB | - |
| Import time | 817ms | +3ms, +0.3% |
bin:sanity
| Metric | Value | vs main (7d2118d) |
|---|---|---|
| Internal (raw) | 1023 B | - |
| Internal (gzip) | 486 B | - |
| Bundled (raw) | 9.87 MB | - |
| Bundled (gzip) | 1.77 MB | - |
| Import time | 1.89s | +1ms, +0.0% |
🗺️ View treemap · Artifacts
Details
- Import time regressions over 10% are flagged with
⚠️ - Sizes shown as raw / gzip 🗜️. Internal bytes = own code only. Total bytes = with all dependencies. Import time = Node.js cold-start median.
📦 Bundle Stats — @sanity/cli-core
Compared against main (7d2118d4)
| Metric | Value | vs main (7d2118d) |
|---|---|---|
| Internal (raw) | 96.3 KB | - |
| Internal (gzip) | 22.7 KB | - |
| Bundled (raw) | 21.64 MB | - |
| Bundled (gzip) | 3.43 MB | - |
| Import time | 783ms | +4ms, +0.6% |
🗺️ View treemap · Artifacts
Details
- Import time regressions over 10% are flagged with
⚠️ - Sizes shown as raw / gzip 🗜️. Internal bytes = own code only. Total bytes = with all dependencies. Import time = Node.js cold-start median.
📦 Bundle Stats — create-sanity
Compared against main (7d2118d4)
| Metric | Value | vs main (7d2118d) |
|---|---|---|
| Internal (raw) | 908 B | - |
| Internal (gzip) | 483 B | - |
| Bundled (raw) | 931 B | - |
| Bundled (gzip) | 491 B | - |
| Import time | ❌ ChildProcess denied: node | - |
Details
- Import time regressions over 10% are flagged with
⚠️ - Sizes shown as raw / gzip 🗜️. Internal bytes = own code only. Total bytes = with all dependencies. Import time = Node.js cold-start median.
sanity init and add sanity skills topicsanity init and add sanity skills commands
- Mention the new `sanity skills add` / `sanity skills update` commands in the changeset. - Drop the stale `npx skills add` reference in the init flow comment. - Soften the `skills update` no-op message so it reads correctly whether the lockfile is missing or only contains non-Sanity skills.
Coverage Delta
Comparing 11 changed files against main @ Overall Coverage
|
…tion `fileURLToPath` returns backslash-separated paths on Windows, so the regex needs `[\\/]` instead of a literal `/` to match on both platforms.
sanity init and add sanity skills commandsThere was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 61275bf. Configure here.
| trace, | ||
| workDir, | ||
| }) | ||
| await installSkills() |
There was a problem hiding this comment.
Missing installSkills() call in --env early-return path
Medium Severity
The options.env early-return path exits without calling installSkills(), even though setupMCP has already run and may have populated mcpResult.skillsToInstall. The other two exit paths (initNextJs at line 265 and initStudio/initApp at line 310) both call installSkills(). Since skills install is global (not project-scoped), it doesn't depend on the project directory and the omission appears unintentional.
Additional Locations (2)
Reviewed by Cursor Bugbot for commit 61275bf. Configure here.
There was a problem hiding this comment.
🤔 - we do setup the mcp but return early and dont try to install the skills. But it seems like it was intentionally left out @jwoods02, imo I don't see an issue doing the skills install here as well since we're automatically setting up the mcp already 🤷♂️
mwritter
left a comment
There was a problem hiding this comment.
lgtm - test are passing and I was able to verify locally that each command works as intended.
sanity initsanity init --no-skillssanity init --no-mcpsanity init --no-mcp --no-skillssanity mcp config
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|


Description
sanity initnow sets up the Sanity MCP server and installs thesanity-best-practicesagent skill for detected AI editors in a single combined prompt, so users who already have MCP wired up still get the skill they're missing.This replaces the earlier separate
sanity skillstopic — no new commands are added.What changed in
sanity initA single editor-setup step replaces what used to be two separate flows:
detectAvailableEditors()runs once per init.computeEditorSetupPlandecides, for each editor, whether MCP needs configuring (or re-auth) and whether the skill still needs installing — keying off the global~/.agents/.skill-lock.jsonlockfile (XDG-aware).initApp/initStudio/initNextJsso the project directory exists.The install is global, not project-scoped. That matches how the bundled
skillsCLI lays skills out (~/.agents/<skill>), and how almost every editor reads them — installing for one agent effectively makes it available to most others. Claude Code is the one outlier (reads from~/.claude/skills/), so it still gets its own agent fan-out.Only
sanity-best-practicesis installed; init is opinionated about which skill new projects should get.--no-mcp/--no-skills--no-mcpand--no-skillsare independent. They mask only their own work.--no-mcp --no-skillsshort-circuits editor detection entirely.sanity mcp configureis unchangedThe MCP-only command does not install skills. Skill setup only happens during
sanity init.skillsis bundled as a dependencyThe bundled
skillsCLI is added as a direct dependency of@sanity/cliand resolved viaimport.meta.resolve('skills/bin/cli.mjs', import.meta.url). Renovate keeps it pinned.Trade-off: ~430 KB unpacked in the
@sanity/clipackage, no other tree growth (yamlwas already ours). In return:npxcold-start latency on everysanity init.What to review
resolveEditorSetupordering: detect → validate-tokens → classify → mask (--no-*) → prompt (or auto).computeEditorSetupPlan— the per-editor matrix ofmcpAction×skillAction, and how "fully configured" is detected.readSkillState— reads the global~/.agents/.skill-lock.json(XDG-honoured) to dedup re-installs.--no-mcp/--no-skillsmatrix.initApp/initStudio/initNextJs.Testing
Unit
setupSkills: agents-provided path, editor-derived path, dedup, default skill, empty inputs.computeEditorSetupPlan: every combination of MCP state × skill state, plus editors without a skills-agent mapping.promptForEditorSetup: choice rendering, selection split between MCP/skill, empty selection.readSkillState: global lockfile viaXDG_STATE_HOMEand~/.agents, malformed JSON, absent entries.sanity initmocks updated to cover the combined prompt + skill setup.Manual
sanity init— combined prompt fires, skill installs after scaffold.sanity init --no-skills— MCP still configures, skill is not installed.sanity init --no-mcp— skill still installs, MCP doesn't.sanity init --no-mcp --no-skills— neither runs, editor detection skipped.sanity mcp configure— does not touch skills.AIGRO-4661
Note
Medium Risk
Touches init and MCP flows, spawns a bundled CLI that writes global editor config, and creates MCP tokens; failures are mostly best-effort but broaden the init blast radius.
Overview
sanity initnow offers a single editor setup step that can configure Sanity MCP and install the globalsanity-best-practicesagent skill (via the bundled VercelskillsCLI) for detected AI editors.Editor detection runs once;
setupMCPclassifies each editor (MCP-only, skill-only, combined, or done), honors independent--no-mcp/--no-skillsmasking and a newskillsMode(auto/prompt/skip), and returnsskillsToInstallagent IDs.initActioncallssetupSkillsafter scaffolding (app/studio/Next.js paths).sanity mcp configureexplicitly passesskillsMode: 'skip'so it stays MCP-only.Editor configs gain
skillsCliAgentmappings (e.g. VS Code →github-copilot); skill presence is probed withskills list -g --json. Init telemetry adds askillsSetupstep. Theskillspackage is a direct@sanity/clidependency (pinned bin viaimport.meta.resolve).Note: the changeset text mentions
sanity skills add/updatecommands; this diff only shows init + shared actions, not new oclif topic files.Reviewed by Cursor Bugbot for commit 61275bf. Bugbot is set up for automated code reviews on this repo. Configure here.