Brennan BensonandOrca 7d46eb08dd Activity page agent terminal view (#1723)
* fix(activity): align unread dot with row icon

Anchor the unread mini-dot to the icon's own bounding box (relative
inline-flex with -top-1 -left-1) instead of the 24x24 cell. The previous
absolute positioning was relative to the cell, so the dot landed visibly
off-center against the centered AgentStateDot/Plus glyph. Adds a
ring-2 ring-background halo for contrast against the row's tinted unread
background. Applies to both AgentEventRow and WorktreeEventRow.

Co-authored-by: Orca <help@stably.ai>

* fix(activity): drop top padding so content sits flush with titlebar

Outer wrapper used py-3, plus the right-pane <section> had pt-2 and the
thread-list header had py-2 — the stacked top whitespace produced a
visible gap above the first row against the titlebar. The
ActivityTitlebarControls bar already provides the breathing-room band.

Drop the wrapper's top padding (py-3 → pb-3), drop the right-pane
section's pt-2, and tighten the thread-list header to pt-1.5 pb-2 so the
WORKTREES label aligns with the right-pane worktree title row.

Co-authored-by: Orca <help@stably.ai>

* fix(activity): make event row the click target for navigate + ack

The inline "Jump to agent" button only rendered when agentAlive was
true, so retained-done rows had no jump affordance, and in compact mode
it was hover-only. Users naturally click anywhere on the row expecting
it to navigate.

Move the navigate-and-ack logic onto the row's onClick (with role,
tabIndex, and Enter/Space keyboard support) and drop the inline buttons.
Per the design doc (option 1), drop the agentAlive gate entirely:
activateAndRevealWorktree is safe unconditionally and
activateTabAndFocusPane silently no-ops on a missing tab id, so a
stale-tab click is a soft no-op.

Mirror the same pattern on WorktreeEventRow so clicking a "Worktree
created" row navigates to that worktree.

Co-authored-by: Orca <help@stably.ai>

* fix(activity): bell glyph for unread + larger row state icon

The unread mini-dot stacked on the AgentStateDot competed with the dot
itself for the eye and read like a status badge on the agent state.
Replace it with a small BellDot glyph at the icon's top-right corner so
the unread cue rhymes with the bell button on ThreadRow — one unread
vocabulary across both surfaces.

While here, bump the row state icon to a new 'lg' AgentStateDot size
(18px) so the green check sits center-of-mass in its 32px column instead
of floating small and high. Bump the WorktreeEventRow Plus glyph to
match.

Co-authored-by: Orca <help@stably.ai>

* fix(activity): drop left padding so thread list reaches the window edge

The page wrapper used px-4, which left a 16px gap to the left of the
thread list — visually inconsistent with how sidebars abut the window
chrome elsewhere. Switch to pr-4 (keep right padding for the right
pane). Inner thread-list and right-pane padding remain unchanged.

Co-authored-by: Orca <help@stably.ai>

* fix(activity): use left-edge bar for unread instead of an icon overlay

Mini-dot and bell-glyph attempts both crowded the AgentStateDot/Plus
icon column. Switch to the same left-edge primary bar that ThreadRow
already uses for unread — a row-level cue keeps the icon column clean
and unifies the unread vocabulary across both panes.

Co-authored-by: Orca <help@stably.ai>

* fix(activity): page extends to both edges, restore right-pane top padding, rename to "workspace"

- Drop horizontal padding on the page wrapper (pr-4 → none) so the
  thread list reaches the left edge and the right pane reaches the
  right edge — matches how sidebars abut the chrome elsewhere.
- Restore a small top padding (pt-2) on the right-pane title row so
  the workspace heading isn't pinned to the titlebar. Earlier Fix 2
  over-corrected by removing it entirely.
- Rename user-facing "Worktree(s)" → "Workspace(s)" (column label,
  event title "Worktree created", description copy, "Jump to
  worktree" button, empty state). Internal identifiers stay as
  worktree* since that's the data-model name.

Co-authored-by: Orca <help@stably.ai>

* fix(activity): remove redundant "Jump to workspace" header button

Clicking any event row already calls markThreadRead +
activateAndRevealWorktree (plus a tab focus, so it's a strict superset
of what the header button did). The button's only unique behavior was
"go to the workspace without picking a tab" — thin justification when
the latest event is one row down. cursor-pointer + hover already signal
that rows are clickable.

Co-authored-by: Orca <help@stably.ai>

* fix(activity): wrap agent summary instead of truncating

The summary line used 'truncate' with a max-width, hiding the rest of
the agent's message behind an ellipsis. The Activity page is meant to
let users scan what each agent said without leaving the surface, so
truncation defeats its purpose. Switch to break-words +
whitespace-pre-wrap so the full message renders and multi-line output
keeps its line breaks.

Co-authored-by: Orca <help@stably.ai>

* fix(activity): clamp agent summary to 3 lines

Showing the full message made tall rows for chatty agents. Cap at 3
lines (line-clamp-3) — long enough to convey what happened, short
enough that rows stay scannable. Users open the workspace if they want
the full transcript.

Co-authored-by: Orca <help@stably.ai>

* feat(activity): switch left list from workspaces to agent panes

Restructure the activity feed so each thread is one *agent pane* (a
terminal tab + pane id) rather than one workspace. Internal model goes
from WorktreeThread → AgentPaneThread keyed on paneKey.

Renderer changes:
- Left list: each row shows the pane title (with agent icon + repo
  badge), then the workspace name as secondary context. Section label
  changes "Workspaces" → "Agents".
- Right pane: header shows the pane title, agent icon, repo badge, and
  the workspace name beneath. Drops the Today/Yesterday/Earlier day
  grouping per design — the relative timestamp on each row is enough
  orientation, and a flat chronological list scans more cleanly.
- Drops the workspace-created event kind entirely (and the
  WorktreeEventRow + ActivityRow union dispatcher), since the surface
  is now strictly agent activity.

Side effects:
- Mark-read no longer needs the locallyReadEventIds layer or the
  worktree-unread store calls (markWorktreeUnread/clearWorktreeUnread).
  Acknowledge by paneKey is the only persistence path.
- Removes Plus and groupForTimestamp (unused after the refactor).

Co-authored-by: Orca <help@stably.ai>

* feat(activity): label panes like the per-workspace agents dropdown

Pane labels now follow the same hierarchy DashboardAgentRow uses inside
the WorktreeCardAgents dropdown:

  customTitle (user rename) > non-default OSC title > last prompt
  > defaultTitle / "Terminal"

The prompt fallback is the important one — agents that haven't been
renamed and don't set an OSC title now render with what the user asked
the agent to do (e.g. "Fix the unread dot alignment") instead of the
generic "Terminal 1" placeholder. Matches the visual + naming pattern
on each workspace card so the activity page reads as a flat-feed
extension of that surface.

Co-authored-by: Orca <help@stably.ai>

* fix(activity): smaller titles, allow 2-line prompt clamp

Long prompts were getting truncated at one line, hiding most of the
ask. Switch the thread row title from truncate to line-clamp-2, with
break-words so long words wrap, and tighten size to text-[13px] +
leading-snug so two clamped lines don't dominate the row vertically.
Anchor the agent icon to the first line via items-start + pt-[3px].

Right-pane heading drops text-base → text-sm to match.

Co-authored-by: Orca <help@stably.ai>

* fix(activity): right-pane title gets the same 2-line clamp + smaller size

Mirror the ThreadRow change on the right-pane heading: line-clamp-2 +
break-words + leading-snug so a long prompt title shows two lines
instead of a single-line ellipsis. The repo badge moves down to the
secondary line (next to the workspace name) so it doesn't shift with
the title height.

Co-authored-by: Orca <help@stably.ai>

* fix(activity): match WorktreeCard's selected/hover/unread cues

Three stacked tints (selected + unread row tint + hover) made an unread
hovered row look identical to a selected row, and hover even fought
selected. Mirror WorktreeCard:

- selected → solid black/white tint + faint shadow, hover suppressed
  (the active class wins so the row stays visually fixed)
- non-selected → only then does hover apply (bg-accent/40)
- unread → weight + left-edge primary bar carry the cue; row tint
  removed (matches WorktreeCard's "weight alone carries the unread
  signal")

Co-authored-by: Orca <help@stably.ai>

* feat(activity): portal selected agent terminal

Co-authored-by: Orca <help@stably.ai>

* fix(activity): keep completed entries after terminal input

Co-authored-by: Orca <help@stably.ai>

* fix(activity): tighten portal target, unread count, and selection edges

- activity-terminal-portal: replace document.body MutationObserver with a
  module-level pub/sub registry; the page publishes the target via a ref
  callback, Terminal subscribes. Removes body-wide DOM observation.
- Terminal: memoize activityTerminalPortal so WorktreeSplitSurface's
  React.memo bail-out is preserved across unrelated Terminal re-renders.
- ActivityPrototypePage: cap events per-pane (5) so a chatty pane can't
  push quiet panes off the left list; render an empty-state when a
  retained thread's tab is gone; skip workspace mutation in
  activateThreadTerminal when the tab is no longer live; keep the
  selected thread visible in unread-only mode after auto-mark-read.
- ActivityTitlebarControls: walk stateHistory in the unread accumulator
  (mirrors the new feed semantics); drop worktree-created counting since
  the new feed has no surface to dismiss them.
- AgentStateDot: remove the dead 'lg' size variant.
- App: hide worktree sidebar on the Activity view and include it in the
  back/forward shortcut + button cluster.

Co-authored-by: Orca <help@stably.ai>

* fix(activity): double-buffer portal slots to remove cold-mount flash

Switching threads on the Activity page used to expose xterm's empty
canvas for ~133ms while a newly-mounted TerminalPane attached. Replace
the single portal target with a double-buffered set of slots: keep the
previously displayed terminal visible while the next selected terminal
mounts in an invisible same-size slot, then flip slots once the staged
slot contains the selected terminal DOM with xterm's screen and PTY
binding (with one extra frame only after observing an empty mount).

Skips publishing a portal target when the selected retained thread no
longer has a live tab so the previous tab's target doesn't linger.

Co-authored-by: Orca <help@stably.ai>

* fix(activity): remove single-option Display style settings dropdown

The activity page's gear menu only held a "Compact list" toggle. Drop
the dropdown along with the leftSidebarCompact state, the
ActivityDensity type, and the unused dropdown-menu / Settings imports.
The thread list keeps the compact layout (the previous default).

Co-authored-by: Orca <help@stably.ai>

* fix(activity): vertically center Jump to workspace button

The header row uses items-start so a 2-line prompt clamps without the
badge jumping. self-center on the button overrides that just for the
action so it sits in the middle of the title block instead of pinned to
the top edge.

Co-authored-by: Orca <help@stably.ai>

* fix(activity): prefer prompt over OSC live title for thread label

paneTitleForEvent put the non-default tab.title ahead of the prompt, so
agent CLIs that set "Claude Code" / "Codex" via OSC pinned every row
and the right-pane heading to the agent name. The dashboard row this
function claims to mirror uses the prompt directly. Re-order to:
customTitle (explicit rename) → prompt → non-default liveTitle →
defaultTitle, so sending "hi" actually shows "hi" in the title.

Co-authored-by: Orca <help@stably.ai>

* fix(activity): drop extra row height when prompt is one line

The thread row's right column stacked time over the count badge with a
gap, which forced the row to ~48px even when the left column's prompt
was a single line. Collapse the right column into one horizontal
cluster (count + time/bell) so single-line rows stay tight, while
two-line prompts still drive the row taller as before.

Co-authored-by: Orca <help@stably.ai>

* fix(activity): add top/bottom padding to thread rows

Bump py-1.5 → py-2.5 so single-line rows breathe and don't sit flush
against the row dividers.

Co-authored-by: Orca <help@stably.ai>

* fix(activity): even out optical row padding (top read heavier than bottom)

Symmetric py-2.5 looked top-heavy because the title's leading-snug adds
internal whitespace above the cap-height that the secondary row
doesn't have below it. Trim the top to pt-2 / pb-2.5 so the row reads
balanced.

Co-authored-by: Orca <help@stably.ai>

---------

Co-authored-by: Orca <help@stably.ai>
2026-05-12 20:50:18 -07:00
2026-04-06 23:32:45 -07:00
2026-05-04 20:42:03 -07:00
2026-03-16 22:27:51 -07:00
2026-03-28 10:19:14 -07:00
2026-05-13 03:46:39 +00:00

Orca Orca

Supported Platforms Discord Follow on X

English · 中文 · 日本語 · Español

The AI Orchestrator for 100x builders.
Run Claude Code, Codex, or OpenCode side-by-side across repos — each in its own worktree, tracked in one place.
Available for macOS, Windows, and Linux.

Download 🐋

Orca Screenshot

Supported Agents

Orca supports any CLI agent (not just this list).

Claude Code   Codex   Gemini   Pi   Hermes Agent   OpenCode   Goose   Amp   Auggie   Autohand Code   Charm   Cline   Codebuff   Continue   Cursor   Droid   GitHub Copilot   Kilocode   Kimi   Kiro   Mistral Vibe   Qwen Code   Rovo Dev


Features

  • No login required — Bring your own Claude Code or Codex subscription.
  • Worktree-native — Every feature gets its own worktree. No stashing, no branch juggling. Spin up and switch instantly.
  • Multi-agent terminals — Run multiple AI agents side-by-side in tabs and panes. See which ones are active at a glance.
  • Built-in source control — Review AI-generated diffs, make quick edits, and commit without leaving Orca.
  • GitHub integration — PRs, issues, and Actions checks linked to each worktree automatically.
  • SSH support — Connect to remote machines and run agents on them directly from Orca.
  • Notifications — Know when an agent finishes or needs attention. Mark threads unread to come back later.

Install

Mac, Linux, Windows

Alternatively, install from a package manager:

macOS (Homebrew)

brew install --cask stablyai/orca/orca

Arch Linux (AUR)

# Precompiled binary
yay -S stably-orca-bin

# Build from GitHub source
yay -S stably-orca-git

[New] View Live Status of All Agents

See what every agent is doing — at a glance.

Track the live status of every agent across every worktree from one place. Spot which agents are working, waiting on input, or done — without clicking through tabs.

Orca Agent Statuses — view live status of all agents across worktrees


[New] Annotate AI Diff

Comment directly on AI-generated diffs.

Annotate any line in an AI-generated diff with your feedback, then send it back to the agent to revise. Keep the review loop tight — no copying line numbers, no context switching.

Orca Annotate AI Diff — comment on AI-generated diffs and send feedback to the agent


[New] Hot Swap Codex Accounts

Multiple Codex accounts? Switch in one click.

If you run multiple Codex accounts to get the best token deal, Orca lets you hot-swap between them instantly — no re-login, no config files. Just pick an account and keep building.

Orca Codex Account Switcher — hot swap between multiple Codex accounts


[New] Per Worktree Browser & Design Mode

See your app. Click any element. Drop it into the chat.

Orca ships with a built-in browser right inside your worktree. Preview your app as you build, then switch to Design Mode — click any UI element and it lands directly in your AI chat as context. No screenshots, no copy-pasting selectors. Just point at what you want to change and tell the agent what to do.

Orca Design Mode — click any UI element and drop it into the chat


[New] Introducing the Orca CLI

Agent orchestration from your terminal.

Let your AI agent control your IDE. Use AI to add projects to your IDE, spin up worktrees, and update the current worktree's comment with meaningful progress checkpoints directly from the terminal. Ships with the Orca IDE (install under Settings).

npx skills add https://github.com/stablyai/orca --skill orca-cli

Community & Support

  • Discord: Join the community on Discord.
  • Twitter / X: Follow @orca_build for updates and announcements.
  • Feedback & Ideas: We ship fast. Missing something? Request a new feature.
  • Privacy: See the privacy & telemetry docs for what anonymous usage data Orca collects and how to opt out.
  • Show Support: Star this repo to follow along with our daily ships.

Developing

Want to contribute or run locally? See our CONTRIBUTING.md guide.

S
Description
Orca is the ADE for working with a fleet of parallel agents. Run any coding agent with your own subscription. Available on desktop, mobile and remote runtime.
Readme MIT
1.5 GiB
Languages
TypeScript 95.2%
JavaScript 4%
Swift 0.2%
CSS 0.2%
HCL 0.1%