* fix(codex-hooks): name Orca's Codex hooks so Codex's hook review stops showing "Hook N"
Codex's hook review names a hook by its statusMessage and lists one without
it as "Hook 1", "Hook 2" and so on. Orca's nine Codex hooks had none, and a
name added by hand was stripped on the next reconcile, because Orca
replaces any entry that differs from its own.
Orca's entries now carry statusMessage "Reporting status to Orca". Codex
hashes the status message, so every trust entry Orca writes or recognizes
includes it: the local, remote and WSL installs, the status probe, and the
locally computed hashes. Approval cleanup still recognizes approvals made
for the unnamed entries.
The Codex hash memo was keyed by Codex version and command only, so after
this change it would have handed back the unnamed hashes as Codex's answer.
Records now store the status message, and a record without the current one
is ignored, which makes Orca ask Codex again. Old records still count as
known Orca approvals.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(codex-hooks): name only form-2 hook commands and bump the form
Older builds share ~/.codex and rewrote the named entry back to unnamed on
every launch, since the command bytes were unchanged. Bump the POSIX command
form to 2 so they leave it alone, and name only commands that carry the form
marker. Windows, SSH and WSL commands have no marker and keep their frozen
bytes unnamed. Memo, stopgap and rollback stay command-keyed, which the form
bump already separates.
---------
Co-authored-by: Teddy Chan <1013507+teddychan@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Avoid refetching every linked Linear badge on window focus
* Preserve sourced badge updates without focus polling
* Use a fixed clock in linked issue refresh contracts
* Resolve linked issue refresh scope from its source
Neil's Q1 answer: a plan id on the Stripe Price/Product maps to the repo catalog's entitlements.
seatPriceMatch reads price.metadata.orca_plan (after env ids and price history, before lookup key
and product); the catalog sync logs a lookup-key/tag mismatch; stripe-test-setup tags every price.
* Stream usage source caches without whole-document strings
* Keep the validated source-array type through migration
* Narrow migrated source records without an assertion
* Assert cache preservation without runtime-specific error copy
* 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
* fix(workspace-cleanup): warn before deleting a workspace's ignored local files
git worktree remove deletes ignored files such as .env and local config,
and git status never reports them, so cleanup showed "Clean git" and the
delete dialog said nothing. Read them with a bounded ls-files listing,
skip regenerable output, symlinks and byte-identical copies of the main
checkout, and surface the rest as an approval-only cleanup blocker and a
warning in the delete confirmation.
* fix(workspace-cleanup): show an unchecked warning when the ignored-files check fails
* style(workspace-cleanup): format merged fact status list
* fix(sidebar): keep a user-set workspace name over linked task titles
The card title guessed whether a name was user-set by comparing it with the branch, so a pinned name equal to the branch lost to a linked issue or PR title. It now reads displayNameMode. The Workspace details dialog also pins the name when the field was edited, even if the text ends up equal to the branch.
* test(sidebar): drop title case that passes without the fix
* fix(mobile): exclude overlay permission and clear removed-host diagnostics
* fix(mobile): ignore late diagnostics for removed hosts
A closing client or a re-acquired open that fails with host-not-found could
append after removal and re-persist diagnostics for the removed host.
The cleanup scan ran only in desktop main over its own saved repos, so
workspaces on a paired server or an SSH host's orcad never showed up, and an
SSH host's retained source rows showed as "Remote unavailable" even while its
orcad served them.
Each host now runs the same scan over the repos it owns through a new
workspaceCleanup.scan RPC. The dialog merges every known host's answer,
names remote rows by this window's runtime host id so removal goes through
the existing worktree.rm route, cancels remote legs with their scan id, and
builds "Remote unavailable" rows from its catalog only when a host can't be
reached. Desktop main scans only the repos it shows.
The test reads the catalog at ref master but created it with plain git init, so
it failed wherever init.defaultBranch is main (e.g. Xcode's git on macOS).
* 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
* perf(sidebar): share mounted row scans across review visibility checks
* refactor(sidebar): drop review-visibility parameters the hook no longer uses
The hook now gates on enabled and filters on-screen cards itself, so visibleReviewCardIds no longer needs enabled or isOnScreen.
---------
Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
* fix(sidebar): keep the session name first on a monitoring agent row
Leading with "Monitoring background tasks" made every monitoring row in a
narrow sidebar truncate to the same text. The row's dot already draws the
monitoring glyph, so the status can trail the name like every other state.
* fix(agents): keep a monitoring child row's name first too
Sub-agent rows (desktop sidebar, chat strip and mobile) share one lead/trail
rule that also put "Monitoring background tasks" before the name.
* perf(sidebar): share mounted row scans across review visibility checks
* refactor(sidebar): drop review-visibility parameters the hook no longer uses
The hook now gates on enabled and filters on-screen cards itself, so visibleReviewCardIds no longer needs enabled or isOnScreen.
---------
Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
* fix(sidebar): keep the session name first on a monitoring agent row
Leading with "Monitoring background tasks" made every monitoring row in a
narrow sidebar truncate to the same text. The row's dot already draws the
monitoring glyph, so the status can trail the name like every other state.
* fix(agents): keep a monitoring child row's name first too
Sub-agent rows (desktop sidebar, chat strip and mobile) share one lead/trail
rule that also put "Monitoring background tasks" before the name.