Auto-install the coding agent skill during install.sh/install.ps1 - #61
Open
mattpodwysocki wants to merge 1 commit into
Open
mattpodwysocki wants to merge 1 commit into
mattpodwysocki wants to merge 1 commit into
Conversation
AGI-1149 (Phase 1 of the coding-agent-setup epic): mapbox generate-skills and mapbox agent-skills install already auto-detect the caller's coding agent, but only run if someone remembers to invoke them after installing the CLI. Both installers now run them right after placing the binary. - src/skill_dest.rs: "no agent detected, none named with --agent/--global/ --dir" now carries a stable no_agent_detected CliError code instead of a plain anyhow error with the generic `error` code. Same message, same non-zero exit for every existing caller — only the code a caller can match on is new. This is what lets the installers tell "nothing to do" apart from a real failure without parsing JSON, and it comes for free from the existing `?` early-return: generate-skills and agent-skills install/update already return before making any network call in this case, so no other Rust changes were needed. - install.sh/install.ps1: a new best-effort, silent step after the binary is placed. --global (not the project-scoped default), since the installer runs in whatever directory the shell happened to be in, not a project. Tries `agent-skills install` first and falls back to `agent-skills update --yes` on the one error code that means "already installed from a previous run of this same script" — never `--force`, which would blindly discard anything a user customized. Opt out with MAPBOX_CLI_NO_AGENT_SETUP, same boolean spellings as MAPBOX_CLI_NO_TELEMETRY. install.ps1 additionally switches $ErrorActionPreference to Continue around both calls, the same fix test-install.ps1's own Invoke-Installer already needed for the identical Windows PowerShell 5.1 native-stderr-is-terminating quirk. - test-install.sh/test-install.ps1: three new scenarios each (detected agent, none detected, opt-out), plus a HOME-isolated per-case environment and a fake generate-skills/agent-skills stand-in so the scenarios run for real rather than against a stub that doesn't know the new subcommands. The already-installed-then-update fallback and every other path were also verified by hand against the real compiled binary and the real network (fresh install, reinstall, and a local edit restored without any prompt, piped and run locally both) — see the PR body for specifics; not something the offline harness can exercise on its own. Not verified: install.ps1's actual behavior on real Windows PowerShell 5.1 — this machine can only run cross-platform pwsh, and test-install.ps1's own C# stand-in binary (built via csc.exe, Windows only) wasn't extended to understand the new subcommands, since iterating on it needs a real Windows machine. The PowerShell logic itself was verified via pwsh against the real binary instead, including under an explicit $ErrorActionPreference = 'Stop' to match install.ps1's own. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
zmofei
requested changes
Sep 29, 2026
zmofei
left a comment
Member
There was a problem hiding this comment.
Thanks for this, the goal makes sense. But the installer must not set up agent skills without the user's explicit, interactive consent.
As written, both installers do this by default whenever ~/.claude, ~/.codex, etc. exist:
- They write into directories this CLI doesn't own, and download the whole Mapbox Agent Skills library, without asking.
agent-skills install/updateoutput is discarded, so the user isn't even told it happened.- On reinstall,
agent-skills update --yesoverwrites files the user edited, with no prompt. That contradicts the changelog's "a customized skill directory is never silently discarded". - The only way out is
MAPBOX_CLI_NO_AGENT_SETUP, which someone runningcurl … | shwon't know about beforehand. An opt-out nobody sees in time isn't a choice.
Requested changes:
- Ask before installing. In an interactive terminal, prompt via
/dev/tty(and the PowerShell equivalent), naming the detected agent and what will be written where. Install only on an explicit yes. - No prompt possible (CI, no TTY): skip the step and print one line telling the user how to run it by hand (
mapbox generate-skills --global,mapbox agent-skills install --global). - Drop
--yesfromupdate. If the user has modified files, skip and say so rather than overwrite. - When something is installed, print what and where.
The no_agent_detected error code is useful on its own. Consider splitting it into a separate PR, and documenting it in docs/commands.md with a test, since it's a new machine-readable contract.
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.
What
AGI-1149 (Phase 1 of the coding-agent-setup epic):
mapbox generate-skillsand
mapbox agent-skills installalready auto-detect the caller's codingagent, but only run if someone remembers to invoke them after installing
the CLI. Both installers now run them right after placing the binary,
so an agent can use the CLI's skill immediately with no extra step.
Rust: a stable error code, not a behavior change
src/skill_dest.rs'sresolve()returned a plainanyhow!when no codingagent was detected and none was explicitly named with
--agent/--global/--dir. That's the common case for most machines running the installer(no coding agent at all), and the error had no way to be told apart from
an unrelated internal failure,
-o jsonrendered both with the samegeneric
"code":"error".Fixed: that path now returns a
CliErrorwith a stableno_agent_detectedcode. Same message, same non-zero exit, for every existing caller, human
or script. This is not a behavior change, exit codes are a documented
promise in this repo (CONTRIBUTING.md#compatibility), and I checked that
before touching it.
No other Rust changes were needed.
generate-skills/agent-skills install/updatealready return via?before making any network callin this case (confirmed by timing a real run: 0.038s against a scratch
$HOMEwith no agent, versus a real tarball fetch when one is detected),so the installers never pay for a wasted network call on a plain human
install either.
install.sh / install.ps1
A new best-effort, silent step after the binary is placed and before the
Tilesets CLI section:
--global, not the default project-scoped write: the installer runs inwhatever directory the shell happened to be in, not a project, so the
skill goes under the agent's own home instead.
agent-skills installfirst; on a reinstall/upgrade this failswith
already_installed(the skill directory is already there from theprevious run), and it falls back to
agent-skills update --yesratherthan the command's own suggested
--force, which would blindly discardanything a user customized in that directory.
(see above); a genuine failure (no network, disk full, etc.) is treated
the same way, matching this script's own established best-effort
precedent elsewhere.
MAPBOX_CLI_NO_AGENT_SETUP, same boolean spellingsas
MAPBOX_CLI_NO_TELEMETRY.$ErrorActionPreference = 'Continue': both commands write theirfailures to stderr on purpose, and a child writing to stderr is a
terminating
NativeCommandErrorin Windows PowerShell underStop(set globally at the top of the script), the exact problem
test-install.ps1's ownInvoke-Installerhelper already had to workaround for the same reason, so this reuses that fix rather than
reinventing one.
Tests
test-install.sh/test-install.ps1each get three new scenarios(detected agent, none detected, opted out), a
HOME-isolated per-caseenvironment (new: nothing previously touched
$HOME, and this neededto, without leaking into whoever's real coding agent setup happens to be
present on the machine running the suite), and a fake
generate-skills/agent-skillsstand-in so these run for real ratherthan against a stub that only understood
--version.Every path was also verified by hand against the real compiled binary
and the real network, not just the stub:
~/.claude/skills/....already_installedcorrectly triggers theupdatefallback.content, with zero prompt, piped (
</dev/null) and run locally in areal terminal both.
MAPBOX_CLI_NO_TELEMETRY's acceptedfalse-spellings (
0,off,no,false) behave the same for the newvariable.
Not verified: real Windows PowerShell 5.1. This machine only runs
cross-platform
pwsh, andtest-install.ps1's own C# stand-in binary(built via
csc.exe, Windows-only) wasn't extended to understand the newsubcommands, since iterating on that needs a real Windows machine, which I
don't have here. The PowerShell logic itself was verified via
pwshagainst the real compiled binary instead, including under an explicit
$ErrorActionPreference = 'Stop'to match what install.ps1 actually runsunder. Worth a manual check on Windows before this ships, or leaning on CI
if it covers this.
Verification
cargo build/fmt/clippy --all-targets -- -D warnings/testallclean.
shellcheck -s shclean on both modified shell scripts.test-install.shandtest-install.ps1both pass in full, including thesix new scenarios.
PSScriptAnalyzerrun on install.ps1: the two newwarnings it raised (
Write-Host, empty catch block) both already existdozens of times elsewhere in the same file, not a new class of issue.
🤖 Generated with Claude Code