Commit Graph
2946 Commits
Author SHA1 Message Date
Neil 75d5a65633 Add notebook preview support (#1725)
* Add notebook preview support

* Fix notebook reopen and browser routing

* Add editable runnable notebooks

* Restore notebook highlighting and defer source serialization

* Mark notebook editor beta

* Fix notebook Python syntax highlighting

* Improve notebook cell controls and dark editing

* Fix notebook focus and save shortcuts

* Fix restored notebook file loads

* Harden notebook perf and output rendering

* Fix notebook source toggle shutdown noise

* Harden notebook execution trust prompt
2026-05-13 19:28:19 -07:00
Brennan BensonandOrca 5e9f54808a Show Codex permission requests as waiting (#1788)
Co-authored-by: Orca <help@stably.ai>
2026-05-13 18:53:52 -07:00
Jinjing 14953089a2 fix: restore dead terminal setup e2e hook (#1787) 2026-05-13 18:48:14 -07:00
Neil a2ae62fccd Rename mobile README showcase asset
Rename the mobile companion showcase files to ensure GitHub renders the updated background asset.
2026-05-13 18:36:09 -07:00
NeilandJinjing 638b7e07bb Rename Activity tab to Agent View (#1773)
* rename Activity tab label to Agent View

Renames the user-visible tab label from 'Activity' to 'Agent View' in
the sidebar nav and the activity-page titlebar (plus matching tooltip
and aria-label). Internal view ID, store slice names, and component
filenames remain 'activity' to avoid behavioral risk — this is a pure
copy change.

* rename activity view labels to agents

---------

Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
2026-05-13 18:35:18 -07:00
Neil 58e5e5dc19 Polish mobile README showcase
Update the mobile companion README copy, download text, translations, and showcase media.
2026-05-13 18:28:36 -07:00
Neil c713c81eb3 Rename showcase tile to Native Search
Rename Keyboard Native to Native Search in README showcase and translations.
2026-05-13 18:16:57 -07:00
Neil 915e177783 Add Linear and mobile README showcase
Add Linear to the README feature showcase, add mobile companion download links, and update translated READMEs.
2026-05-13 18:12:54 -07:00
Neil f3d8f59567 Focus floating terminal on hotkey toggle (#1775) 2026-05-13 17:52:10 -07:00
Will Hampson 8b12ac658b Fix Linux Wayland terminal WebGL glyph corruption (#1743)
Fixes #1579.
2026-05-13 17:36:27 -07:00
Neil a04964630e Fix relative Codex file links in terminal (#1779) 2026-05-13 17:36:25 -07:00
github-actions[bot] 21b6f013fe release: v1.4.0 v1.4.0 2026-05-13 23:42:33 +00:00
Brennan BensonandOrca 29e8eae70e perf(session): prune local terminal scrollback from persisted sessions (#1753)
Co-authored-by: Orca <help@stably.ai>
2026-05-13 16:34:44 -07:00
Brennan BensonandOrca 180b5c29a7 test(e2e): make terminal-attention BEL emission PATH-independent (#1771)
Co-authored-by: Orca <help@stably.ai>
2026-05-13 16:32:33 -07:00
Brennan BensonandOrca 6e482a00d7 fix(terminal): set paneKey env on CLI-spawned terminals so agent status surfaces (#1727)
Co-authored-by: Orca <help@stably.ai>
2026-05-13 16:20:59 -07:00
Neil 07210ae24c Fix floating terminal default migration (#1767)
* Fix floating terminal default migration

* Add floating terminal icon context menu
2026-05-13 16:18:22 -07:00
Jinjing 5a6b2994ea fix: address review findings (#1770) 2026-05-13 16:14:50 -07:00
Brennan BensonandOrca 575b1d42ed Fix live Activity thread metadata (#1760)
Co-authored-by: Orca <help@stably.ai>
2026-05-13 16:02:32 -07:00
Brennan BensonandOrca be7825adb9 Make Activity default-on (#1765)
Co-authored-by: Orca <help@stably.ai>
2026-05-13 15:39:45 -07:00
Neil e68468d403 Update usage tracking showcase title
Rename the showcase tile to Account Switcher & Usage Tracking and update translated README labels.
2026-05-13 15:37:25 -07:00
github-actions[bot] 8603f62195 release: v1.3.52-rc.2 [rc-slot:2026-05-13-15] v1.3.52-rc.2 2026-05-13 22:30:48 +00:00
Neil c47f02f963 Update minimum release age in .npmrc from 1->3 days 2026-05-13 15:26:10 -07:00
Neil 39f0779da7 Improve README feature showcase
Add a responsive GIF-first feature showcase to README files and update translations.
2026-05-13 15:18:55 -07:00
github-actions[bot] 2823bf651c release: v1.3.52-rc.1 v1.3.52-rc.1 2026-05-13 21:54:35 +00:00
Jinjing c8d97f3b98 fix: include gitignored files in quick open (#1762) 2026-05-13 14:29:30 -07:00
Jinwoo HongandOrca a076656ff8 Update Orca Mobile Android release link (#1759)
Co-authored-by: Orca <help@stably.ai>
2026-05-13 13:59:05 -07:00
Prateek RungtaandJinjing 74373c2deb Drop the per-workspace AGENTS toggle in the sidebar (#1738)
* Drop the per-workspace AGENTS toggle in the sidebar

The chevron header above each card's inline agent list re-litigated a
decision the global "inline-agents" view option already controls, and
sat one row above the agent it labelled — so aiming for the agent and
hitting the chevron collapsed the section the user wanted to interact
with. Collapsed state was session-only, so there was no payoff for the
misclick.

Always render the inline agent list when the global toggle is on; never
render it when it's off. The wrapper keeps a stopPropagation handler so
clicks on the empty row gutter don't reach WorktreeCard's outer
activate/edit-meta handlers, plus role="group" + aria-label="Agents" so
screen-reader users still get a labeled region.

Also drops the leading pl-1 on DashboardAgentRow so the freed row gets
a touch more horizontal room. DashboardAgentRow's only call site is
this inline list, so there's no asymmetry to fix elsewhere.

* Added more tests

---------

Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
2026-05-13 13:34:28 -07:00
Jinjing 0273e38240 Fix start-from-PR display refresh (#1751) 2026-05-13 13:08:45 -07:00
Jinwoo HongandOrca e0b5a544a8 Improve Orca Mobile discoverability (#1758)
Co-authored-by: Orca <help@stably.ai>
2026-05-13 12:41:10 -07:00
Jinwoo Hong abcd2d5836 fix: harden Windows computer use runtime (#1757) 2026-05-13 12:37:47 -07:00
github-actions[bot] a9ea3c129d release: v1.3.52-rc.0 v1.3.52-rc.0 2026-05-13 19:34:23 +00:00
Brennan BensonandOrca 2d5fb175d7 Show running agents in Activity threads (#1754)
* fix: show running agents in activity threads

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

* polish activity thread prompt alignment

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

* polish activity thread controls

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

* match activity thread agent state icons

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

* polish activity thread state icon size

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

---------

Co-authored-by: Orca <help@stably.ai>
2026-05-13 12:33:41 -07:00
Brennan BensonandOrca f4009fdaa9 fix(activity): polish thread-row hover and widen list (#1750)
* fix(activity): polish thread-row hover, restore stable layout, widen list

The activity thread list had several hover regressions: the cursor wasn't
indicating clickability, hovering shifted the row contents because the
bell-toggle replaced the timestamp under the cursor, and the timestamp
tooltip could get stuck open after the trigger faded out (Radix didn't
dismiss because opacity:0 left it interactable). The Jump-to-workspace
button in the right pane header also read as easy-to-miss chrome.

Surface per-card actions on hover (Open + Mark-unread) in a reserved
slot so the worktree-name's flex width doesn't reflow when the buttons
appear. Drop the redundant header button. Bump the default thread list
width 340 → 480px (range 320–720) and let prompts wrap to 3 lines so
the cards work as the primary surface — the terminal is supplementary.

Mark-unread only appears for already-read threads (selecting an unread
thread auto-marks it read, so a "mark read" button would be redundant).
The remove-events-count badge change was already staged locally and is
included to keep the row chrome consistent with the new layout.

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

* fix(activity): replace 'Open' label with ExternalLink icon-only button

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

* fix(activity): move Mark-unread into the bell slot on hover

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

* fix(activity): match WorktreeCard bell pattern in thread rows

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

* fix(activity): drop AGENTS heading, add overflow menu with Mark all read

The 'AGENTS' uppercase header was redundant — the activity titlebar
already names the surface. The 'Mark all read' button was also stuck in
the titlebar far from the threads it acts on.

Drop the heading and surface 'Mark all read' as a per-list overflow menu
(MoreVertical) next to the Filter input + unread-only toggle. The action
disables when there's nothing unread to mark.

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

---------

Co-authored-by: Orca <help@stably.ai>
2026-05-13 12:13:18 -07:00
Jinwoo HongandOrca 96f35dcfaf Enable Floating Terminal by default (#1752)
Co-authored-by: Orca <help@stably.ai>
2026-05-13 11:52:48 -07:00
Brennan BensonandOrca d0f4246807 fix(tasks): remove duplicate top band on Tasks page (#1749)
* fix(tasks): remove duplicate top band on Tasks page

The Activity-page work in #1703 tightened App.tsx's `workspaceActive` to
require `activeView === 'terminal'`, so App.tsx now keeps its full-width
titlebar on the Tasks page. TaskPage's own `workspaceActive` was still
just `activeWorktreeId !== null`, so it kept rendering its own 36px
placeholder strip below the App titlebar — producing the doubled band.

TaskPage only mounts when `activeView === 'tasks'`, where App.tsx never
hides its titlebar, so the placeholder strip is always redundant. Drop
it along with the now-unused `sidebarOpen` / `activeWorktreeId` reads.

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

* fix(tasks): remove stale titlebar comment

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

---------

Co-authored-by: Orca <help@stably.ai>
2026-05-13 11:31:09 -07:00
buf0-bot[bot]andorca-bug-scan-bot cd4aa06f85 fix: pr-bug-scan validated finding from #1700 (#1728)
Clear initializedHandlesRef on reconnect so the auto-resubscribed scrollback frame re-inits xterm instead of being dropped by the has(handle) guard.

Co-authored-by: orca-bug-scan-bot <orca-bug-scan-bot@stably.ai>
2026-05-13 11:12:30 -07:00
github-actions[bot] 75a28bb960 release: v1.3.51 v1.3.51 2026-05-13 17:46:15 +00:00
github-actions[bot] d172988e1f release: v1.3.51-rc.8 [rc-slot:2026-05-13-03] v1.3.51-rc.8 2026-05-13 10:55:31 +00:00
Jinwoo HongandOrca 0314643244 Fix macOS Computer Use permission helper window behavior (#1722)
Co-authored-by: Orca <help@stably.ai>
2026-05-13 01:40:04 -07:00
github-actions[bot] f2aa36bc39 release: v1.3.51-rc.7 v1.3.51-rc.7 2026-05-13 07:54:24 +00:00
Brennan BensonandOrca 77871a06c1 feat(activity): isolate the agent's pane in the activity view (#1740)
* feat(activity): isolate the agent's pane in the activity terminal view

When the activity page hosts a tab that has split panes, only the agent's
specific pane should be visible — not the whole tab. Implemented as a
transient layout override using the existing applyExpandedLayoutTo helper
with a separate snapshot ref, so it never touches the user-facing
expanded-pane state or the persisted layout snapshot. Closing the
activity page restores the original split layout untouched.

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

* fix(activity): pass isolatedPaneId from the live tab-group render path

TabGroupPanel renders the actual TerminalPane in tab-group mode (the
default modern path); Terminal.tsx is the legacy single-group fallback.
Without this, isolatedPaneId never reached TerminalPane, so the activity
view kept showing all split panes side-by-side.

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

* fix(activity): refit terminals when isolation override is removed

The activity-isolation useLayoutEffect only called safeFit on the apply
path, so removing isolation (or hitting the early-return when
applyExpandedLayoutTo returned false) left xterm sized for the
single-pane geometry until an unrelated event triggered another fit.
Extract scheduleRefit() and run it from all three branches.

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

---------

Co-authored-by: Orca <help@stably.ai>
2026-05-13 00:50:52 -07:00
Jinwoo HongandOrca fa769edb8d Move mobile settings to beta section (#1741)
* Move mobile settings to beta section

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

* Add mobile setup guidance

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

* Use global App Store URL for mobile

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

---------

Co-authored-by: Orca <help@stably.ai>
2026-05-13 00:29:52 -07:00
Jinwoo HongandOrca 954fb9f316 Add multi-select worktree actions (#1732)
Co-authored-by: Orca <help@stably.ai>
2026-05-13 00:18:17 -07:00
Brennan BensonandOrca 13fff0f1fb fix(activity): shrink thread-row title, stop branch-name truncation (#1733)
* fix(activity): shrink thread-row title and stop branch-name truncation

Move the time + count + unread cluster up onto the title row so the
secondary row is full-width for the repo badge and branch name (long
branch names were being clipped by the right cluster). Also drop the
title from 13px to 11px and the branch metadata to match.

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

* fix(activity): swap "New" badge for BellDot icon on unread thread rows

The bell-with-dot already represents unread elsewhere (filter toggle,
thread-row hover swap), so the text badge was redundant.

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

* fix(activity): cluster unread BellDot in the top-right with timestamp

Match the position of the existing hover-bell so unread cues live in the
row's time/action column instead of inline with the title text.

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

* fix(activity): fill the unread bell and merge it into the timestamp slot

The static BellDot now lives in the same right-most slot as the timestamp,
so on hover the slot's contents (bell + time) fade out and only the
hover-toggle button fades in — no more double-bell on hover. Also
fill="currentColor" so the unread bell reads as a solid indicator.

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

---------

Co-authored-by: Orca <help@stably.ai>
2026-05-12 23:00:53 -07:00
Neil 4608f622bf fix: open markdown file images in Orca (#1734) 2026-05-12 22:42:39 -07:00
Jinwoo HongandOrca aa0a1d2ed9 feat(ssh): preserve remote PTY sessions across app close (#1706)
Co-authored-by: Orca <help@stably.ai>
2026-05-12 21:09:51 -07:00
Brennan BensonandOrca 605ee4476a perf(runtime): compare mobile session sync key by reference, not JSON.stringify of large maps (#1730)
* perf(runtime): compare mobile session sync key by reference instead of stringifying large maps

`getRuntimeMobileSessionSyncKey` used to `JSON.stringify` `terminalLayoutsByTabId` and `runtimePaneTitlesByTabId` whole, which scaled with the lifetime accumulation of tabs in a workspace and pinned the main thread for ~750ms per click in workspaces with hundreds of tabs while an agent was working. The maps reallocate on real changes and stay reference-stable otherwise, so the key now holds them by reference and only pre-serializes the small projected shapes that need value-level comparison. Subscriber gate also early-returns when those two maps are reference-stable, so the common click path (`updateTabTitle` reallocating `tabsByWorktree`) skips the key build entirely.

See docs/agent-working-pane-typing-lag.md for the trace and root-cause writeup.

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

* docs: correct misleading comment on the relevant-fields gate

The earlier comment claimed adding terminalLayoutsByTabId /
runtimePaneTitlesByTabId to the gate prevented updateTabTitle from
falling through. That's wrong — updateTabTitle reallocates
tabsByWorktree, which is a separate field already in the gate and
already fails the AND-chain. The two added fields actually catch a
different path: layout-only mutations like setTabLayout that don't
touch any other gate field. Comment now describes the real intent:
the gate is a strict superset of every input to
getRuntimeMobileSessionSyncKey, so passing it guarantees the key is
unchanged without materializing one.

Doc updated to match.

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

* chore: drop perf writeup from branch (kept in commit history)

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

* test(runtime): pin down by-reference invariant of mobile sync key comparator

Reworks the existing reference-stable test to use two distinct AppState instances sharing every comparator-checked map, and adds a negative test that detects a regression to deep equality on terminalLayoutsByTabId. Extracts a makeSharedOverrides() helper so tests can isolate a single field without makeState's fresh-default churn defeating the assertion.

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

---------

Co-authored-by: Orca <help@stably.ai>
2026-05-12 21:08:42 -07:00
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
github-actions[bot] ca737a617e release: v1.3.51-rc.5 v1.3.51-rc.5 2026-05-13 03:46:39 +00:00
Neil 15d51dfac2 fix: open markdown image file links in orca (#1731) 2026-05-12 20:38:45 -07:00