Skip to content

feat(onboarding): ask users to choose coding agent#347

Open
Nima-Naderi wants to merge 2 commits into
mainfrom
codex/agent-onboarding-choice
Open

feat(onboarding): ask users to choose coding agent#347
Nima-Naderi wants to merge 2 commits into
mainfrom
codex/agent-onboarding-choice

Conversation

@Nima-Naderi
Copy link
Copy Markdown
Collaborator

Summary:

  • replace fixed Claude/Codex setup shortcuts with an explicit coding-agent chooser in onboarding notes
  • extend setup terminal actions for Claude, Codex, OpenCode, Gemini CLI, and shell-only setup while showing manual guidance for unsupported choices
  • align the landing prompt, public skills.md, local Matrix skill, onboarding plugin skill, and developer workflow docs around detect + confirm behavior
  • fix a React Doctor finding in MarkdownViewer and harden a flaky onboarding tool-pack timeout test

Tests:

  • flox activate -- bun run typecheck
  • flox activate -- bun run check:patterns
  • flox activate -- npx react-doctor@latest shell
  • flox activate -- bun run test tests/gateway/onboarding-tool-packs.test.ts
  • flox activate -- bun run test tests/shell/manual-setup-stickers.test.tsx tests/shell/terminal-launch.test.ts tests/shell/markdown-viewer-svg.test.tsx
  • flox activate -- bun run test

Invariants:

  • Source of truth: matrix run remains command-explicit; the onboarding chooser only drives guided UI/copy, not a saved CLI default.
  • Lock/transaction scope: no database writes or transactions are introduced by the onboarding agent-choice flow.
  • Acceptable orphan states: unsupported agent choices show manual setup guidance and do not claim launch or verification support.
  • Auth source of truth: installed/auth-needed suggestions still come from the existing /api/agents signal; no credentials or provider secrets are accepted in the UI.
  • Deferred scope: full auth/probe integrations for OpenClaw, Cursor/Cline, Custom, and other non-terminal agents remain out of scope.

Summary:
- replace fixed Claude/Codex setup shortcuts with an explicit coding-agent chooser in onboarding notes
- extend setup terminal actions for Claude, Codex, OpenCode, Gemini CLI, and shell-only setup while showing manual guidance for unsupported choices
- align the landing prompt, public skills.md, local Matrix skill, onboarding plugin skill, and developer workflow docs around detect + confirm behavior
- fix a React Doctor finding in MarkdownViewer and harden a flaky onboarding tool-pack timeout test

Tests:
- flox activate -- bun run typecheck
- flox activate -- bun run check:patterns
- flox activate -- npx react-doctor@latest shell
- flox activate -- bun run test tests/gateway/onboarding-tool-packs.test.ts
- flox activate -- bun run test tests/shell/manual-setup-stickers.test.tsx tests/shell/terminal-launch.test.ts tests/shell/markdown-viewer-svg.test.tsx
- flox activate -- bun run test

Invariants:
- Source of truth: matrix run remains command-explicit; the onboarding chooser only drives guided UI/copy, not a saved CLI default.
- Lock/transaction scope: no database writes or transactions are introduced by the onboarding agent-choice flow.
- Acceptable orphan states: unsupported agent choices show manual setup guidance and do not claim launch or verification support.
- Auth source of truth: installed/auth-needed suggestions still come from the existing /api/agents signal; no credentials or provider secrets are accepted in the UI.
- Deferred scope: full auth/probe integrations for OpenClaw, Cursor/Cline, Custom, and other non-terminal agents remain out of scope.
@vercel
Copy link
Copy Markdown

vercel Bot commented Jun 3, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
matrix-os-www Ready Ready Preview, Comment Jun 3, 2026 7:51pm

Request Review

Copy link
Copy Markdown
Collaborator Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@Nima-Naderi
Copy link
Copy Markdown
Collaborator Author

@greptile review this PR please

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Jun 3, 2026

Greptile Summary

This PR replaces the fixed Claude/Codex setup shortcuts in the onboarding UI with an explicit eight-choice coding-agent picker, and extends terminal-launch to cover OpenCode, Gemini CLI, and shell-only setups. The skill docs, landing prompt, and developer-workflow guide are all updated to align on a detect-then-confirm flow.

  • ManualSetupStickers.tsx: adds CODING_AGENT_CHOICES, a /api/agents fetch that calls parseSuggestedAgent to highlight the detected agent, and a grid of agent buttons; manual-only choices (OpenClaw, Cursor/Cline, Custom) show inline guidance text instead of opening a terminal.
  • terminal-launch.ts: renames claude-login/codex-login to agent-* scheme and adds agent-opencode, agent-gemini, agent-shell; parseTerminalLaunchPath regex is updated accordingly.
  • MarkdownViewer.tsx: replaces a useEffect-based reset of the SVG failure flag with the React-recommended render-time state adjustment pattern, fixing the React Doctor finding.

Confidence Score: 5/5

Safe to merge — the changes are additive UI/copy updates with no database writes, no auth changes, and no regressions to existing terminal-launch flows.

The core logic changes are contained to the onboarding sticker component and the terminal-launch lib. The rename from claude-login/codex-login to the agent-* scheme is consistent across source, regex, and tests. The /api/agents fetch is properly guarded with an AbortController, a mounted flag, and a 10-second timeout. The MarkdownViewer fix correctly applies the React render-time state-adjustment pattern. The gemini detection gap and agent-shell test gap both flagged in previous review rounds are addressed here.

No files require special attention.

Important Files Changed

Filename Overview
shell/src/components/onboarding/ManualSetupStickers.tsx Adds 8-choice coding-agent picker, a /api/agents detect-and-suggest fetch with a 10s timeout and mounted guard, and inline guidance copy for non-terminal agents. Gemini is correctly included in detectable candidates via dynamic filtering.
shell/src/lib/terminal-launch.ts Renames claude-login/codex-login to agent-* scheme, adds agent-opencode, agent-gemini, agent-shell; regex in parseTerminalLaunchPath updated to match all new action names.
shell/src/components/preview-window/MarkdownViewer.tsx Replaces useEffect-based SVG failure-flag reset with React's render-time state-adjustment pattern; correctly handles the transitional render where key has changed but state hasn't re-run yet.
tests/shell/terminal-launch.test.ts All five new agent actions (including agent-shell) are exercised in the roundtrip test; queue tests updated to new action names.
tests/shell/manual-setup-stickers.test.tsx New tests cover agent-chooser rendering, Codex suggestion badge, Gemini CLI suggestion badge, manual-copy guidance for Cursor/Cline, and the existing Hermes test. fetch is correctly stubbed in beforeEach and unstubbed in afterEach.
tests/gateway/onboarding-tool-packs.test.ts linuxToolsTimeoutMs bumped from 500ms to 2000ms to reduce test flakiness; one-line change with no logical impact.
www/src/app/page.tsx Landing-page prompt updated to instruct coding agents to detect the local agent and ask for confirmation; mirrors the new onboarding skill docs.
skills/matrix-os/SKILL.md Adds explicit coding-agent choice menu with explicit matrix run commands per agent; OpenClaw/Cursor/Cline/Custom correctly described as manual-only flows.
www/public/skills.md Public skills.md aligned with private SKILL.md; agent-chooser section, explicit commands per agent, and manual guidance for non-terminal agents all consistent.
plugins/matrix-onboarding/skills/matrix-onboarding/SKILL.md Onboarding plugin skill updated to detect-and-confirm flow and full eight-option agent list; Hermes role clarified as system agent separate from coding-agent choice.
www/content/docs/guide/developer-workflow.mdx Developer workflow guide updated to use confirmed-agent-command placeholder and detect-then-confirm copy; consistent with rest of PR.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[ManualSetupStickers mounts] --> B[fetch /api/agents]
    B --> C{Response ok?}
    C -- No / timeout --> D[suggestedAgent = null]
    C -- Yes --> E[parseSuggestedAgent]
    E --> F{Any agent installed + authState ok/required?}
    F -- No --> D
    F -- Yes --> G[suggestedAgent = first match from CODING_AGENT_CHOICES order]
    G --> H[Render agent grid with Suggested badge]
    D --> H
    H --> I{User clicks choice}
    I -- has launchAction --> J[createTerminalLaunchPath / onOpenTerminal]
    I -- no launchAction --> K[setSelectedManualCopy / show inline guidance]
    J --> L[Terminal opens with agent-claude / agent-codex / agent-opencode / agent-gemini / agent-shell / github-ssh-login]
Loading

Reviews (4): Last reviewed commit: "fix(onboarding): suggest detected gemini..." | Re-trigger Greptile

return null;
}
const agents = (value as { agents: unknown[] }).agents;
for (const candidate of ["claude", "codex", "opencode"] as const) {
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.

P1 parseSuggestedAgent checks only ["claude", "codex", "opencode"] but omits "gemini", even though Gemini CLI has a full terminal launch action (agent-gemini) and appears as a first-class choice in CODING_AGENT_CHOICES. If the /api/agents endpoint returns a Gemini entry with installed: true and a recognized authState, the "Suggested" badge will never render for it — silently breaking the detection feature for Gemini users.

Suggested change
for (const candidate of ["claude", "codex", "opencode"] as const) {
for (const candidate of ["claude", "codex", "opencode", "gemini"] as const) {
Prompt To Fix With AI
This is a comment left during a code review.
Path: shell/src/components/onboarding/ManualSetupStickers.tsx
Line: 128

Comment:
`parseSuggestedAgent` checks only `["claude", "codex", "opencode"]` but omits `"gemini"`, even though Gemini CLI has a full terminal launch action (`agent-gemini`) and appears as a first-class choice in `CODING_AGENT_CHOICES`. If the `/api/agents` endpoint returns a Gemini entry with `installed: true` and a recognized `authState`, the "Suggested" badge will never render for it — silently breaking the detection feature for Gemini users.

```suggestion
  for (const candidate of ["claude", "codex", "opencode", "gemini"] as const) {
```

How can I resolve this? If you propose a fix, please make it concise.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Jun 3, 2026

Greptile Summary

This PR replaces the fixed Claude/Codex login shortcuts in the onboarding sticker with an explicit 8-choice coding-agent picker, extends TerminalLaunchAction with new agent commands, and aligns all SKILL.md/docs copies around a detect-then-confirm pattern. It also fixes a React Doctor finding in MarkdownViewer by switching from useEffect-based failure reset to the synchronous during-render state comparison React recommends.

  • Agent chooser (ManualSetupStickers.tsx): a 2-column grid of all eight choices fetches /api/agents on mount to badge the detected agent as "Suggested"; unsupported choices (OpenClaw, Cursor/Cline, Custom) show inline manual guidance instead of opening a terminal.
  • Terminal launch expansion (terminal-launch.ts): renames claude-login/codex-login to agent-claude/agent-codex and adds agent-opencode, agent-gemini, agent-shell; regex and action map stay in sync.
  • Test hardening: new sticker tests cover the chooser grid, suggested-badge, and manual-copy paths; flaky onboarding-tool-packs timeout bumped to 2 000 ms.

Confidence Score: 4/5

Safe to merge; the agent-chooser flow is additive and does not touch auth, data persistence, or any server-side logic.

The core change is straightforward UI wiring. The one functional gap is that parseSuggestedAgent iterates over ["claude", "codex", "opencode"] but not "gemini", meaning Gemini CLI will never receive the Suggested badge even if the API reports it as installed — inconsistent with the way OpenCode was added to the same list in this PR. The agent-shell roundtrip is also untested. Neither issue causes incorrect behavior today, but both are worth addressing before the API gains a Gemini probe.

ManualSetupStickers.tsx — the parseSuggestedAgent candidates list; tests/shell/terminal-launch.test.ts — missing agent-shell roundtrip assertion.

Important Files Changed

Filename Overview
shell/src/components/onboarding/ManualSetupStickers.tsx Replaces two hard-coded login buttons with an 8-choice agent picker; adds /api/agents fetch for auto-suggestion. parseSuggestedAgent omits "gemini" from its candidate list even though Gemini CLI is a fully supported launch target.
shell/src/lib/terminal-launch.ts Extends TerminalLaunchAction with agent-opencode, agent-gemini, and agent-shell; renames claude-login/codex-login to agent-claude/agent-codex. Regex and TERMINAL_ACTIONS map are consistent with each other and with the new type union.
shell/src/components/preview-window/MarkdownViewer.tsx Replaces useEffect-based failure reset with a synchronous during-render state comparison (React's recommended derived-state pattern), eliminating the flash-of-old-state that caused the React Doctor finding.
tests/shell/manual-setup-stickers.test.tsx Adds beforeEach fetch stub and three new tests covering the agent chooser grid, suggested-badge detection, and manual-copy display for unsupported choices.
tests/shell/terminal-launch.test.ts Updates all test fixtures to the renamed action keys; adds opencode/gemini roundtrip assertions. agent-shell is not exercised in the roundtrip test.
tests/gateway/onboarding-tool-packs.test.ts Increases linuxToolsTimeoutMs from 500ms to 2 000ms to fix a flaky test; no logic change beyond that.
www/src/app/page.tsx Landing-page prompt updated to request detect-then-confirm agent selection rather than hard-coding Claude/Codex.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[ManualSetupStickers mounts] --> B[fetch /api/agents]
    B -->|ok + agent found| C[parseSuggestedAgent\ncandidates: claude, codex, opencode]
    B -->|error / timeout| D[suggestedAgent = null]
    C -->|match found| E[setSuggestedAgent\nshows Suggested badge]
    C -->|no match| D
    E --> F[User sees 8-choice grid]
    D --> F
    F -->|Claude/Codex/OpenCode/Gemini/Shell| G{choice.launchAction?}
    F -->|OpenClaw/Cursor-Cline/Custom| H[setSelectedManualCopy\nshow inline guidance]
    G -->|yes| I[createTerminalLaunchPath action]
    I --> J[onOpenTerminal called\nopens terminal tab]
    J --> K[parseTerminalLaunchPath\nvalidates path regex]
    K --> L[TerminalLaunchConfig\ncommand executed]
Loading
Prompt To Fix All With AI
Fix the following 2 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 2
shell/src/components/onboarding/ManualSetupStickers.tsx:128
`parseSuggestedAgent` checks `["claude", "codex", "opencode"]` but omits `"gemini"`. All four of those IDs are backed by a `launchAction` in `CODING_AGENT_CHOICES`, yet if the `/api/agents` endpoint returns a Gemini CLI entry with `installed: true`, no "Suggested" badge will ever appear for it. The three other terminal-launch agents were clearly included intentionally (opencode was added alongside this PR), so this looks like an oversight.

```suggestion
  for (const candidate of ["claude", "codex", "opencode", "gemini"] as const) {
```

### Issue 2 of 2
tests/shell/terminal-launch.test.ts:17-38
**`agent-shell` not exercised in roundtrip test**

`agent-shell` is the only new terminal-launch action that isn't covered by the `maps onboarding setup actions to startup commands` test. A typo in its `command` field or a regex gap would be invisible until a user actually clicks "Shell only".

Reviews (2): Last reviewed commit: "feat(onboarding): ask users to choose co..." | Re-trigger Greptile

return null;
}
const agents = (value as { agents: unknown[] }).agents;
for (const candidate of ["claude", "codex", "opencode"] as const) {
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.

P2 parseSuggestedAgent checks ["claude", "codex", "opencode"] but omits "gemini". All four of those IDs are backed by a launchAction in CODING_AGENT_CHOICES, yet if the /api/agents endpoint returns a Gemini CLI entry with installed: true, no "Suggested" badge will ever appear for it. The three other terminal-launch agents were clearly included intentionally (opencode was added alongside this PR), so this looks like an oversight.

Suggested change
for (const candidate of ["claude", "codex", "opencode"] as const) {
for (const candidate of ["claude", "codex", "opencode", "gemini"] as const) {
Prompt To Fix With AI
This is a comment left during a code review.
Path: shell/src/components/onboarding/ManualSetupStickers.tsx
Line: 128

Comment:
`parseSuggestedAgent` checks `["claude", "codex", "opencode"]` but omits `"gemini"`. All four of those IDs are backed by a `launchAction` in `CODING_AGENT_CHOICES`, yet if the `/api/agents` endpoint returns a Gemini CLI entry with `installed: true`, no "Suggested" badge will ever appear for it. The three other terminal-launch agents were clearly included intentionally (opencode was added alongside this PR), so this looks like an oversight.

```suggestion
  for (const candidate of ["claude", "codex", "opencode", "gemini"] as const) {
```

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines 17 to 38
it("maps onboarding setup actions to startup commands", () => {
vi.spyOn(Date, "now").mockReturnValue(1_779_788_800_000);

expect(parseTerminalLaunchPath(createTerminalLaunchPath("claude-login"))).toMatchObject({
label: "Claude login",
expect(parseTerminalLaunchPath(createTerminalLaunchPath("agent-claude"))).toMatchObject({
label: "Claude Code setup",
command: "claude",
claudeMode: true,
});
expect(parseTerminalLaunchPath(createTerminalLaunchPath("codex-login"))).toMatchObject({
label: "Codex login",
expect(parseTerminalLaunchPath(createTerminalLaunchPath("agent-codex"))).toMatchObject({
label: "Codex setup",
command: "codex",
});
expect(parseTerminalLaunchPath(createTerminalLaunchPath("agent-opencode"))).toMatchObject({
label: "OpenCode setup",
command: "opencode",
});
expect(parseTerminalLaunchPath(createTerminalLaunchPath("agent-gemini"))).toMatchObject({
label: "Gemini CLI setup",
command: "gemini",
});
expect(parseTerminalLaunchPath(createTerminalLaunchPath("github-ssh-login"))?.command).toContain("gh auth login --hostname github.com --git-protocol ssh --web");
});
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.

P2 agent-shell not exercised in roundtrip test

agent-shell is the only new terminal-launch action that isn't covered by the maps onboarding setup actions to startup commands test. A typo in its command field or a regex gap would be invisible until a user actually clicks "Shell only".

Prompt To Fix With AI
This is a comment left during a code review.
Path: tests/shell/terminal-launch.test.ts
Line: 17-38

Comment:
**`agent-shell` not exercised in roundtrip test**

`agent-shell` is the only new terminal-launch action that isn't covered by the `maps onboarding setup actions to startup commands` test. A typo in its `command` field or a regex gap would be invisible until a user actually clicks "Shell only".

How can I resolve this? If you propose a fix, please make it concise.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

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