Skip to content

feat(native-chat): + menu shows chat, disabled chat and CLI rows - #29074

Merged
brennanb2025 merged 71 commits into
mainfrom
brennanb2025/new-tab-menu-chat-cli-rows
Oct 19, 2026
Merged

brennanb2025 merged 71 commits into
mainfrom
brennanb2025/new-tab-menu-chat-cli-rows

Conversation

@brennanb2025

@brennanb2025 brennanb2025 commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor
Files Added Deleted Net
Test 21 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​682 $\color{#cf222e}{\Huge{\mathbf{−}}}$​60 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​622
Prod 48 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​1425 $\color{#cf222e}{\Huge{\mathbf{−}}}$​303 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​1122

ELI5

With Chat UI on, the + menu did not explain whether each agent opens a chat or a terminal. Enabled chats that cannot run in this workspace could disappear, and opening a chat agent’s terminal once required changing a preference.

The menu now groups runnable chats, disabled chats with their reasons, and terminal choices labelled “(CLI)”. Clicking a chat row starts a chat; hovering it shows a terminal button at its right edge that opens that agent in a terminal once instead. Typing in search and sending review notes to a new agent use the same choices. Chat UI off and older paired servers retain their existing plain list.

What Changed

Each runtime owns one shared agent health snapshot. It checks registered agents’ location rules and version support in that machine’s home folder, and publishes complete snapshots only to clients that support the stream. A restart, launch-setting change or explicit agent Refresh refreshes health; every health pass first captures fresh shell facts. Workspaces and menu reopens reuse the retained snapshot, including during contact loss.

The renderer derives one loading or settled menu observation. During initial acquisition, quiet placeholders reserve the agent region and search exposes no provisional agent action. Settled rows and search share the same availability and installation facts. Failed reads retain independently known terminal choices, show truthful disabled reasons and preserve the existing inventory explanation. Generic search, New Terminal and Agent settings remain usable.

The clicked row, or its terminal button, carries its requested surface through the existing launcher. An explicit chat refusal reports the problem once without opening a terminal; ordinary preference-based launches retain their existing routing.

Why

This follows the common pattern of host-owned readiness and derived picker choices while preserving independent client/server updates. Retained host facts avoid repeated per-workspace checks, and a shared menu observation prevents a search result from changing its launch surface as loading finishes.

Intended differences from the common pattern and accepted product costs:

  • Intended: Orca supports terminal agents as well as chat, so it has explicit terminal rows and a terminal button on each chat row.
  • Intended: Health refreshes on launch-setting changes, Refresh and restart. It does not poll or probe on menu open.
  • Intended: Home-folder health can disagree with a folder-specific version-manager shim. Actual workspace launch admission remains authoritative.
  • Intended: Older paired servers retain their current launch path. A version-gated agent can appear chat-capable until clicked when an older server cannot publish health.

Enabled unavailable agents remain visible with a reason. Settings → Agents Disabled still hides an agent everywhere. No provider default changes.

Visual Proof

Current look, captured on the final code (e995e707f3e) with Chat UI on: a hidden test copy of Orca with throwaway settings, Mac on an M4Air and Windows native on Windows high spec. The only later commit changes the chat rows' tooltip and screen-reader label to "Start a chat with ". WSL QA is blocked because the test copy cannot isolate the WSL guest's home folder (the WSL row comes from an unchanged client rule). Full review notes are in the status comment.

Mac, main acc235187f62 versus this branch:

Flow Main Branch
Codex switched off in Settings → Chat → Providers Main provider-off menu Branch provider-off menu: Codex (CLI) in the terminal group
Typed "codex" search Main Codex search Branch Codex search
Default menu (branch) Hovering a chat row shows its terminal button Chat UI off keeps today's plain list
Branch grouped menu Codex row hovered with its terminal button Chat UI off plain list

Windows native, main 10505696a2c3 versus this branch (Antigravity shows as a disabled chat row with its reason, and as a CLI row):

Main, Chat UI on Branch, Chat UI on Branch, hovering Codex Branch, Codex switched off in Providers
Windows main menu Windows branch grouped menu Windows hovered Codex row Windows provider-off menu

What the row and its button do (Windows native QA of the terminal button, 6/6 at 38733100b31 and 6/6 at 44e54cbcda0):

Terminal button on each chat row, Windows native at 44e54cbcda0 (the code in the final head; Claude terminal and keyboard focus from the same design at 38733100b31):

Hover a chat row Row click starts a chat Button opens a terminal
Codex row hovered with its terminal button Grok chat from a row click Claude terminal from the button
Keyboard: ArrowRight focuses the button Press on +, drag onto the button, release
Focused terminal button Codex terminal from drag-release

Real chat replies (Mac, before the terminal button replaced the earlier › control; the chat itself is unchanged): main Claude reply, branch Claude reply.

The first-open loading placeholder (grey bars while agents are still being detected) appears too briefly on a local machine to capture: six tries at e995e707f3e found the list already complete, and an immediate reopen showed the full list at once. The placeholder code is unchanged since its capture at ea92205bc09 (rows 32px in both states).

Testing

  • Automated tests added/updated.
  • Windows native QA of the terminal button at 44e54cbcda0 (6/6) and 38733100b31 (6/6); Mac and Windows screenshots of the current menu at e995e707f3e; macOS and Windows menu QA at ea92205bc09; WSL blocked (see Visual Proof).

Targeted backend and renderer tests passed. Full PR workflow 39205965263 (aggregate PR checks passed 117911432779) succeeded at 07db62a, after the final main merge. CI is the full lint and typecheck gate.

Linked Issue

N/A (maintainer).

AI Disclosure

Review

Fresh full review loop: four rounds at ea92205bc09, no unresolved proven P0/P1/P2. The later terminal-button change (replacing the earlier › submenu, which users could mistake for the row's only action) had an independent review; its three minor findings (drag-release onto the button, arrow keys from the button, the row's screen-reader name) are fixed in 44e54cbcda0. The chat rows' label now reads "Start a chat with " (it read "Start a OpenCode chat"). main was merged at the end.

Agent skill upstream boundary

  • Not applicable; this change copies no upstream skill-installer material.

Notes

SSH workspaces retain their terminal path and show unavailable chats with a reason. Native Windows and WSL use their existing execution-host routing. Independent client/server updates and older-server launch paths remain supported. Mobile click admission is unchanged. Author: @BrennanKB5.

Checklist

  • User problem, behavior, mechanism and tradeoffs explained.
  • Source reviewed for correctness, security and performance.
  • Cross-platform, SSH, folder workspace and mixed-version behavior considered.
  • Full PR workflow passed on the current head.
  • Fresh screenshots attached after platform QA.

Settings → Chat gets a Providers list. Each agent the host can open as a chat
has a switch; off opens that agent in a terminal instead. Only choices the user
makes are saved. Unchosen: Claude and Codex on, others on when their CLI is
installed on this computer.

The renderer's route and the host's launch-mode decision both read one rule, so
the tab menu, shortcuts, CLI, orchestration and relayed phone launches agree.
With Chat UI on, each agent whose chat provider is on gets a chat row, disabled
with the reason where the workspace's machine can't run that chat (not
installed, SSH, WSL, not on this host). Every other installed agent gets a row
marked (CLI) that opens its terminal. With Chat UI off, or on an older server
that opens no chats, the menu is unchanged.
@brennanb2025
brennanb2025 force-pushed the brennanb2025/new-tab-menu-chat-cli-rows branch from d1b20b8 to 8b964f9 Compare October 15, 2026 08:35
A chat row whose CLI is installed on the workspace's machine gets a › beside
it. Its side menu offers '<Agent> (CLI)', which opens that agent's terminal for
this launch only; nothing is saved and the row itself still opens a chat.
…li-rows' into brennanb2025/new-tab-menu-cli-popover

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 2


ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 848cb26a-2272-4e64-b84e-9481baeebd84
📥 Commits

Reviewing files that changed from the base of the PR and between ee4fd06 and 6904654.

⛔ Files ignored due to path filters: 1
  • src/shared/rpc-contract/rpc-params-catalog.generated.ts is excluded by !**/*.generated.*
📒 Files selected for processing: 55
  • src/main/preflight/workspace-agent-detection.ts
  • src/main/runtime/orca-runtime.ts
  • src/main/runtime/rpc/methods/structured-agent-session-agents.ts
  • src/main/runtime/rpc/methods/structured-agent-session-schemas.ts
  • src/main/runtime/rpc/methods/structured-agent-session-subscription-id.ts
  • src/main/runtime/structured-agent-availability.test.ts
  • src/main/runtime/structured-agent-availability.ts
  • src/main/runtime/structured-agent-launch-support.ts
  • src/renderer/src/components/settings/NativeChatProvidersSetting.tsx
  • src/renderer/src/components/tab-bar/QuickLaunchButton.launch-status.test.tsx
  • src/renderer/src/components/tab-bar/QuickLaunchButton.test.ts
  • src/renderer/src/components/tab-bar/QuickLaunchButton.tsx
  • src/renderer/src/components/tab-bar/TabBar.context-menu.test.ts
  • src/renderer/src/components/tab-bar/TabBar.tsx
  • src/renderer/src/components/tab-bar/TabBarCreateEntry.tsx
  • src/renderer/src/components/tab-bar/TabBarCreateEntryRow.tsx
  • src/renderer/src/components/tab-bar/new-tab-host-chat-answers.ts
  • src/renderer/src/components/tab-bar/tab-agent-launch-options.test.ts
  • src/renderer/src/components/tab-bar/tab-agent-launch-options.ts
  • src/renderer/src/components/tab-bar/tab-agent-row-presentation.ts
  • src/renderer/src/components/tab-bar/tab-bar-surface.tsx
  • src/renderer/src/components/tab-bar/tab-bar-windows-shell-launch-render-stubs.ts
  • src/renderer/src/components/tab-bar/tab-create-entry-active-option.ts
  • src/renderer/src/components/tab-bar/tab-create-entry-network-selection.ts
  • src/renderer/src/components/tab-bar/tab-create-entry-props.ts
  • src/renderer/src/components/tab-bar/use-new-tab-agent-menu-rows.test.tsx
  • src/renderer/src/components/tab-bar/use-new-tab-agent-menu-rows.ts
  • src/renderer/src/components/tab-bar/use-tab-bar-create-menu-controller.ts
  • src/renderer/src/components/tab-bar/use-tab-bar-runtime-model.ts
  • src/renderer/src/components/ui/dropdown-menu.tsx
  • src/renderer/src/i18n/en-runtime-required.json
  • src/renderer/src/i18n/locales/en.json
  • src/renderer/src/lib/agent-launch-routing.ts
  • src/renderer/src/lib/agent-session-launch-plan.ts
  • src/renderer/src/lib/chat-provider-agents.ts
  • src/renderer/src/lib/launch-agent-in-new-tab-host-agents.test.ts
  • src/renderer/src/lib/launch-agent-in-new-tab-host-agents.ts
  • src/renderer/src/lib/launch-agent-in-new-tab.ts
  • src/renderer/src/lib/launch-structured-agent-session.test.ts
  • src/renderer/src/lib/new-tab-agent-menu-rows.test.ts
  • src/renderer/src/lib/new-tab-agent-menu-rows.ts
  • src/renderer/src/lib/structured-agent-session-host-admission.ts
  • src/renderer/src/lib/structured-agent-session-launch-admission.test.ts
  • src/renderer/src/lib/structured-agent-session-launch-admission.ts
  • src/renderer/src/runtime/host-structured-agent-availability.test.ts
  • src/renderer/src/runtime/host-structured-agent-availability.ts
  • src/renderer/src/runtime/structured-agent-session-client.ts
  • src/renderer/src/runtime/use-host-structured-agent-availability.ts
  • src/shared/agent-session-agent-availability.ts
  • src/shared/protocol-version.ts
  • src/shared/rpc-contract/structured-agent-session-params.ts
  • src/shared/structured-agent-session-surface-capabilities.ts
  • tests/e2e/cross-version-wire/structured-agent-session-surface-calls.ts
  • tests/e2e/cross-version-wire/structured-agent-session-surface-execution.ts
  • tests/e2e/cross-version-wire/structured-agent-session-surface-manifest.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 1 remain after this review.

…own, and learns them while the workspace is shown
The + menu no longer checks chat availability per workspace. Each Orca
runtime keeps one agent health snapshot: every agent's location rule on
this machine plus a typed observation of its installed release, probed
in the server's own home. It is taken on first use and replaced only on
a launch setting change, an explicit agent Refresh (after a fresh shell
capture), or a restart, and kept without readers.

- The version probe reports supported, unsupported or inconclusive; a
  launch still refuses an inconclusive run, while the snapshot reads it
  as unknown rather than a refusal.
- agentSession.subscribeAvailability takes no params and publishes that
  snapshot; a replay that closes the transport releases its reader.
- The renderer keeps the snapshot per host, runtime and pairing, through
  lost contact and across workspace switches on the same host.
- The menu hook drops the per-open createSupport display reads, their
  deadline and answer cache; older hosts show client facts and the
  click's admission, unchanged, states any refusal.
…menu-chat-cli-rows

# Conflicts:
#	src/main/runtime/structured-agent-runtime-metadata.ts
#	src/renderer/src/components/settings/NativeChatProvidersSetting.tsx

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to GitHub limitations.

⚠️ Outside diff range comments (2)

🟡 Minor · Hold agent search until availability settles. · use-tab-bar-create-menu-controller.ts:94

src/renderer/src/components/tab-bar/use-tab-bar-create-menu-controller.ts:94
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Hold agent search until availability settles.

When agentMenu.settling is true, typed search can select a provisional CLI row and Enter can launch a terminal. After the host reports availability, the same agent can become a chat row. Do not expose agent options to typed search until the snapshot settles.

Suggested fix
-  const agentLaunchOptions = buildTabAgentLaunchOptionsFromRows(agentMenu.rows, commandOverrides)
+  const agentLaunchOptions = agentMenu.settling
+    ? []
+    : buildTabAgentLaunchOptionsFromRows(agentMenu.rows, commandOverrides)
🟡 Minor · Keep the settling agent region to one row minimum. · QuickLaunchButton.tsx:181

src/renderer/src/components/tab-bar/QuickLaunchButton.tsx:181
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Keep the settling agent region to one row minimum.

ProjectedAgentMenuItems renders at least two placeholders. A workspace with one candidate resolves to one agent row after the first availability snapshot, so the open + menu shrinks vertically. The w-72 width constraint prevents horizontal resizing, but it does not prevent this height change.

Suggested fix
-        {PLACEHOLDER_WIDTHS.slice(0, Math.max(rows.length, 2)).map((width) => (
+        {PLACEHOLDER_WIDTHS.slice(0, Math.max(rows.length, 1)).map((width) => (

ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 665576d3-ec06-47a1-87d9-4279cc1357e2
📥 Commits

Reviewing files that changed from the base of the PR and between dc4db63 and 26ee03b.

⛔ Files ignored due to path filters: 1
  • src/shared/rpc-contract/rpc-params-catalog.generated.ts is excluded by !**/*.generated.*
📒 Files selected for processing: 32
  • src/main/agent-cli-version-probe.test.ts
  • src/main/agent-cli-version-probe.ts
  • src/main/pi/rpc-launch-resolution.ts
  • src/main/pi/rpc-runtime-metadata.ts
  • src/main/pi/rpc-runtime-registration.test.ts
  • src/main/runtime/orca-runtime.ts
  • src/main/runtime/rpc/methods/structured-agent-session-agents.ts
  • src/main/runtime/structured-agent-availability.test.ts
  • src/main/runtime/structured-agent-availability.ts
  • src/main/runtime/structured-agent-launch-support-probe-omp.test.ts
  • src/main/runtime/structured-agent-launch-support-probe.test.ts
  • src/main/runtime/structured-agent-launch-support.test.ts
  • src/main/runtime/structured-agent-launch-support.ts
  • src/main/runtime/structured-agent-runtime-metadata.ts
  • src/main/runtime/structured-agent-runtime-registration-types.ts
  • src/main/runtime/structured-agent-shell-environment.ts
  • src/renderer/src/components/settings/NativeChatProvidersSetting.tsx
  • src/renderer/src/components/tab-bar/QuickLaunchButton.launch-status.test.tsx
  • src/renderer/src/components/tab-bar/use-new-tab-agent-menu-rows.test.tsx
  • src/renderer/src/components/tab-bar/use-new-tab-agent-menu-rows.ts
  • src/renderer/src/i18n/en-runtime-required.json
  • src/renderer/src/i18n/locales/en.json
  • src/renderer/src/lib/agent-session-launch-plan.ts
  • src/renderer/src/lib/structured-agent-session-host-admission.ts
  • src/renderer/src/runtime/host-structured-agent-availability.test.ts
  • src/renderer/src/runtime/host-structured-agent-availability.ts
  • src/renderer/src/runtime/use-host-structured-agent-availability.ts
  • src/shared/agent-session-agent-availability.ts
  • src/shared/rpc-contract/structured-agent-session-params.ts
  • src/shared/structured-agent-session-surface-capabilities.ts
  • tests/e2e/cross-version-wire/structured-agent-session-surface-execution.ts
  • tests/e2e/cross-version-wire/structured-agent-session-surface-manifest.ts
🚧 Files skipped from review as they are similar to previous changes: 2
  • src/renderer/src/i18n/en-runtime-required.json
  • src/renderer/src/i18n/locales/en.json

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 7 remain after this review.

…menu-chat-cli-rows

# Conflicts:
#	src/renderer/src/components/settings/NativeChatProvidersSetting.tsx
Hovering a chat row in the + menu, or pressing ArrowRight on it, now opens
the "<Agent> (CLI)" submenu to the right instead of needing a separate
chevron button. Clicking the row, or Enter/Space, still starts the chat
and closes the menu; hosts pass closeMenu since a submenu trigger never
closes the menu on its own.
Clicking a chat row in the + menu starts a chat. Hovering the row (or
pressing ArrowRight on it) reveals a terminal button at its right edge that
opens the agent in a terminal instead. This replaces the submenu, whose
chevron made the row look like it only opened a submenu. The button's click
bubbles into the row, so the menu closes as for any item and the hosts no
longer need a closeMenu callback.
…s and screen readers

A press on + dragged onto a chat row's terminal button and released there
now opens the CLI: the row reads whether the pointer or focus is on its
button instead of the click target, which a drag-release never sets.
Arrow, Home and End keys pressed on the focused button move between rows
as they do on the row. The row is announced as "Start a <Agent> chat"
instead of including the button's label.
"Start a OpenCode chat" was ungrammatical for agents whose name starts with a vowel.
@brennanb2025
brennanb2025 merged commit 503d919 into main Oct 19, 2026
82 of 83 checks passed
@brennanb2025
brennanb2025 deleted the brennanb2025/new-tab-menu-chat-cli-rows branch October 19, 2026 07:29
brennanb2025 added a commit that referenced this pull request Oct 19, 2026
#29074 landed a per-agent "is this version string supported" predicate and a
supported/unsupported/inconclusive observation for the + menu's agent health
snapshot. Keep one version policy: an agent's launch check now returns the
shared minimum-version result (ready, tooOld, unknown, missing), create
support runs anything but tooOld or missing, and the health snapshot reads
ready as available, tooOld as refused and anything else as unknown.
brennanb2025 added a commit that referenced this pull request Oct 19, 2026
The old picker change counted managed agents as detected CLIs, which #29074's
menu now uses for terminal rows. Everything else it carried has landed on main.
The rework follows in the next commits.
smwbev added a commit to smwbev/orca that referenced this pull request Oct 19, 2026
227 commits landed on main between 91b696b and 1529b0f, and only en-runtime-required.json conflicted; it is taken from main and regenerated. The six catalogs merged cleanly, so the earlier prune carries over. On the merged tree the detector found three more keys: the Checking chat support placeholder and the Could not build launch command message that stablyai#29074 left behind when it reworked the + menu, and the native-chat cannotResume message whose last reader stablyai#29150 removed. The prune is now 1,509 keys and none left the set. en.json goes from 16,395 entries to 14,886; en-runtime-required.json keeps 578 of them.
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