* fix(computer): stop echoing written text and secure read-backs in action results
* fix(computer): treat a truncated set-value read-back as unverifiable
* fix(computer): accept code-point truncated read-backs as unverifiable
* feat(plugins): Featured and Newly added rows in the plugin catalog
Featured shows the most installed plugin per category; Newly added lists plugins
by the catalog's new entry-level addedAt (hidden when no catalog dates entries),
with a New badge for 24h and an Added this week filter. Snapshots move to a v3
cache key so older builds never read addedAt.
* feat(plugins): derive Newly added dates from release dates, as the website does
Drops the catalog-level addedAt field (schema, docs, v3 snapshot key). Main now
estimates a listing date for each non-official plugin from its oldest dated
release, and the Newly added row, New badge and This week filter read it through
shared helpers that mirror orca-site's pluginNew.ts: 30-day window, newest first,
dates more than an hour in the future ignored, "just now / N hours ago / N days ago".
* feat(plugins): show nine Newly added plugins, drop the counts release dates inflate
Listing dates come from each community plugin's oldest kept release, and
catalogs keep only recent releases, so almost every plugin looks new: 181
of 182 fall in the 30-day window and 142 count as this week. Remove what
that inflates rather than flag it: the "N this week" count and its See all,
the This week filter, and the 24h New badge.
The Newly added row now offers the website's nine in the catalog's normal
wrapping grid, the same columns and card widths as the catalog groups.
* fix(plugins): pick Featured winners by every kind a plugin belongs to
Featured used only a plugin's first filter kind, while the category filters
count every kind, so category order could change winners or drop a kind's only
candidate. Each plugin, walked by installs with a key tie-break, now fills one
unfilled kind it belongs to (the one with the fewest candidates left, then by
name). Also note why Featured is a capped one-row teaser and pin the cap.
* fix(plugins): hide Featured when Newly added is empty
Without Newly added, Featured sat directly on the Official catalog, whose
leading cards are the same popular plugins in the same columns, so back-to-back
rows repeated and read as a render bug. Featured now shows only alongside
Newly added. Leaving featured plugins out of their catalog instead would move a
card into the catalog the moment it's installed and skew the catalog's N of M.
Adds a PluginManager test that no plugin card shows twice in the empty state,
and page-level fixtures (390, 600, 1440, empty 1440) for screenshots.
* fix(plugins): cap Newly added at two full rows of the current columns
At phone width nine stacked cards pushed the catalogs about 3.5 screens
down. The grid now shows two full rows of its container-query column
count (8 at four columns, 4 at two, 2 at one), hides a partial last row,
and the pick renders at most eight. Hidden plugins stay listed in their
catalog group, so there's no See all.
* Correct plugin catalog fixture evidence
* Make plugin highlight tests match observable behavior
* feat(wsl): turn WSL hosts on by default; ORCA_INTERNAL_WSL_HOSTS=0, false, off or no turns them off
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(wsl): review follow-ups for WSL hosts on by default
- Off words also match when quoted (cmd.exe's set NAME="0" keeps the quotes).
- The refusal now says WSL hosts are turned off for this launch, not missing from the build.
- New preload test pins when the renderer gets the WSL hosts API.
- Unit tests no longer inherit the gate state an Orca terminal publishes.
---------
Co-authored-by: Claude <noreply@anthropic.com>
* Tidy the Settings → Agents installed list
Rows line up on one line, the default agent gets a Default pill, and
Set as default moves into each row's ⋯ menu. Chat/CLI stays in place,
grayed out, when an agent is off. Click a row to expand its settings.
* Keep a saved default clearable when its agent isn't installed
The ⋯ checkbox follows the saved default, not the badge, so a saved
agent that isn't detected still shows Default and can go back to Auto.
Row hover uses the list-row accent token.
* Use plain items in the agent row's ⋯ menu
No checkmark column: Set as default, or Clear default agent on the saved
default, then Docs/Install aligned to the menu edge.
* test: remove 60 low-value cases and orphaned conversion fixtures
* docs(ci): list supported Windows SSH host cells
* test: recognize direct Windows orcad server entry
---------
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
design-squad's #385 P3s. The not-set-up and paste-token strips used the dashed ring, which reads as
loading; they now use the agent sheet's neutral info icon (spinners stay for real waits). On the
paste step under ~560 px the input takes the space, so the detail ('never to a sand…') leaves the
line and stays the region's description and the title's tooltip.
While a Restart runs the strip no longer promises 'Picking up where you left off.' (the recorded session
may have no conversation). When the backstop starts the agent fresh, the strip says 'Started a new
conversation.' for 3 s, then clears. An end-to-end test drives resume → 'No conversation found' → one
fresh relaunch → the line once; catalog synced (restartingResume removed).
* fix(agent-status): skipping a Codex async question clears it on SSH panes too
An SSH pane's Codex hooks are normalized by orcad on the host, so the
desktop's own hook server had no row to apply the skip keystroke to. The
renderer now sends a remote pane's skip to the owning runtime through a new
terminal.inferCodexQuestionSkip RPC, which applies it to the host's tracker.
* test(e2e): skipping a Codex async question clears a managed SSH terminal's row
m4air run 3: same tab, same leaf, new PTY, and state 1 after, but the relaunch was a new conversation
(no --resume; new session id). Orca Cloud tabs are host-surface tabs: the desktop reconnect only
attaches, and the host woke the slept leaf with its original launch. After the reversible stop, the
desktop now asks the host to ensure the agent on the pane's own provider session, placed in the same
host tab and leaf, then reconnects. A pane with no session keeps the host's fresh launch ('Starts a
new conversation'). A host that does not stop or resume shows the failure with the reason.
Strip (design-squad): 'Restarting Claude…' is the spinner and words only, with no button and no ×.
The failure says it once: the body names the reason when known ('The workspace didn't respond.')
and is otherwise empty; Try again and × stay.
On click the strip stays as 'Restarting Claude…' (spinner, button disabled, no ×). It settles on the
relaunched agent's first status, after which it follows the account (state 1 again if the sign-in is
still bad). No relaunch within 10 s, no startup to launch, or a startup that throws shows
'Couldn't restart Claude · Try again.' with Try again and Dismiss. A relaunch that stays quiet past
10 s counts as restarted. The forced past-the-mid-turn mark now clears on launch, failure or timeout,
so a stale queued restart never jumps the account-switch wait rule.
The pane runner is extracted (runReadyPaneAccountRestarts) and covered end to end through the real
store: a 'blocked' Claude relaunches in place with its resume startup, an account-switch restart still
waits, and each failure path reports.
* feat(automations): redesign the automation detail overview
Group the overview into a run-health band (last run, next run, spend), Schedule and Execution property panels, and a Prompt panel with copy and a fading show-more. Run Now is now the primary action next to Edit; Pause and Delete move into an overflow menu with Delete separated as destructive.
* test(e2e): align prompt disclosure spec with the 8-line clamp
The redesign raised the collapsed prompt clamp from 4 to 8 lines and caps the
prompt at 80ch, so the resize prompt no longer overflowed at 820px. Lengthen it
so it wraps to ~11 lines at 820px and ~6 at 1400px, and assert line-clamp 8.
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
- When the Orca account goes from active/expiring to expired/revoked, every running Orca Cloud
Claude/Codex pane shows the strip (same component, place, height as #315): 'Your Claude sign-in
expired' / 'Renew to keep working. Your conversation is kept.' / Renew (compact: 'Claude sign-in
expired' + Renew). The process keeps running; nothing is parsed from terminal output.
- One Renew clears state 1 everywhere; the panes that showed it move to state 2: 'Claude sign-in
renewed' / 'Restart Claude to pick up where you left off.' (or 'Starts a new conversation.') /
Restart Claude / Dismiss. Restart reuses the account-restart path (queuePaneAccountRestarts), which
resumes the pane's own session. Never automatic; a turn that ends cleanly after the renewal clears it.
- Kill switch / never offered: nothing new on a running pane. A held launch keeps #315's strip.
- Account reads while a running cloud agent pane is mounted: on window focus and at most once a
minute (one timer per window).
- #315 P2: the strip is a pane-top banner (useReservePaneTopSpace), so the terminal refits below it
and no row is covered; a spacer keeps it under a chromeless pane's title-row buttons.
- Spec: terminal starts below the strip and its last row stays visible (held and running); state 2's
Dismiss sits a full title row below the pane's ×. Removes the debug screenshot left in #315's spec
and polls the resize assertion (it raced the layout).
From the m4air real-app shots:
- The width class was frozen at mount, so a pane narrowed after mount collapsed the text to 'Y.'/'S.'.
The strip now lays itself out from its own width (ResizeObserver): wide / narrow / tiny, plus a
compact class below 360 px with one line ('Claude sign-in expired') and Renew; the detail stays the
region's aria-describedby and tooltip. Height stays 56 px.
- The strip sat under the pane's split and close buttons. CloudStripLayer (shared by the pane and the
fixture) starts it below the pane title row (--orca-pane-title-height), and the renew strip drops
its own × (Renew is the action; Escape still cancels).
Specs: resize after mount keeps the title readable at 520 and 320 px; the pane's split and close
buttons are hit-testable above the strip in three states.
AI provider accounts becomes Agent accounts: a page whose first part is This computer (or the
selected host), holding the existing provider accounts, switching and usage. renderAccountsSettingsSection
takes additionalSections so other parts can be added below it with AgentAccountsSubsection. The
section id stays 'accounts', so every deep link keeps working.
The Settings nav, its group labels and the matching section titles move to sentence case
(Orca account, Computer use, SSH hosts, ...). In-app, CLI and docs references to
'AI Provider Accounts' now say 'Agent accounts'.