mirror of
https://github.com/stablyai/orca.git
synced 2026-10-31 09:07:40 +00:00
da620ad63285bb01f9fa5fa69472243f5cd011c0
3566
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
cd59239927 |
fix(workspaces): add main-owned project move pause barrier (#32940)
* fix(workspaces): add main-owned project move pause barrier * test(workspaces): type project move pause reply fixtures |
||
|
|
1cc2a2afd8 | refactor(shared): group remote runtime shared-control lifecycle (#32977) | ||
|
|
fb1f4b3e6f |
Agents: store each agent's permission itself; terminals and new chats read it (#31315)
* feat(agents): store each agent's permission itself instead of typing flags into Arguments Terminals and new chats read one stored choice per agent (Use the agent's own settings, Ask for approval, Accept edits, Approve for me, Full access). Orca adds the flag at launch; Arguments hold only the user's own text. A one-time move lifts Orca's flags out of saved Arguments. Older clients still see and write the flag as part of Arguments; the host translates. * fix(agents): say the all-agents switch resets agents set separately; keep primitives unstyled * test(agents): the one-time move returns every launch-profile field * Fix permission carrier ownership and surface-specific defaults * Preserve uncertain permission operands and name the option inventory * Check env entries without indexing typed agent maps * Combine Chat permission capability imports * Use folder execution-host platform for permission environment * Preserve launch map replacement and acknowledge permission saves * Keep permission feedback fallbacks statically discoverable * Provide preload platform to Agents settings render tests * Preserve Gemini approval arguments under Full access * fix(settings): retain complete environment edits through save outcomes * fix(settings): narrow local failure scope and preserve host messages * fix(settings): retire argument drafts after acknowledged saves * fix(settings): keep Goose environment editable after reset * fix(settings): show resolved arguments for legacy hosts * Preserve pending environment resets and bound launch settings work * Keep optional settings fallback in repository metadata reads * Read repository visibility defaults through the raw settings fixtures * Prepare whole Environment edits and retire unchanged drafts * Keep Environment settings transitions in an acyclic module * Update raw settings reader test fixtures * Place test fixture safety notes on assertion starts * test: pin permission settings work and recovery contracts * test: type permission settings work fixtures * test: cover migrated permission inputs and captured CLI grammar * test: preserve typed permissions in WSL Claude restarts |
||
|
|
9a5da64fdd | refactor: group remote runtime requests and subscriptions (#32952) | ||
|
|
2c53a550ff | feat(connectors): pending prompts, answers and turn events behind experimentalConnectors (B3) (#32160) | ||
|
|
0008e0cdf5 |
fix(orcad): add --reclaim-stale-lock for a lock no start can judge after a reboot on a shared home (#32915)
* fix(orcad): add --reclaim-stale-lock for a lock no start may judge On a Linux host with no machine id whose ~/.orca is on a network or FUSE home, a lock left by the host's own previous boot names a PID that is evidence only on the machine that issued it, so every start after a reboot refused it, and the only way out was deleting orcad.lock by hand. Starts still refuse it: losing contact is not proof of exit, and a home other machines may share must never be taken over automatically. Now: - `orca serve --reclaim-stale-lock` (and `orcad --reclaim-stale-lock`) checks that the lock was written on this host, in an earlier boot, at least 2 minutes ago, and that nothing answers at its holder's endpoints. It prints the pid, host, boot and age and warns about other machines sharing the home, and clears the lock only with --yes, through the normal race-safe reclaim of that exact record. - Lock records now name their host, as evidence for that command. - The refusal has its own code, orcad_instance_lock_holder_unverifiable, names the command, and exits 3, so `orca serve --supervise` waits on it instead of giving up, and the desktop refuses on it like a held lock. - orcad advertises orcad.stale-lock-reclaim.v1 so a client can offer the command on hosts that have it. Fixes #32177 Co-authored-by: Jesse Sanford <108698+jessesanford@users.noreply.github.com> * fix(orcad): let --reclaim-stale-lock clear a reclaimer cut short by the reboot, and probe IPv6 A reclaimer from the same earlier boot on this host that the reboot cut short left a recovery owner the command could never judge, so --yes always failed. The confirmation now covers such an owner too, and only one from this host's earlier boot. An IPv6 WebSocket endpoint is probed by its bare address. Co-authored-by: Jesse Sanford <108698+jessesanford@users.noreply.github.com> * fix(cli): ship the stale-lock reclaim module with packaged builds, and refuse an unreachable lock The CLI loads main modules from out/main after the main build replaces it, so the reclaim module becomes a stable plain-Node entry and is unpacked from the asar. A lock that cannot be stat'ed for any reason other than absence (a permission error, say) is now a refusal, not "nothing to reclaim". Co-authored-by: Jesse Sanford <108698+jessesanford@users.noreply.github.com> * fix(orcad): make --reclaim-stale-lock name the real data root and report a status - The refusal prints a runnable command for the data root it refused: an orcad names its own runtime and entry plus `--data-root <dir>`, since managed hosts have neither `orca` nor `orcad` on PATH and their data root is not the default. The hint is Linux-only. - Both entry points take `--data-root` and `--json` and report one of none, eligible, refused or reclaimed, each with its own exit code (4, 2, 1, 0), so a missing lock never reads as a recovery. - The evidence says nothing answers on this machine, and that the host name and boot checks cannot rule out another machine with the same name; --yes stays the gate. - wss endpoints default to port 443, a same-boot branch that could never run is gone, and the supervisor's standby line points at the command. Co-authored-by: Jesse Sanford <108698+jessesanford@users.noreply.github.com> * fix(orcad): point the eligible message at the same command plus --yes Co-authored-by: Jesse Sanford <108698+jessesanford@users.noreply.github.com> * fix(orcad): refuse an empty --data-root, and name the right program in reclaim hints - `--data-root` with no usable value (a trailing flag, an empty or blank string) prints usage and exits 1 on both entry points, never falling back to the default profile. - A refusal raised while the reclaim command itself runs names `orca serve --reclaim-stale-lock`, not the binary the CLI runs under; an orcad still names its own runtime and entry. - The supervisor's standby hint includes this profile's --data-root. - The unreadable-lock test is skipped when running as root. Co-authored-by: Jesse Sanford <108698+jessesanford@users.noreply.github.com> * test(cli): reuse the existing client stub for the --data-root refusal test Co-authored-by: Jesse Sanford <108698+jessesanford@users.noreply.github.com> --------- Co-authored-by: Jesse Sanford <108698+jessesanford@users.noreply.github.com> |
||
|
|
291e2e807e | feat(browser): open links beside their pane, focus link tabs, honor window.close() (#31844) | ||
|
|
e268135719 |
feat(native-chat): chat agents are offered wherever their chat program runs, not only where their CLI is installed (#28709)
* feat(acp): ACP agents can declare a managed runtime installed on first chat start An ACP launch spec may name a pinned runtime Orca installs under its locked data folder. The stock lookup searches it last (Command, PATH, install directories, managed folder); a start whose lookup missed installs it under the acquisition's signal, then resolves the launch again. A Command setting, restart-recovery reads and catalog probes never install. The pinned-runtime materializer can now publish a verified multi-member folder: extract once into staging, check each member's sha256, rename into place, with a per-asset download size limit. Node's runtime path is unchanged. * Fix ACP managed runtime lookup precedence * feat(acp): ACP agents can run with a private per-process temp folder * feat(acp): old managed runtime versions are removed at host start Once per host start, the ACP registration removes every version beside an agent's current managed runtime folder, and staging left by an earlier process. One host owns the data root and ACP servers are never reattached across host runs, so nothing runs from them. This process's own staging is kept (a publish may be in flight). Best effort: a failure is logged and never holds up a launch. * feat(acp): a sign-in prompt on an ACP agent's stderr ends the start or turn signed out An agent that waits for a browser sign-in prints a link on stderr and blocks for minutes. A launch spec can now name that line (signInPrompt); the connection then closes with a typed sign-in failure through the existing process owner, so a start reads notSignedIn and a running turn fails signed out instead of settling unknown. The matched line, which carries the sign-in URL, never enters the retained stderr tail, errors or diagnostics. * Prevent sign-in URLs leaking from long stderr lines * feat(acp): an agent can enforce the permission mode itself through a session config option An optional launch-spec field names the session config option and its ask/full values. Every new or reopened session gets the value for the chat's full-access posture before it is exposed, and a refusal fails the start. With the field present Orca no longer answers permission requests for the person. No agent sets it yet. * fix(acp): reject unconfirmed permission mode during acquisition * feat(acp): an agent enforcing the permission mode itself runs the chat's own mode The launch spec maps each chat permission mode to its session option value; a start sets the value for the mode the host launches with (ask when it names none), replacing the global Agent Permissions full-access read. A mid-chat change takes effect through the host's existing restart of a child launched with another mode before the next send. * Keep ACP session acquisition within the line limit * feat(acp): open Antigravity in the Chat UI over its ACP server With the experimental chat setting on, Antigravity chats run Google's Antigravity ACP server, which Orca installs on the first chat start: a pinned 1.3.0 release whose archive and both executables are verified by hash (macOS arm64/x64, Linux x64/arm64). Each host keeps one private sign-in folder for these chats under Orca's data folder, made owner-only before every start; the server keeps its sign-in there as a file. A chat signs in with the server's Google method through the existing auth-required retry; with no saved sign-in the server's sign-in prompt ends the chat signed out. The Agent Permissions setting maps to the server's own mode, and a question the server asks shows as a question that takes one of its choices, never auto-answered. A chat reopens its session with session/resume. * fix(acp): separate Antigravity chat command and require pinned host * test(acp): assert Antigravity launch arguments across hosts * feat(acp): Antigravity chats offer Ask, Accept edits and Full access per chat Each mode maps to the server's own (default, auto_edit, yolo). No Approve for me: the server has no automatic reviewer. Accept edits gets its own description, since auto_edit approves file edit tools only. * feat(native-chat): offer host-provided chats without their CLI detected A host now marks each agentSession.agents row whose chat program Orca provides there (an ACP managed runtime with a pinned build on this host). With Chat UI on, the tab-bar picker, the empty-workspace default chat and the new-agent shortcut offer those agents beside the detected ones when the launch opens as a chat. Terminal launches still follow detection, and an older host that sends no mark keeps today's detection-only offer. * Fix CLI-free chat fallback and picker updates * Fix admission refusal reason test expectation * feat(native-chat): the host health snapshot says whether each chat's program is on the machine Antigravity's chat runs Orca's own download of Google's ACP program, not the agy CLI, so clients could not tell from CLI detection whether it can open as a chat. Each snapshot row now carries an optional chatProgram (available, installable, missing, unknown), found through the agent's own launch resolver without spawning anything, and re-derived after a managed runtime install or removal. Health state and reason are unchanged, so older clients decode the frame as before. * feat(native-chat): one renderer reading of whether an agent can open as a chat on its host Pickers asked CLI detection whether an agent can open as a chat, which is wrong for Antigravity, whose chat runs a program Orca downloads. This module answers from the host's published chat program fact, and for hosts that publish none, from the host's managed-runtime mark and install capability or else CLI detection. Facts not yet learned read as unlearned, not as no. * fix(native-chat): a declined chat opens its agent's terminal only where the CLI is installed Once a chat can be offered without its CLI, a host refusal used to fall back to a terminal that runs a CLI that is not there. The one admission boundary now reports the host's refusal instead when the workspace host's detected agents lack the CLI, for new-tab, work-item and workspace creation launches alike. A caller's own fallback, like the empty workspace's shell, still opens. * feat(native-chat): the + menu and Settings offer a chat wherever its program runs With Chat UI on and no agy CLI, Antigravity had no chat row in the + menu (or a disabled 'Not installed' one when switched on), because both read CLI detection. The menu now reads the host's chat-program answer: a chat row where the program runs or installs from the chat, no '(CLI)' row or terminal button without the CLI. A failed CLI check no longer keeps the menu from learning that answer. Settings shows an unchosen provider on when its CLI or the program Orca runs for it (downloaded or found outside Orca) is installed, and holds the switch until that is known. A saved default that opens as a chat no longer says it is not detected. * feat(native-chat): a default agent that opens as a chat starts without its CLI An empty workspace and the new-agent shortcut skipped a default agent whose CLI is not detected, even when it opens as a chat on that host (Antigravity without agy). Both now honor that default, waiting briefly for the host's chat facts when they are not known yet, while the automatic pick with no default still chooses only detected agents. Blank and the shell fallback are unchanged. * feat(native-chat): new workspaces, work items, continuations and the dashboard offer chat-only agents The new-workspace composer, work-item launches, session continuation and the dashboard launcher listed only agents whose CLI is detected, so an agent that opens as a chat without its CLI could not be picked, and an explicit pick of it was dropped. They now also offer agents that open as a chat on the workspace's host, keep such an explicit choice, and the dashboard republishes when the host's chat facts arrive. Automatic picks still choose only detected agents. * feat(native-chat): Source Control and Fix Checks accept a chosen agent that opens as a chat The Source Control action dialog, its saved auto-start, the checks panel, recovery launches and Fix Checks (before and after its workspace exists) rejected a saved or default agent whose CLI is not detected, even where it opens as a chat. They now accept it there and list it, through the shared source-control pick, while the automatic pick still chooses only detected agents. * fix(native-chat): an empty workspace does not wait on chat facts for a Claude or Codex default Claude and Codex have no program Orca downloads, so without their CLI only the host's own answer could offer them as a chat; holding the workspace empty for the host's agent list could not change that. * test(native-chat): pin the chat-program fact, cold explicit defaults and the CLI-less decline Covers the host's program lookup and its re-read after an install, older and unknown snapshot values falling back to the managed mark and install capability of the same host, an explicit default opening as a chat with CLI detection failed while automatic and blank picks stay on detected agents, kept composer and saved Source Control choices, and a declined chat reporting the refusal instead of opening a terminal for a missing CLI on both launch paths. * refactor(source-control): the action dialog's agent list lives in its own hook The dialog hook was over the file-length limit after it learned which agents open as a chat without their CLI; detection and that offer now live together in use-source-control-launchable-agents. * fix: typed test mocks and record the dialog's pre-existing reset effect The Source Control dialog's open-cycle reset effect was already on main; the changed-code gate reported it because the effect now also learns which agents open as a chat. * fix(native-chat): a declined chat refuses its terminal only when the CLI is known to be missing When a host declines a chat, Orca falls back to that agent's terminal. A chat can now be offered without its CLI, so the fallback must not open a terminal that cannot start. But a failed or still-pending CLI check is not proof the CLI is missing: treating it that way blocked a working terminal fallback (for example an OpenCode version that runs in a terminal but not as a chat). Each detection producer (local, paired server, SSH) now records the outcome of its latest attempt for the exact target, next to the IDs it already keeps. The decline check refuses the terminal only when the same host's latest attempt succeeded and did not list the CLI; pending, failed or unresolved outcomes keep the existing fallback, and a caller's own shell fallback is untouched. * fix(native-chat): every launch surface learns whether a chat opens before it decides A chat whose program runs on the host without its CLI (for example Antigravity) could be missing, greyed out or swapped for another agent depending on which surface launched it: the composer dropped an explicit pick while the host was still answering, Fix Checks and the Checks panel refused a saved chat agent, an inactive paired host was never asked about its chats, the Providers switch flashed off, and session continuation auto-picked an agent that was only offered. One lease per host, runtime and pairing now acquires the host's agent list and health stream for whoever needs it: the + menu, composers, Settings, the dashboard and its pop-out, Source Control and Checks, Fix Checks, work items, shortcuts and continuation. Actions wait for those facts within one bounded deadline (ordinary CLI detection keeps its own wait), cancel when the workspace's host is genuinely replaced, and re-read settings before launching. A saved, default or explicit choice may open as a chat without its CLI; automatic picks still come only from detected agents. Pending or unknown facts never erase a choice or flash a switch off. The dashboard's holds are reconciled by the publishers that read them, and a hold that notifies while it is being created no longer leaks a second stream holder. * fix: the new-workspace composer memoizes its launch workspace from its own fields * fix: a declined chat reads the launch host's own agent inventory; test fixtures match their types * fix: work-item launches detect before waiting on chat facts; the composer and Source Control list agents from one owner The composer card no longer holds its own chat-facts lease beside its modal's, Source Control reads agent inventory only while its dialog is open, and a work-item launch keeps the new workspace's own detection when the store has not loaded that workspace yet. * fix(native-chat): keep acquisition tied to the current host resource * fix(native-chat): verify the current acquisition before returning choices * fix(i18n): retain legacy terminal-list English entries in the runtime catalog * fix(native-chat): the dashboard republishes launch options when the active workspace's host changes Both dashboard publishers now watch the active workspace and its selected host, which own its launch options. Two QuickLaunchButton tests assert the current "couldn't list terminal agents" wording. Restores base forms and drops a duplicate workspace helper to stay inside the change budget. * test: the dashboard publisher test reads its watched state from the function it tests * fix(native-chat): dashboards watch one checked route-input view; saved Source Control discovery settles every outcome Both dashboard publishers observe and derive launch options from one exhaustive, compiler-checked view of the store slices the launch-route readers take, so a route input can no longer be missed by one list. A saved Source Control action's discovery now ends as success, cancelled or failed; only success can auto-start, and a cancelled or failed attempt reveals the editable dialog instead of launching on a replacement runtime. Restores base forms and shares one worktree workspace helper to stay inside the change budget. * style: format the runtime metadata resolver * fix: merge duplicate imports the code-quality gate rejects * test: the dashboard watch fixture seeds every route-input field * test: the dashboard watch fixture is fully typed without a cast * fix: an unknown agent scan stays unknown for Fix Checks and recovery, and a saved Checks agent keeps its message * fix: the action-first chat path asks the same missing-CLI check before opening a declined terminal; compact to the size cap * refactor: compact the chat-program changes to the size cap after merging main * Pickers list an agent that can't open here as disabled with its reason instead of hiding it The Create workspace and continuation pickers only searched the agents the caller could launch, so an enabled agent with no chat on this host (for example Antigravity when the host can't run it) lost its disabled row, while the + menu showed it. * Continuation test accepts more than one disabled subfolder row now that disabled rows are listed * Re-run CI: the code scan was cancelled across the repository * test: cover chat selection without terminal CLI * test: compact host chat program fixtures |
||
|
|
aeb039938f |
refactor(jira): colocate shared contracts and capabilities (#32927)
* refactor(jira): colocate shared contracts and capabilities * test(jira): validate title width against panel budget |
||
|
|
b090d5a04d |
perf(quick-open): prepare separator variants once per query (#32252)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com> |
||
|
|
914b260fa6 | fix(deps): resolve security advisories across desktop, mobile, and docs (#32326) | ||
|
|
965d6d153e |
Revert child workspace status summary toggle (#32842)
* Revert "Show child workspace statuses in the children toggle (#32224)"
This reverts commit
|
||
|
|
4c7991509f | feat(browser): say why a page failed to load and reload it when it can (#31847) | ||
|
|
846851237c | feat(browser): per-repo or per-workspace browser profile for new tabs (#32039) | ||
|
|
41402a5811 | refactor(jira): colocate status error parsing with Jira owners (#32430) | ||
|
|
816fcee742 |
Every view of a shared file stays current after undo or discard, and non-UTF-8 files ask before converting (#32413)
* fix(editor): keep every view of a shared record on its text; ask before a lossy UTF-8 save - A clean record's draft may reach a view's live model. Views of a record share one draft, so a commit that reads clean (a rich-mode undo that differs from disk only in trailing whitespace) is the record's text; refusing it left the source view showing undone text, and typing there resurrected it. - A rich view applies another view's text (or a reload) without an undo step, so its Cmd+Z no longer reverts the source view's typing or re-applies text undone there. - An outside change to a path (Source Control discard, watcher) now reaches views of the same record in other workspaces' panels, not only the named workspace's, so their cached copy of the discarded text is dropped and reloaded. - Explicit saves send the lossless-UTF-8 precondition. A non-UTF-8 file asks for confirmation (Save as UTF-8, destructive) before replacing characters that aren't valid UTF-8; declining leaves the bytes alone. The autosave-paused notice no longer promises a lossless conversion. - Dev builds resolve worker-thread entries from the main output folder when the caller was bundled into a shared chunk (packaged builds resolve from resources and are unchanged). Co-Authored-By: Claude <noreply@anthropic.com> * fix(editor): say why save-and-close refused a non-UTF-8 file --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
699c17ca16 |
fix(ssh): never block or over-read on an SSH identity file (#32274)
Every place Orca reads an SSH key or identity file now goes through one reader that refuses directories, FIFOs and devices (including through symlinks) with a nonblocking open, and caps the read at 1 MB. An auth failure now names any identity file that was skipped and why. Fixes #31965. Reported by @Huge, who also proposed the first fix in #31966. Co-authored-by: Martin Vlach <mr.huge@seznam.cz> |
||
|
|
7b0a7ee79f |
fix(terminal): a timed-out CLI split names its pending pane, and a retry can never re-run its command (#32278)
* fix(terminal): a timed-out CLI split names its pending pane and can be retried without splitting again Fixes #32169 * fix(terminal): a blank retry id or a closed pane never re-runs a split's command * refactor(terminal): a split retry only waits for its pane and never asks the window again * fix(terminal): a split missing from the graph is reported pending, never closed |
||
|
|
88de2dbacb |
fix(web): the browser client advertises the desktop's chat capabilities, so its host opens chats (#32253)
* fix(web): the browser client advertises the desktop's chat capabilities, so its host opens chats The browser client's handshake never named agent-session.structured.v1, so a paired host refused every agentSession call with structured_agent_session_unsupported and withheld chat tabs. The desktop window, the Electron remote handshake and the browser client now build their lists from one shared array of what the renderer's chat implements. Fixes #32145 * refactor(web): keep the browser client's capability list beside the desktop's in shared The host-side test parses both handshakes with the host's own parser, which the node typecheck project can only import from src/shared. * test(web): assert close-intent support in the auth frame, not the whole capability list |
||
|
|
c32d46850b |
fix: offload macOS deletion spawns and reduce branch cleanup (#32227)
* fix: reduce worktree deletion branch cleanup overhead Refresh only the remote base branches needed to prove a branch merged, with automatic maintenance disabled. Skip merge simulation when no common ancestor is available and preserve the branch when its remote base cannot be refreshed. * fix: preserve fetch mappings and live branch cleanup fallbacks * fix: spawn macOS worktree deletion commands off the main thread |
||
|
|
c74ff91b85 |
Show task names for Codex subagents (#32243)
* fix: name Codex subagents from rollout metadata * Hide generic default role in child agent rows * Reject non-regular Codex identity transcripts without blocking |
||
|
|
352b29a030 |
fix: preserve workspace review references when clearing active reviews (#32263)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com> |
||
|
|
b4ee652bcf |
Show child workspace statuses in the children toggle (#32224)
* Show child workspace status counts in lineage toggle * Give child status summaries room and wrap narrow layouts * Use solid working dots and keep child summaries on one line * Restore children icon and clarify worktree tooltip * Keep child totals clear of status counts in narrow layouts |
||
|
|
47484b13d6 |
fix(native-chat): keep queued messages in the chat's own record, so a refused one can't be skipped (#30418)
* fix(native-chat): a refused queued message still blocks the queue when its card write fails Every reader of a queued card goes through one derived view of the journal's dispatch facts, so a card whose message was refused reads as returned even when its card-table update and heal both failed. One decision and one writer store the derived state for every action. * refactor(native-chat): keep each queued message in the chat's journal, not a second table A queued message lived in its own SQL table, and a hook that may be skipped copied each refusal from the journal into it. When that write failed, a refused card vanished: the cards behind it sent, and its Send and Delete did nothing. Each queued message is now a `queue` row in the chat's journal beside the submission that hands it off and the dispatch row that answers it. The reducer folds the card from those rows, so a refusal returns the card and holds the cards behind it with nothing written, and replay reads the same. Every action writes its own rows in one transaction. Cards an earlier build stored are read through the same classification until they move: each action moves its own card, and a bulk import runs once per open. A new epoch restates every card still owed an answer in the transaction that deletes the old rows. The settlement hook and its savepoint, the open-time heal, the drain's heal and the derived-card view are gone. The published card list is unchanged. * test(native-chat): adapt the queue tests to cards kept in the journal Cards are written through the journal, so tests queue them with their body alone and hand them off under their real fingerprint. Tests of the removed settlement hook, heal and SQL store are deleted; the text-update spec now covers the edit decision alone, and a test of an earlier build's stored holds seeds the legacy table and reads the imported cards. Rolling over an epoch now keeps a card whose hand-off was never handed over, so that test checks the retried id never sends rather than that nothing sends. * test(native-chat): a refused card holds the queue through rewind, a new epoch and a restart One whole-flow test through the host: the refusal writes no card row, a rewind that retires the refused hand-off and a rolled-over epoch keep the card returned, a restart and Resume send nothing behind it, its own Send refused again still holds the queue, and its Delete releases the next card in order. * test(native-chat): an earlier build's queued cards move into the journal once, each read the same One mixed-import test through the host. The first open's import fails and moves nothing, yet every card reads as it will; Delete and Send each move only their own card. The next open moves the rest in one transaction, writing a refusal only where its hand-off is gone, nothing for answered cards, and leaving an unreadable row on disk. A later command turn spends a moved command card, a third open writes nothing, an old Delete replays from its receipt, and a chat with only answered legacy rows clears them in a delete-only transaction. * test(native-chat): adapt typechecked tests to cards kept in the journal The row-kind table lists a queue row, the clear and legacy-import tests match the current signatures, and the downgrade test keeps only the leftover-send case: a queued card is now a newer-version journal row an older build keeps read-only, and users don't downgrade. * refactor(native-chat): drop the journal row writer's unused transaction hook No caller passes one since the queue's savepoint bookkeeping left. * test(native-chat): downgrade probes write rows at the version older builds read The highest version this build reads is now 4, the queue row's. A newer build's row in these probes is written at version 3 so the older build meets its kind, not a newer version, and the Stop-event probe hands the older build the rows as stored, since a read raises each row's version. * test(native-chat): unit tests follow the queue row's version 4 The legacy-import test opens real SQLite, so it runs in the Node runtime project. The newest version this build reads is now 4, and a read raises a row's version to it, so the turn-lifecycle test no longer pins the in-memory version (the written one stays pinned by journalRowSchemaVersion). * fix(native-chat): one batch echoing two refused queued messages spends both The per-row delivery check returned only the first waiting card an echo proved delivered, so when one settlement carried echoes for two cards the second stayed waiting and was sent again. It now returns every card the row proves delivered, and the fold withdraws each; replay folds the same. * fix(native-chat): a rewind moves an earlier build's cards into the journal first While the open's import had failed, an earlier build's card that read as refused through its hand-off lost that reading when an in-place rewind retired the hand-off: it disappeared and the card behind it sent. The rewind now adopts every legacy card ahead of its tombstones and deletes their rows in its own transaction, as an epoch replacement already does, so the fold latches each card's reading before its hand-off is gone. * fix(native-chat): keep an earlier build's card whose hand-off is still unconfirmed The import dropped a legacy card handed off as a send whose delivery was unknown, though the fold keeps such a card linked and a later refusal returns it. The import now keeps every card whose hand-off a later row can still answer, through the same check the reducer folds dispatch rows by. * fix(native-chat): one delivery echo withdraws at most one queued card One provider echo proves one delivery, yet it withdrew every waiting card with the same text whose hand-off was refused, so a second identical card was lost. The fold now pairs each echo with one card: on its own row the earliest-positioned match no other echo of that row took, and for a card that waits again the earliest applied echo no card has taken. Paired echoes live in the fold's state, so live and replay pair the same; readers of cards not yet imported work on a copy. * fix(native-chat): a queued message handed to the agent is sent again only on proof it never got it Pressing Stop after Orca handed a queued or steered message to the agent, before the agent confirmed it, put the card back in the queue, and Resume or the next send sent it again. A check matching the agent's echo of the text was the only guard against a double send, and it kept trading a resend for a lost card. Whether the card waited again was decided by the rejection's category, not by proof the agent never got the message. A refused hand-off now waits again only where Orca proves the agent never received it: the host still held it, or whoever settled it recorded that. A failure still returns the card and holds the cards behind it. Anything else may have reached the agent, so the card is spent and its message reads as sent, derived on every fold from the stored rejection: with the turn it was answered into, as that turn's unconfirmed message where it was handed over; withdrawn before any turn opened, as a person's own send a Stop took back. The reopen mark ignores a recovered doubt, and the restart reconciler no longer judges a queued hand-off unsent from what history lacks. The echo text matching and its pairing are deleted. A close or quit while the agent starts settles sends with the unrun hold. The host hands nothing to a child before its start answers (structured-agent-session-delivery-loop.ts: a handover needs phase ready), so such a send went to an earlier child and may have run: it now reads as sent instead of waiting again. * fix(native-chat): Claude's report that it removed a queued message unrun lets the card wait again Claude says when it removed a send without running it: the interrupt receipt's cancelled list, or a command_lifecycle cancelled, discarded or refused frame for a command that never started. Every one settles through rejectClaudeDispatchWaiters, which now marks the settlement unrun. For a queued card's hand-off the host records that as proof the agent never got it, so the card waits again under the queue's pause. A direct send keeps the plain refusal: there the proof would owe it as stopped history. * fix(native-chat): an earlier build's card stopped after hand-over follows the same rule on upgrade Earlier builds put a card back to waiting after any refusal without a verdict and cleared its link, so a card the agent may already have would be sent again after the upgrade. The card's own hand-offs in the journal decide now: unchanged and last sent as one that may have reached the agent, it is spent on that hand-off and its message reads as sent; edited or sent again since, it is held for its own Send under a host-only marker that publishes as a plain hold; with no hand-off in doubt, including one that never left Orca, it waits as before. The import writes a card spent on a hand-off in doubt, so its message shows. * fix(native-chat): read a queued row's hand-off before the lookup that uses it The lookup's callback lost the narrowing of the row's change, which the mobile test typecheck rejects. * test(native-chat): a card steered into a turn a Stop ends stays sent in the Stop tests Three tests pinned the old rule, that a card handed into a running turn comes back to waiting when a Stop ends it. Under the new rule nothing proves the agent never got it, so the card is spent: with the turn named, its message reads as that turn's unconfirmed one; without, as a send the Stop took back. Neither is ever sent again. * fix(native-chat): a queued message stopped before Orca handed it to the agent waits again A Stop that aborts a hand-off after its row is written but before the agent call now records the withdrawal as never reaching the agent, for queued hand-offs only, so plan D's rule returns the card to waiting under the Stop's pause instead of spending it. Direct sends keep the plain withdrawal (the flag would owe them as stopped history). The agent's own refusal while aborted is kept rather than overwritten, and an abort thrown during the call stays in doubt. * fix(native-chat): a queued message stopped while the agent prepares it waits again The abort signal reaches only an adapter's preparation (its options, the previous turn opening), never its write, so the signal's own reason thrown back is the adapter saying nothing was written. The handover now reads that, for queued hand-offs only, as never reaching the agent, so the card waits again under the Stop's pause. Claude no longer wraps that abort as an option refusal, which had returned a stopped card as a refused one blocking the queue. A real refusal keeps its cause and its barrier; any other throw stays in doubt and is never resent. * test(native-chat): the usage-limit Continue backlog case writes its card through the journal queue Main's #30396 wrote its backlog card with the stored fingerprint and host-instance stamp the journal queue derives instead; the card the Continue must yield to is the same waiting card. * test(claude): the real-CLI queued Stop expects the unrun mark Claude's cancelled-unrun receipt carries * fix(native-chat): retain spent legacy messages when import fails |
||
|
|
fd1875084f | fix(chat): allow visuals to declare open without breaking scripts (#32226) | ||
|
|
c43ec4ddbb |
test: keep explicit regressions without legacy algorithm copies (#32218)
* test: keep explicit regressions without legacy algorithm copies * test: use Number.NaN in latency fixtures --------- Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com> |
||
|
|
a5b2543d85 |
test: retire copied oracles and implementation inventories (#32206)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com> |
||
|
|
456e5830bb |
test: consolidate discovery coverage and replace copied oracles (#32211)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com> |
||
|
|
52e413ec85 |
fix(mobile): finish bundle downloads over slow links with smaller ranges (#32174)
* fix(mobile): serve bundle ranges within slow-link stall budget * test(mobile): consolidate range compatibility coverage and typed dispatch |
||
|
|
3f7b34106a |
Refine Agent Dashboard lifecycle handling (#32172)
* Track Agent Dashboard adoption and daily visible use - Record enablement, board opens, and per-surface daily visibility - Persist daily limits across restarts and respect consent and window visibility * Track dashboard telemetry at surface roots |
||
|
|
075ed138bd |
Fix GitHub PR auto-merge eligibility (#32075)
* Fix GitHub PR auto-merge eligibility handling * Preserve GraphQL auto-merge state over REST fallback |
||
|
|
26f677ee94 |
fix(codex): pair structured launches with the CLI runtime (#32061)
* fix(codex): pair structured launches with the CLI runtime * test(codex): align launch snapshots with runtime pairing * fix(agent-session): keep this app's CLI ahead of the paired runtime dir Pairing ran after the Orca CLI prepend, so a runtime dir that also holds an `orca` (e.g. /usr/local/bin with node+codex+orca) shadowed this app's launcher for the child. Pair first; the CLI dir stays first on PATH. Drops a PATH-shape test the parity snapshots already cover. Co-Authored-By: Claude <noreply@anthropic.com> * fix(cli-runtime): skip compiled CLIs and keep inherited PATH when pairing a sibling node A native codex/claude beside a node (Homebrew, /usr/bin) never runs on it, so pairing only reordered PATH. An env naming no PATH now pairs over the PATH the child inherits instead of replacing it with the CLI dir alone. Co-Authored-By: Claude <noreply@anthropic.com> * test(cli-runtime): type the PATH-less env fixture Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
1ec8f079d8 |
fix(usage): read Cursor Unified Ultra current-period quotas (#31978)
* fix(usage): read Cursor Unified Ultra current-period quotas * fix(usage): fall back when Cursor serves the current-period route as HTML Cursor answers unknown /api/dashboard routes with a 200 HTML app shell, so a retired current-period endpoint would surface as a permanent parse error for every Unified Ultra account instead of the summary fallback. Co-Authored-By: Claude <noreply@anthropic.com> * fix(usage): stop labelling Cursor plan usage as monthly Unified Ultra now reports a weekly period, so the Accounts heading and search copy no longer promise a monthly window. Co-Authored-By: Claude <noreply@anthropic.com> * fix(usage): read weekly Cursor periods for all unified and idle-pool plans Cursor's weekly X Subscription plans (Plus/Premium/Super/Ultra, incl. enterprise seats moved to Premium) all keep stale monthly zeros in usage-summary. Gate on unified_* membership, or on idle summary pools with a sub-monthly current period; non-unified plans ignore current-period failures so their behavior is unchanged. Co-Authored-By: Claude <noreply@anthropic.com> * fix(usage): skip the Cursor current-period request for unlimited non-unified plans Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
722bb2495a | fix(chat): retain unlisted reported Codex models (#32068) | ||
|
|
6c38b40984 |
fix(git): retain authentication guidance for push failures (#32078)
* fix(git): retain normalized authentication diagnostics in push errors * fix(git): label auth failures for every remote operation Pull, fetch, fast-forward and rebase toasts leaked the IPC wrapper around the normalized auth message; Git <2.46 also reports 'could not read Password' for remotes whose URL carries a username. Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
6a96733ba9 |
Install Orca's skills with one click on every setup screen (#31918)
* Add Orca's own bundled-skill planner and installer (not wired in yet) One planner decides what installing Orca's bundled skills does to each target folder; execute re-plans under per-path locks and runs only a plan whose digest still matches; a shared summary derives badge, wording and exit code. A copy counts as Orca's untouched one only when its SKILL.md bytes match a version some build shipped (resources/skills/released-digests.json, generated from git history and checked add-only). Nothing calls this yet; the npx path is unchanged. * Report left-alone folders as warnings and keep backups in the home A leave is no longer a failure: the outcome line says what happened plus "N left alone: <reason>", and the exit code is 1 only for a failed or changed op. Backups for every scope go to <home>/.agents/.orca-skill-backups on the executing host, so a project Replace never writes into the repo; moving there falls back to copy, verify, then remove across filesystems. * Update Orca's skills with Orca's own installer instead of npx skills The app's Update skills dialog, badge, nudge and status pills now read the bundled-skill plan and summary, and Update executes the reviewed plan's digest. `orca skills install|update` runs the same planner in-process with --dry-run, --force, --json and per-summary exit codes. Removes both npx spawn sites, the freshness inventory modules and the npx round-trip CI. * Update only where the skill already is; one provider-root rule for app and CLI installedOnly now drops every location that holds nothing (keeping the shared slot only when an existing agent link points at it), so Update never adds a skill for another agent. The app and CLI resolve the Claude skills folder through the same rule in localBundledSkillInput; a test asserts both plan identically. * Compact Update skills dialog: one row per skill, locations named by agent summarizeBundledSkillPlan now returns each skill's locations, labelled by agent (or "Shared folder") with a ~-collapsed path; the dialog shows one row per skill that needs something, collapses up-to-date skills into one line, and lists every location behind "Show all locations". The result reads "Updated N skills · M left alone". Under installedOnly a Replace with no shared copy replaces in place instead of adding one. * fix(skills): keep location paths readable by putting the state under the path * fix(skills): hold the last plan in state, not a ref mutated during render Split the update dialog's rows, headline and footer into components, move the Update label next to the other plan copy, and use z.strictObject for the request schemas. * Escape non-ASCII characters in bundled-skill regex and wording The orcad bundle rejects a literal non-ASCII character in a regex. * fix(cli): escape non-ASCII apostrophes in the skills install help text * Plan and update Orca's skills on paired servers, SSH hosts and WSL * Show the skills pill for paired hosts; real-WSL installer test * test(orcad): check the bundled CLI plans a skill install without npx Drop the deleted roundtrip workflow's group from the closed-PR cancellation fixture. * Let the WSL installer create the backups folder itself * Review fixes: follow the active workspace's host, keep hosts' plans and runs apart, never boot WSL for a background check * test: execute requests carry the plan request; CLI pill follows the local target * Write large WSL skill files in chunks that stay under the command-line limit * Make bundled-skill test fixtures link folders the way the product does on Windows Directory links in fixtures are junctions on Windows, which need no Developer Mode; the one file-link fixture is skipped there. * Let a client ask a host to install named Orca skills, not only update installed ones * WIP surfaces * fix casts * Prune ratchet and shard entries for deleted files * Review fixes: disable feature-wall Install without a host, name unknown-skill errors, drop leftovers * Setup buttons follow the plan: Update only when it would change something, Replace for an edited copy; complete translations * Plan an SSH workspace on the managed server that serves its host; ask to connect otherwise * Translate the remote skill states into every locale * Install on SSH workspaces through their managed server; ask to connect an unserved SSH host * Resolve legacy skill agent keys canonically * Reject stale skill replacements when auxiliary content changes * Remove the Windows-hosted WSL bundled skill installer * Wait for active workspace ownership before planning bundled skills * Keep legacy WSL skill setup on its inline npx flow * Use each setup surface's target for discovery and installation * Describe skill setup actions and results from their install plans * Keep ordinary bundled skill classification shallow * Leave unreadable skill replacements alone without aborting plans * Show blocked skill setup plans as needing attention * Resolve skill setup discovery and installation from workspace ownership * Keep legacy WSL setup scoped to the selected runtime * Pass force-all through shallow planning and describe unreadable copies * Keep skill setup previews shallow until Replace is clicked * Stop Replace when its explicit plan cannot replace a selected copy * Keep skill setup within the focus and workspace-record read ratchets * Clarify skill update statuses and folder details * Clarify skill setup results and blocking reasons * Keep selected skill replacements in place with one status * Use first-install wording when no agents have the skill * Report completed skill replacements with their backup confirmation * Preserve main’s skill selection for unavailable Computer Use * Derive setup status and coverage from the install plan * Use shared plan status labels on every setup panel * Show blocking skill folders and keep incomplete setup steps pending * Clarify available skill updates and skipped copies * Pass setup execution outcomes to the skill result API * Use update skipped wording in skill setup results * Keep skill update results in preview order * Show skipped skill copies before installing for more agents * Show unsupported skill setup guidance before installation * Use the host install plan for orchestration agent coverage * Show each skill skip reason once * Count skipped skills instead of skipped folders * Make installer input and link tests work on Windows * Show disconnected host guidance before offering skill installation * Bound bundled skill classification reads and parse names linearly * Keep workspace skill roots inside the resolved workspace * Compare workspace skill roots with native path semantics * Restrict bundled skill backups to their owner on POSIX * Keep bundled skill updates on the proven local workspace host * Keep skill details on the originating setup target * Keep recovered skills needing attention until they are updated * Expect recheck after a failed skill setup plan * Count completed skill updates in the status tooltip * Count only usable skills in orchestration agent coverage * Sync the runtime localization catalog |
||
|
|
fa71556085 |
Install and update Orca's skills on paired servers and SSH hosts (#31867)
* Add Orca's own bundled-skill planner and installer (not wired in yet) One planner decides what installing Orca's bundled skills does to each target folder; execute re-plans under per-path locks and runs only a plan whose digest still matches; a shared summary derives badge, wording and exit code. A copy counts as Orca's untouched one only when its SKILL.md bytes match a version some build shipped (resources/skills/released-digests.json, generated from git history and checked add-only). Nothing calls this yet; the npx path is unchanged. * Report left-alone folders as warnings and keep backups in the home A leave is no longer a failure: the outcome line says what happened plus "N left alone: <reason>", and the exit code is 1 only for a failed or changed op. Backups for every scope go to <home>/.agents/.orca-skill-backups on the executing host, so a project Replace never writes into the repo; moving there falls back to copy, verify, then remove across filesystems. * Update Orca's skills with Orca's own installer instead of npx skills The app's Update skills dialog, badge, nudge and status pills now read the bundled-skill plan and summary, and Update executes the reviewed plan's digest. `orca skills install|update` runs the same planner in-process with --dry-run, --force, --json and per-summary exit codes. Removes both npx spawn sites, the freshness inventory modules and the npx round-trip CI. * Update only where the skill already is; one provider-root rule for app and CLI installedOnly now drops every location that holds nothing (keeping the shared slot only when an existing agent link points at it), so Update never adds a skill for another agent. The app and CLI resolve the Claude skills folder through the same rule in localBundledSkillInput; a test asserts both plan identically. * Compact Update skills dialog: one row per skill, locations named by agent summarizeBundledSkillPlan now returns each skill's locations, labelled by agent (or "Shared folder") with a ~-collapsed path; the dialog shows one row per skill that needs something, collapses up-to-date skills into one line, and lists every location behind "Show all locations". The result reads "Updated N skills · M left alone". Under installedOnly a Replace with no shared copy replaces in place instead of adding one. * fix(skills): keep location paths readable by putting the state under the path * fix(skills): hold the last plan in state, not a ref mutated during render Split the update dialog's rows, headline and footer into components, move the Update label next to the other plan copy, and use z.strictObject for the request schemas. * Escape non-ASCII characters in bundled-skill regex and wording The orcad bundle rejects a literal non-ASCII character in a regex. * fix(cli): escape non-ASCII apostrophes in the skills install help text * Plan and update Orca's skills on paired servers, SSH hosts and WSL * Show the skills pill for paired hosts; real-WSL installer test * test(orcad): check the bundled CLI plans a skill install without npx Drop the deleted roundtrip workflow's group from the closed-PR cancellation fixture. * Let the WSL installer create the backups folder itself * Review fixes: follow the active workspace's host, keep hosts' plans and runs apart, never boot WSL for a background check * test: execute requests carry the plan request; CLI pill follows the local target * Write large WSL skill files in chunks that stay under the command-line limit * Make bundled-skill test fixtures link folders the way the product does on Windows Directory links in fixtures are junctions on Windows, which need no Developer Mode; the one file-link fixture is skipped there. * Let a client ask a host to install named Orca skills, not only update installed ones * Plan an SSH workspace on the managed server that serves its host; ask to connect otherwise * Translate the remote skill states into every locale * Resolve legacy skill agent keys canonically * Reject stale skill replacements when auxiliary content changes * Remove the Windows-hosted WSL bundled skill installer * Wait for active workspace ownership before planning bundled skills * Keep ordinary bundled skill classification shallow * Leave unreadable skill replacements alone without aborting plans * Pass force-all through shallow planning and describe unreadable copies * Clarify skill update statuses and folder details * Keep selected skill replacements in place with one status * Report completed skill replacements with their backup confirmation * Clarify available skill updates and skipped copies * Keep skill update results in preview order * Show each skill skip reason once * Count skipped skills instead of skipped folders * Make installer input and link tests work on Windows * Bound bundled skill classification reads and parse names linearly * Keep workspace skill roots inside the resolved workspace * Compare workspace skill roots with native path semantics * Restrict bundled skill backups to their owner on POSIX * Keep bundled skill updates on the proven local workspace host * Keep recovered skills needing attention until they are updated * Count completed skill updates in the status tooltip * Sync the runtime localization catalog |
||
|
|
d3dbd9683f |
Update Orca's skills with Orca's own installer instead of npx skills (#31688)
* Add Orca's own bundled-skill planner and installer (not wired in yet) One planner decides what installing Orca's bundled skills does to each target folder; execute re-plans under per-path locks and runs only a plan whose digest still matches; a shared summary derives badge, wording and exit code. A copy counts as Orca's untouched one only when its SKILL.md bytes match a version some build shipped (resources/skills/released-digests.json, generated from git history and checked add-only). Nothing calls this yet; the npx path is unchanged. * Report left-alone folders as warnings and keep backups in the home A leave is no longer a failure: the outcome line says what happened plus "N left alone: <reason>", and the exit code is 1 only for a failed or changed op. Backups for every scope go to <home>/.agents/.orca-skill-backups on the executing host, so a project Replace never writes into the repo; moving there falls back to copy, verify, then remove across filesystems. * Update Orca's skills with Orca's own installer instead of npx skills The app's Update skills dialog, badge, nudge and status pills now read the bundled-skill plan and summary, and Update executes the reviewed plan's digest. `orca skills install|update` runs the same planner in-process with --dry-run, --force, --json and per-summary exit codes. Removes both npx spawn sites, the freshness inventory modules and the npx round-trip CI. * Update only where the skill already is; one provider-root rule for app and CLI installedOnly now drops every location that holds nothing (keeping the shared slot only when an existing agent link points at it), so Update never adds a skill for another agent. The app and CLI resolve the Claude skills folder through the same rule in localBundledSkillInput; a test asserts both plan identically. * Compact Update skills dialog: one row per skill, locations named by agent summarizeBundledSkillPlan now returns each skill's locations, labelled by agent (or "Shared folder") with a ~-collapsed path; the dialog shows one row per skill that needs something, collapses up-to-date skills into one line, and lists every location behind "Show all locations". The result reads "Updated N skills · M left alone". Under installedOnly a Replace with no shared copy replaces in place instead of adding one. * fix(skills): keep location paths readable by putting the state under the path * fix(skills): hold the last plan in state, not a ref mutated during render Split the update dialog's rows, headline and footer into components, move the Update label next to the other plan copy, and use z.strictObject for the request schemas. * Escape non-ASCII characters in bundled-skill regex and wording The orcad bundle rejects a literal non-ASCII character in a regex. * fix(cli): escape non-ASCII apostrophes in the skills install help text * test(orcad): check the bundled CLI plans a skill install without npx Drop the deleted roundtrip workflow's group from the closed-PR cancellation fixture. * Make bundled-skill test fixtures link folders the way the product does on Windows Directory links in fixtures are junctions on Windows, which need no Developer Mode; the one file-link fixture is skipped there. * Resolve legacy skill agent keys canonically * Reject stale skill replacements when auxiliary content changes * Keep ordinary bundled skill classification shallow * Leave unreadable skill replacements alone without aborting plans * Pass force-all through shallow planning and describe unreadable copies * Clarify skill update statuses and folder details * Keep selected skill replacements in place with one status * Report completed skill replacements with their backup confirmation * Clarify available skill updates and skipped copies * Keep skill update results in preview order * Show each skill skip reason once * Count skipped skills instead of skipped folders * Make installer input and link tests work on Windows * Bound bundled skill classification reads and parse names linearly * Keep workspace skill roots inside the resolved workspace * Compare workspace skill roots with native path semantics * Restrict bundled skill backups to their owner on POSIX * Keep recovered skills needing attention until they are updated * Count completed skill updates in the status tooltip * Sync the runtime localization catalog |
||
|
|
6768988ed6 |
Add Orca's own bundled-skill planner and installer (not wired in yet) (#31662)
* Add Orca's own bundled-skill planner and installer (not wired in yet) One planner decides what installing Orca's bundled skills does to each target folder; execute re-plans under per-path locks and runs only a plan whose digest still matches; a shared summary derives badge, wording and exit code. A copy counts as Orca's untouched one only when its SKILL.md bytes match a version some build shipped (resources/skills/released-digests.json, generated from git history and checked add-only). Nothing calls this yet; the npx path is unchanged. * Report left-alone folders as warnings and keep backups in the home A leave is no longer a failure: the outcome line says what happened plus "N left alone: <reason>", and the exit code is 1 only for a failed or changed op. Backups for every scope go to <home>/.agents/.orca-skill-backups on the executing host, so a project Replace never writes into the repo; moving there falls back to copy, verify, then remove across filesystems. * Escape non-ASCII characters in bundled-skill regex and wording The orcad bundle rejects a literal non-ASCII character in a regex. * Make bundled-skill test fixtures link folders the way the product does on Windows Directory links in fixtures are junctions on Windows, which need no Developer Mode; the one file-link fixture is skipped there. * Reject stale skill replacements when auxiliary content changes * Keep ordinary bundled skill classification shallow * Leave unreadable skill replacements alone without aborting plans * Bound bundled skill classification reads and parse names linearly * Keep workspace skill roots inside the resolved workspace * Compare workspace skill roots with native path semantics * Restrict bundled skill backups to their owner on POSIX |
||
|
|
5a097e7739 |
feat(mobile): decode page-bundle download windows natively (#31817)
* feat(mobile): decode page-bundle download windows natively Each 384 KiB window of the page-bundle download cost about 200-300 ms of Hermes JS time (tweetnacl secretbox open, fflate gunzip, a base64 re-encode check and the TextDecoder polyfill), which kept the JS thread busy for the whole download. The phone now opens v2 frames with react-native-libsodium (secretbox open and strict base64) and decodes ranges with a local Expo module, orca-bundle-window-codec (bounded gunzip via system zlib on iOS and java.util.zip.Inflater on Android, plus strict UTF-8). The shared v2 session takes these as optional primitives; the desktop keeps tweetnacl. If any native piece is missing or fails a known-answer probe, the phone keeps today's JS path, with the base64 re-encode replaced by an O(1) canonical check. * refactor(mobile): name the native decode for every inbound frame, not just bundle windows The native secretbox, base64 and UTF-8 primitives decode every inbound v2 frame on the phone, so the files and the Expo module are renamed for what they cover (paired-e2ee-native-*, orca-gzip-utf8-codec). A throw from the native UTF-8 decode now falls back to TextDecoder, since the frame is already open and its counter advanced. * test(mobile): pin the TextDecoder fallback when native UTF-8 throws * fix(mobile): hand the native decode to the transport from the app entry The transport modules are reached by shared, desktop and e2e code. Importing the native bindings there pulled expo-modules-core into the e2e typecheck, whose global types make NODE_ENV required and broke ~20 e2e files. The app entry now provides the bindings; without them the transport runs the JS path. * fix(mobile): a native-codec lookup before the app provides bindings does not pin the JS path |
||
|
|
ca1e870dbb |
feat(connectors): reopen a closed or exited agent on its next message (B2c) (#32119)
* feat(connectors): reopen a closed or exited agent when its conversation gets a message (B2c) Behind experimentalConnectors. When a connector message reaches a conversation whose agent tab was closed or whose agent exited, the seam resumes the agent's own session in the same workspace through resumeAgentSessionInWorkspace, waits for its composer, delivers the message and answers accepted with reopened. The session id is copied onto the conversation link as hooks report it. Refusals: agent_asleep_in_window, no_session_to_reopen, reopen_refused; a session another pane may still hold (an SSH host out of contact included) stays agent_not_reachable. Resume claims now end as soon as the hook store reports the resumed session, rather than at the next claim, since an agent that exits to its shell drops its hook row and kept the claim held. * fix(session-resume): end a resume claim when the hook store reports it, not at the next claim A resume claim (#31718) ended only when a later claim found the hook store naming the session in the claimed pane. An agent that quits to its shell drops its hook row, so that later check found nothing and the claim stayed held for as long as the shell lived: every other resume of the session was refused as held_elsewhere. Claims now watch the hook store's provider-session changes while any is held and end each hold as soon as it is reported. * fix(connectors): pin reopened process before readiness and capture existing session * fix(connectors): watch persisted links' sessions from host startup and after re-enable A fresh seam (connectors turned back on, or a runtime restart) watched only the links its own calls touched, so a session that changed before the next connector call was missed and a reopen resumed the old conversation. A new seam now snapshots every persisted link's hook-reported session and watches it, and the runtime builds the seam when its hook store attaches at startup rather than on the first connector call. * fix(session-resume): end a hold on report only when it covers one bound spawn The report names a pane, not a spawn, so with a second overlapping open of the same pane still unsettled or bound to its own PTY, ending the hold early could let another pane resume while that spawn still writes. Those holds keep the existing PTY-exit and next-claim ends. * fix(session-resume): settle a lost-reply resume attempt when a retry of the same request binds A targeted resume whose spawn reply was lost keeps its share held, since its process may run. A retry of the same request reconciles that same create, so when the retry binds its PTY the earlier attempt's share is accounted for by it: the hold now ends when that PTY exits instead of never. A different request's spawn still accounts only for itself, and a lost reply is never read as an exit. * fix: preserve overlapping resume holds during lazy report checks * test: verify disabled connector startup and restored capture |
||
|
|
41661e3312 |
feat(sidebar): main runs workspace sleep; the window follows (P3b) (#31564)
* fix(sidebar): land flip-a's switch-on fixes on main, still dark (no flip) The fixes found while the sidebar ran from main's feed, without turning that on: ORCA_SIDEBAR_INPUTS_IS_MAIN stays false, and none of flip-a's stop-gaps come along. - Main stops counting a closed tab's terminal once it was asked to stop and no pane shows it; a failed or refused stop takes the request back, and a host out of contact stays unverifiable. - Main fetches a paired server's rows with the transport's normal bound, so a server slower than 5 s still lists. - A deferred unread raise flips the folder row it was decided for, and a read while the owner check is out cancels it. - Phone: no worktree.ps flash before the feed; a host's last installed feed stands in while a fresh read is out; it highlights its own last-opened workspace and a fold never scrolls; projects file under their project group with the desktop's indent; the collapse spinner shows only after 500 ms; "Reopen to update" keeps the rows on screen. - e2e helpers and journeys for the switch-on suite. * fix(sidebar): keep an owed relay stop marked, clear a thrown stop, and prune pending unread raises - A stop-and-wait that throws takes its stop request back, like one that fails. - A final stop the legacy relay still owes stays marked, since the relay retries it. - Pending unread raises are tracked only while one waits, so the map no longer grows. - The paired-server fallback poll test gives its third fetch a reply and asserts live. * feat(sidebar): main publishes cached snapshots and announces its own stores; detected, view and live-content domains (inert) * fix(sidebar): keep links confirmed only by a new git run, no rescan on metadata writes, no phone wait on detected checkouts * fix(sidebar): rescan the workspace rows when the Windows runtime default changes * feat(sidebar): one lifecycle queue per workspace in main, with in-progress hints (switch-gated) Create, delete, terminal.closeAll, terminal.sleep and worktree.sleep now run through one first-in, first-out queue per host-qualified workspace: strict order, no merging, delete cancels what has not started and waits for what has, an unconfirmed outcome pauses until the host's own answer. Hints publish in a new inProgress feed domain (no reader yet); the creations domain is its projection. A finished create or delete keeps its hint until a scan started after it applies, in the same revision. Adds the paired-server metadata serializer (saving domain, no caller yet). Replaces the creation registry. * fix(sidebar): a create never queues behind the previous occupant's delete * feat(sidebar): main runs sleep; the window follows (P3b) * fix(sidebar): keep electron out of the headless server's sleep path The desktop registers how sleep reaches paired servers; a headless serve has none. Co-Authored-By: Claude <noreply@anthropic.com> * test(sidebar): type-check the sleep e2e specs; drop the removed VM suspend stub Co-Authored-By: Claude <noreply@anthropic.com> * fix(sidebar): resume a paused workspace by re-observing, never replaying - A command issued while paused waits behind the pause; when the owner answers again main re-reads terminal liveness and the listing, then carries on. A forced delete runs past it. - Commands keep their arrival order across a workspace lookup; deletes by name key by the resolved id, so they wait for that workspace's running sleep. - A second delete with different options is refused as already in progress. - Close and delete read lost contact as sleep does. - A create always frees its own queue entry, even after a retry took over its id. - Drops the unused opId, and the paired-server write serializer and its feed section, which land with their first caller. Co-Authored-By: Claude <noreply@anthropic.com> * fix(sidebar): main is the only writer of a sleep's wake records; sleep classifies only lost contact as unconfirmed - The window no longer captures wake records for a sleep main runs; it takes main's records from main's answer, which its wake and tab-open resume then read. - A workspace reopened during its sleep keeps its VM running (the window and a phone's activation tell main). - Only lost contact pauses: a definite chat-stop failure or a server's still-live answer is a plain failure with today's toast. - A paired server's chats are asked with the Sleep mark, and again without it when an older server refuses the field, instead of reading an unprobed status. - A phone's worktree.sleep is answered on acceptance and its activation no longer waits on a queued wake, so neither can outlast the phone's request timeout. The web client passes markChatsAsleep and keeps the receipts. - One desktop adapter, passed where the desktop builds the runtime, replaces the two module slots; a headless server gets none. Co-Authored-By: Claude <noreply@anthropic.com> * chore(sidebar): share worktree.sleep's params with the RPC catalog; lint fixes Co-Authored-By: Claude <noreply@anthropic.com> * test(sidebar): test the paired-server sleep where main runs it; drop the window's copies The window no longer sleeps a paired server's terminals, so its convergence and order tests for that path move to main (remote-workspace-terminal-sleep.test.ts) or follow main's answer. Co-Authored-By: Claude <noreply@anthropic.com> * test(sidebar): retry the sleep spec's liveness read while terminals stop Co-Authored-By: Claude <noreply@anthropic.com> * fix(sleep): main resumes every workspace-sleep wake; the window only attaches - Main claims and starts each slept pane through its windowless resume path, with or without a window: the "window present" check is gone. - A phone's open queues main's wake, which finishes only once the resumes have started, and always notes the reopen so a running sleep leaves the VM up. - The window no longer relaunches a workspace sleep's records in fresh tabs; opening a slept pane asks main to resume it and the pane's spawn attaches to main's terminal. - A window save cannot overwrite main's workspace-sleep records. - A VM that would not suspend no longer reads as "kept open": the terminals slept, and the toast says the machine is still running. * test(e2e): main resumes a slept pane once, in place, and keeps its record * chore(i18n): add the VM-still-running sleep message * fix(sleep): a phone's or the CLI's failed sleep shows the desktop toast again * fix: restore main's final P2 test fixes a merge reverted * fix(sleep): window saves never write or clear main's sleep records; headless wake report counts only real sleeps * test: a same-id twin's grace follows the rows' change, not the removed catalog hook * fix(sleep): drop the 1 s settle wait after an observed exit, and wake a slept workspace's mounted agents on phone open A workspace sleep stopped each terminal through main's stop-and-verify, which polled for a further second after the exit it had already seen. And a phone opening a slept workspace no longer reached the window's mounted panes of agents that had finished before the sleep, so they stayed asleep until the window opened their tab. * test: give the workspace-sleep wake record its prompt field * refactor: match slept-agent records to the workspace with worktreeIdsEqual * chore(sleep): one import from sleep-record-pane-claim * test(sleep): route the disconnected-sleep SSH spec, declare the desktop sleep adapter, and open the workspace after its sleep starts * test(sleep): delete a workspace the spec creates, not the seeded one later specs share --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
5288d26a10 | fix(mobile): copy OSC 52 terminal writes to the phone clipboard (#32042) | ||
|
|
1ac2c6a827 | fix(agent-status): keep a finished turn done when the agent reports an approval at idle (#32015) | ||
|
|
2266260bbd | fix(links): end autolinked urls at CJK punctuation in chat, terminal and mobile (#32013) | ||
|
|
e0bd073930 | feat(browser): Chrome-style page context menu and DevTools window shortcuts (#31821) | ||
|
|
f4974b8958 | fix(mobile): send multi-line chat messages as one bracketed paste (#31776) | ||
|
|
4b65d95964 |
feat(connectors): connector follow-ups, held during approvals, behind the off-by-default experimentalConnectors flag (B2b-2) (#31806)
* feat(connectors): connector seam lifecycle, conversation links and start behind experimentalConnectors (B2b-1) * feat(connectors): connector follow-ups, held while the agent asks, behind experimentalConnectors (B2b-2) * feat(agent-write): opt-in launch cancel, approval wait and binding fence on the shared writer executeAgentLaunch takes an optional signal; sendTerminalAgentPrompt (and sendAgentTurn) take optional onPermission: 'wait' and expectedBinding. No existing caller sets them, so every current path is unchanged. * fix(agent-write): keep the default writer path main's; fence cancel and real submit boundary Only opted-in writes take the submit layer, so default timing and the leaf re-read are unchanged. Cancellation is rechecked before a structured-refusal terminal fallback, and an opted-in launch learns Enter from an onSubmitWritten callback at the write itself, OMP's combined frame included. * fix(connectors): pass the seam's signal to the launch, read links from each host's rows, and keep delivery ids on orchestration's durable receipts (B2b-1) * fix(agent-launch): a cancel after a failed startup spawn recovers the created workspace * fix(connectors): keep an unknown receipt once the launch published, and restore local-only metadata ownership (B2b-1) * fix(connectors): settle a lane when its process is lost; removal stays host-qualified; folder delete announces removal * fix(plugins): keep folder removals out of public worktree events * fix(connectors): a launch admits its process for the lane, so queued sends never adopt a successor * fix(connectors): classify connector RPCs as host-owned; CLI start output claims a start only when definite |
||
|
|
44ab202965 | fix(native-chat): show spelling suggestions when right-clicking chat inputs (#32035) | ||
|
|
57b5082404 |
feat(connectors): connector start and conversation links behind the off-by-default experimentalConnectors flag (B2b-1) (#31805)
* feat(connectors): connector seam lifecycle, conversation links and start behind experimentalConnectors (B2b-1) * feat(agent-write): opt-in launch cancel, approval wait and binding fence on the shared writer executeAgentLaunch takes an optional signal; sendTerminalAgentPrompt (and sendAgentTurn) take optional onPermission: 'wait' and expectedBinding. No existing caller sets them, so every current path is unchanged. * fix(agent-write): keep the default writer path main's; fence cancel and real submit boundary Only opted-in writes take the submit layer, so default timing and the leaf re-read are unchanged. Cancellation is rechecked before a structured-refusal terminal fallback, and an opted-in launch learns Enter from an onSubmitWritten callback at the write itself, OMP's combined frame included. * fix(connectors): pass the seam's signal to the launch, read links from each host's rows, and keep delivery ids on orchestration's durable receipts (B2b-1) * fix(agent-launch): a cancel after a failed startup spawn recovers the created workspace * fix(connectors): keep an unknown receipt once the launch published, and restore local-only metadata ownership (B2b-1) * fix(connectors): classify connector RPCs as host-owned; CLI start output claims a start only when definite |