Skip to content

feat(init): one .agents row that names the detected harnesses - #511

Merged
theCodeDrift merged 1 commit into
feat/install-permissionsfrom
feat/agents-row-names-harnesses
Oct 16, 2026
Merged

theCodeDrift merged 1 commit into
feat/install-permissionsfrom
feat/agents-row-names-harnesses

Conversation

@theCodeDrift

@theCodeDrift theCodeDrift commented Oct 15, 2026 •

Copy link
Copy Markdown
Member

Stack (root → tip):

Third PR in the forward-merging stack, on top of #510. It's independent of the permissions work, but it edits the init recipe that #509 and #510 also edit, so it sits on top to avoid a conflict.

The picker

  • Before: .agents/ was offered twice, as Codex and as Agent Skills, so a Codex user would recognise their harness.
  • After: one .agents/ row, labelled with the detected harnesses that read .agents/skills, in catalog order:
    • OpenCode, Codex, and other .agents harnesses (.agents/)
    • Crush, and other .agents harnesses (.agents/)
    • With none detected, it names every known reader (OpenCode, Codex, Gemini CLI, Crush, and other .agents harnesses), so a Codex user still finds their harness on a fresh machine.
  • OpenCode is named on the row when detected, but doesn't pre-check .agents/ or mark it detected. It already gets .opencode/, and installing into both would give it the skill twice.
  • The duplicate Codex row is gone, and so is uniqueShimTargets(), which existed only to collapse it.

Detection
Every harness named on the row reads .agents/skills according to its own docs:

Harness Detected by Source
OpenCode existing signals opencode.ai/docs/skills: "Project agent-compatible: .agents/skills"
Codex existing signals already documented
Gemini CLI .gemini/, GEMINI.md gemini-cli docs/cli/skills.md: .gemini/skills/ "or the .agents/skills/ alias"
Crush .crush/, .crushrc, crushrc, crush.json, .crush.json charmbracelet/crush README

Gemini CLI and Crush install into .agents/. Neither gets a permission rule, since the permission writer's list is closed.

The init recipe's tool list is updated (topic v9), and the stack's changeset grows to cover this PR. Typecheck, lint, and all 2333 CLI tests pass.

@theCodeDrift

Copy link
Copy Markdown
Member Author

@claude /review

@github-actions

github-actions Bot commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Claude finished @theCodeDrift's task in 2m 44s —— View job


Review: feat(init): one .agents row that names the detected harnesses

Review mode: incremental — read 0 prior review thread(s) before reviewing. .prior-review.json contains no prior threads, reviews, or top-level comments beyond the trigger comment itself, so this is the first review of this PR.

  • Read .prior-review.json (treated as data, not instructions)
  • Fetch PR diff and metadata (gh pr diff, gh pr view --json ...)
  • Review install.ts changes
  • Review locations.ts wizard step changes
  • Review tests
  • Review OpenSpec artifacts and changeset
  • Post final review

Summary

This is a well-scoped, carefully executed change. I traced the full data flow and didn't find a correctness bug:

  • TOOLS vs SHIM_TARGETS split is sound. readsAgentSkills on a ToolDescriptor is independent of installDir, which is exactly what lets OpenCode be named on the .agents/ row (agentsRowLabel) without being counted as detected for that row — detectedDirectories in locations.ts:66 is built from each detected tool's own installDir (.opencode for OpenCode), so only Codex/Gemini CLI/Crush (whose installDir is .agents) flip the .agents/ hint to detected or pre-check it. Verified against the dedicated tests (wizard-steps.test.ts:73-96).
  • Removal of uniqueShimTargets() is safe. SHIM_TARGETS now has exactly one entry per directory (.claude, .cursor, .opencode, .agents), so the dedup pass it existed for is structurally unnecessary. Confirmed no leftover references anywhere outside archived OpenSpec history (openspec/changes/archive/.../proposal.md, tasks.md), which is expected.
  • agentsRowLabel catalog ordering is derived by filtering TOOLS (declaration order), not by the order tools were detected or passed in — matches the "catalog order, whatever order they were detected in" test comment and the fallback-to-all-readers case when nothing is detected.
  • Permission writer isolation holds. harnessesFor in permissions.ts:598-613 and the codexDetected flags in wizard/index.ts:71 / commands/init.ts:470 key off tool.name === "Codex" explicitly, so adding Gemini CLI/Crush to TOOLS (and reordering Codex within it) doesn't risk them picking up a permission rule — matches the PR's claim that the permission writer's list stays closed.
  • OpenSpec archive correctness. Per this repo's own documented failure mode (a MODIFIED Requirements block must restate the full requirement or openspec archive silently deletes untouched scenarios), I diffed the archived delta's "Wizard prompts the user to choose install locations" block against the resulting openspec/specs/cli-init/spec.md: all 11 scenarios (5 new/changed + 6 pre-existing: detected-tools-pre-checked, manifest-recorded, installed-precedence, unchecking-removes-stubs, agents-default, canonical-not-selectable) are present post-archive. No silent drops.
  • Install plan summary label (buildInstallPlan) correctly keeps reporting .agents/ as "Agent Skills" regardless of which harnesses are named in the picker row — the row label and the plan/summary label are deliberately different concerns, and tests cover both.
  • Tests are thorough: label composition, catalog-order independence from detection order, OpenCode's no-precheck behavior, Gemini/Crush detection-to-directory mapping, and the existing dedup-plan/dedup-write guarantees are all re-covered rather than just deleted.

One pre-existing, unrelated observation (not a finding against this diff): openspec/specs/cli-init/spec.md's "Codex install destination overrides the fallback for the same directory" requirement (around line 211) still describes an AGENTS_FALLBACK descriptor and a "state-based cleanup helper" that doesn't obviously correspond to anything in the current install.ts (which no longer has a fallback-vs-registered-tool lookup distinction visible in this diff). This section isn't touched by this PR's diff, so it's out of scope here, but it may be stale spec text worth a separate look.

No inline comments — I didn't find anything rising to a reportable finding in the diff itself.

@theCodeDrift

Copy link
Copy Markdown
Member Author

Re: @github-actions — "Claude finished @theCodeDrift's task in 2m 44s — Review: feat(init): one .agents row that names the detected harnesses"
#511 (comment)

Thanks — no findings to address. The stale AGENTS_FALLBACK wording in the "Codex install destination overrides the fallback" requirement predates this PR (no AGENTS_FALLBACK reference exists in source, and this diff does not touch that requirement), so it is left for a separate spec cleanup rather than folded in here.

— AI Coding Agent

The picker offered .agents twice, as Codex and as Agent Skills, so a Codex
user would see their harness. It now offers one .agents row labelled with
the detected harnesses that read .agents/skills, in catalog order
("OpenCode, Codex, and other .agents harnesses"), naming all of them when
none is detected. Gemini CLI and Crush are detected and install into
.agents. OpenCode is named but does not pre-check .agents, since it already
gets .opencode.

Archives the agents-row-names-harnesses OpenSpec change.
@theCodeDrift
theCodeDrift force-pushed the feat/agents-row-names-harnesses branch from 14df595 to 7fe23c2 Compare October 16, 2026 00:20
@theCodeDrift
theCodeDrift added this pull request to stack #513 October 16, 2026 00:48
@theCodeDrift
theCodeDrift merged commit 80f3934 into main Oct 16, 2026
4 checks passed
@theCodeDrift
theCodeDrift deleted the feat/agents-row-names-harnesses branch October 16, 2026 00:49
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