Skip to content

feat(init): a picker row per harness, grouped by where it was detected - #561

Merged
theCodeDrift merged 2 commits into
mainfrom
feat/553-harness-picker-rows
Oct 21, 2026
Merged

theCodeDrift merged 2 commits into
mainfrom
feat/553-harness-picker-rows

Conversation

@theCodeDrift

Copy link
Copy Markdown
Member

A Codex user on 0.13 did not find Codex in the setup wizard's tool list. They picked .agents only because they happened to know Codex reads it. Users know which harness they run, not which skill directory it reads, and the single .agents/ row from 80f3934a fell back to "Agent Skills" when nothing was detected, which names no harness at all.

What changes

  • One row per harness: Claude Code, OpenCode, Cursor, Codex, Gemini CLI, Crush, Devin, plus "Other Agent Skills harnesses (.agents/)". Several rows can share a directory; the install plan, manifest and summary stay keyed by directory, so two checked .agents/ rows still install once.
  • Three sections via groupMultiselect: Detected in this project (pre-checked), Detected on this machine (unchecked), Other harnesses.
  • Machine detection checks each harness's documented home location and override (CLAUDE_CONFIG_DIR, CODEX_HOME, CURSOR_CONFIG_DIR, OPENCODE_CONFIG_DIR, GEMINI_CLI_HOME, CRUSH_GLOBAL_CONFIG/CRUSH_GLOBAL_DATA, ~/.config/devin). It only decides the section; nothing is written outside the project.
  • Devin is new. Its docs place project skills in .devin/skills, and it also reads .agents/skills, so it installs into .devin/ when the project has one and .agents/ otherwise. Taskless never creates .devin/.
  • Claude Code always installs into .claude/. The issue's "Claude Multi-Harness (.agents)" row is not offered: Claude Code reads AGENTS.md when there is no CLAUDE.md, but never anything under .agents/ (code.claude.com/docs/en/memory), so a skill there would be invisible to it.
  • Checking Codex writes its permission rule, without needing .codex/ in the project first. --no-interactive keeps using detection, which the written rules file satisfies on later runs.
  • agentsRowLabel is removed and the SHIM_TARGETS comment rewritten to say why a row per harness is what makes a harness discoverable.
◆  Which tools do you want to enable Taskless for?
│   Detected in this project
│    ◼ Claude Code (.claude/)
│   Detected on this machine
│    ◻ Codex (.agents/)
│    ◻ Gemini CLI (.agents/)
│   Other harnesses
│    ◻ OpenCode (.opencode/)
│    ◻ Cursor (.cursor/)
│    ◻ Crush (.agents/)
│    ◻ Devin (.agents/)
│    ◻ Other Agent Skills harnesses (.agents/)
└

Verification

  • pnpm typecheck, pnpm lint, and the full CLI suite pass.
  • Ran the built wizard in a pseudo-TTY: the picker above is the captured frame. In an empty project with Codex only in a scratch home, checking Codex alone wrote .agents/skills/taskless/SKILL.md and .codex/rules/taskless.rules, and the scratch home was unchanged.

OpenSpec

harness-picker-rows is archived on this PR. "Wizard prompts the user to choose install locations" is REMOVED and replaced by the ADDED "Wizard offers a row per harness", since several of its label scenarios are intentionally superseded. The permissions table's Codex row is MODIFIED in full. Delivery shape: single PR, patch changeset.

Fixes #553

@theCodeDrift

Copy link
Copy Markdown
Member Author

@claude /review

@github-actions

github-actions Bot commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

Claude finished @theCodeDrift's task in 3m 36s —— View job


Review complete

Review mode: incremental — read 0 prior review thread(s) before reviewing. The .prior-review.json snapshot contains no prior review threads, reviews, or inline comments (only the @claude /review trigger comment itself), so this is the first review of this PR. Nothing to classify as already-addressed or still-open; everything below is [New].

Todo list

  • Read .prior-review.json (empty — first review)
  • Fetch PR diff and metadata
  • Review changed files for correctness, security, performance, tests, clarity
  • Post inline comments for concrete issues
  • Post final summary

Summary

This is a clean, well-scoped change. I traced the row→directory resolution end to end (TOOLS catalog → rows() → locationChoices pre-check/section logic → resolveSelection → buildInstallPlan → syncPermissions's new codex flag) and the logic holds together:

  • The covered set in locationChoices is deliberately computed once, before the manifest-coverage loop, so it reflects only project-detected rows (the spec's clause (a)), not rows added by the loop itself (clause (b)) — this looks correct on first read but is subtle enough to be worth a one-line comment explaining why it's a snapshot rather than updated per iteration.
  • codex (checked Codex row / detected-in-project in --no-interactive) always coincides with .agents being a selected directory, since Codex's installDir is fixed at .agents with no ownDir — so harnessesFor dropping the old selected.includes(".agents") guard doesn't create a decoupled state.
  • Devin's ownDir resolution is the one harness-specific wrinkle (only harness where the row's directory depends on project detection), and the pre-check/resolve code and tests correctly follow it through, including the "machine-detected only" case still installing to .agents.
  • Test coverage (install.test.ts, wizard-steps.test.ts, permissions.test.ts, wizard-integration.test.ts) is thorough and maps directly onto the new spec scenarios, including the env-override edge cases (empty override treated as unset, override naming a missing directory, file vs. directory).

One finding worth a look, posted inline:

  • [New] ToolDescriptor.readsAgentSkills (packages/cli/src/install/install.ts) is now dead. It was read only by agentsRowLabel, which this PR removes; nothing else references the field (confirmed via search across src/ and test/). It's set on five catalog entries but has no remaining effect on behavior — worth deleting in this PR or a fast follow, since a field named for "what the picker shows" that the picker no longer reads is exactly the kind of drift that caused issue Installer picker overhaul: a row per harness, and harnesses detected on this machine #553 (a label not reflecting what a harness actually does).

No correctness, security, or test-adequacy issues found beyond that — the machine-detection functions, Codex permission-rule gating, and Devin's directory fallback are all behaving as documented and specified.

Comment thread packages/cli/src/install/install.ts Outdated
@theCodeDrift

Copy link
Copy Markdown
Member Author

Re: @github-actions — "Claude finished @theCodeDrift's task in 3m 36s"…
#561 (comment)

The one finding (dead readsAgentSkills) is fixed in 196e681. I also added the suggested comment explaining why covered is a snapshot of the project-detected rows.

— AI Coding Agent

Every catalog harness gets its own row, so a user finds the harness they
run without knowing which skill directory it reads. Rows are grouped into
harnesses detected in the project (pre-checked), on this machine
(unchecked), and the rest. Machine detection only moves a row up; nothing
is written outside the project. Devin joins the catalog, installing into
.devin/ when the project has it. Checking Codex writes its permission
rule without needing .codex/ first.
It was read only by agentsRowLabel, removed with the per-harness picker
rows. Also note why the picker's covered set is a snapshot.
@theCodeDrift
theCodeDrift force-pushed the feat/553-harness-picker-rows branch from 196e681 to 571167c Compare October 21, 2026 06:02
@theCodeDrift
theCodeDrift merged commit d5112cb into main Oct 21, 2026
4 checks passed
@theCodeDrift
theCodeDrift deleted the feat/553-harness-picker-rows branch October 21, 2026 06:05
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.

Installer picker overhaul: a row per harness, and harnesses detected on this machine

1 participant