mirror of
https://github.com/stablyai/orca.git
synced 2026-11-03 02:27:43 +00:00
8482a3fbb1576dc2a5e005a362e698da3e0ab1c9
168
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
3aec926fe5 |
Chat renames are saved as the chat's name, so Session History shows them after the tab closes (#31602)
* Chat renames are saved as the chat's name, so Session History shows them after the tab closes Renaming a native chat tab only changed that window's tab. Session History, phones and other windows read the host's saved name, so the rename vanished from History once the tab closed or Orca restarted. A rename now goes to the host that owns the chat (agentSession.rename) and is saved as the chat's one name, the field History, tabs, sidebars and phones already read. The record remembers that the user chose it, so automatic naming never replaces it. A window's pre-upgrade tab rename is uploaded once and only fills a name Orca chose. Hosts without the new capability keep the old tab-only rename. Every native agent's History row now shows the chat's name once it has one. * Keep saved chat names consistent across readers and reconnects * Carry qualified chat names into cached readers * Reuse the history recorder context across platforms * Use recorded chat ownership for legacy name transfer * Transfer legacy chat names only from known catalog ownership * Correct recorder path matching and History subscription order * Require complete evidence for bridged parity exclusions * Preserve sparse array lengths in complete recording comparisons * Initialize History observation before loading workspace context * Integrate measured History recordings and scoped parity evidence * fix chat naming retries and certify both replay modes * fix ambiguous chat rename labels after navigation * preserve chat rename intent across tab updates * type dashboard snapshot fixtures without assertions * fix: align chat name observation with store contracts * test: update chat name consumer fixtures * test: distinguish sender naming metadata from status * Preserve saved Activity chat names across tab focus * Clarify Activity tab projection identity * Remove package-manager lockfile churn from main merge * fix(runtime): validate tab property edits before saving chat names * fix: refresh History ownership after conversation clear * fix: commit History request identity before refresh effects * Fix History scan scope typing and integration test placement * test: cover saved chat name reader contracts * test: make chat naming fixtures deterministic |
||
|
|
883b768bc7 |
A chat never starts writing a conversation a terminal is still writing, and restored panes respect open chats (#30930)
* fix(native-chat): one ownership index with link roles, and a chat refuses to start while a terminal writes its conversation Each chat link now carries its role (head or earlier) and key; Session History names the chat continuing a conversation first, duplicate adoption checks only head links in both the pre-commit check and the store transaction, and terminal resumes stay refused exactly as before. The terminal-writer check now also runs inside acquireOwner before the spawn, refusing with the typed pre-spawn reason conversationOpenInTerminal. * fix(native-chat): hold a terminal start Orca issues until its terminal reports it An in-memory registry of managed terminal starts per conversation, registered in the same step as the resume admission (terminal.send with a resume command, createTerminal with a command), bound to the PTY execution that runs it, and ended only when that terminal's hooks report the conversation or the execution is gone. A chat's agent start refuses while an entry may hold its conversation. * fix(terminal): an automatic pane restore never resumes a conversation an open chat continues Resume recipes built from a pane's saved facts (cold restore, deferred and late reattach, sleeping wake, host mobile materialization) carry resumeOrigin 'saved'. The execution host decides before any command is issued: while an open chat continues the conversation, or a chat may be writing it, the pane starts its plain shell with the started-fresh notice and its saved claim is forgotten; with unreadable records only a saved restore is refused and its record kept. An admitted resume registers its managed start in the same step, so the chat's agent start refuses until the terminal reports it or exits. Clearing the last saved record now reaches disk. * Fix saved terminal resume ownership and effective launch results * Preserve conversation case and clear refused cold restore identity * fix: publish effective terminal launch results on attachment * fix: preserve terminal launch callback and candidate ownership * fix: keep existing terminal attachments observational * fix: consolidate terminal launch imports * test: document snapshot runtime fixture boundary * fix: preserve terminal launch identity types * fix: accept reattach payload policy sessions * fix: preserve terminal result validation contracts * refactor: separate terminal create contract * test: document partial terminal runtime fixtures * test: align sleeping resume store fixture * Fix terminal create type contracts * fix: return the terminal main started to its waiting view * fix: register reattached terminals before publishing their handles * Check unavailable-resume test fixture types * Complete sidebar resume test store fixture * test: bound saved resume ownership and refusal work * Settle refused saved resume claims from actual launch results * Fix saved resume test type contracts * test(e2e): capture exact terminal parking diagnostics * test: verify parked terminal with fresh host inventory * Consolidate agent session imports in remote terminal transport * Clarify terminal conversation refusal guidance * Admit note-only saved conversations without hiding live writers * Retain terminal writer proofs through final admission |
||
|
|
7d6603aa17 |
[comment audit] Complete repository-wide comment cleanup (#33249)
* [comment audit] Align legacy failure-read counts with cached display * [comment audit] Condense shared provider lifecycle and browser recovery comments [skip ci] * [comment audit] Condense shared generation, path and preview comments [skip ci] * [comment audit] Condense host, file and Git contract rationale [skip ci] * [comment audit] Tighten Git lifecycle and provider contract comments [skip ci] * [comment audit] Clarify shared host authority and launch isolation [skip ci] * [comment audit] simplify local access mobile and native chat contracts [skip ci] * [comment audit] simplify native chat presentation and state contracts [skip ci] * [comment audit] simplify native runtime and provider contracts [skip ci] * [comment audit] simplify migration and orchestration contracts [skip ci] * [comment audit] simplify plugin trust and process capture rationale [skip ci] * [comment audit] simplify terminal delivery and remote compatibility rationale [skip ci] * [comment audit] clarify remote recovery and launch wire rationale [skip ci] * [comment audit] shorten shared RPC compatibility and runtime evidence comments [skip ci] * [comment audit] simplify secure storage shell startup and sidebar rationale [skip ci] * [comment audit] clarify sidebar, skill and SSH invariants [skip ci] * [comment audit] condense structured chat delivery and timing rationale [skip ci] * [comment audit] condense terminal replay and telemetry invariants [skip ci] * [comment audit] clarify launch permission and terminal delivery rationale [skip ci] * [comment audit] clarify workspace ownership and layout contracts [skip ci] * [comment audit] wait for fitted and painted SSH terminal links * [comment audit] clarify layout persistence and session ownership [skip ci] * [comment audit] clarify host routing and workspace lifecycle contracts [skip ci] * [comment audit] clarify startup persistence and app lifetime comments [skip ci] * [comment audit] clarify recovery and activity boundaries [skip ci] * [comment audit] condense activity and artifact invariants [skip ci] * [comment audit] condense automation authority contracts [skip ci] * [comment audit] simplify automation scheduling and history contracts [skip ci] * [comment audit] clarify browser chrome and annotation lifecycles [skip ci] * [comment audit] clarify browser routing and retained guest ownership [skip ci] * [comment audit] clarify browser recovery and document ownership comments [skip ci] * [comment audit] restore hosted runners required by native IME fixtures * [comment audit] shorten preview, palette and dashboard invariants [skip ci] * [comment audit] clarify terminal preview, dashboard and retention comments [skip ci] * [comment audit] clarify diff-note recovery and editor lifecycle comments [skip ci] * [comment audit] shorten rich-text and combined-diff ownership comments [skip ci] * [comment audit] shorten autosave, draft recovery and model ownership comments [skip ci] * [comment audit] shorten save-queue, notebook and Markdown constraints [skip ci] * [comment audit] shorten Monaco, PDF and rich Markdown safeguards [skip ci] * [comment audit] clarify rich Markdown source and selection safeguards [skip ci] * [comment audit] clarify editor loading and emulator stream lifetimes [skip ci] * [comment audit] trim emulator and feature tour narration [skip ci] * [comment audit] clarify floating workspace and GitHub cache ownership [skip ci] * [comment audit] trim provider controls and Linear filter explanations [skip ci] * [comment audit] clarify pairing and chat resume lifetimes [skip ci] * [comment audit] clarify chat delivery and transcript lifetimes [skip ci] * [comment audit] clarify session options and host-owned status [skip ci] * [comment audit] clarify draft durability and live-status precedence [skip ci] * [comment audit] Trim chat send and model ownership explanations [skip ci] * [comment audit] Shorten transcript ownership and send recovery comments [skip ci] * [comment audit] Simplify native chat composer and transcript hook comments [skip ci] * [comment audit] Shorten native chat scroll and structured session explanations [skip ci] * [comment audit] Trim workspace picker and onboarding commentary [skip ci] * [comment audit] Simplify pet rendering, review cache and quick open comments [skip ci] * [comment audit] Trim sidebar and session history explanations [skip ci] * [comment audit] Condense session resume and review checks comments [skip ci] * [comment audit] Shorten checks state and file explorer refresh comments [skip ci] * [comment audit] Trim plugin bridge and source-control action rationale [skip ci] * [comment audit] Trim source-control listing and review rationale [skip ci] * [comment audit] Shorten sidebar lifecycle and explorer safeguards [skip ci] * [comment audit] Condense Settings account and appearance rationale [skip ci] * [comment audit] Trim pairing and repository Settings explanations [skip ci] * [comment audit] Condense Settings search SSH and terminal safeguards [skip ci] * [comment audit] Shorten Settings voice and provider ownership comments [skip ci] * [comment audit] Condense Settings draft persistence and host-state rationale [skip ci] * [comment audit] Trim Settings hooks and sidebar setup rationale [skip ci] * [comment audit] Condense sidebar deletion and board-filter safeguards [skip ci] * [comment audit] Condense worktree cards, host ownership and Markdown contracts [skip ci] * [comment audit] Condense sidebar drag, folder and filtering contracts [skip ci] * [comment audit] Condense sidebar parity, sleep and host ownership contracts [skip ci] * [comment audit] Prune focus-read baseline after comment cleanup * [comment audit] Clarify sidebar visibility, board drops and agent evidence [skip ci] * [comment audit] Tighten sidebar listing, drag and reveal contracts [skip ci] * [comment audit] Clarify viewport geometry and skill update safeguards [skip ci] * [comment audit] Tighten skill inventory, usage and host status comments [skip ci] * [comment audit] Clarify usage ownership and resource kill safeguards [skip ci] * [comment audit] Tighten tab selection, rename and search contracts [skip ci] * [comment audit] Tighten tab-strip geometry and drag ownership comments [skip ci] * [comment audit] Tighten Tasks recovery, pagination and mutation comments [skip ci] * [comment audit] Tighten provider loading and terminal recovery comments [skip ci] * [comment audit] Tighten completion, cadence and PTY ownership comments [skip ci] * [comment audit] Clarify terminal restore and parked-pane boundaries [skip ci] * [comment audit] Tighten PTY startup and replay explanations [skip ci] * [comment audit] Clarify PTY identity and delivery ownership [skip ci] * [comment audit] Shorten remote reconnect and input replay rationale [skip ci] * [comment audit] Condense terminal parking clipboard and file link comments [skip ci] * [comment audit] Clarify IME ownership and trim trace history [skip ci] * [comment audit] Shorten pane recovery and parked watcher explanations [skip ci] * [comment audit] Condense snapshot replay and visibility recovery rationale [skip ci] * [comment audit] Shorten terminal parking and keyboard ownership rationale [skip ci] * [comment audit] Trim renderer lifecycle and menu rationale [skip ci] * [comment audit] Condense workspace cleanup ownership and settlement notes [skip ci] * [comment audit] Clarify renderer hook evidence and source ownership [skip ci] * [comment audit] Tighten IPC ownership and reconnect explanations [skip ci] * [comment audit] Trim renderer focus, paste and attention comments [skip ci] * [comment audit] Shorten scroll, locale and agent lifecycle comments [skip ci] * [comment audit] Trim agent launch, resume and ownership commentary [skip ci] * [comment audit] Shorten account, browser and editor comments [skip ci] * [comment audit] Clarify host-mirror waits, previews and input ownership [skip ci] * [comment audit] Condense launch recovery and editor tokenization comments [skip ci] * [comment audit] Condense workspace selection and terminal pane rationale [skip ci] * [comment audit] Condense terminal fitting and rendering recovery comments [skip ci] * [comment audit] Condense terminal input and host routing explanations [skip ci] * [comment audit] Condense ownership and sleeping-session recovery rationale [skip ci] * [comment audit] Condense structured launch and terminal link explanations [skip ci] * [comment audit] Condense terminal ownership and workspace file routing rationale [skip ci] * [comment audit] Condense session persistence and workspace activation rationale [skip ci] * [comment audit] Condense workspace routing and browser ownership rationale [skip ci] * [comment audit] Condense mirror recovery and layout authority rationale [skip ci] * [comment audit] Condense runtime transport and file safety rationale [skip ci] * [comment audit] Condense runtime graph and structured session rationale [skip ci] * [comment audit] Condense browser creation and remote tab recovery rationale [skip ci] * [comment audit] Condense snapshot authority and publisher recovery rationale [skip ci] * [comment audit] Condense frame, startup and provider cache rationale [skip ci] * [comment audit] Condense host twin and agent lifecycle rationale [skip ci] * [comment audit] Condense browser authority and editor cleanup rationale [skip ci] * [comment audit] Condense editor buffer identity and review cache rationale [skip ci] * [comment audit] Condense provider lifetime and repository ownership rationale [skip ci] * [comment audit] Condense reconnect, hydration and terminal retirement rationale [skip ci] * [comment audit] Condense recovery, reconciliation and persistence rationale [skip ci] * [comment audit] Condense cleanup ownership and listing admission rationale [skip ci] * [comment audit] Condense teardown ordering and terminal ownership rationale [skip ci] * [comment audit] Condense recovery ledger and web host-boundary rationale [skip ci] * [comment audit] Condense web reconnect and credential lifecycle rationale [skip ci] * [comment audit] Condense cloud rollout and assignment safety rationale [skip ci] * [comment audit] Condense relay session and database recovery rationale [skip ci] * [comment audit] Condense relay placement and protocol compatibility rationale [skip ci] * [comment audit] Condense build and packaging constraints [skip ci] * [comment audit] Condense CI gates and validation isolation rationale [skip ci] * [comment audit] Condense catalog identity and browser validation rationale [skip ci] * [comment audit] Condense mobile browser and frame-budget rationale [skip ci] * [comment audit] Shorten mobile route and browser test explanations [skip ci] * [comment audit] Condense editor and session seam test rationale [skip ci] * [comment audit] Trim session and terminal closure history [skip ci] * [comment audit] Shorten terminal browser and census explanations [skip ci] * [comment audit] Preserve root-only E2E diagnostic baseline * [comment audit] Condense mobile seam and HTML preview test rationale [skip ci] * [comment audit] Condense preview instrumentation and render harness rationale [skip ci] * [comment audit] Condense bundle contracts and native-build constraints [skip ci] * [comment audit] Shorten native packaging and CI routing rationale [skip ci] * [comment audit] Condense release tooling and benchmark constraints [skip ci] * [comment audit] Condense packaging and platform gate rationale [skip ci] * [comment audit] Shorten mobile route and history rationale [skip ci] * [comment audit] Condense mobile browser and component rationale [skip ci] * [comment audit] Shorten drawer and workspace-form rationale [skip ci] * [comment audit] Trim mobile review and editor-document explanations [skip ci] * [comment audit] Condense editor lifecycle and Markdown explanations [skip ci] * [comment audit] Trim mobile file, diagnostics and dictation commentary [skip ci] * [comment audit] Simplify mobile host-list and workspace-view explanations [skip ci] * [comment audit] Clarify mobile shell lifetime and bridge delivery constraints [skip ci] * [comment audit] Condense bridge stream, native request and audio rationale [skip ci] * [comment audit] Reduce bridge schema and page-client commentary [skip ci] * [comment audit] Tighten mobile page bridge contracts [skip ci] * [comment audit] Clarify mobile cache and session constraints [skip ci] * [comment audit] Condense mobile route and lifecycle rationale [skip ci] * [comment audit] Tighten mobile shell hook timing rationale [skip ci] * [comment audit] Clarify route handoff and notification compatibility [skip ci] * [comment audit] Clarify push registration and dictation cleanup constraints [skip ci] * [comment audit] Condense keyboard geometry and native media ownership rationale [skip ci] * [comment audit] Tighten mobile chat scroll and composer concurrency rationale [skip ci] * [comment audit] Condense mobile reply compatibility and upload ownership rationale [skip ci] * [comment audit] Condense optimistic echo and scroll ownership rationale [skip ci] * [comment audit] Tighten stream replay and queued session ownership rationale [skip ci] * [comment audit] Condense mobile composer and reply-schema constraints [skip ci] * [comment audit] Clarify mobile transcript recovery and session ownership [skip ci] * [comment audit] Clarify mobile queue and source-control compatibility [skip ci] * [comment audit] Condense storage and task launch constraints [skip ci] * [comment audit] Clarify task schemas and terminal document ownership [skip ci] * [comment audit] Tighten terminal input and viewport rationale [skip ci] * [comment audit] Shorten terminal and RPC recorder contracts [skip ci] * [comment audit] Condense recorder engine and connection contracts [skip ci] * [comment audit] Shorten host credential and relay recovery comments [skip ci] * [comment audit] Tighten pairing recovery and bundle transport rationale [skip ci] * [comment audit] Clarify RPC delivery and workspace catalog boundaries [skip ci] * [comment audit] Condense catalog and relay entry contracts [skip ci] * [comment audit] Shorten shutdown and SSH relay delivery contracts [skip ci] * [comment audit] Condense WSL relay and E2E regression rationale [skip ci] * [comment audit] Shorten cross-version harness and renderer fixture explanations [skip ci] * [comment audit] Condense paired-host and E2E lifecycle rationale [skip ci] * [comment audit] Shorten layout oracle and regression explanations [skip ci] * [comment audit] Condense paired recovery and ownership regression contracts [skip ci] * [comment audit] Shorten restart, sidebar and SSH lifecycle contracts [skip ci] * [comment audit] Condense terminal rendering and IME regression rationale [skip ci] * [comment audit] Shorten terminal recovery and benchmark contracts [skip ci] * [comment audit] Condense tooling and Windows lifecycle proof rationale [skip ci] * [comment audit] Condense workflow routing and release rationale [skip ci] * [comment audit] Condense mobile security and installer contracts [skip ci] * [comment audit] Shorten native rationale and stylesheet workarounds [skip ci] * [comment audit] Shorten Windows visibility probe rationale [skip ci] * [comment audit] Condense embedded release and signing rationale [skip ci] * [comment audit] Retain current main test behavior in final reconciliation [skip ci] * [comment audit] Complete final comment review across current source inventory * [comment audit] Handle consolidated audit reports before final CI * [comment audit] Preserve credential storage census detail [skip ci] * [comment audit] Scale broad changed E2E selections with verified timing shards * [comment audit] Align E2E assertions with browser close and settled session metadata * [comment audit] Match existing E2Es to current resource and windowing contracts * [comment audit] Observe the shared server outage notice in reconnect coverage * [comment audit] Make existing renderer probes measure settled tab and PTY work * [comment audit] Align palette E2E selector with task search * [comment audit] Refresh remaining palette search selectors * [comment audit] Keep selector correction within selected audit specs * [comment audit] Await emoji fixture settings inside renderer evaluation * [comment audit] Cancel fixture fit retries between terminal tests --------- Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com> |
||
|
|
aeb039938f |
refactor(jira): colocate shared contracts and capabilities (#32927)
* refactor(jira): colocate shared contracts and capabilities * test(jira): validate title width against panel budget |
||
|
|
5c666d2974 |
fix(native-chat): retry a failed chat name, show the failure on the tab's hover card, and add Regenerate name (#30646)
* fix(native-chat): name a chat from its first message at once; the generated name replaces it A native chat's one stored name was written only by a best-effort, one-shot generation, so any failure left every surface on the 'Codex Chat' placeholder. The first prompt now names the chat when its first turn starts, and the generated name replaces it only while the field still holds that seed. * fix(native-chat): the chat names setting says a chat shows its first message until it is named * fix(native-chat): retry a failed first chat name twice before keeping the first message A failed name generation was final for the chat's lifetime. The first name now gets two retries, after 2 and 4 seconds, and stops early once the first-message name was replaced. * fix(native-chat): show a failed chat name on the tab hover card, with Regenerate name A chat whose name generation failed after every retry gave no sign of it, and nothing could run it again. The host now keeps the last failure in memory and publishes it with the chat's status while the chat still has the name it failed to replace; the tab hover card shows it with the error dialog, and a new agentSession.regenerateName (behind a capability) makes one more try. * fix: derive chat naming progress from host jobs * fix(native-chat): merge duplicate import CI caught * fix(native-chat): declare agentSession.regenerateName in the cross-version surface manifest * fix(native-chat): stub naming-failure hook in SortableTab rename shortcut test |
||
|
|
c93514db5b |
refactor(protocol): each area owns its published runtime capability list (#30641)
* refactor(protocol): each area owns its published runtime capability list RUNTIME_CAPABILITIES now spreads one array per area instead of a flat hand-appended list, and runtime-capability-constants.ts is split into the areas that own each constant. The published set is unchanged and pinned by an exact sorted test. * test: preserve capability baseline while allowing additions |
||
|
|
6c7a6ddd54 |
fix(native-chat): save every chat reply and tool output whole; bound only the copy sent to clients (#29982)
* fix(native-chat): save every chat reply and tool output whole; bound only the copy sent to clients Orca cut Codex replies, every agent's reasoning, plans, prompts and all tool output to a 16 KB head when it saved them, and threw the rest away. The limit existed so a reconnecting client is not replayed a huge row, but it was applied at save time, so every transport limit became permanent data loss. The journal now keeps what the agent said. One outbound form, applied to every history page, live batch and catch-up, sends a client the same 16 KB head of each tool output and diff it always got, and marks the item `shortened`. A new capability-gated `agentSession.item` RPC returns the whole item, and the desktop and phone show "Show full output" / "Show full message" when the copy was cut. Items past half a page are shortened and marked instead of replaced with "too large to show". Two bounds stay, both named: a 4 MiB ceiling per text (head and tail), applied where every provider's rows enter the write queue so one write can never stall a chat, and a preview on Grok/OpenCode/OMP/Pi calls while they run, whose closing row is built from the whole value the translator held. * test(native-chat): an over-budget history item is shortened and marked, not replaced * fix(native-chat): format, keep the sink and projection under the line limit, update method count and tests * fix(chat): preserve complete writes and keep detail current * test(chat): align final tail reservation with captured content * Prototype source-batch journal ownership for Claude * Pin the resolved iterator promise in ownership experiment * Revert "Pin the resolved iterator promise in ownership experiment" This reverts commit |
||
|
|
d406e0c8ab |
feat(native-chat): edit a queued message's images on desktop: remove, paste, drop or attach (#30815)
* feat(native-chat): a queued message's Save can replace its images (host, wire and capability) * feat(native-chat): edit a queued message's images on desktop: remove, attach, paste or drop * refactor(native-chat): share the queued edit's image rules and drop the rarely-shown Save reasons * fix(native-chat): a queued edit's refusal says the edit wasn't saved, and its wire takes a full image set An expired upload refused on Save read "The command didn't run": the queued message update fell through to the command write kind. It now has its own kind whose sentence is "Your edit wasn't saved." The images param caps at MAX_BLOCKS, matching the shared edit rule that counts them with the text. * fix(native-chat): a queued edit keeps image markers right and owns drops and pastes on its card - Removing a kept image drops its [Image #k] marker from the edit's text and renumbers the later ones (shared rule, reused by the phone), so the agent never reads a marker that names the wrong image. - A file dragged from Orca's own tree onto the editing card goes to the edit, like a Finder/Explorer drop; the chat box overlay no longer covers the card. - Cmd/Ctrl+V with focus on the card's buttons goes to the edit, not the chat box. - A "changed" answer says "Your edit is in the chat box" only when something went there; otherwise it says the edit wasn't saved. - The empty hint counts an uploading image as content and is not shown for agents without image input; the list grows only while thumbnails show. - Every hand-off releases the edit's preview URLs. * fix(native-chat): an in-app drop on the editing card goes through the chat box's owner check The edit no longer runs its own copy of the in-app drop check, which resolved the target host through a path that can read the Active Server setting. The chat box's claim checks the drop and routes it by the chat's owner as before, then hands the files to the editing card's sink when the drop landed on it. Also: the kept-image id list is readonly where it is read, and the marker rule looks up the remaining images in a Set. * fix(native-chat): only an edit that takes images keeps its card's pastes, and no drop joins a Save in flight The pane paste bridge no longer skips every paste inside a queued editor: the card's own paste handler already claims image and file pastes, which the bridge respects. A menu paste is left to the card only when the edit takes images (the card is a drop owner), so an older host or an agent without image input behaves as before, and text pasted with focus on the card's buttons goes to the chat box. An in-app drop handed to the card while its Save is in flight adds nothing. * fix(native-chat): a failed capability re-check keeps the host's last answer, and an edit takes no files before its lease A re-check after regained contact that failed wrote "unknown" over a known answer for the same host, so features the host had reported (such as editing a queued message's images) vanished on a connection blip, mid-edit. A failed check now keeps the last answer; a different host still starts at unknown. Paste, Attach and OS or in-app drops into a queued edit are now blocked while it acquires its lease, as typing already is. * fix(native-chat): an image change is never saved as text alone when the host stops reading as taking images Reverts the shared capability hook to keep main's behavior: a failed re-check reads as unknown. Instead the queued edit derives from live state that an edit whose image set changed can't be saved while the host doesn't read as taking images, so a connection blip never saves renumbered markers over the old images or drops added ones. Save comes back once the host answers again. * fix(native-chat): keep queued image markers and drop feedback in sync * fix(native-chat): derive queued image markers without changing edit text * test(native-chat): the pane drop test's intake append returns the paths it didn't take * fix(native-chat): route menu paste to the focused queued edit * fix(native-chat): honor queued edit paste ownership before focus redirection * fix(native-chat): preserve native paste without clipboard access * fix(native-chat): keep paste in the owning queued edit |
||
|
|
cffcef7be0 |
fix(projects): setup edits and removals name the host, so the twin on another host is never touched (#30664)
* fix(projects): setup edits and removals name the host, so a twin on another host is never touched Repo-backed project host setups take the repo id, so a project on two hosts has two setups with one id. Update and delete took the first match by id, so editing or removing the SSH copy could rename or remove the local one. The args gain an optional hostId (older peers strip it and keep the first match). * fix(projects): tolerate only the legacy runtime stamp when a named host misses an independent setup * fix(projects): refuse a twin edit on a server that would act on the wrong twin; read legacy runtime stamps as local * fix(cli): refuse setup --host on a server that would ignore it * refactor(projects): exact host match only; name the host on the wire only for twins on one route * fix(projects): a named host the catalog lacks refuses; settings remove stays by id * refactor(projects): name hosts on the wire only for this computer's catalog; paired servers keep the by-id request |
||
|
|
699b9a0637 |
feat(files): guarded file writes that refuse to overwrite a changed file (#30605)
* feat(files): guarded file writes that refuse to overwrite a changed file Adds an optional disk precondition to file writes: the writer compares the file on disk with an expected signature inside the write, serialized per file (path then inode), and refuses with a typed changed/missing result instead of writing. Remote hosts serve it as files.writeIfUnchanged behind a capability; older hosts get a client-side compare that fails closed, pinned to the probed runtime and connection. Undo of a delete and the MCP starter config use it to write only into a missing or identical file. Groundwork for guarding editor saves. * fix(files): pin guarded writes on the sending socket; keep refused undo; narrow not-found and pinning * fix(files): pin a guarded save to one pairing; keep only refused undo steps * fix(files): ENOENT by code only; resolve symlink chains fully; pin lost-reply recovery to the save's pairing |
||
|
|
503d919e64 |
feat(native-chat): + menu shows chat, disabled chat and CLI rows (#29074)
* feat(native-chat): choose which agents open as a chat
Settings → Chat gets a Providers list. Each agent the host can open as a chat
has a switch; off opens that agent in a terminal instead. Only choices the user
makes are saved. Unchosen: Claude and Codex on, others on when their CLI is
installed on this computer.
The renderer's route and the host's launch-mode decision both read one rule, so
the tab menu, shortcuts, CLI, orchestration and relayed phone launches agree.
* fix: keep chat provider settings with the other chat settings types
* test: route input carries this computer's detected agents
* feat(native-chat): the + menu shows chat, disabled chat and CLI rows
With Chat UI on, each agent whose chat provider is on gets a chat row, disabled
with the reason where the workspace's machine can't run that chat (not
installed, SSH, WSL, not on this host). Every other installed agent gets a row
marked (CLI) that opens its terminal. With Chat UI off, or on an older server
that opens no chats, the menu is unchanged.
* fix: new tab menu rows use a launch variant instead of restyling the menu item
* fix: name every route blocker the menu rows map
* fix: menu row subscriptions render on the server too
* feat(native-chat): open a chat agent's CLI from beside its + menu row
A chat row whose CLI is installed on the workspace's machine gets a › beside
it. Its side menu offers '<Agent> (CLI)', which opens that agent's terminal for
this launch only; nothing is saved and the row itself still opens a chat.
* fix: keep new tab agent surfaces authoritative
* fix: handle unknown host support reasons
* fix(chat): resolve provider choices from their owning computer
* fix: include chat launch feedback translations
* test(chat): use checked native inventory fixtures
* chore: retrigger PR checks
* test: pin pending chat row behavior
* chore: retrigger PR checks after cancellation
* Fix launch preparation lifetime and execution host startup
* fix: keep agent menu choices bound to their launch
* Simplify agent menu support reads and preserve explicit surfaces
* Keep focused menu behavior coverage within its budget
* Keep menu host fixtures typed as execution hosts
* Assert notes payload on the current launch action
* Combine agent session launch type imports
* fix(chat): keep unchosen providers on without discovery
* fix(chat): use workspace installation for menu defaults
* test(chat): type provider routing fixtures against store contracts
* fix(tab-bar): keep + menu chat rows clickable while the host answers
Each menu open discarded the host's answers, so every open showed the chat
rows disabled with 'Checking chat support' until the host replied. Answers
now outlive the menu and refresh in the background, rows use this client's
facts until the host answers, and a slow host no longer reads as a refusal.
* test(chat): align shared launch fixture with private settings reader
* fix(tab-bar): keep known + menu refusals and never treat a silent host as one
Closing the menu dropped the workspace's agent list, which changed which agents
the menu asks about and threw away the host's earlier answers, so a reopen showed
a refused chat as clickable. A support read that could not answer was stored as
"No chat on this host", disabling chats the client knows are supported.
The menu now keeps the stored agent list while closed (only fetching waits for
it to open) and only a real host answer relabels a row. The workspace's
detection target is resolved where main already resolves it (QuickLaunchButton
and the tab-bar runtime model) and passed in, so no new focus read is added.
Tab-bar test mocks now stub the QuickLaunchButton exports the menu imports.
* fix: sync runtime English catalog for agent menu
* test(chat): give the structured-session RPC fixture the private settings reader
The host now reads saved chat choices through requireStore().getSettings(); the
shared RPC fixture only had getClientSettings, so the launch-mode reader saw no
settings and create support refused Claude. The fixture now follows each test's
client settings.
* test(chat): pin create support's options argument and kept decline reason
* fix(native-chat): + menu chat rows wait disabled for the host and share its answer across tab groups
A chat the host refuses showed clickable for up to the 10s host read, then flipped to disabled,
once per tab group. Rows now stay quietly disabled until their host answers (or the read times
out), and every tab group on the same workspace host reads the same answers.
* fix(native-chat): + menu rows also wait before the host's chat list loads, and on every reopen of a host that could not answer
Asking the host no longer waits for its chat list, so Claude and Codex no longer show clickable,
then disabled, while it loads. A read that times out releases rows for that open only, so the
next open waits again instead of flipping on a late refusal. Agents not installed skip the read.
* fix(native-chat): typed + menu search puts a launchable row ahead of a disabled chat
In a WSL workspace, typing an agent's name and pressing Enter highlighted its disabled chat row,
so nothing launched where main opened the CLI. Search now ranks rows that can launch first.
* fix: preserve provider choice and cached native inventory
* feat(native-chat): hosts publish each workspace's chat availability as one stream
A new negotiated stream, agentSession.subscribeAvailability, advertised as
agent-session.structured.availability.v1. The host keeps one in-memory resource per
workspace, shared by every reader, that asks the existing createSupport check for every
registered agent in that workspace and publishes only complete generations. It answers
again when a launch setting changes, after an explicit agent refresh, and (for answers
that could not be checked) when a workspace appears; the last reader leaving retires it.
A check that could not answer is unknown, never a refusal. agentSession.agents stays
static and unchanged.
* feat(native-chat): + menus read a publishing host's workspace availability
The renderer holds the workspace's availability stream while its tab bar is mounted
(not while a menu is open), shared by every tab group, with runtime and contact fences.
It exposes a readiness model, { ready: false } | { ready: true; byAgent }, from
useHostStructuredAgentAvailability and the menu hook. On a host advertising the
capability the menu reads its answers from that model and makes no per-agent
createSupport reads; an older host keeps the per-agent reads, answer cache and deadline
unchanged. Row building and presentation are unchanged.
* fix(native-chat): workspace availability checks only what the shown workspace needs
Only the shown worktree (or an open menu) holds its host's availability stream, and only with Chat
UI on. Display checks no longer force a fresh login shell for an agent that isn't installed, so
Claude and Codex answer without waiting on it. A change to the Windows runtime default or a project's
WSL choice re-checks, and a workspace still on its first check answers again when one appears.
* fix: keep main's bytes for the create-support file the merge reformatted
The pre-commit formatter rewrapped main's unformatted lines during the merge and pushed the file past its line limit.
* test: type the + menu rows hook mocks without assertions
* test: match the availability stream's types in three tests
* test(cross-version): declare the workspace availability stream in the agent-session surface
* feat(native-chat): + menu holds a placeholder until its agents are known, and learns them while the workspace is shown
* feat(native-chat): + menu reads one agent health snapshot per machine
The + menu no longer checks chat availability per workspace. Each Orca
runtime keeps one agent health snapshot: every agent's location rule on
this machine plus a typed observation of its installed release, probed
in the server's own home. It is taken on first use and replaced only on
a launch setting change, an explicit agent Refresh (after a fresh shell
capture), or a restart, and kept without readers.
- The version probe reports supported, unsupported or inconclusive; a
launch still refuses an inconclusive run, while the snapshot reads it
as unknown rather than a refusal.
- agentSession.subscribeAvailability takes no params and publishes that
snapshot; a replay that closes the transport releases its reader.
- The renderer keeps the snapshot per host, runtime and pairing, through
lost contact and across workspace switches on the same host.
- The menu hook drops the per-open createSupport display reads, their
deadline and answer cache; older hosts show client facts and the
click's admission, unchanged, states any refusal.
* fix: a failed shell recapture still publishes the agent health snapshot
* fix(native-chat): capture fresh shell facts for every health snapshot
* fix(tab-menu): share settled agent actions across menu surfaces
* fix(tab-menu): preserve loading row line height
* feat(native-chat): the whole chat row opens its CLI submenu
Hovering a chat row in the + menu, or pressing ArrowRight on it, now opens
the "<Agent> (CLI)" submenu to the right instead of needing a separate
chevron button. Clicking the row, or Enter/Space, still starts the chat
and closes the menu; hosts pass closeMenu since a submenu trigger never
closes the menu on its own.
* fix(tab-menu): line the CLI submenu up with its chat row
* feat(native-chat): a chat row's terminal button opens its CLI
Clicking a chat row in the + menu starts a chat. Hovering the row (or
pressing ArrowRight on it) reveals a terminal button at its right edge that
opens the agent in a terminal instead. This replaces the submenu, whose
chevron made the row look like it only opened a submenu. The button's click
bubbles into the row, so the menu closes as for any item and the hosts no
longer need a closeMenu callback.
* fix(native-chat): the chat row's terminal button handles drags, arrows and screen readers
A press on + dragged onto a chat row's terminal button and released there
now opens the CLI: the row reads whether the pointer or focus is on its
button instead of the click target, which a drag-release never sets.
Arrow, Home and End keys pressed on the focused button move between rows
as they do on the row. The row is announced as "Start a <Agent> chat"
instead of including the button's label.
* fix(native-chat): chat rows read "Start a chat with <Agent>"
"Start a OpenCode chat" was ungrammatical for agents whose name starts with a vowel.
|
||
|
|
e3c9370da4 |
feat(agent-status): read OSC 7501 program status beside hooks (#30261)
Programs can tell Orca what they are doing through the Program Status Protocol (OSC 7501); Claude Code, Codex, Grok, pi and oh-my-pi already do. Orca answers the protocol's feature-detection probe (visible xterm and the hidden-pane emulator), parses reports from PTY output on the execution host (src/shared/program-status/), and keeps two lanes: - Lifecycle state keeps one owner per pane. Hooks win; OSC 7501 drives the row when hooks are off, missing, or silent on a state the program has left (server/program-status/hook-precedence). - The program's own report (progress, its one-line message, blocks such as sign-in) is a live-only `programStatus` facet kept per pane (server/program-status/facet-store), stitched onto rows at publish time and carried to the renderer store, mobile, paired clients and `worktree ps`. Facet-only changes patch just the facet. Title-driven readers (idle edges, delivery, tui-idle, exit inference) classify by the program's OSC 7501 activity while it reports one and fall back to title glyphs only for agents that report nothing explicit, so they keep working when Claude stops painting its title glyph after the probe. |
||
|
|
cf7423c8f4 |
feat(mobile): redesign the chat composer with file attachments and inline skills (#30359)
* refactor(native-chat): move the slash picker builder and upload chunking to shared Mobile builds the same skill and command list as desktop. * feat(mobile): redesign the chat composer with file attachments and inline skills * fix(mobile): the composer field owns its input style The page's font-size census cannot follow a style passed in as a prop. |
||
|
|
6fd2172b3f |
feat(runtime): remove an agent's downloaded runtime only once nothing on the host can still run it (#29139)
* feat(runtime): remove an agent's downloaded runtime only once nothing on the host can still run it
managedRuntime.remove {agent} (host-admin, capability managed-runtime.remove.v1)
deletes the agent's releases inside the launch gate. Before anything is deleted the
gate aborts starts under way (chat starts and conversation copies), stops the
agent's loaded chats on this host, and proves every retained child gone: failed
chat starts and sign-in children whose close was never proven. Every close settles
before the gate releases; if any owner stays unproven, Remove fails and keeps the
files. Stopping chats by agent is now one generic host helper that sign-in shares.
Install refuses while a removal runs, Remove refuses while an install runs, and a
removal cannot be cancelled.
* fix(runtime): status says whether a copy is there to remove, damaged copies included
canRemove is set whenever Orca's copy is present, whole or damaged, so Settings offers Remove for a
damaged copy too. The failed-start retain is dropped: the launch gate already holds every child it
admitted until it exits.
|
||
|
|
002320c17d |
fix(native-chat): verify the actual CLI conversation during resume (#29124)
* fix(native-chat): identify the owner when resume create is refused * test(native-chat): consolidate transcript refusal cases * test(native-chat): keep ownership coverage at the launch boundary * test(native-chat): update adoption fixture for early ownership admission * test(native-chat): align resume admission assertions with host ownership * test(native-chat): keep RPC coverage focused on ownership proof * test(native-chat): assert blank request presence before optional source * fix(native-chat): admit the actual CLI source during chat creation * fix(native-chat): satisfy source admission lint checks * test(native-chat): provide the waiting hook prompt * test(native-chat): isolate source admission fixtures from host homes * test(native-chat): canonicalize adoption fixture directories * test(native-chat): preserve early ownership admission in source stack * fix(native-chat): preserve resume refusal behavior and honest transcript feedback * fix(native-chat): retain import read evidence in typed result * fix(native-chat): preserve admitted source and prepared execution home * fix(chat): retain source evidence for dispatched adoption * fix(chat): keep source capture within module limits * test(chat): allow host evidence in create routing * fix(native-chat): admit an unsaved transcript under a linked account folder A missing transcript stayed unresolved while its account root resolved through symlinks, so containment failed and a not-yet-saved conversation showed a load error instead of the unsaved notice. * refactor(native-chat): move the newest-item import window into its own module Keeps journal-legacy-import.ts under the line limit after the source identity observer landed on top of the streaming import. * fix(native-chat): restore the refusal error import lost in the main merge * fix(native-chat): admit Pi transcripts against the root Session History walks A PI_CODING_AGENT_DIR that already ends in sessions, or any custom folder, made admission expect <dir>/sessions while the lookup searched <dir>, so a found conversation was refused. * refactor(native-chat): admit and look up CLI transcripts in one store per account Each agent's import described where an account keeps its conversations twice, once for the path check and once for the lookup, and the two could disagree (the linked-folder and Pi custom-root refusals). The import now names one conversation store per account; the create path resolves it once and both the hook-path check and the fallback lookup judge that same store. OpenCode's store is its exact database. |
||
|
|
634ca45fbb |
feat(acp): hosts install a managed runtime over RPC, and mark agents whose program Orca provides (#29024)
* feat(acp): hosts install a managed runtime over RPC, and mark agents whose program Orca provides
managedRuntime.status / managedRuntime.install / managedRuntime.cancel, negotiated by
managed-runtime.install.v1, act on the host that receives them, the one that runs the agent's
chats, with no workspace needed. A status read naming the revision it shows is a long-poll on its
own call-queue lane, so every client sees another's start, progress and outcome.
agentSession.agents marks an agent whose program Orca provides on that host.
* fix(runtime): install status says a copy outside Orca's runs only when a start would really run it
* fix(runtime): install status is pushed to subscribers instead of long-polled, and Cancel answers with the outcome
managedRuntime.subscribe {agent} sends a full snapshot on subscribe, then one
snapshot per install state change, and closes with the transport. It replaces
the managedRuntime.status long-poll and its slot registrations.
|
||
|
|
8c1ade9e44 |
Keep pending chat decisions available outside loaded history (#29121)
* fix(native-chat): retire acknowledged send echoes after catch-up * test: follow phone lint rules in reconnect regression * test: format reconnect message expectation * Keep current chat requests independent of loaded history * Read current chat requests in bounded cursor pieces * Fix current request subscription static checks * Match generated request schema import ordering * fix(native-chat): correct current request type boundaries * Exercise current request reads in wire compatibility inventory * Align current request fixtures with provider commit and RPC surface * test(native-chat): include current request browser capability * Keep the mobile chat session hook within its line budget * Format mobile current request readers * fix(native-chat): reopen once for a current-request version whose read keeps failing A deterministic read failure reopened the subscription, whose first frame re-read the same version and reset the backoff, so the pane resubscribed every 750 ms forever. * test(native-chat): type the current-request snapshot fixture * test(native-chat): wait for the hydrated open before driving the subscription |
||
|
|
6ae1386f98 |
fix(native-chat): never run a chat on an older host with more access than Ask for approval allows (#29442)
* fix(native-chat): refuse to start or send on a host that ignores Ask for approval * fix(native-chat): hide Continue on a host held for its permission mode * fix(native-chat): hold queued cards and goal turns on a held host; re-check on reconnect * fix(native-chat): hold goal objectives and start retries on a held host; re-ask while held * test(native-chat): give the remote Continue test a host that applies permission modes |
||
|
|
7c23f79622 |
fix(quick-commands): save agent prompts whole, bounded by what a chat message carries (#24488)
* fix(quick-commands): save agent prompts whole, bounded by what a chat message carries Agent quick-command prompts were silently cut to 6,000 characters on save: the editor accepted a long paste, settings normalization trimmed it, and reopening showed the shortened copy. The 6,000 was a Windows launch speed threshold, not a limit on prompts. - Storage no longer trims. A save is refused, never trimmed, when a prompt's chat text block is over 256 KiB of JSON (measured on its real escaped size, the measure the chat send schema applies) or the list is too large for one paired reply. Host and desktop store both check before writing. - The editor shows the size against the limit and blocks Save past it, and stays open with the text when the host refuses the save. - terminal.quick-commands.long-prompts.v1: hosts withhold prompts over 6,000 characters from clients that do not advertise it (older clients reject a whole list holding one); editors keep an older host's 6,000 cap. - The phone editor no longer drops pasted text past 6,000 via maxLength. Launch delivery of long prompts is left to the launch-prompt series (#24257, #23962, #24080); this branch's earlier paste-after-ready delivery duplicated it and is removed. * fix(quick-commands): drop a stale duplicate doc comment * fix(quick-commands): advertise long prompts to this build's own host too * fix(quick-commands): keep submitted editor immutable until save settles * test(quick-commands): keep storage and save lifecycle coverage focused * fix(quick-commands): keep portalled choices within pending form ownership * Preserve retained credentials when settings validation refuses a save --------- Co-authored-by: OrcaWin <alpha-eng@stably.ai> |
||
|
|
1b1d09cfb5 |
Open a native chat copy in the CLI without waiting for History (#29126)
* Prepare native chat CLI copies from the host record * Apply staged-file lint and formatting checks * Cover pairing replacement before queued preparation dispatch * Reuse CLI failure feedback and complete the pairing test response * Isolate Codex materialization test user data * Preserve native chat CLI copy completion and preparation ownership * test: consolidate native conversation fork contracts * fix(native-chat): refuse a Codex chat fork whose saved account home has no CODEX_HOME path |
||
|
|
e5e6189f96 |
Split Jira issue workspace hooks and IPC param checks (#28759)
* refactor(jira): split issue workspace hooks and IPC param checks - Move IPC argument normalization into jira-ipc-params.ts so the jira:* handlers and its tests share one validator. Issue edits are now also checked for labelOperations, which the host reads, so malformed label edits are rejected before they reach Jira. - Move issue hydration and remote detail state out of JiraIssueWorkspace.tsx into use-jira-issue-workspace-data.ts, and comment submission into use-jira-issue-comment-submission.ts, so the component stays under the file-size limit. - Split the reopened-issue and rollback optimistic-edit tests into their own files to keep each test file focused. - Move runtime capability constants into runtime-capability-constants.ts and re-export them from protocol-version.ts, so the values keep the same names and exports for existing importers. * refactor(protocol): use named imports for runtime capability constants Import the runtime capability constants by name instead of destructuring them from a namespace object. The bindings and values are unchanged. Named imports make the dependency explicit to readers and tooling, and the protocol version comment now sits next to the constants it describes. |
||
|
|
a0c46b405f |
feat(jira): load attachment images outside issue Markdown (#28631)
Load Jira attachment images separately from issue Markdown so descriptions and comments stay small while screenshots load lazily and open in the existing lightbox. Downloads begin when an image mounts, capture its owning host, require negotiated image support, and use bounded authenticated byte streams and caches. Older clients retain their inline-image handlers. Keep legacy and cancellable downloads in separate in-flight domains so cancelling a new image reader cannot abort a legacy reader; completed bytes share the bounded cache. Preserve the landed assignee, board, transition/comment queue and request lifetimes. Move unchanged project metadata IPC handlers into their domain module and tighten two inherited focus-check ceilings without changing behavior. Validation:410 tests/54 suites; all changed-source quality stages, lint, format, routing and contract checks; exact final node/web types; independent source review;48/48 fresh hidden Electron checks with226 stable source hashes and nine inspected screenshots. Synthetic transports exercise production clients and UI. Current CI static checks, mobile bundle, wire compatibility, Linux/Windows packaging and Windows serve pass; five test shards were pending at review. Extends the existing attachment work credited to Frank (@lifefloating) and Brennan Benson in PR #8938; existing contribution credits and media remain in this PR. |
||
|
|
624c4148cc |
View Jira work on a board and filter the current sprint (#28633)
Show Jira issues as a board alongside the existing list and add the current-sprint preset. Status moves use the existing owner-scoped mutation queue, collect required workflow fields/comments, retain rejected drafts, and reload the mounted comment timeline once after success. Source/session fences keep older detail failures from undoing newer board moves. Preserve statuses plus sprint in query preview and Edit-as-JQL. Older hosts must advertise sprint support; unsupported peers fail clearly. Existing capability definitions and test fixtures are split without changing public exports, wire strings, or coverage to meet current lint limits. Validation:351 tests/42 suites,all46 changed sources full-file lint/anti-slop and7quality stages,localization/RPC checks,and independent source review passed. Node types passed on runtime-identical99d and web types passed on final602d. Fresh hidden Electron54/54 checks passed on99d; final two test-only changes were hash and emitted-runtime audited. The inherited IPC301-line failure is byte-identical main and being corrected separately by the image PR. Adapted Eugenio Valeiras (@EugeValeiras)'s board contribution from PR #13054. Co-authored-by: Eugenio Valeiras <eugenio.valeiras@gmail.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
eb1ee8f908 |
fix(jira): collect required fields before changing status (#28588)
Collect required Jira transition fields through the shared issue save queue, preserve entered fields after rejected saves, and refresh the comment timeline after successful transition comments. Keep captured-host and older-peer compatibility. Co-authored-by: Wooseong Kim <innocarpe@gmail.com> |
||
|
|
702777e2fe |
Filter Jira preset views by multiple workflow statuses (#28623)
Combine remembered Jira status filters with presets and saved JQL on the connection host, protecting obsolete owner actions and keeping incompatible controls hidden in linked mode. Co-authored-by: Brennan Benson <brennankbenson@gmail.com> |
||
|
|
d7315af456 |
Save and reuse named Jira JQL filters on the execution host (#28600)
Save and apply named Jira queries on their connection host. Reject obsolete owner actions and exit linked mode only after a saved query is actually applied. Co-authored-by: no-support <jwan0131@gmail.com> |
||
|
|
51173e45d4 |
feat(jira): generate issue titles on the connection host (#28625)
Generate Jira issue titles through the selected execution host, protecting cancelled requests and treating Jira content as quoted prompt data. Co-authored-by: Kazuki Hanai <kazukihanai@sakana.ai> |
||
|
|
7ac2dcc7d4 |
feat(cli): let agents read and update Jira tickets safely (#28592)
Expose host-owned verified Jira reads and single-attempt writes through the CLI. Preserve site ambiguity checks, old-host capability refusal, atomic label changes, and uncertainty after failed writes. Refs #11986 and #26055. Co-authored-by: Dan Cieslak <dcieslak19973@users.noreply.github.com> Co-authored-by: kokbee <kok2209@gmail.com> |
||
|
|
5f134d8f01 |
feat(mobile): show and use the desktop's server workspaces on the phone (#26501)
* test(e2e): add a paired phone client helper and phone-mirror baseline specs
Later phone-mirror slices need one oracle that drives a real mobile-scoped device with the
phone's own capabilities against a serve host or a paired desktop. Pins #26022 across a serve
restart and today's gap: a desktop's phone does not list the desktop's server workspaces.
Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb
* feat(mobile): show SSH host health on the workspace row host badge
Rows on an SSH host the desktop cannot reach looked healthy on the phone. The badge now
adds the desktop sidebar's own word ("devbox · Disconnected"), derived by the same shared
function from the connection status ssh.listTargetSummaries already sends; old desktops keep today's badge.
Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb
* test(e2e): compose the phone-mirror topology and check the cold snapshot
Slices need one composer for host, desktop and phone with a single teardown, so specs stop
copying setup. The serve-restart spec now reads the first tab-stream snapshot after the cold
start, which is what the phone builds its tab strip from.
Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb
* feat(mobile): name an unhealthy SSH host even in a single-host list
The desktop card shows SSH status on any host count, so the phone now reads target summaries
whenever a repo is on SSH and badges an unhealthy host alone too. Labels and health share one
target-to-host keying, and a hook-level test pins the reply-to-row wiring.
Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb
* test(e2e): keep phone-mirror teardown errors from masking test failures
Teardown failures become a test attachment instead of replacing the real failure, and the
cold-snapshot poll reports stream errors together with the PTY list.
Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb
* fix(mobile): clear stale SSH host badges and announce them without the dot
A catalog that no longer spans hosts or holds an SSH repo now clears the health and label maps,
so a host that left cannot keep badging rows. The badge gets a screen-reader label ("devbox,
Disconnected") instead of reading the middle dot.
Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb
* feat(runtime): let a paired desktop register its phones as delegated mobile devices
A desktop paired to this runtime can now call pairing.delegatedMobileDevice.sync to make each of
its phones an ordinary mobile-scope device it owns, so the phone mirrors that host through the
desktop. Children are never pending, inherit the parent's reach, and die with the parent's grant.
Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb
* refactor(runtime): move the mobile device revoke primitive below dispatch
Dispatch binds the caller-bound delegated-device context, so the revoke path it needs now lives in
a layer under it as a pure move; this drops the abstract method seam. No behaviour change.
Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb
* fix(runtime): keep a runtime grant until its delegated phones are revoked
A failed child cleanup now leaves the parent in place so a retry can still find the children, and
revokeRuntimeAccess lives beside the revoke it cascades to. Adds restart, rename and bounds coverage,
shares credential minting, and drops the timing-dependent census.
Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb
* fix(runtime): fail a delegated sync whose dropped phone cannot be revoked
Matches the parent revoke: a child whose cleanup could not be saved is kept and the sync errors
before minting anything, so the desktop retries instead of believing the server matches its list.
Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb
* feat(mobile): relay a paired phone's server-workspace requests through the desktop
A phone mirrors its desktop, including workspaces on the desktop's configured servers. The desktop
now forwards a request that names `executionHost: runtime:<env>` to that server over one socket per
(phone, server), signed in as the phone's delegated device; replies pass through untouched except
stream ids. Hidden until the phone client ships: the relay capability is not advertised yet.
Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb
* test(mobile): type the single-host health fixtures inline so the test tsc passes
Fixtures hoisted into consts widened their health maps to string, which the now-required
hostHealthById rejects under the tests-typecheck ratchet; passing them inline keeps the union.
Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb
* docs(mobile): state the desktop relay contract in its entry module
main dropped docs/reference, so the relay's contract lives beside the code. Also pins that a
server whose delegated sync fails (e.g. delegated_device_revoke_failed) is unavailable until a
later request syncs it again.
Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb
* test(mobile): pin the relay's configured-server adapter
The production hosts adapter was only typechecked; this pins that it resolves configured servers
by exact id only (never a name or a removed server), fences by pairing revision and runtime
identity, and stops reporting retirements once unsubscribed.
Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb
* test(mobile): re-record the repo-metadata goldens for SSH host health
The settled metadata state now carries hostHealthById, and an SSH-only catalog now reads the
target summaries so a lone unhealthy host can be badged. Scoped re-record via rpc-recording.mts.
Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb
* refactor(mobile): tighten the desktop relay after elegance review
Reuses the shared E2EE socket opener, folds relay state into fewer fields, never sends a request
whose link ended while opening, passes failure codes through, relays only this desktop's own
phones, and drops the unused host-state reader until S2 needs one.
Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb
* fix(mobile): bound relay frames and stop sticky relay verdicts
Restores the 8 MiB frame cap on every remote runtime socket, re-checks an update-needed server on
each new link so an in-place upgrade relays, answers a phone the server just declined without
syncing again, and ends a link whose mirrored capability update cannot be queued.
Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb
* fix(mobile): run targeted desktop-owned calls on the desktop
The phone tags every call on a workspace screen with its execution host, so a
paired-desktop method carrying `runtime:<env>` now runs locally instead of
failing 'forbidden'. The Mac stays the only reader of the routing table.
Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb
* feat(mobile): list the desktop's configured servers and their last workspace rows for the phone
The phone needs the same host list the desktop shows, including servers that are offline or
too old to relay to. mobileRelay.hosts.list/worktrees answer from the desktop's own status and
its own worktree.ps fetches, cached per server and fenced by pairing, never from relayed replies.
Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb
* refactor(mobile): list server rows through one desktop fetch, with no side effect on listing
The phone now always lists a server's rows through mobileRelay.hosts.worktrees, so the
desktop's own fetch is both the live source and the cache, and stamping stays in main.
Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb
* fix(mobile): fetch a server's full workspace list within a bound, and forget removed servers
The desktop now asks for the phone's full-catalog limit, answers within 5s with the last rows
when a server hangs, drops a server's rows when it is removed or re-paired, and checks the
server's identity after the fetch so a reply from before a re-pair is never served.
Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb
* feat(mobile): name a server workspace's host on the phone's calls
A phone reaches a server's workspace through its desktop only if each call names the host; the
direct, cloud-relay and shell-bridge transports now carry `executionHost`, streams keep it for
replay and unsubscribe, and an older shell (no `executionHost` grant) refuses rather than strips it.
Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb
* fix(mobile): list managed servers as the desktop sidebar does, and hide rows mid-delete
A server Orca manages on an SSH host now lists once under that host's name, or not at all while
the host is reached over the SSH relay, using the sidebar's own folding. Rows the server is
deleting are left out at reply time, as a phone asking the server itself would see.
Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb
* fix(mobile): keep a disconnected server's last rows, and never join a re-paired server's fetch
Retirement also fires on a manual disconnect or managed-server update, which wrongly emptied
the phone's list; rows are now pruned only once a server is no longer configured. Fetches are
shared per server identity, so a poll after a re-pair asks the new server right away.
Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb
* feat(mobile): list the paired desktop's server workspaces on the phone
Fixes the phone missing a desktop's `orca serve` workspaces: rows come from the desktop's
mobileRelay.hosts.* with each server's health ("Update needed", "Disconnected"), open through the
relay, follow the desktop's hidden hosts, and the desktop now advertises the relay capability.
Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb
* test(mobile): pin that a desktop failing the hosts list leaves only its own rows
The page asks a relaying desktop for its servers; a refusal such as method_not_found must leave
today's list with no server rows and no catalog error.
Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb
* fix(mobile): mirror the desktop's shown hosts exactly, one host included
Jinwoo's call: the phone follows visibleWorkspaceHostIds as the desktop sidebar does, so a
one-host list narrows the phone too instead of being read as a single-host focus.
Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb
* fix(mobile): scope a server workspace at its route, never the desktop
Every screen under a server workspace's route now reads one context and
gets that server's client and a router that keeps pushes on it, refusing
to fall back to the desktop; pins write to the row's owner like the Mac.
Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb
* fix(mobile): never open an unreachable server workspace, and prove the relay in e2e
A server workspace the phone can't reach now gets one explicit screen at its route
and no row tap or action-sheet entry opens it; native routes read the route's host,
a census pins every workspace route, and the e2e reads files and git on the server.
Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb
* feat(mobile): gate a server workspace on that server's own features
A targeted status.get now relays to the server, so a server workspace's route
provides that server's status to every screen under it and its action sheet,
while whether the phone can reach the server stays the desktop's answer.
Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb
* fix(ci): run the remote-runtime WebSocket opener test on Node
Under the bun vitest project, `ws` resolves to Bun's built-in client, which
ignores maxPayload, so the frame-cap test hung. The opener only ships on
Node/Electron, so run its test in the Node runtime project like its siblings.
Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb
* fix(mobile): give the file preview the workspace router, back to 128 page assets
The preview was the one workspace screen on the plain router, so the scoped router
was reached by a route set of its own and esbuild split it into an extra chunk
(129 assets); every workspace screen now uses it and it shares the route's chunk.
Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb
* refactor(mobile-relay): derive the phone allowlist from the routing table
Adding a phone method now takes one edit (its route). A server-targeted call on a
legacy non-E2EE socket is refused instead of running locally, and only
execution-host methods enter the relay.
Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb
* refactor(mobile-relay): drop unread freshness fields from server workspace lists
The phone reads only the rows, so stale, fetchedAt, totalCount and truncated
were dead wire weight. The desktop still serves a server's last rows while
the server is unreachable.
Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb
* refactor(mobile): read only the rows of a server's workspace list
The desktop no longer sends a freshness flag, so the phone's schema drops it.
The relay capability list names the delegated-devices constant instead of
repeating its literal, which also retires a now-circular type check.
Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb
* fix(mobile): show a server workspace as disconnected while its server is down
The phone read the desktop's connection state for a server workspace, so a stopped
server kept a green dot and "Loading tabs" spun forever. The workspace route now
narrows that state by the server's health from mobileRelay.hosts.list, reusing the
existing disconnected session UI and refetching tabs when the server returns.
Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb
* refactor(mobile): share one desktop server-list feed between the host list and workspaces
A server workspace polled mobileRelay.hosts.list beside the host list's own read, so
the phone could ask the desktop twice per tick and the row badge and the screen could
disagree. One feed per desktop client now owns that read; both readers join it.
Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb
* test(e2e): read a server's reachability from the hosts list, not a dropped stale flag
|
||
|
|
b8e49222a3 |
fix(remote-runtime): wait for the desktop's terminal list before opening a terminal (#28154)
* fix(remote-runtime): wait for the host's terminal list before opening a terminal A paired client opening a workspace whose terminals it had not heard about yet read "no answer from the host" as "zero terminals" and asked the host for one. When the host's list then arrived with terminals, the workspace gained an extra terminal; when it arrived empty, the first-frame bootstrap created a second one. The client now treats an unknown host count as unknown. Activation without explicit startup work waits, and the active subscription's first real answer seeds the workspace if it is empty. An "ask me later" frame from a host that has not published yet no longer records a count of zero, and the host's later answer (sent as an update) is accepted as the first answer for seeding. * fix(remote-runtime): count an unknown host as empty unless it answers later Hosts before #25736 answer an empty workspace with "ask me later" and never follow it with a real answer, so waiting for that answer left a blank workspace with no terminal against them. Wait only on hosts that advertise session-tabs.empty-worktree-answer.v1; older hosts keep main's behaviour. Workspaces this client just created are known empty and open their first terminal without waiting. Co-Authored-By: Claude <noreply@anthropic.com> * fix(remote-runtime): log a failed delayed terminal open; drop an inert flag Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
fee083fa47 |
feat(runtime): session-only browser keys and opt-in for pairing from plain-http pages (host) (#27540)
* feat(runtime): session-only browser keys and an opt-in for pairing from plain-http pages (host) - pairing.registerDeviceKey accepts ephemeral: true (advertised as pairing.device-key-ephemeral.v1). Such keyed rows are dropped when the host restarts and after 12 hours with no live socket; a sweep removes them and cuts any socket still bound to them, so later key auth gets device_revoked. - The WebSocket upgrade Origin is recorded per socket. A first pairing (a never-used pairing code) from an http:// page on another machine is refused with a sealed insecure_origin error unless the operator sets ORCA_ALLOW_INSECURE_WEB_PAIRING=1. Already-paired browsers, https and loopback pages, and native clients are unchanged. - Registry file reading moved to device-registry-file-read.ts to keep the registry under the size cap. * fix(runtime): gate first pairings only for the marked web client, never phones React Native sends an http Origin on every LAN WebSocket, so the Origin alone refused first-time QR pairing from released phones. The web bundle now marks its upgrade with ?orca-client=web; only a marked socket from an http page on another machine is gated. Released hosts ignore the query string. --------- Co-authored-by: m4air <m4air@Mac.localdomain> |
||
|
|
47b94ef64a |
fix(daemon): keep tweetnacl out of the relocated Windows daemon-host graph; guard daemon externals at build (#27504)
Co-authored-by: m4air <m4air@Mac.localdomain> |
||
|
|
6ffbdcd875 |
feat(runtime): device-key authentication and per-installation key migration (host) (#27493)
* feat(runtime): device-key authentication and per-installation key migration (host) * fix(runtime): corrupt registry is never a revocation verdict; keyed sockets dispatch without a token; forks keep their Relay binding * fix(runtime): keep an unparseable device registry aside; an unlisted key is never 'revoked' while it exists * fix(runtime): a set-aside corrupt registry keeps verdicts doubtful even when the registry file is missing * test(runtime): registerDeviceKey reaches the bound socket through the dispatcher for runtime and mobile rows --------- Co-authored-by: m4air <m4air@Mac.localdomain> |
||
|
|
08b65edc5c |
feat(serve): let the owner resume paused automatic restores (#27459)
* feat(serve): let the owner resume paused automatic restores The terminal daemon now answers automaticWorkStatus and resumeAutomaticWork. Resume clears a recorded same-boot crash pause or a pressure pause, writes the cleared state durably, and wakes restores that were waiting. The runtime exposes runtime.automaticWork.status and runtime.automaticWork.resume (host-admin; advertised as runtime.automatic-work.v1), the CLI adds 'orca serve restore resume', and a sleeping pane paused by its host offers 'Resume automatic restores'. A daemon that predates the requests reports no gate. * fix(serve): a stale daemon cannot resume, and an old one says so Resume now re-reads endpoint ownership right before it runs, so a daemon replaced by a successor cannot rewrite the successor's run marker. A gate-bearing daemon from before resume existed is reported as 'terminal host predates resume' instead of 'no gate'; the CLI says to run the command again after the terminal host restarts, and a sleeping pane still resumes when the user asks for it. --------- Co-authored-by: m4air <m4air@Mac.localdomain> |
||
|
|
10d5108671 |
feat(runtime): accept a declared spawn intent from paired clients (#27452)
* feat(runtime): accept a declared spawn intent from paired clients Paired clients can now say whether a terminal restore is the pane the user is looking at (user-resume) or a hidden one (automatic-restore). The host forwards the intent to its fork gate, advertises terminal.spawn-intent.v1 so clients only send it to hosts that accept it (terminal.ensureAgentSession params are strict), and reports a deferred fork as terminal_spawn_deferred with its reason. No client sends the field yet; that lands next with the sleeping-pane handling. * fix(daemon): a claimed agent resume cannot declare itself interactive Interactive forks skip the gate, and paired clients can now declare intent, so the host keeps inferring from the claim when a request says interactive. * fix(runtime): clients may only declare restore intents A daemon kept running across an update still lets a declared interactive request skip its gate, even for a claimed resume. The RPC and local IPC now accept only user-resume and automatic-restore, and the daemon request boundary turns a claimed interactive into an automatic restore. --------- Co-authored-by: m4air <m4air@Mac.localdomain> |
||
|
|
de00a4f03c |
feat(runtime): let a paired desktop register its phones as phone devices (#26427)
* feat(runtime): let a paired desktop register its phones as delegated mobile devices A desktop paired to this runtime can now call pairing.delegatedMobileDevice.sync to make each of its phones an ordinary mobile-scope device it owns, so the phone mirrors that host through the desktop. Children are never pending, inherit the parent's reach, and die with the parent's grant. Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb * refactor(runtime): move the mobile device revoke primitive below dispatch Dispatch binds the caller-bound delegated-device context, so the revoke path it needs now lives in a layer under it as a pure move; this drops the abstract method seam. No behaviour change. Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb * fix(runtime): keep a runtime grant until its delegated phones are revoked A failed child cleanup now leaves the parent in place so a retry can still find the children, and revokeRuntimeAccess lives beside the revoke it cascades to. Adds restart, rename and bounds coverage, shares credential minting, and drops the timing-dependent census. Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb * fix(runtime): fail a delegated sync whose dropped phone cannot be revoked Matches the parent revoke: a child whose cleanup could not be saved is kept and the sync errors before minting anything, so the desktop retries instead of believing the server matches its list. Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb * fix(runtime): refuse pairing admin to phones delegated through a paired desktop A delegated child phone could call the mobile-allowlisted pairing-admin methods (push registration, relay provisioning) that its parent desktop is never granted. The caller scope now marks delegated phones and denies them that permission. Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb |
||
|
|
bcc50483bb |
fix(vm): a recipe VM's SSH root runs on a managed Orca server (#27366)
* fix(vm): a recipe VM's SSH root runs on a managed Orca server A recipe VM's hidden SSH target was counted as owned by another runtime, so every connect refused to deploy a managed server and fell back to the relay. Its runtime owner only records when the VM is created and destroyed, so it no longer blocks the deploy. The VM's workspace then lives on that server: the server adopts the provisioned root as its main worktree, and removing the project destroys the VM and forgets its server. * fix(vm): release the server of a relay-era VM that converted on connect * fix(vm): resume reconnects an SSH VM's server; removal stays on its own VM * fix(vm): removal and the remove dialog find a VM's server before the catalog loads * fix(vm): a catalog refresh failure never blocks a VM create --------- Co-authored-by: m4air <m4air@Mac.localdomain> |
||
|
|
e6af89741f |
feat(ssh): a paired client can manage the server's own SSH hosts (ssh.target-management.v1) (#27329)
* feat(ssh): manage a paired server's own SSH targets over RPC (ssh.target-management.v1) * fix(ssh): keep a browsed remote path untrimmed --------- Co-authored-by: m4air <m4air@Mac.localdomain> |
||
|
|
f361455c73 |
fix(files): links to this computer in a remote terminal open on the client with trusted provenance (#27234)
* fix(files): a link to this computer in a paired-server terminal opens here when the host disowns it * fix(files): keep client-local link tabs on this computer; gate the fallback on host support and native clients --------- Co-authored-by: m4air <m4air@Mac.localdomain> |
||
|
|
fff0bb0d06 |
feat(runtime): the host refuses a request meant for another runtime (#27224)
A CLI launched from an Orca terminal now sends, with each request, the runtime it verified before sending (expectedRuntimeSource: the launching profile's installation id plus the verified runtime id). The host checks it before parsing params or running any handler and refuses a mismatch with runtime_source_mismatch, so a runtime that took over the endpoint between the CLI's check and its send cannot apply the request. Optional field: an old CLI sends none and an old host ignores it (the CLI's pre-send probe stays the fence there). Hosts advertise runtime-source-fence.v1. Co-authored-by: m4air <m4air@Mac.localdomain> |
||
|
|
0ba67e1181 |
fix(mobile): agents for workspaces another runtime owns show why (#27196)
* fix(mobile): agents for workspaces another runtime owns show why The paired host no longer lists its own agents for a workspace another Orca server owns: preflight.detectAgents refuses with workspace_on_other_runtime, and the phone shows 'Agents on Another Server - Pair that server directly'. The phone also recognises an unambiguous runtime-owned repo row itself, so an older host is never asked. * fix(mobile): a shared repo id with a runtime-owned row defers to a refusing host Rows on several hosts can share a repo id, and the first row's SSH connection could name the paired host's own target. When any row is runtime-owned the phone now asks a host that advertises preflight.other-runtime-refusal.v1 to decide by worktree, and shows the other-server row on an older host. * fix(mobile): keep the agent-loader change inside the web bundle budget Move the refusal code beside its capability in protocol-version, read the capability in the loader, and test the runtime: prefix directly: importing execution-host into the loader split a web bundle chunk (129 > 128 assets). --------- Co-authored-by: m4air <m4air@Mac.localdomain> |
||
|
|
180e8c186f |
feat(ports): host-scoped port scan and stop on the server (#27188)
* feat(ports): host-scoped port scan and stop on the server Add workspacePorts.scanHost/killHost, addressed by workspace and resolved on the server to the workspace's own execution host (this machine or one of its SSH hosts). Stop is bound to the host its row was scanned on and is refused on SSH hosts, where ownership cannot be proven. Advertised as workspace-ports.host-scoped.v1. * fix(ports): only this host's workspaces authorize Stop; a failed relay scan is not empty Port ownership probes now come from host routing instead of the repo row's connectionId, so an SSH repo that carries only executionHostId (or a runtime- hosted repo) can no longer make a local listener look workspace-owned. The relay's ports.detect now fails when it could not read the socket table (unreadable /proc/net/tcp, or neither Windows scanner answering) instead of answering an empty list, so a host scan reports unavailable rather than none. --------- Co-authored-by: m4air <m4air@Mac.localdomain> |
||
|
|
d3e3b173e6 |
fix(agents): one host-routed agent-detection entry point (#27054)
* fix(agents): one host-routed agent-detection entry point
preflight.detectAgents / refreshAgents take an optional { worktreeId } and the
host resolves that workspace's project runtime (WSL included) or SSH target.
Gated by preflight.workspace-scoped.v1; old peers keep the host default.
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(agents): route detection by the worktree's own host record
A repo id shared by local and SSH rows made the first row pick the detection
host. Resolve the worktree from the host's list and apply the shared
execution-host routing rule; ambiguous rows refuse. Dashboard falls back to the
host-default list until a workspace's own list loads.
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(agents): refuse an ambiguous workspace instead of probing the host
Only selector_not_found keeps the host default; selector_ambiguous now fails
closed. Adds runtime-level coverage of the lookup.
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(agents): refuse an ambiguously owned folder workspace
Co-Authored-By: Claude <noreply@anthropic.com>
* test(agents): quick-launch runtime target carries the workspace
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: m4air <m4air@m4airs-MacBook-Air.local>
Co-authored-by: Claude <noreply@anthropic.com>
|
||
|
|
59631b8b26 |
fix(native-chat): edit a queued message in place, even while a question is open (#26886)
* feat(native-chat): edit a queued message in place on the host A queued card's Edit used to copy its text into the composer and delete the card, so the message lost its place, an agent-mail card lost its sender, and while a question or approval replaced the composer the text vanished. The execution host now edits the card itself: - agentSession.queuedMessageUpdate replaces only the card's text, as a compare-and-set on the body fingerprint the client last saw. It keeps the id, position, sender, kind, send mode and attachments; a command card is not editable. A resent Save answers from the card as it stands (unchanged or changed), so a lost answer never overwrites newer text. - agentSession.queuedMessageEditHold acquires, renews and releases an in-memory edit lease per caller and edit. While one is live, automatic delivery stops at the card (earlier cards still send, later ones wait); an explicit Send still overrides. Leases expire after two minutes on their own, re-derive validity from the card on every read, and die with the conversation. Release uses cleanup admission. - The published card carries an optional editHeld marker, never `paused`. - Both methods sit behind the new agent-session.queued-message-edit.v1 capability, independent of the dark mid-turn queue capability, and are on the mobile allowlist for the phone follow-up. * feat(native-chat): edit a queued card inline on desktop Edit message now opens an editor inside the queued card instead of moving the text into the composer. The card keeps its place and sender, and the editor stays usable while a question or approval holds the composer's slot (it does not lose focus to the prompt card). - Enter or Cmd/Ctrl+Enter saves, Shift+Enter is a newline, Escape cancels; IME composition keys never save or cancel. Save and Cancel replace the card's own actions while it is edited; one editor per pane. - The editor holds the host's edit lease, renewing every 30 seconds and taking it again after a lapse. Lease failures are only logged: they never block typing, Save or Cancel. - If the card is sent or removed elsewhere mid-edit, a clean edit just closes; changed text goes into the chat box after any existing draft, with one toast. A Save that lands and then sends counts as success. - Against a host without agent-session.queued-message-edit.v1 the card offers no Edit (no copy-and-delete fallback); an empty overflow menu is hidden. * fix(native-chat): name every queued-edit notice in its switch * fix(native-chat): keep queued-edit typing safe and stop disabling Send elsewhere - Save with an unreadable answer (dropped for a moved runtime fence, or lost) now reads the published card: saved text shown -> close; card gone -> the sent-as-saved / chat-box path; otherwise keep the editor quietly. - Send and Steer stay enabled on a card edited on another device; the published editHeld marker is gone (no reader left). Automatic delivery still stops at an edited card on the host. - Save answering changed moves the typing to the chat box and reopens the editor on the newer text. Notices say when the chat box is hidden by a question or approval. - Closing the pane or switching chats with unsaved typing appends it to that chat's box quietly. - Lease renewal no longer publishes, so an open editor is not idle-sweep activity. - The consume compare-and-set also matches the body fingerprint. - Saving unchanged text keeps the original blocks. * fix(native-chat): keep Agent in the Japanese queued-edit notices, as the catalog does * fix(native-chat): close a queued edit its own Save already landed, wake the queue for a pruned lease, keep typing across a reload A Save whose answer was lost now closes once the card shows the saved text, and a card that went out with exactly the typed text closes quietly instead of copying it to the chat box. A renew that prunes another editor's lapsed lease wakes the queue in place of the timer it cancels. A reload, which unmounts nothing, hands unsaved typing to the chat box like closing the pane. * refactor(native-chat): move the queued-edit notices to their own module * fix(native-chat): unref the edit-lease timer in a way the phone's typecheck accepts The lease module reaches the mobile test program through journal-store, where setTimeout answers a number, so `timer.unref?.()` failed mobile's tests typecheck ratchet. * test(cross-version-wire): call the queued-edit methods in both skew directions The manifest must name every agentSession method; the two edit methods reach their host methods on a new build and are only called by clients on a host advertising agent-session.queued-message-edit.v1. * test(rpc): count the two queued-edit methods on the structured surface * fix(native-chat): lay out the inline queued-message editor as a header, field and Save footer While a card is edited, its row shows a pencil, "Editing message", the sender and an X that cancels; the field at full width; and a footer with the key hint and Save. The card's queue icon and its status line are hidden until editing ends. * fix(native-chat): show the Enter key on the queued-message editor's Save button The editor footer's muted key hint is gone. Save now carries the same inline key badge as the new-workspace composer's Create button, extracted into a shared ButtonKeyHint so both buttons render one badge. |
||
|
|
573ff0bca3 |
Save a new chat's first message during create (#26332)
* fix(native-chat): the host owns the send queue; the window keeps no saved outbox The desktop kept each structured chat's unsent messages in localStorage and sent them in order, so one message whose fate was unknown froze every later send, Retry dropped it silently, failed sends could not be discarded, and an offline chat could send hours later. The host already records every message and owns the queue; the window now only sends. - One in-memory sender for composer, launch prompts and messages sent from outside the chat. One send in flight per chat; a transport failure resends the same id for up to 30 s; a refusal that proves nothing was recorded puts the text back in the composer with the reason; a send that went out and was never answered shows an in-doubt line with Send again and holds nothing up. - The host's "unknown" rows get the same in-doubt line and Send again, from the journal, in every window. - A message an older build left in localStorage is never sent: the host's conversation outline decides what goes back to the composer, and the copy is deleted once that is saved. * fix(native-chat): send through the structured chat RPC wrapper, with its timeouts The sender called the runtime RPC directly, skipping the per-method timeouts every other structured chat call gets. Only a remote host's request skips the compatibility check the sender already ran. * fix(native-chat): an unconfirmed send goes back to the composer, with no new row line The common pattern draws nothing extra on a message whose delivery is in doubt once its turn is over, and puts a failed send's text back in the composer with the reason. So a send nobody answered in time, or one a host answers in a way that proves nothing, goes back to the composer worded as unconfirmed, and a host "unknown" row shows nothing extra. Removes the in-doubt phase, Send again, and its strings. A host's made-up row for an id its journal lost now reads as unconfirmed, not as recorded, so that message comes back instead of vanishing. * test(native-chat): pin that nothing resends a send given back as unconfirmed * fix(native-chat): sends survive a tab close, never resend after a Stop, and keep remote images - A normal tab close lets sends on their way settle; what the host never took goes back to the conversation's draft. Only a cancelled launch or a worktree purge drops them. - After any Stop, a send already on its way is never sent again under its id: a doubtful answer, or a resend that was due, hands its text back worded as unconfirmed. - A returned image keeps the SSH connection it lives on; the connection never goes to the host. - An older build's saved message the host recorded and then rejected is left to the host's own row, never handed back. * fix(native-chat): a Stop or a tab close never resends a send already out, and a kept card is the card's A Stop that landed while a same-id resend was being readied (its timer fired, its request not out yet) let that resend go out after the Stop. The sender now tracks whether a request is awaiting its answer: a Stop hands back every send between attempts as unconfirmed, lets one whose request is out settle from its answer, and never issues a request after it. A normal tab close withdraws the same way instead of doing nothing, so nothing more goes out and nothing is dropped. A send the host rejected but kept as a card (keptAsQueuedMessageId) is the card's, from its reply or the journal, and never goes back to the composer. Adds the freeze tests: a send whose fate is unknown holds later sends no longer than its deadline, and one the host can neither confirm nor deny releases the next at once. * fix(native-chat): read a resend's turned-away call or reused id as unproven Ports the send-answer proof contract. A call the host turned away before running it (method_not_found, invalid_argument, unauthorized) proves only that this request wrote nothing, so it reads as never sent on a first attempt only; on a resend an earlier attempt may have landed, and it goes again under the same id. A resent id the host says was already used for other content (messageIdReused) proves nothing either, like an expired or conflicting id. Pins the rest of the contract: any row the host returns is its own, a thrown error is no answer whatever its code, and an older build's refused, held or outlived-Stop copy is handed back once and never sent. * refactor(native-chat): type the structured composer's send with its attachment type Keeps NativeChatStructuredSession.tsx within the file length limit. * refactor(native-chat): drop the kept-card guards the sender never needed A kept send's row is a rejection that was never a Stop's, so the sender already reads it as recorded, from its reply or the journal. The test that pins it stays; the two extra checks only covered a kept row that is also a withdrawal, which the host never writes. * test(native-chat): route launch tests' sends through the client wrapper the sender calls The sender sends through callStructuredAgentSession, but these launch tests replaced that module with a factory that answered nothing (and still named a probe that no longer exists), so every launch prompt resent until its 30 s deadline and the tests timed out. Each factory now hands sends to the runtime RPC mock the tests already answer, and expectations of a local send no longer ask for the remote-only compatibility option. * fix(native-chat): hand a message back without importing the composer's attachment hook The worktree purge reaches the launch prompt, which hands text back, and the attachment hook's imports reach the store. A test that builds the real store behind a mocked one then waited on itself and hung. Handing back now writes images to the draft store directly, as the hook's helper did, and a test pins that each returned image keeps its SSH connection. * fix(native-chat): one send per chat, with no line of sends behind it A chat with a send out took further messages into an in-memory line and sent them one by one. A message typed behind one in doubt then hit its own 30 s deadline and came back as not sent without ever going out. Now, as the common pattern does, a chat takes one send at a time: while it is out, Send is disabled and Enter leaves the text in the box. The sender refuses a second send instead of lining it up, so the 30 s deadline always runs from the send itself. A Stop or a tab close stops the one send: settled from its answer if its request is out, handed back as unconfirmed between attempts, or silently if it never went out. Notes sent from outside the chat while its send is out stay with their sender (not ready); a launch prompt that meets the person's own first message waits in the composer instead of being lost. * fix(native-chat): give a Stop-withdrawn note back to its chat once its notes were cleared Notes sent from outside a chat clear once their message is recorded. A message the host recorded as pending and a Stop then withdrew came back only to its sender, which had already let go of it, so the text was lost. The chat's draft now takes it, as an earlier build's outbox did. * test(native-chat): type the composer-actions probe without a cast * chore(native-chat): drop outbox wording left in comments and an empty locale group * fix(native-chat): pace failed checks, keep the host's reason, and hold the chat for its launch prompt - A send whose checks failed before its request went out (an unreachable or incompatible host, an unreadable history) was tried again at once, about a thousand times a second for 30 s. Attempts are now paced by the attempts made, whether or not their request went out. - A host that refuses every resend by throwing (native chat turned off, a journal that won't open) gave back only "couldn't confirm". The host's reason now comes first, still without claiming not sent. - A launch's prompt now holds the chat's one send from the click, drawn as sending, so a message typed while the chat starts can't overtake it; it goes out once the chat exists, and a cancelled launch frees it. - Notes whose send nobody could confirm say so instead of "did not accept", and notes launched into a new chat let go of their text once that chat's composer holds it. - An open chat keeps drawing a recorded send until its row arrives, so a reply that beats the history no longer makes the message flicker out. * fix(native-chat): hold a chat's sends until it has started, and send a failed chat's message with its restart A message sent to a chat still starting went out at once to a host that had no record of the chat yet, read for a fence it could not get, and came back as not sent. A message sent to a chat whose start failed restarted it but no longer went with the restart. While a chat starts, Send stays off and Enter leaves the text in the box, as with a send already out. A text message sent to a chat whose start failed restarts it and goes as the restart's first message, through the same staged-prompt path a launch prompt takes: it holds the chat's one send slot, drawn as sending, until the chat exists, and comes back to the composer if the restart fails again. Notes wait while a chat starts and ride a failed chat's restart, keeping their text until it is sent. * chore(native-chat): test the queue request, rejection words and card hand-offs; drop an unused clear - Pin which sends ask the host to queue, the moved rejection wording, and that a queue send whose card was handed off and then refused or withdrawn, or whose replay names a withdrawn card, is never handed back. - The send-at-most-once gate now says what the desktop promises after a reload: it never sends the id again, and hands the text back. - The legacy read names when it goes, and drops the notice clear nothing called. * fix(native-chat): keep a sent launch prompt's entry, and give back at once what can't go out - Cleaning up a launch prompt released its send slot even after the prompt had gone out, which deleted the entry the sender keeps once the host records it. A launch prompt recorded as pending and then withdrawn by a Stop was lost from both the chat and the box, and an open chat dropped the new chat's first message before its row arrived. The slot now gives back only a reservation that was never sent. - A send stopped before its request went out by something trying again won't clear (this client and the server can't talk, or the host refused the history read) kept Send off for 30 s and then said Orca couldn't reach the agent. It now comes back at once with its own cause: not sent, since nothing went out, or unconfirmed if an earlier attempt did. Transport errors keep the paced retries. * fix(native-chat): notes keep their own text through a new agent's launch Notes sent to a New agent whose start failed came back to the notes and also sat in the new chat's composer, so sending both delivered the text twice. The notes keep their text until it goes out (they hold it from the click), so the launch now says so and no composer gets a copy, on a failed start or a refused prompt alike. The tests that asserted the copy in the composer pinned the old double ownership and now assert the notes are its only owner. Notes that rode a failed chat's restart and ended unconfirmed now say Orca couldn't confirm them, as notes sent directly do, instead of that the agent did not accept them. * chore(native-chat): the send-once gate says what the desktop keeps across a reload The desktop keeps a send's id in memory only: a send still unsettled at a reload or crash is not resent and not handed back. The coverage notes no longer credit the renderer tests with durable identity across a remount. * fix(native-chat): say once why notes sent to a new agent did not go Since notes keep their own text through a new agent's launch, a prompt the host refused, nobody could confirm, or that found the chat's send taken came back to the notes with nothing said anywhere: the chat shows no notice for text its caller keeps. The notes menu now reports it once, with the toast a send to an existing chat already uses: not accepted, couldn't confirm, or not ready. A start that failed still says so in the new chat instead. * fix(native-chat): retry a history refusal the host says clears, and name it at the deadline A send stopped before its request went out came back at once for any refusal of the history read, including ones the host names as clearing (its journal briefly unavailable, a chat detached while the host quits), so the automatic retry was lost. Only a version mismatch and refusals that won't clear come back at once now; the rest go again on the paced schedule, and if the deadline still finds nothing sent, the words are the host's refusal rather than Orca couldn't reach the agent. * feat(native-chat): a send makes one request, and nothing ever sends it again The desktop resent a message under its own id for up to 30 s when the answer was lost. A send now makes exactly one request, as the common pattern's clients do: - An answer that is lost, dropped or proves nothing hands the text back at once with "couldn't confirm… check the chat". - A failure before the request goes out (the environment check, the history read for the fence, a refused connection) means nothing went out: the text comes back at once with its own reason, or as not sent. - The 30 s cap stays on the one request, so a host that never answers can't hold Send. Nothing ever resends, so nothing can go out after a Stop: a Stop only takes back a send still in its pre-send checks. The resend state goes with it (tries, generation, awaiting, stopped, the resend timer, the send-answers-proof probe, and the first-attempt/resend split in the evidence), and the send-once gate says the desktop never resends. * fix(native-chat): notes keep the chat's line, and a send held behind a rewind says it was not sent - Only a send whose text belongs to the chat's composer clears the chat's line. Notes sent from outside the chat no longer wipe a "couldn't confirm... Check the chat" line that explains text already back in the box. - A send the host turns away behind a rewind it could not confirm went back as "not sent" but said "couldn't confirm what happened. Check the chat". It now gives the rewind's reason and says the message was not sent. - Reliability gate names the single-request test and records a fresh evidence run; the sender test drops its leftover resend mocks and a duplicate Stop test. * fix(native-chat): a send ends even when putting its text back fails If writing the returned text into the chat's draft threw, the send never settled: it stayed "sending", the chat refused every later send until a reload. The send now always ends after a hand-back, the failure is logged, and the chat's line adds "Couldn't save your message." * fix(native-chat): a message typed during /clear stays in the box and follows the chat A /clear moves the chat to a new conversation, and its host refuses any send while it runs. A message sent then went out, came back refused into the old conversation's draft with its line, and vanished when the chat moved on: the box and the line now belong to the new conversation. - A /clear holds the chat's one send slot while it runs: Enter does nothing, Send shows busy and the text stays in the box, as for a send that is out. Notes sent from outside get "busy". - Once it moves the chat, the old conversation keeps taking no send until the view leaves it, and what is left of its draft moves into the new conversation's draft, after anything there: when the composer's /clear settles, and again when the view moves. * fix(native-chat): no "Send message?" or queue clear while the chat's send is out While a send is out (or a /clear runs) the chat takes no message, yet Enter over a held queue still opened "Send message?", and Clear queue deleted every card before its message was refused. Enter now does nothing there and the text stays; Clear queue re-checks and deletes nothing if a send went out after the question opened. * refactor(native-chat): take the /clear draft carry out of this change Moving the old conversation's draft into the one a /clear replaces it with fixes a bug main has too (text left in the box during a /clear stays with the old conversation), so it goes in its own change. Kept here: a /clear holds the chat's send slot while it runs, and the conversation it moved away from takes no send until the view leaves it. * fix(native-chat): a /clear's hold on sends always ends - A view that unmounted while a /clear that moves the chat was out left the old conversation holding its sends until a reload: the late reply kept the hold for a view that was gone. The reply now releases it. - The local call for a conversation command has no deadline of its own, so a /clear that never answers kept Send off for good. The hold now also ends at the command's deadline (195 s, the one the remote call already uses), whichever comes first. * test(native-chat): opening a chat an older build left stuck; hand back its copy in send order Pins, through the real chat hook, sends, legacy recovery and draft store, what opening such a chat does: the queued messages behind a message the host recorded in doubt come back to the composer once, in order, with the "not sent" or "couldn't confirm" wording; the chat is free to send under its read's fence; nothing happens while the chat has no fence here. The legacy reader now hands entries back in the order they were sent (queuedAt), as the older build's reader did, instead of array order. * fix(native-chat): a send this window turned away for a re-paired server comes back as not sent A managed server's update rotates its pairing, and this window's main process then answers the next call itself, before forwarding anything, with runtime_environment_changed. The send read that thrown answer as proving nothing, so the person was told Orca couldn't confirm a message that never left. It is now handed back as not sent, with the reason. Every other thrown answer still reads as unconfirmed once the request may have gone out. * Save a new chat's first message during create * Align opening-message types with the user-message wire * Keep chat publication and cleanup outside store initialization * Complete the create refusal fixture ledger * test(native-chat): prove a created first message waits for the agent's start and is handed over once * refactor(native-chat): keep the host and session hook under the line limit after the main sync * test(native-chat): a chat created with its first message and no pick still teaches its agent's default After the main sync, a created chat's agent starts from the delivery loop rather than the create call. Grok (through the real ACP adapter and model catalog) and Claude (through the real adapter) each still report the model their own config resolved to once the chat reads its options. |
||
|
|
8b2a5e45f1 |
Re-land Claude per-account folders (#24434, #26405) with the upgrade and proxy fixes (#26801)
* Revert "Revert Claude per-account folders (#24434, #26405) before release (#26638)"
This reverts commit
|
||
|
|
55eb48c137 |
Let automations pass extra agent arguments on each run (#26659)
* Let automations pass extra agent arguments on each run Automations could only use the host's default agent Arguments, so a per-automation choice such as a different model needed a settings change that affected every run. Automations can now save extra arguments that are appended to the host's defaults on each fresh run. Extras are allowlisted to model, effort, and Claude's --add-dir, and are refused for permission, config, prompt, and session options. - Add the field through the CLI (`automations create/edit --extra-agent-args`), the RPC contract, the automation store, and the editor's Advanced section, with validation at save and at launch. - Merge extras over the defaults by replacing a model or effort option the defaults already set, then re-tokenize to confirm the launch argv matches what was validated. - Gate writes behind a new runtime capability, and refuse to save or migrate extras to a host that would silently drop them. - Require a fresh session, since reused sessions cannot take new arguments. * Simplify automation argument validation and launch handling * improve the extra args display * fix translation * Validate automation extra args during ORCA migration Dormant automations imported from the migration manifest skipped the extra-args check. A disallowed flag, or Reuse combined with extra args, could persist and then fail every later run. The manifest parser now rejects those rows. Also move the automation runtime capability constants into `automation-runtime-capabilities.ts`. `protocol-version.ts` re-exports them, so existing imports keep working. * add more demo with effort |
||
|
|
4735ecefac |
fix(native-chat): a /compact sent while the agent works waits in line instead of being refused (#25704)
* fix(native-chat): a /compact sent while the agent works waits in line instead of being refused * test(native-chat): build the admission test's submissions without a type assertion * fix(native-chat): a /clear refused while the agent works says so plainly; a /compact behind an unsent message waits for it quietly * test(native-chat): name the admission test's cases for the sends they model * fix(native-chat): a /compact refused while the agent works reads plainly too; a command card offers no Edit * test(native-chat): a refused /compact reads the plain sentence * fix(native-chat): a refused command card is spent and said once; a command card offers Send while the agent is idle; /compact behind an unsent message is not taken * test(native-chat): keep the queued receipt's narrowing inside the wait * fix(native-chat): spend a command card only when its own turn says why; refuse a queued command without a hand-off, with its reason; a queue send on its way reads as sending * fix(native-chat): a recorded send is no sending card; queue lists land at once; a spent card's wait says to run it again; only /compact or /clear give way to returned text * refactor(native-chat): derive the sending cards inside the queued-messages hook * fix(native-chat): keep protocol-version and the agent-session params under the line limit; the send capabilities get their own module * fix(native-chat): with the agent idle, a command behind this window's own unsent message says it is still being sent * fix(native-chat): the queued-commands capability stays a plain constant beside the others; main's send capabilities back to its text * test(native-chat): keep the rewind suite under its line limit after main's growth * fix(native-chat): one import per module in the command send; a rewind on its way holds commands, tested * test(native-chat): type the rewind module mock with a type import * test(native-chat): a command card cut short by a restart waits or is kept like any card; kept-card captions name only controls shown * fix(native-chat): a held command card, which the queue skips, no longer forces later sends to queue * fix(native-chat): a command's refusal line goes once what it waits on is gone A refusal that names something the chat shows (the agent working, a pending prompt, background tasks, an unsent message) is said only while that still holds, derived each render, and dropped once it ends. Other composer errors are unchanged. * fix(mobile): a command's refusal banner goes once what it waits on is gone The phone's banner keeps a refusal naming the agent working or a pending prompt only while the chat still shows it, dropped each render once it ends. Background tasks, which the phone can't see, and generic errors behave as before. The host-reason mapping is shared with desktop. * fix(native-chat): a refusal behind an earlier message names whether it is being sent or offers Retry Each line now goes when its own state ends: a send that fails stops being sent, and a resend stops offering Retry. * test(native-chat): a Stop behind a typed /compact keeps the taken-back message on screen; the in-doubt case says so * fix(native-chat): a command refused while the queue is about to send reads working, as the pane does * Update held command fixture for the merged queue model * Restart one host at a time in the recovery ordering test * fix: preserve person queue reserve for chat commands |
||
|
|
9ca9b4e36b |
Revert Claude per-account folders (#24434, #26405) before release (#26638)
Users with a saved Claude account were signed out of every Claude feature in Orca until they signed in again, and proxy setups (API key plus ANTHROPIC_BASE_URL) got 401s after signing in. Reverting before release to rework the upgrade path. The terminal daemon protocol moves forward to 43 so dev builds' v42 daemons with the claude function are not reused; v41 and v42 stay attachable. Nothing is deleted: per-account folders are left unused and the old saved-account store was never touched. |
||
|
|
b41e2730db | Persist multiple workspace references with atomic edits |