Skip to content

feat(init): configure Sanity MCP and install agent skill in one combined step#1124

Open
jwoods02 wants to merge 9 commits into
mainfrom
aigro-4661/configure-agent-skills-2
Open

feat(init): configure Sanity MCP and install agent skill in one combined step#1124
jwoods02 wants to merge 9 commits into
mainfrom
aigro-4661/configure-agent-skills-2

Conversation

@jwoods02
Copy link
Copy Markdown
Contributor

@jwoods02 jwoods02 commented May 21, 2026

Description

sanity init now sets up the Sanity MCP server and installs the sanity-best-practices agent 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 skills topic — no new commands are added.

What changed in sanity init

A single editor-setup step replaces what used to be two separate flows:

  • Detect once. detectAvailableEditors() runs once per init.
  • Classify per editor. computeEditorSetupPlan decides, for each editor, whether MCP needs configuring (or re-auth) and whether the skill still needs installing — keying off the global ~/.agents/.skill-lock.json lockfile (XDG-aware).
  • Prompt once. A single checkbox prompt covers both MCP setup and skill install. Editors that are already done show up as a one-line "already configured" confirmation, not in the prompt.
  • Install after scaffold. Skills install runs after initApp / initStudio / initNextJs so the project directory exists.

The install is global, not project-scoped. That matches how the bundled skills CLI 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-practices is installed; init is opinionated about which skill new projects should get.

--no-mcp / --no-skills

  • --no-mcp and --no-skills are independent. They mask only their own work.
  • --no-mcp --no-skills short-circuits editor detection entirely.
  • When MCP is skipped but skills aren't, the prompt still fires so the user can opt in to skill-only install.
  • We never claim "skill installed" when MCP wasn't — messaging tracks the actual outcome.

sanity mcp configure is unchanged

The MCP-only command does not install skills. Skill setup only happens during sanity init.

skills is bundled as a dependency

The bundled skills CLI is added as a direct dependency of @sanity/cli and resolved via import.meta.resolve('skills/bin/cli.mjs', import.meta.url). Renovate keeps it pinned.

Trade-off: ~430 KB unpacked in the @sanity/cli package, no other tree growth (yaml was already ours). In return:

  • Deterministic version across user installs — no surprise behaviour drift.
  • No npx cold-start latency on every sanity init.
  • Upstream changes land via a Renovate PR we can review before publishing.

What to review

  • resolveEditorSetup ordering: detect → validate-tokens → classify → mask (--no-*) → prompt (or auto).
  • computeEditorSetupPlan — the per-editor matrix of mcpAction × skillAction, and how "fully configured" is detected.
  • readSkillState — reads the global ~/.agents/.skill-lock.json (XDG-honoured) to dedup re-installs.
  • --no-mcp / --no-skills matrix.
  • Init ordering: skills install runs after 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 via XDG_STATE_HOME and ~/.agents, malformed JSON, absent entries.
  • sanity init mocks 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 init now offers a single editor setup step that can configure Sanity MCP and install the global sanity-best-practices agent skill (via the bundled Vercel skills CLI) for detected AI editors.

Editor detection runs once; setupMCP classifies each editor (MCP-only, skill-only, combined, or done), honors independent --no-mcp / --no-skills masking and a new skillsMode (auto / prompt / skip), and returns skillsToInstall agent IDs. initAction calls setupSkills after scaffolding (app/studio/Next.js paths). sanity mcp configure explicitly passes skillsMode: 'skip' so it stays MCP-only.

Editor configs gain skillsCliAgent mappings (e.g. VS Code → github-copilot); skill presence is probed with skills list -g --json. Init telemetry adds a skillsSetup step. The skills package is a direct @sanity/cli dependency (pinned bin via import.meta.resolve).

Note: the changeset text mentions sanity skills add / update commands; 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.

jwoods02 and others added 4 commits May 21, 2026 09:56
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.
@jwoods02 jwoods02 requested a review from a team as a code owner May 21, 2026 14:19
@claude
Copy link
Copy Markdown

claude Bot commented May 21, 2026

Claude finished @mwritter's task in 2m 53s —— View job


Review

Two real issues plus one description/code mismatch.


1. Typo in --skills flag description (bug, easy fix)

packages/@sanity/cli/src/commands/init.ts:185:

description: 'Install Sanity agent skills globally for detecated AI editors',

"detecated" → "detected". The commit 951b4e9 is titled fix: changeset text, skills flag description but the typo is still there.

Fix this →


2. --env early-return path skips skills install (bug)

packages/@sanity/cli/src/actions/init/initAction.ts:270-285 returns without calling installSkills(), even though setupMCP has already produced mcpResult.skillsToInstall. The other two exit paths (line 265 after initNextJs, line 310 after initStudio/initApp) both call it.

Since skills install is global (-g), it has no dependency on the project directory and the omission looks unintentional. Cursor and @mwritter both flagged this — please either move await installSkills() above the trace.complete(); return here, or add a one-line comment explaining the intentional asymmetry.

Fix this →


3. PR description mismatch — --no-mcp does not prompt

The description says: "When MCP is skipped but skills aren't, the prompt still fires so the user can opt in to skill-only install."

But init.ts:227-230 only ever sets skillsMode to 'auto' or 'skip' — never 'prompt'. With --no-mcp (interactive, prod), the code path is mcpMode='skip' + skillsMode='auto'shouldAuto = true in setupMCP.ts:230 → skills install without a prompt.

Not a code bug if auto-install is the intent, but the PR description is misleading. Either update the PR description, or set skillsMode='prompt' when flags.yes is false to match the described behavior.


Other observations (non-blocking)

  • setupSkills is best-effort and never throws — correct.
  • readSkillState returns empty set on any error, so re-installs are idempotent — correct.
  • Changeset (.changeset/pr-1079.md): minor bump is appropriate; copy is one concise sentence and follows product-copy conventions. LGTM.
  • The PR body still references ~/.agents/.skill-lock.json and "lockfile (XDG-aware)" reading, but the actual implementation in readSkillState.ts calls skills list -g --json. Worth updating the description for accuracy.
  • Test coverage is reasonable. setupSkills (92.6%) and readSkillState (100%) are well covered. The initAction.ts coverage drop (-3.9%) reflects the new installSkills closure — adding a test that asserts setupSkills is invoked in the --env path would naturally come with the fix for issue 2.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 21, 2026

📦 Bundle Stats — @sanity/cli

Compared against main (7d2118d4)

@sanity/cli

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.

@jwoods02 jwoods02 changed the title feat: configure agent skills via sanity init and add sanity skills topic feat: configure agent skills via sanity init and add sanity skills commands May 21, 2026
- 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.
Comment thread packages/@sanity/cli/src/actions/init/initAction.ts
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 21, 2026

Coverage Delta

File Statements
packages/@sanity/cli/src/actions/init/initAction.ts 93.2% (- 3.9%)
packages/@sanity/cli/src/actions/init/types.ts 100.0% (±0%)
packages/@sanity/cli/src/actions/mcp/editorConfigs.ts 100.0% (±0%)
packages/@sanity/cli/src/actions/mcp/promptForMCPSetup.ts 100.0% (±0%)
packages/@sanity/cli/src/actions/mcp/setupMCP.ts 99.2% (- 0.8%)
packages/@sanity/cli/src/actions/skills/readSkillState.ts 100.0% (new)
packages/@sanity/cli/src/actions/skills/setupSkills.ts 92.6% (new)
packages/@sanity/cli/src/commands/init.ts 100.0% (±0%)
packages/@sanity/cli/src/commands/mcp/configure.ts 90.0% (±0%)
packages/@sanity/cli/src/services/mcp.ts 77.8% (- 22.2%)
packages/@sanity/cli/src/telemetry/init.telemetry.ts 100.0% (±0%)

Comparing 11 changed files against main @ 7d2118d4509f4d0a7406b1e262d17f4b531d1d07

Overall Coverage

Metric Coverage
Statements 84.4% (+ 0.1%)
Branches 74.5% (+ 0.2%)
Functions 84.2% (+ 0.0%)
Lines 84.8% (+ 0.1%)

…tion

`fileURLToPath` returns backslash-separated paths on Windows, so the
regex needs `[\\/]` instead of a literal `/` to match on both platforms.
@jwoods02 jwoods02 changed the title feat: configure agent skills via sanity init and add sanity skills commands feat(init): configure Sanity MCP and install agent skill in one combined step May 27, 2026
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ 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()
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 61275bf. Configure here.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔 - 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
mwritter previously approved these changes May 28, 2026
Copy link
Copy Markdown
Contributor

@mwritter mwritter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm - test are passing and I was able to verify locally that each command works as intended.

  • sanity init
  • sanity init --no-skills
  • sanity init --no-mcp
  • sanity init --no-mcp --no-skills
  • sanity mcp config

@mwritter mwritter requested a review from a team May 29, 2026 13:02
@socket-security
Copy link
Copy Markdown

socket-security Bot commented May 29, 2026

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addednpm/​skills@​1.5.77910010097100
Addednpm/​@​vercel/​detect-agent@​1.2.39910010091100

View full report

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants