Skip to content

feat(cli): install agent skill at user level#284

Merged
kunchenguid merged 3 commits into
mainfrom
fm/skill-user-install-q7
Jun 12, 2026
Merged

feat(cli): install agent skill at user level#284
kunchenguid merged 3 commits into
mainfrom
fm/skill-user-install-q7

Conversation

@kunchenguid

Copy link
Copy Markdown
Owner

Intent

Change no-mistakes init so it stops vendoring the agent skill into every target repo and installs it at user level instead. Old behavior: init wrote SKILL.md into .claude/skills/no-mistakes/ and .agents/skills/no-mistakes/ inside each target repo, polluting every initialized repo with tool-generated files that had to be committed. New behavior: (1) init writes no skill files into the target repo; (2) it installs/refreshes the skill at user level, ~/.claude/skills/no-mistakes/SKILL.md and ~/.agents/skills/no-mistakes/SKILL.md - these two locations were verified against each supported harness's documented user-level skill discovery: Claude Code reads ~/.claude/skills (OpenCode reads it too), and Codex, OpenCode, Rovo Dev, and Pi all read the vendor-neutral ~/.agents/skills; the existing symlink-aware Install logic is reused unchanged with the home directory as root via a new skill.InstallUser(); (3) install stays idempotent and best-effort exactly as before - failure prints the dim 'skipped' note and never fails init; (4) legacy cleanup: when init runs in a repo that still contains a vendored copy, it does NOT delete it - it prints a one-line dim notice that the vendored copy is no longer needed and can be removed (new skill.Vendored helper detects them); (5) deliberate decision: the metadata.internal: true frontmatter marker is dropped entirely - it existed solely to hide vendored per-repo copies from repo skill listings, and the user-level copy is a genuine user installation that should stay discoverable, so InstalledMarkdown() and the markdown(internal bool) split were deleted and only the public Markdown() rendering remains; (6) deliberate decision: this repo's own committed vendored copy (.agents/skills/no-mistakes/SKILL.md and the .claude/skills symlink) is removed and cmd/genskill now renders only the canonical skills/no-mistakes/SKILL.md - the vendored copy's stated rationale was 'identical to what init writes into any target repo', which no longer holds, and keeping it would make init print the legacy notice inside our own repo; contributors get the skill at user level by running init. Init output text now says 'installed for agents at user level'. Docs updated (guides/agents.md, concepts/gate-model.md, reference/cli.md, start-here/introduction.md, quick-start.md, README sample output). Tests: skill package tests rewritten for the single rendering plus new InstallUser (HOME/USERPROFILE isolated via t.Setenv) and Vendored tests; e2e assertSkillInstalled now checks the user-level copies under the harness home, asserts no internal marker, and asserts the repo tree stays untouched; TestInitIsIdempotent now proves a stale user-level copy is refreshed; new TestInitLegacyNotice proves the notice prints and the vendored file is left byte-identical (test name kept deliberately short because the macOS Unix socket path limit applies to NM_HOME under t.TempDir, same as TestInitRepoRename). A dual-location compatibility flag was deliberately left out per the task constraint - user-level only is the desired end state. gofmt, make lint, go test -race ./..., and make e2e all pass; manual verification was done with HOME and NM_HOME pointed at temp dirs, never the real home.

What Changed

  • Updates no-mistakes init to install or refresh the agent skill in user-level Claude and vendor-neutral skill directories instead of writing skill files into each target repo.
  • Leaves existing repo-vendored skill copies untouched while printing a legacy notice that they are no longer needed.
  • Removes the repo-vendored generated skill copy and updates generated skill output, docs, and init/e2e coverage for the new user-level installation behavior.

Risk Assessment

✅ Low: The change is well-bounded to init skill installation, generated skill output, and matching documentation/tests, and I did not find a material correctness, security, or migration issue in the reviewed diff.

Testing

Targeted skill tests, targeted init e2e tests, and a manual isolated no-mistakes init transcript all exercised the user-level install and legacy-notice behavior successfully; the full race suite passed after retrying one transient local git status segfault in an unrelated pipeline-step test.

Evidence: Manual init user-level skill transcript

Source: Manual init user-level skill transcript

Shows clean `init` output with `skill /no-mistakes installed for agents at user level`, PASS checks for both user-level skill locations, PASS that the clean repo has no vendored skill files, PASS that user-level skills do not contain `internal: true`, and a legacy-repo notice with byte-identical preservation.
- Outcome: ⚠️ 1 warning across 1 run (9m38s)

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

🔧 **Review** - 1 issue found → auto-fixed ✅
  • ⚠️ docs/src/content/docs/start-here/quick-start.md:89 - This quick-start sentence still says no-mistakes init installed the /no-mistakes skill into the repo, which contradicts the new user-level installation behavior and can make users look for or expect committed .claude/.agents files that init no longer creates.

🔧 Fix: Fix quick-start skill install wording
✅ Re-checked - no issues remain.

⚠️ **Test** - 1 warning
  • ⚠️ internal/pipeline/steps/test_test.go:70 - The first full go test -race ./... run failed in TestTestStep_FixMode because a git status --porcelain subprocess exited with signal: segmentation fault. The exact test passed on immediate retry, and the full race suite passed on the next run, so this appears to be an intermittent local git/subprocess flake rather than a deterministic failure in this change.
  • go test -race ./internal/skill
  • go test -tags=e2e ./internal/e2e -run 'TestInit(IsIdempotent|LegacyNotice)$' -count=1
  • Manual CLI verification using a locally built ./cmd/no-mistakes binary with isolated HOME, USERPROFILE, and NM_HOME: initialized a clean git repo and checked user-level skill files plus absence of repo-vendored skill files; initialized a repo with a legacy .agents/skills/no-mistakes/SKILL.md and checked the notice plus byte-identical preservation.
  • go test -race ./... (first run exposed transient git status --porcelain segfault in TestTestStep_FixMode)
  • go test -race ./internal/pipeline/steps -run '^TestTestStep_FixMode$' -count=1
  • go test -race ./... (retry passed)
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

…to repos

`no-mistakes init` no longer writes SKILL.md into each target repo's
.claude/skills and .agents/skills. It now installs/refreshes the skill at
user level: ~/.claude/skills/no-mistakes/SKILL.md (Claude Code, OpenCode)
and ~/.agents/skills/no-mistakes/SKILL.md (Codex, OpenCode, Rovo Dev, Pi).
Both locations were verified against each harness's documented user-level
skill discovery. The symlink-aware install logic is reused unchanged with
the home directory as root, and install stays idempotent and best-effort.

When init finds a vendored copy left by an older version it prints a
one-line notice that the copy can be removed, without touching it.

The metadata.internal frontmatter marker is gone: it existed solely to
hide vendored per-repo copies from repo skill listings, and the user-level
copy is a genuine user installation that should stay discoverable. With no
vendored copies anywhere, InstalledMarkdown() is deleted, genskill renders
only the canonical skills/no-mistakes/SKILL.md, and this repo's own
committed .agents/skills copy and .claude/skills symlink are removed.
@kunchenguid kunchenguid merged commit f6760aa into main Jun 12, 2026
9 checks passed
@kunchenguid kunchenguid deleted the fm/skill-user-install-q7 branch June 12, 2026 05:38
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.

1 participant