mirror of
https://github.com/stablyai/orca.git
synced 2026-11-14 18:07:45 +00:00
de3da487fa6bbfde6f9e4b53fba7672fada5322c
171
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
3e9ca6e85a |
perf(mobile): open the PR tab with its last state and refresh only what a write changed (#39709)
* perf(mobile): open the PR tab with its last state and refresh only what a write changed * fix(mobile): allow the phone's comment re-read and settle review findings * fix(mobile): keep PR reads current across path switches and overlapping writes * refactor(mobile): share PR query keys and simplify PR write rollbacks * chore(mobile): list every PR action and comment write kind explicitly * fix(mobile): read the push-time PR reread through an effect event * fix(mobile): report a comment write interrupted by a path switch as unconfirmed * fix(mobile): settle a comment write whose reply was lost from the re-read comments * style(mobile): format host-query after rebase onto Q12 |
||
|
|
b4eda05c81 |
perf(mobile): show the last task list per filter while it refreshes (#39668)
* perf(mobile): show the last task list per filter while it refreshes * perf(mobile): read Tasks repos six at a time * fix(mobile): hold Tasks paging while kept rows re-read * test(mobile): pin Tasks paging held during a query switch * perf(mobile): read Tasks repos four at a time, the desktop's gh limit * test(mobile): give the Linear connect recording the revalidating input * perf(mobile): open Tasks on its kept hydration and lists through host query families * fix(mobile): keep the desktop's newer Tasks state and only cancel screen-read queries * fix(mobile): type the Jira refresh harness and Tasks list read for CI |
||
|
|
db7ff5c8ff |
fix(mobile): re-subscribe Home and the follow-up preference after the client event stream ends (#39655)
* fix(mobile): re-subscribe Home and the follow-up preference after the client event stream ends * fix(mobile): try a refused client event wire once per connected edge * refactor(mobile): mark replayed client event readies in the shared stream * test(e2e): give the phone feed socket client a state listener |
||
|
|
34cd1161bb |
perf(mobile): show the workspace list from memory and refresh it on desktop changes (#39453)
* perf(mobile): show the workspace list from memory and refresh it on desktop changes * fix(mobile): import the host list queries type without an import() annotation * fix(mobile): keep host labels on a not-connected read and update the phone feed e2e helper * fix(mobile): keep the event router listening when its stream ends while opening * fix(mobile): reuse the shared read-view base and remount for the cache-return recording |
||
|
|
11f31112db |
perf(files): page large folders on the phone with Show 500 more and Search all (#39438)
* perf(files): page large folders on the phone instead of reading them whole * fix(files): page from hasMore, refresh closed folders, retry a superseded Show more * fix(files): rerun a refresh that paging displaced, and keep an old host's whole folder from duplicating rows * test(mobile): re-record the Files matrix goldens for paged reads * test(files): type the paging fake host's params without widening * fix(files): filter folder reads that land after the folder closes |
||
|
|
a9f65f71d2 |
feat(mobile): handle renames and the workspace list while the desktop is offline (#39448)
* feat(mobile): add host mutations with draft, block and queue modes, starting with rename * fix(mobile): settle a lost rename through the reconnected client and keep server rows routed * fix(mobile): offer Retry on the offline banner once the host is unreachable * fix(mobile): let the offline banner's Retry redial from the page * fix(mobile): date the offline banner from the drop, not the connect * fix(mobile): keep the terminal rename sheet's state updates pure * test(mobile): mount rename and close-action tests inside a query client * refactor(mobile): share one draft rename sheet between workspace and terminal rename, and retry a confirm after a path switch * fix(mobile): keep another target's unsaved rename and show the offline reason over an old refusal * fix(mobile): keep a newer rename draft when an older save lands late |
||
|
|
ed3a3fd9f6 |
perf(mobile): reuse the connection's status in the automation editor and chat capability check (#39345)
* perf(mobile): route the last status.get callers through the shared status read * refactor(mobile): drop the unused one-shot Codex reset capability read * fix(mobile): open the chat transcript when the text-append check fails, and key connections on one epoch |
||
|
|
de6c2b6f5c |
perf(mobile): open a session with one terminal list read and a loading body under the cached tabs (#39412)
* perf(mobile): open a session without the startup terminal polls * test(mobile): re-record session startup goldens * perf(mobile): cache the session strip from host snapshots and drop phone-closed tabs * fix(mobile): keep a shown terminal over the offline and loading body states * test(mobile): re-record the last-strip reopen golden * refactor(mobile): drop a startup guard that can no longer fire * fix(mobile): drop a pending-terminal activation reply from an earlier route * test(mobile): type the pending terminal tab fixture * test(mobile): import the last-tabs module type without an import() annotation |
||
|
|
481f61152d |
perf(mobile): reopen agent session history from memory (#39387)
* perf(mobile): reopen agent history from memory * fix(mobile): reread history after association changes without restarting reads, and share the connection's status with query reads * fix(mobile): reread history after an association change only when the query can read, including after a failed scan * refactor(mobile): name every history screen state * fix(mobile): keep history's connected-edge watcher by not gating its query on the connection |
||
|
|
2ec6ea4aad |
perf(mobile): prefetch the next and previous file in Review (#39355)
* perf(mobile): prefetch the next and previous file in Review * perf(mobile): open Review on the tapped file without reading the first file * fix(mobile): show failed Review diff reads and re-read refused deleted files A re-keyed worktree diff that fails now shows its error instead of the older lines. A deleted-file stand-in from a refused read is re-read on the next visit and by Retry. Without git status, the branch section no longer waits on an unused compare. |
||
|
|
b0cd6d391c | perf(mobile): open a session with its last tab strip (#39158) | ||
|
|
1763014bea |
perf(mobile): reopen Files folders from memory (#39175)
* perf(mobile): reopen Files folders from memory * test(mobile): re-record Files explorer goldens for query reads * fix(mobile): paint cached Files rows before the host client attaches * refactor(mobile): share query observer options and Files' empty-state rules * test(mobile): type the Files explorer test host |
||
|
|
51f532115e |
perf(mobile): open Review with the Changes data already loaded (#39159)
* perf(mobile): open Review with the Changes data already loaded * fix(mobile): keep the open diff through re-keys and wait for Review rebuilds * fix(mobile): release Review writes once their files show, retry only fixed diffs * fix(mobile): follow language switches in Review's diff states * fix(mobile): keep Changes' compare key out of render and type the Review adapters |
||
|
|
22f09f4257 | refactor(mobile): read host capabilities from one status read per connection (#39157) | ||
|
|
9dacf1e6db |
fix(mobile): make dictation start reliably on a slow or sleeping desktop (#39142)
* fix(mobile): keep speech said while dictation starts and fail fast on a dead host * fix(mobile): let a tap or long-press end dictation while it starts * fix(mobile): wait for the host's cancel before the next dictation starts * fix(mobile): let a start wait out the previous start on the host too * refactor(mobile): track host dictation work per client, not per screen * test(mobile): read the start's dictation id without a cast * fix(mobile): finish instead of cancel when a held mic is released while starting |
||
|
|
bb5f37c916 |
feat(pairing): unscanned desktop pairing codes expire (QR 10 min, link 60 min) (#37957)
* feat(pairing): unscanned desktop pairing offers expire (QR 10 min, link 60 min) Headless serve/orcad mint offers without a TTL, so they never expire. Paired rows and rows without offerExpiresAt are unaffected. * feat(pairing): refresh the mobile QR before it expires and show runtime link expiry The QR re-mints a minute before expiry while visible; an unused runtime link shows its expiry and, once expired, is replaced by a notice. Web clients rejected while pairing now suggest asking for a new link. * feat(mobile): say a refused pairing code expired or was replaced A first pairing the desktop refuses (direct or Relay) now asks for a new code instead of showing the raw transport error. * refactor(pairing): replace type assertions in code-refusal detection and tests * test(mobile): re-record pairing race golden for refused-code error * fix(pairing): keep pairing codes valid across sleep and stale registry writers - QR refresh rechecks the wall clock every 15 s and on window focus, so a computer waking from sleep never keeps showing an expired code. - A registry save from a process with an older copy can no longer reset a paired row back to unscanned (which would let its offer expire). - The QR caption says how long a copied code works. * test(pairing): annotate the IPC handler stub cast |
||
|
|
489a6a66a4 |
perf(mobile): reopen Source Control's Changes list from memory instead of rescanning (#38988)
* perf(mobile): reopen Source Control's Changes list from memory instead of rescanning * fix(mobile): keep action errors through background status reads * fix(mobile): let only explicit status reads clear Source Control's action error * refactor(mobile): simplify the query layer and the Changes compare trigger * fix(mobile): follow language switches in Changes' empty states |
||
|
|
f6653a44d5 |
fix(mobile): keep the rename sheet open until the desktop accepts (#38934)
Terminal rename closed its sheet before sending terminal.rename, then ignored a refused reply and swallowed errors, so the typed name vanished with no message. The sheet now stays open with the name while the desktop answers, shows the refusal with Retry, and closes only after the desktop accepts, the same way the workspace rename sheet works. |
||
|
|
f9efd9fbaa |
fix(mobile): keep Tasks drafts across reconnects and item updates (#38935)
Reconnects no longer close the open item, project row, create sheet or workspace form, and draft resets key on item identity instead of the item object, so status edits and refreshes keep typed comments. The "+" button no longer clears the create title and body. |
||
|
|
c884428609 |
feat(mobile): copy, save and share an image from the full-screen image viewer (#38303)
* feat(mobile): copy, save and share an image from the chat image viewer * refactor(mobile): pass image viewer actions in so diagrams skip them * fix(mobile): name the image verb native.image.act and serialize image actions * fix(mobile): queue image actions per page and skip SVG links * refactor(mobile): share the cache-folder helper and table the viewer's image actions * fix(mobile): keep the toast's live region mounted so screen readers hear it * test(mobile): re-record agent history goldens for the always-mounted toast region * test(mobile): import the declared routes in the moved routes test |
||
|
|
dd1784f55b |
Keep partial check details from replacing complete PR status (#38514)
* Keep PR check status tied to complete observations * Correct checks presentation types and count import * Preserve localized empty states and declared runtime support * Correct discovery fixture stack types * Omit empty failed-check subtitles * Preserve check identity through refresh and row publication * Withhold row identity for malformed check errors * Limit local capability wakes to local task sources * Correct PR check regression fixtures * Preserve browser APIs in PR check regression fixture * Settle PR check adoption after failed detail reads * Use the parsed PR check detail type during refresh * Preserve PR metadata across checks discovery and committed query lifetimes * Keep complete checks proof separate from legacy publication policy * Keep PR lookup fixtures independent from complete checks collection * Keep complete-check fixtures within lint contracts * test: align PR recordings with source check discovery |
||
|
|
b8969c9c53 |
feat(mobile): split Home into Feed, Usage, Automations and Settings tabs (#38206)
* revert(mobile): drop the details card on session tab taps
Reverts
|
||
|
|
8a4dd3a7bb |
feat(mobile): improve mobile terminal input (#37900)
* feat(mobile): bring back the terminal key row and one live input Every terminal tab, shell or agent, gets the dock from before #36166: the scrolling key row (desktop width, Paste, the built-in keys, custom keys, add) above one live field that types straight into the terminal, with the attach and mic buttons beside it. The field keeps today's 3:1 outline and focus ring, and the keys use today's chips and press styles. The Keys/Message toggle, the Message composer, the arrow pad, the ⋯ sheet on the row and the per-terminal mode preference go. A stored mode from an older build is never read. Sticky ctrl/alt/shift and the More keys sheet stay only behind the iPhone Duo rail, which shipped shells still draw; the page reports no composer, so shipped shells grey their input-mode key and newer shells hide it. * refactor(mobile): delete the buffered terminal line With one live input there is no way to write a terminal line first and send it, so the per-terminal drafts and their storage, the Send path, command-field dictation, draft restoration and the terminal setting for autocomplete and autocorrect (which only applied to that line) go. Dictation in a terminal always types into it live. Drafts and the setting saved by older builds are never read. |
||
|
|
a9676ea6eb |
Distinguish cancelled PR checks from failures (#37789)
Show cancelled PR checks as Cancelled with separate counts on desktop and mobile, preserving genuine failures, pending checks, existing action permissions and older-client fallback. Carry complete provider summaries through caches and presentation; preserve Azure source completeness, folder attention priority and muted cancellation details. Tracked in #15847 and STA-5102. |
||
|
|
a56e6de883 |
Keep phone fork pull requests on their selected repository (#36762)
* Keep opened GitHub work items bound to their exact repository
* Bind GitHub work item ownership through consumers and dispatch
* Keep empty mention lists from consuming selection keys
* Preserve GitHub action and consumer ownership across resource changes
* Exercise repository account updates through their production store action
* Exercise account publication and cache settlement through GitHub consumers
* Simplify fork PR contract verification
* Make contract verification imports and clocks deterministic
* Correct mobile task test fixtures and model types
* Correct task recording fixtures and CI types
* Correct task fixture types and static checks
* Consolidate replay test RPC imports
* Separate GitHub metadata imports from Linear hooks
* Scope mobile PR sidebar reads to the selected resource
* Separate desktop GitHub changes from phone updates
* Preserve complete phone GitHub repository identity updates
* Fix relay authority probe census across topology cases
* Repair repository owner proof fixtures and compiler allocation
* Preserve repository row observation in host lookup
* Seed metadata fixture before server-side store acquisition
* Preserve nullable fixture settings and discover mixed test types
* Refetch phone reviewer list after a connection change
A disconnect or session change while the reviewer list loaded left the drawer showing an empty list until it was reopened. The drawer now shows its loading state while disconnected and fetches the same repository again once connected, still ignoring the cancelled load's result. Also merges a duplicate type import that failed mobile lint.
* Keep phone reviewer rows through connection changes
The reviewer picker now owns one query per open visit of a client, worktree and repository. A connection or session change retires the in-flight request at once but keeps the people already loaded; reconnecting refreshes them in the background. Without loaded people the drawer shows its spinner, or the existing connection explanation once an outage is revealed, and never a false empty list. Closing, retargeting or reopening starts a fresh visit that no earlier reply can paint. Also wraps the synchronous bridge teardown steps so the cleanup loop awaits only promises.
* Keep the viewed phone PR through connection changes
A relay/direct switch or reconnect selected a fresh, hidden PR observation in Source Control and Diff Review, so the next render unmounted the PR, closed the reviewer picker and erased an unsent comment. The PR observation is now scoped to the client, worktree and branch. One connection listener retires the in-flight reads when the connection changes and repeats the query the screen already asked for once connected, so accepted content stays mounted and refreshes in place. A failed background refresh keeps the accepted result. Task PR files likewise keep their loaded contents and expansion across a connection loss and read an interrupted file again on reconnect.
* Show a failed PR refresh over kept content; recover task files on every connection change
A failed refresh of an accepted PR (or no-PR) result now keeps the content and shows the existing "Failed to refresh pull request." line with Retry above it, whoever started the read, until the next good read. Task PR file reads are retired and re-read from the task selection's own connection listener, so a reconnect batched into one render or a connection switch at the same state also recovers an interrupted file. The reviewer-picker contract test leaves the React Native test program for now; its checked owner follows.
* Typecheck the phone/host contract tests through emitted declarations
The reviewer-picker contract test and the recorded request params test import real desktop sources, which do not typecheck under the phone's React Native libraries. Both source graphs now emit declarations under their own compiler settings, and a strict Node program checks the two test bodies against them; Vitest still runs them against the original sources through path aliases. The tests typecheck ratchet runs this program and fails unless both bodies are in it and it passes, the CI test runner checks that Bun ran and passed both, and the Mobile workflow finishes compiler work before starting tests. The six other excluded tests stay runtime-only and are labelled that way.
* Name the types phone declaration emission needs
Declaration emission for the phone/host contract program could not name the i18n instance's type or the buffered terminal draft send type; annotate the one and export the other. Also types the drawer mock's children in the Source Control scenario so the React Native test program checks it.
* Stub every icon in the Source Control scenario
Source Control modules read icons at import time, so the scenario's fixed icon list failed to load the file under Bun.
* Give the recorded params check's stand-in method a permission
The recorded request params test is now typechecked and its stand-in method lacked the permission every RPC method declares; parsing never reads it.
* Use the real composer styles in the Source Control scenario
Source Control's list styles read composer style constants at import time, so stubbing that module failed the file under Bun.
* Mock the PR sidebar hooks without loading their native modules
Only the PR sidebar reads these hooks, so the Source Control scenario's mocks need not load the real modules, whose imports reach Expo native code that does not run under Vitest.
* Count recording-internal observations apart from recorded ordinals
The scripted transport runs the real request tracker, and its connection wait, id allocation, completion, late-reply and terminal observations each took the shared write ordinal that requests, frames and effects record. Every recording's ordinals shifted although the same frames went out in the same order. Those observations now use their own counter, keeping their association with the native request, so recorded ordinals match the existing recordings again.
* Record a cleanup checkpoint only when teardown adds effects
Comparing the whole snapshot before and after teardown added a cleanup checkpoint whenever a pending request settled at dispose, which changed about 166 recordings without new evidence. Restore the condition the recordings were made with: teardown effects alone add the checkpoint.
* Run the bridged recording corpus on Node
Its goldens hold V8's TypeError wording, which the Bun pass reports differently, so ten exact error comparisons failed only on engine text. It now runs with family-recordings on Node; the comparison stays exact.
* Bind the probe test's fresh status.get by its actual child
* Edit the GitLab status scenario's GitHub issue only after opening it
* Type the Source Control scenario's composer adapters with the real component props
* Mock the Source Control scenario's icons and protocol gates without loading the real modules
* Give the PR sidebar probe test the shared typed fake client
* Select the GitLab status scenario's GitHub issue as a typed task item
* Declare the buffered terminal draft send as an exported type
* Run the Source Control scenario's focus effect only when its callback changes, as the router does
The router mock ran the loaders' focus effect after every commit, so each status read re-rendered and re-ran it. Also mock AppState for the comments section and stop act from awaiting held PR reloads.
* Re-record the GitHub and Tasks goldens for the selected-repository requests
Re-recorded with pnpm --dir mobile rpc:record for the 71 scenario IDs: 66 changed and 5 added for the exact-target status.get probe, 0 removed. The goldens now carry the selected repository on GitHub requests, the exact-target probe before GitHub operations, the skipped hidden metadata loads and the new item-detail failure copy.
* Declare the probed GitHub operations' params in the order the app sends them
The bridge probe test compares the forwarded frame byte for byte with the declared params, so tk-item-detail-github, tk-item-status-gitlab and tk-project-row-files-merge now declare the exact key order their goldens record. Values are unchanged, and completion matching ignores key order.
* Close the native connection before the page in recordings, and make late replies and inherited timers explicit
Recording teardown now closes the native client, flushes its rejection through the bridge, then closes the page, so page callers see the relayed native close. Sibling rejections name the stable logical site in every mode. Replies scripted after a timeout or disconnect are explicit late replies that must resolve nothing. Four product timers inherited from main are declared by producer, scenario, owner and delay and still reported; every other run keeps zero residual timers. The bridge probe oracle for tk-item-status-gitlab expects the published deadline failure and the exact retained issue.
* Judge unchanged bridged recordings as main does and changed ones by their own outcomes
Unchanged producers follow main's order again: identical earns identical, History keeps its strict path, and other divergences take a legacy label from the reply-meta counterfactual's typed evidence. A bounded guard pins zero unclassified, small-class membership and the branch-base tally less each named moved or removed producer; eight moved producers without a base pin are named as old-class-pending until their baseline replay. The re-recorded producers are judged directly in both page modes against their reviewed goldens, with only the page's refusal of the injected absent result applied, or by their exact strict own-undefined stop, and are pinned as bridge contracts. Bridge-only preludes are observed after their action, and the pending invocation's relayed native close is read from its own page promise. Every producer must be routed exactly once.
* Say what to do when the GitHub server check fails, and share one deadline with the action
The exact-target check runs before a GitHub action is sent, so a timeout or lost connection now shows the existing 'The Orca server connection changed. Try again.' and a refused or unreadable answer shows the existing 'Update Orca on the executing server' message, instead of raw text naming status.get. The check's own connection-changed error passes through. On native, the checks and the action share one 30-second budget, so a dead server fails in 30 seconds instead of 60.
* Pass the scenario manifest to the changed-producer comparison
* Correct the bridged corpus repairs from their first full run
The re-recorded producers no longer stop on the strict own-undefined matcher and all replay in bridge mode, so they are all judged directly; the page's refusal of the GitHub server check now expects the connection-changed copy. Unchanged legacy labels read their first difference from the replay without injected metadata. The sibling timeout and each interruption, including the cutover, end the requests the goldens record as ended, so those replies are explicit late replies. New producers in pinned families get their bridge-contract pins, and an unexpected timer or changed outcome now names its scenario and values.
* Restore six unchanged scenarios to their single own-undefined steps
tw-smart-search-all-providers, tw-smart-search-linear-listed, tk-list-gitlab-items, review-mark-reviewed-persists, review-mark-reviewed-rolls-back and session-create-terminal-without-active-tab had their own-undefined steps split into native and bridge copies, so the page replay no longer reached the strict own-undefined stop and these unchanged producers left their baseline labels. Their steps are the branch-base steps again; native recordings are unchanged.
* Fill the eight moved producers' base classes from the admitted baseline replay
pr-read-surface was identical and the seven github.pr-read matrices were result-absent-settlement at the branch base, so the unchanged tally is exact again with no pending members.
* Deliver the sibling disconnect's trailing replies as late replies too
A disconnect rejects preflight.check, linear.status and jira.status before the suffix replays their replies, exactly as the sibling timeout does, so those declared replies are late in both variants; the cutover stays strict.
* Expect the page's refusal in the two Linear producers' result-absent checkpoints
Natively the injected { ok: true } reads as an empty result, so the Linear detail and status update finish; the page refuses that frame and the screen shows the refusal instead. Each producer now has one finite expectation for that checkpoint, guarded on the reviewed golden's final effects, and everything else must still equal the golden.
* Share one deadline between the shell's server check and the GitHub action
The shell gave the exact-target check and the forwarded action each the page's full timeout unless the page asked otherwise, so a dead server took twice as long to fail on the hosted page as on native. The two legs now always share the page's one deadline; the forwarded options are unchanged.
* Deliver the sibling client cutover's trailing replies as late replies too
* Build the changed producers' page expectations from one finite table before comparing
* Re-record the three exact-target check goldens for the mapped copy
The GitHub check now shows the update-server or connection-changed copy instead of raw reply text; the item detail's empty-message cases now also record their detailError effect. Recorded on the admitted run (check-3949 Job 1).
* Declare the traced inherited timers per inner scenario and recording mode
Each declaration now names the modes where its inner scenario leaves the timer. Adds the inner scenarios traced in check-3949/qa-report-trace.md Job 2, with the ruled delays and owner chains: the reveal's 300 ms first-poll timer for all ten reply partitions of tabs.list-1 and tabs.activate-1 in both modes, and the pr-triage 20,000 ms reconnect waiter for transport-rejection and transport-rejection-no-message in both modes and result-absent through the page only. Exact counts, owners and delays stay enforced.
* Expect the compiler wait before Mobile verify's tests and only the fastlane tools after
* Call recorded timer callbacks through a typed signature
* Show the reviewer picker's no-rows wait with the screen header's connection verdict
The drawer classified only its client's state and counters, so during relay recovery it flipped between Disconnected and Connecting on every dial and never showed relay or pairing verdicts. The source control and diff review screens now pass the host's own verdict inputs (reconnect attempts, last connect, relay recovery status), re-read on host state and path changes, so the drawer shows the same steady verdict as the header.
* Say a timed-out GitHub target check timed out, on native and in the shell
A server check that ran out its own deadline on a connection that never changed now reads "Timed out confirming the executing Orca server.", as the shell's budget already did, and the native shared budget running out uses the same copy. A lost or changed connection still reads "The Orca server connection changed. Try again."
* Name the paired desktop when it is the build missing the exact-target check
When the phone's paired desktop relays to an updated executing server but lacks the exact-target capability itself, the edit now says "Update Orca desktop" instead of pointing at the executing server. An old executing server still gets the executing-server copy.
* Preserve GitHub detail argument types and optional capabilities
* Say what updating the paired desktop enables, as the executing-server copy does
* Drop the tab-reveal timer declarations now that main removed the reveal operation
* Let keyed details queries own pending read replacement
* Repair GitHub RPC and relay test fixture boundaries
* Own the new PR tab's caches, sheets, confirmations and polls by the complete PR
Fork #N and upstream #N were one owner to the tab: check details, open sheets and confirmations keyed by worktree and number survived a repository change, so a fork draft or decision could act on upstream and fork check data could show for upstream. Each is now owned by the PR incarnation (client, worktree, branch and full resource key), selected during render, so a departure closes old requests without retargeting them, A -> B -> A starts fresh, an outgoing sheet renders nothing and sends nothing, a late save closes only its own request, and a departed PR's poll neither blocks nor re-arms its successor.
* Load the reviewers sheet's people through the selected repository's resource-owned query
The new sheet read people once on the first search with no repository, connection recovery or retry, so a fork PR listed the wrong repository and a search while reconnecting stuck on an error. The first search of an open sheet now demands the selected repository's list through the exact-target helper; the query reads only while connected, retires its attempt on every real state or generation change, recovers on reconnect, keeps accepted rows and search through refreshes, and shows the header's own calm connection verdict while it has no candidates. Closing or a PR departure ends the visit; reopening starts fresh.
* Mark a failed PR discovery from every caller, polls included, and keep a poll's checks-only failure quiet
Main's poller made a failed background discovery silent, narrowing the ruled all-caller contract. Any current failed discovery over an accepted PR or no-PR result now keeps it and shows the one refresh-failed row with Retry, and the poll still backs off on 'failed'. A poll whose discovery succeeded but whose checks read failed for the same complete PR lands its discovery (clearing an older warning) and keeps the prior checks, reporting 'failed' once; equal numbers in another repository no longer count as the same PR. A viewed-file update from a departed observation changes nothing.
* Send the phone's addressed details reads with the server's read intent where it is advertised
github.workItemDetails accepts optional canonical:false (ordinary) / true (Refresh), advertised by github.exact-details-read-intent.v1; missing intent means ordinary. The phone's addressed details reads (PR tab and Tasks) now pass that intent through the existing exact-target preparation: a host advertising it gets canonical:false for ordinary loads, recovery and polls and canonical:true for the user's explicit Refresh; a canonical-only host gets ordinary reads without the owner and Refresh with the owner only; hosts with neither keep today's params, and an explicit Refresh there is refused as unsupported. Refresh intent travels only with the Refresh command, never as reconnect demand. The poll's checks-only settling moves into pr-sidebar-load-result to keep the controller within its size limit.
* Keep today's details params for a host with neither read-intent capability, Refresh included
* Drive the reviewer target contract through the new tab's reviewers sheet, first search included
* Cover a poll's discovery warning, its clearing, and a same-PR checks-only poll failure in the controller
* Prove the Source Control PR tab's demand, retained sheet and draft, failure line and fork/upstream request ownership on the new navigation
* Cover the details read intent the phone sends to explicit-intent, canonical-only and older hosts
* Fix the round's test typecheck and assertion findings: awaited controller loads, the diff review props, typed doubles
* Send Refresh's owner to a canonical-only server outside the exact-target check, as the desktop does
* Restore the base's mobile change-scope test, which the base merge dropped by mistake
* Prove the PR poller keeps each fork/upstream incarnation's poll, backoff and cadence its own
* Verify expected GitHub account at repository execution capture
* Give the Linear detail recording adapter the detail Refresh request its loader reads
* Keep the detail Refresh request ref out of the recorded owner projection, like the other ref
* Count cancelled GitHub probes against the desktop request cap main introduced
* Keep the comment tree out of the diff review controller test, as its drawers already are
* Restore the Source Control action icons the scenario rewrite dropped from its icon mock
* Supply the settled-list setter main added to the Tasks list fixture
* Preserve captured GitHub account expectations through client dispatch
* Re-record the Linear team-context goldens for this PR's actionItem owner effect
* Retain observed runtime status after switching environments
* Fix account contract fixture types and RPC setup timing
* Restore the negative-capability switch probe assertion
* Align account fixtures with runtime identity and configured origin
* Consolidate details test imports
* Type the reviewer test's search stand-in locally so native declarations stay out of its Node-checked program
* Add the PR tab Retry label's English entry the localization check requires
* Restore the PR tab Retry label's translations in the other mobile locales
* Pass the phone write reread through the reviewer contract.
The sheet fixture omitted the required reread, so the phone typecheck failed. Desktop settlement tests that main already removed were still on this branch and pulled telemetry into the web typecheck.
* Declare the phone pull request refresh failure.
The sidebar already shows this sentence when a refresh fails. The English catalog omitted it, and the boot bundle still carried two strings no startup call needs.
* Let the phone sidebar tests subscribe to connection state.
The sidebar records the client's connection before it loads a pull request. These tests drive that through the screen's connection prop, so the stand-in client only has to accept the subscription.
* Justify the phone sidebar test client.
The changed-code check rejects a new cast unless the line says why it is sound. These tests still only subscribe and read connection state.
* Name the repository on the phone sidebar details fixture.
A same-numbered pull request in another repository is not this one. The loaded body has to name the repository the test selected.
* Keep phone review-thread feedback on its accepted detail revision
* Capture phone review actions from the current render
* Align phone recording fixtures with the integrated detail loader
* Keep provider-switch detail fixtures addressed to the selected item
* Preserve same-turn bridge refusal evidence across client call shapes
* Publish phone detail revisions through one synchronous owner
* Type the queued publication regression with its provider contract
* Conform phone regression and relay types to static analysis
* Trim duplicate phone RPC tests and focus recorded observations
|
||
|
|
14819eb8c0 |
fix(chat): isolate sends from terminal drafts (#37774)
* fix(chat): isolate sends from terminal drafts * test(chat): expect replacement clear for resume commands * test(chat): refresh draft-clear RPC recordings |
||
|
|
a036446311 |
fix(terminal): pipeline ordered mobile input (#37738)
* fix(terminal): pipeline ordered mobile input Keep unary delivery for desktop relays while the existing host ledger orders complete sends under a capability-gated, bounded input session. * fix(terminal): charge retained raw input controls The dispatcher retains original control values while strict sends wait. Reserve their bytes before normalizing execution controls. * test(terminal): align input fixtures and paste recordings |
||
|
|
a2498a0411 | fix(mobile): preserve host terminal-create error in toast (#37677) | ||
|
|
8084c3ab7e |
fix(hooks): keep the approved script hash when Always trust is ticked (#37520)
A repo id on two hosts makes canUseRepoWideTrust refuse the repo-wide entry, and ticking Always trust saved nothing else, so the prompt came back on every create. Save the shown script's hash too, on desktop and mobile. A changed script still prompts on such repos. Fixes #37484 |
||
|
|
f7047a8fc7 |
feat(mobile): redesigned Changes tab with file-first rows and swipe to discard (#37214)
Rows lead with the file name and put its folder under it, so names stop truncating. The whole row opens the diff, one quiet button stages or unstages, and discard moves to a left swipe that still asks first. A status line, a Commits row and a conflict banner with Abort sit above Uncommitted and Staged sections that carry Stage all and Unstage all. The rarer git actions move into the header's grouped menu. |
||
|
|
5228bff55c | refactor(mobile): group web bundle transfer owners (#37124) | ||
|
|
a3efdcb21b |
feat(mobile): GitHub review threads, viewed sync and line comments on the diff screen (#37073)
* feat(mobile): GitHub threads, viewed sync and line comments on the diff screen Committed files of a GitHub pull request now show its review threads under their lines with Reply and Resolve, take their viewed state from GitHub and sync the checkbox and Viewed · next file back through setPRFileViewed. A tap or a long-press drag picks lines and opens a sheet that sends the note to the workspace's agent through the existing send path, or posts it as a review comment. Threads and GitHub comments appear only while the local branch is at the PR head, the same contents desktop shows them on; otherwise the file says to push. openDiffForFile takes an optional line for a thread's Open in diff. * test(mobile): use a type import for the line-mutations recording adapter * fix(mobile): name the staged or unstaged side in the jump sheet's file labels |
||
|
|
24e7a0ba69 |
feat(mobile): list only this branch's commits, with a page per commit (#37050)
The Commits list now stops where the branch left its base. It groups commits into Not pushed (hollow dots, with Push) and On origin, ends at "Branched from <base>" with Update branch, and loads more past 50. A commit opens its own page: message, author, date, pushed state, files with +/-, and Copy SHA / Open on GitHub in the menu. Older hosts ignore the new params, so the list falls back to the full history without groups or the base marker. |
||
|
|
3edc370cdf |
feat(mobile): diff screen with jump to file, folded context and viewed/stage next (#36998)
The review screen becomes the one diff screen from the approved design.
It walks the Changes section the file came from (uncommitted, staged or on
the branch) or one commit's files, so 'N of M' and next/previous stay in
that list. The title opens a jump-to-file sheet built on the shared
source-control tree, with search and viewed boxes. Unchanged runs fold the
way desktop's diff does. The bar's main button is Stage · next file for
uncommitted files and Viewed · next file otherwise; Discard and Unstage move
to the menu. Filter chips, hunk jumps and Stage Reviewed are gone.
openDiffForFile also takes { kind: 'commit', commitOid, filePath }, read
through git.commitCompare and git.commitDiff.
|
||
|
|
2e1f439620 |
feat(mobile): open every changed file on the diff screen (#36937)
Source Control rows used to open a file three ways: the review screen, a desktop editor tab the session then switched to, or a text-only branch drawer. Every row now calls one openDiffForFile entry point that pushes the review screen. The drawer, the session tab reveal and their handlers are gone; Open in Session stays in the review screen's menu. |
||
|
|
1ad332d8a9 | refactor(mobile): organize native chat view and transcript owners (#37054) | ||
|
|
c883603c75 |
fix(mobile): run the repo's archive hook when deleting a workspace from the phone (#36481)
* fix(mobile): run the repo's archive hook when deleting a workspace from the phone
Mobile's delete sent worktree.rm without runHooks, so the host skipped the
orca.yaml archive hook that desktop runs. The phone now does what desktop's
ensureHooksConfirmed('archive') does: it asks to trust an unapproved shared
archive script, sends runHooks with desktop's reply timeout, and when the hook
fails it shows the host's error with Delete Anyway, which resends with
allowFailedArchiveHook.
repo.hooks now reports archiveTrust (hash and content of the shared orca.yaml
archive script, or null when none needs trust). Older hosts omit it, and the
phone then keeps skipping the hook rather than run a script it cannot check.
* fix(mobile): share one Modal for delete drawers and pin each prompt to its host
Delete's confirm, archive trust prompt and hook failure now share one
BottomDrawerModalHost so iOS never presents over a closing drawer. A pending
prompt or failure keeps the clients it started on, the row hides as soon as
Delete is tapped, repo-wide trust counts server-owned repos, and folder repos
report no archive trust since their removal runs no hook.
* fix(mobile): recheck archive trust before Delete Anyway and count server repos once
Delete Anyway goes back through the trust decision, so a script changed since
approval is asked about again. Repo-wide trust counts each server repo once
rather than once per workspace, and restoring a row never duplicates it.
* fix(mobile): honour repo-wide archive trust only with the desktop catalog loaded
Until the catalog loads, a same-id repo on another host cannot be ruled out,
so only an approval of that exact script counts. The trust drawer's actions
take the pending request synchronously so a double tap cannot both run and
skip the hook.
* fix(mobile): drop archive prompts and failures from another desktop
A trust prompt or hook failure belongs to the desktop it started on. After a
host switch it is no longer shown or acted on, so a retry can never pair one
desktop's trust with another desktop's repo catalog.
* refactor(mobile): one archive trust check and an optional drawer busy flag
* fix(mobile): file delete-failure strings under the host screen overlays
Also pins the host's archive hash as a literal digest so the node test no
longer imports renderer code.
* fix(mobile): carry delete haptics and automations onto the renamed hook trust drawer
|
||
|
|
c0190ff9fa |
perf(mobile): lighter liveness probes, preview-free terminal lists, cheaper terminal gzip (#36903)
The phone's liveness probe read a full status.get (~12 KB, ~2.3 KB gzipped)
and threw it away on every idle and foreground probe. It now sends
`status.get {probe: true}` and the desktop answers `{runtimeId}` alone,
skipping the machine-name wait. status.get keeps accepting any params, as
when it declared none; older desktops ignore the flag and answer the full
status, which still proves liveness.
terminal.list takes `includePreview: false`. The phone's session inventory
and automation pane lookup never read the 300-char output tail, so they ask
the desktop to drop it; older desktops strip the unknown key and keep
sending it.
Compressed terminal binary frames now use gzip level 1. On recorded-style
terminal output it keeps 93-99% of the level-6 saving (57-95% of bytes
saved) at 1.2-4x less main-thread CPU; text replies keep the default level,
where level 1 costs ~45% more bytes on the wire.
|
||
|
|
64021b0f47 |
fix(mobile): guard catalog snapshots against late replies and trim the snapshot paths (#36902)
* fix(mobile): guard catalog snapshots against late replies and trim the snapshot paths A slow unchanged or delta reply that predates a client switch (A→B→A) could re-point the paired-server snapshot token at rows it no longer matched; the next row delta then rebuilt onto the wrong base. Pending reads now carry the token they asked with, and admit drops any non-full reply whose token is no longer held. Single-flight reads with one trailing join move into WorktreeCatalogSnapshotClient.read(), so paired-server rows get the same protection home had; home's own copy goes away. Server rows use one read path for old and new desktops and drop snapshots for servers that leave. The host screen asks for a first page only while nothing is shown and the full read is not failing, and drops it on an invalid reply. The shell no longer seeds the page with a status proven on a connection that has since dropped. Cleanup: drop exactActivity (unreleased; home only ranks by coarsened activity and its exact rows defeated delta reuse), fold the legacy opt-in check into the snapshot resolvers, remove unused worktree.ps result types and a duplicate page subscription, and re-record the affected RPC goldens. * fix(mobile): keep server-row snapshots per client and skip first pages for loaded empty hosts A shared per-host snapshot let a slow read on a replaced client reclaim ownership from the new one, discarding the new client's reply. Snapshots are now kept per client, and a delta rebuild retry runs only for the current owner. An empty host that already loaded no longer asks for a first page on every poll. |
||
|
|
56eb859595 |
perf(mobile): answer the host screen's repo poll unchanged when repos stay the same (#36860)
The host screen re-read repo.list every minute and on every repo or SSH event. Each reply carried every repo's uploaded icon inline as a data URL (up to 400 KB each, barely compressible), although repos rarely change. repo.list now takes an optional afterSnapshotId and answers unchanged when the caller already holds the exact reply. The id is content-derived (the hashing moves to content-snapshot-id.ts, shared with worktree.ps). The phone keeps the last catalog per client, reuses it on unchanged replies and still refreshes SSH host labels and health. repo.list declared no params, so older hosts ignore the field and answer the full catalog as before; callers that send nothing get the byte-exact legacy reply. Icons still render from the same data, at the same size. |
||
|
|
8dde752dc7 |
feat(mobile): put Settings, Source Control and remaining lists on the shared rows and bar (#36719)
The eight native Settings screens use the shared NavBar and grouped rows, Source Control's tabs move into the bar's segmented control, and Accounts, Troubleshoot, the custom key editor, the Tasks pickers and drawers and the workspace details sheet drop their hand-rolled rows for ListRow. |
||
|
|
563ada1343 |
feat(mobile): polish press feedback, sheet motion, states, spacing and layout jumps (#36713)
* feat(mobile): polish press feedback, sheet motion, states, spacing and layout jumps Every control presses and disables the same way, with one haptic rule. Sheets follow the finger and settle without bounce, pickers stack instead of swapping, and screens slide over a dimmed, shifted parent. Loading, empty, error and offline states share one view with plain-language errors, rows and labels line up on one grid, and screens stop jumping as data arrives. * fix(mobile): settle voice, tasks and accounts states; keep host snapshot current Voice settings with no paired desktop shows the connect state instead of loading forever. A failed task settings read after a successful probe retries hydration. The shared host-list snapshot drops on invalidation and ignores stale passes. Accounts shows a re-pair state on auth failure, and busy action-sheet rows keep their disabled state for screen readers. |
||
|
|
5c3938ce76 |
perf(mobile): read home worktree counts through catalog deltas (#36800)
Home re-read the full worktree catalog for every connected host on each focus, reconnect and change event just to show counts and a resume row. It now keeps a snapshot per host and client, so repeat reads are unchanged replies or row deltas. One read runs per host at a time, and a refresh asked mid-read joins a single trailing read, so concurrent reads cannot discard each other's delta and no refresh settles with older rows. Home ranks and shows exact activity, so it asks for it: worktree.ps takes exactActivity to skip poll coarsening, and acceptRowDelta alone now opts a first read into snapshots. Home's first read sends no snapshot id, so a host without row deltas answers its exact legacy catalog and every later read stays legacy; home's data is unchanged on every host version. |
||
|
|
f193548367 |
perf(mobile): send worktree catalog polls as row deltas (#36799)
A working agent's heartbeat changes the catalog snapshot id on nearly every 3 s poll, so the host screen re-downloaded the whole catalog each time (1.5 MB for ~1000 workspaces, ~26 MB/min on a real desktop). Callers that hold the base snapshot now opt in with acceptRowDelta and receive only the changed rows; unchanged rows arrive as indexes into the base catalog. The host keeps only row hashes for the 16 most recent snapshots, so an evicted base falls back to the full catalog. Older hosts ignore the parameter and older phones never send it. |
||
|
|
6071220177 |
refactor(mobile): colocate native chat readability hook and tests (#36699)
* refactor(mobile): colocate native chat readability hook and tests * refactor(mobile): use concrete readability module type in recorder |
||
|
|
d618a85ffd |
feat(mobile): redesign sheets, pickers and list screens (#36585)
Sheets slide on iOS's curve over their own height, ease when their content changes, and paint a lighter surface with grouped rows and a drawn switch. Create worktree, the model picker, the GitHub issue sheet, file preview, Agent Session History and the task list take the redesign draft's layouts at the app's smaller type sizes. |
||
|
|
97582248e7 | feat(mobile): rebuild Home around what needs you, with actions pinned at the bottom (#36520) | ||
|
|
5e6c0494b3 |
feat(mobile): compact top bar, bottom search and filter chips (#36535)
* feat(mobile): compact top bar, bottom search and filter chips Every list screen gets one compact bar (back, centred title, at most two buttons, the rest in a ⋯ pull-down), with search moved to a wide bar at the bottom and filters as chips. The workspaces page shows the host name at the top of the list and folds it into the bar as you scroll. * test(mobile): pass the Tasks bar's accessory in the host subtitle test * fix(mobile): stretch filter chips to fill the row; follow moved header controls in render checks |
||
|
|
f06399f5fc |
Keep refreshed Linear Tasks rows current (#34591)
* Keep Linear refresh results authoritative in Tasks * Preserve scoped Linear edits through read settlement * Complete Linear consumer entry and source teardown * Fix scoped Linear read lifecycle and external refresh * Complete Linear terminal reads and causal refresh dispatch * Cover cached Linear read reconciliation under pending writes * Fix cold Linear lookup invalidation * Make Linear regression fixtures deterministic * Align Linear test fixture naming with lint policy * Consolidate Linear test imports * Keep Linear saved publications coherent through React replay * Preserve confirmed Linear accounts through unavailable checks * fix(linear): retire recovered credential errors on acknowledgement * fix(linear): keep runtime cache reset on account acknowledgement * Fix Linear CI fixtures after final main integration * Correct Linear mobile fixtures and scoped lint annotations * Keep the mobile fixture assertion annotation on its expression * Fix Linear static contracts and integration test boundaries * Complete audited Linear static gates and preserve no-op selection * Separate Linear selection decisions from observations and preserve create completion * Name exported Linear fixture mock types with public annotations * Preserve exact submitted drafts through create settlement * Read draft retention mode from its committed snapshot * Publish the current closing draft after queued form replay * Type Linear create attempts from their form owner * fix: supply complete task creation test fixtures * fix: complete checked Linear creation metadata fixtures * test: complete Linear dialog fixture composition * test: use host-qualified workspace keys for board sync fixture |
||
|
|
a1f7f97671 |
Orchestration v3: coordinators end their turn and Orca wakes them (#36137)
* fix(orchestration): keep a terminal's mail from being consumed by another terminal, and let settled structured workers take further tasks A plain orchestration check consumed the named terminal's mail whatever terminal ran it, so a coordinator checking a worker's handle took the worker's message. A consuming check from a terminal whose own live pane is a different terminal's is now refused; --peek and --all still read it without consuming. worker-start --terminal and dispatch --inject routed a structured worker (structworker_ handle) as a terminal and failed with terminal_unsupported_for_agent_session. Any agent-session party now takes its task as a send into its session, while a structured worker keeps the pane and process authority its first Dispatch had. * fix(orchestration): fence check by live terminal incl. acks; defer injecting structured workers Review fixes for the mail fence and structured worker reuse: - The check fence compares the caller's and the mailbox's live terminal process instead of recorded panes, so exited terminals keep the old behaviour and two processes sharing a recorded pane are told apart. It also covers --ack in every read mode. The caller lookup is shared with the lifecycle caller fence. - dispatch --inject to a structured worker stays refused as before: an injected Dispatch takes no custody, so releasing the first Dispatch could close a session working on the second. worker-start --terminal reuse transfers custody and stays supported. - worker-start decides pane-less chat authority from the resolved party and passes the session down, so delivery and next commands no longer re-derive it from the address spelling. - Receipts name an agent session, not a chat. * fix(orchestration): an exited caller's env pane names no caller The caller lookup fell back to the env pane key whenever the env handle was not live, so an exited terminal's pane resolved to whatever terminal now occupies it, and a tmux worker's own check was refused. The pane fallback now applies only when the env handle is not proven exited. * fix(terminal): keep surviving terminals streaming to main after a restart Main now attaches every live local daemon session it adopts at startup, not only ones a window pane or remote view is showing, and re-attaches after a daemon endpoint drop. The attach snapshot seeds main's screen, tail and title, and an attached-but-silent agent gets an output clock so readiness can see it has gone quiet. Waits on a survivor main could not attach fail at once instead of timing out. * fix(terminal): restore only pane-less streams after endpoint loss; one attach state - Endpoint loss re-attaches in main only sessions no renderer view reports; a pane restores its own. - The attach hide skips views mid-attach and leaves a pane's own hidden claim alone on failure. - One per-session stream state (attaching, attached, lost) replaces three sets and is forgotten on exit. - Waits retry the attach before failing, including after a failed re-attach. - The output clock starts wherever a reattach result is seeded, so pane reattaches get it too. * refactor(terminal): attach survivors at inventory adoption only; waits on unattached survivors fail at once; one ptyId output clock * test(e2e): scope the restart attach spec's terminal listing to the unopened workspace * fix(terminal): narrow survivor attach: waits behave as on main, one quiet clock per generation, keep main's hidden mark on failed attach * Teach the orchestration guide when to hand off and to end the turn after dispatch * Rewrap a messaging reference line * Keep the original placement default and skill trigger; keep the accuracy fixes * Point DAG retries at --retry-of and drop the last blocking-wait instruction * Check the served orchestration guide by its new worker heading * Apply council review: best-effort wake, full completion rule, restored safety rules, fixed scope and settled wording * Say when the orchestration skill applies, and prefer own subagents otherwise * Name the polling, steering, checkout, and worker fan-out habits to avoid * fix(orchestration): wake a coordinator whose turn ended while its program still reports working Claude Code keeps its OSC 7501 report on working while an agent-teams teammate is alive, even after the lead's own turn ends. The mailbox gate, idle edges and tui-idle all read that report, so worker mail was stored and never typed. A hook turn end newer than the program's working report now counts as rest; hook rows re-classify the PTY so the existing idle edge delivers. Agent Teams panes now join their claude hook rows. * fix(orchestration): compare the lead's own turn end, not the row's receipt A child's hook restamps the row's receivedAt while the lead's turn is still the old one, which could mark rest under a newer program working report. Use the lead's turn-end stamp on this runtime's clock, after the latest input. * feat(orchestration): a consuming check marks the batch it returns as handled * Say why watch scripts and open waits block the wake * feat(orchestration): release settled workers automatically after a grace period * fix(orchestration): use checked row reads for delivery cursors * fix(orchestration): trust a live own-process turn end instead of comparing clocks Drop programActivitySince and the turn-end clock mapping: replays and SSH host clocks made the comparison unreliable. A Claude lead counts as at rest under a program working report when its hook turn end is a live transition from this pane's host and launch, past the existing input and respawn floors. * test(orchestration): drop cast in ack no-op check * test(orchestration): seed legacy outstanding batch for held chat nudges * test(orchestration): built CLI check hands its batch over * test(orchestration): annotate unchanged casts and stub the keep item in tab menu tests * fix(orchestration): let real input, explicit release and host releases converge with automatic release - Record worker takeover at the owning runtime when it accepts UI input, before the bytes reach the PTY. - Run remote attachment releases through the same per-resource single-flight as local ones. - Apply the confirmed-release home projection when host observation reports a host-side release, and carry the host deadline in fleet snapshots. - Prove restart recovery with a file-backed database reopened by a fresh runtime. * test(orchestration): classify the keep RPC's worker fields instead of counting methods * fix(orchestration): checked delivery reads and observer and recovery help * refactor(orchestration): end a check when it hands over a batch; wake rides the wait result * fix(orchestration): refuse an automatic close after real input, join remote releases, converge the home - An automatic close checks the terminal's last driving-input time right before closing and keeps a worker someone typed into after worker_done; typing itself does no orchestration database work. - Remote releases share the per-resource single-flight with local release, so a home worker-release joins the host timer's close. - Host fleet snapshots and federationShow report released and the pending deadline; the home applies the existing release projection inside its observation fence. - Real restart tests: a file-backed database reopened by a fresh runtime releases a missed deadline once and finishes interrupted requests. * fix(orchestration): receipt a shared wake batch on arrival and report the applied Run ack * fix(orchestration): deliver the wake to a working coordinator; agents queue mid-turn input The wake was typed only into a live idle pane, so a Claude lead whose program status stayed working (teammate alive) never got it. Agents queue or steer text typed mid-turn, so a pane takes mail when live idle or working; dialogs, permission prompts, exited agents, unsettled panes and cold-parked Enter still hold it. Drops the held-batch Enter deferral and the per-turn-end hook logic. * fix(orchestration): record each remote release request before joining, publish archives only through the conditional commit - Each remote release caller records its own request before joining a close under way, and the close decides on the current row, so an explicit release that overlaps the host timer clears the automatic deadline. - Remote capture publishes its archive through commitWorkerTerminalArchiveForRelease, so a retain during capture leaves no stale archive for worker-read. - Remote worker-show projects the fenced host deadline and its next action. - The input guard lives in its own module instead of the scheduler. * feat(orchestration): start a worker in one step; worker-start creates the coordinator's Run when none is bound worker-start --spec now creates and binds a Run for a root coordinator with no bound Run, through the same path run-create uses, and names the Run it created or joined in every receipt. Workers on a Dispatch keep starting helpers in their own Run and never get a new one. A new CLI against an older runtime runs run-create and retries; old CLIs need no change. * fix(orchestration): drop the older-runtime fallback; check the spec before a Run is created The CLI fallback matched a refusal text the client decorates, could not prove the caller was a root coordinator on an older runtime, and recovered an inner run-create under the worker-start command. Older runtimes keep their refusal and the guide says to run-create first there. The prompt budget check now runs before worker-start can create a Run. * Route report-back requests to coordinators, complete the steer command, and label the wake loop branches * Say workers are done only when worker_done confirms, wait for helpers to settle, and let bare-shell workers exit * Route report-back requests away from handoff and steer supervised workers through their mailbox * docs(orchestration): teach auto-handled check, retry-request and inbox recovery in the guides * Describe the mid-turn wake in the messaging reference * docs(orchestration): say terminal workers are released 2 minutes after worker_done - The guide's Completion section, the reuse recipe and the recovery reference now describe the automatic release and its autoReleaseAt deadline: reuse or worker-retain before it; explicit worker-release still works and is required for chat workers and workers without a deadline. - The worker preamble says the terminal stays available until Orca releases it, about 2 minutes after worker_done unless retained. - Regenerated the bundled guides. * feat(orchestration): receipts say when to end the turn * feat(orchestration): tell the coordinator when a worker stops without worker_done * test+docs: worker stop reports * fix(orchestration): judge the empty-check stop with execution-host verdicts * test: drop casts from worker stop tests * Say that report-back requests still mean end the turn * Say that report-back requests still mean end the turn * fix(orchestration): stop reports wait for children, keep their Dispatch, and relay intact * fix(orchestration): a stop belongs to the Dispatch active when it was seen; restored stamps announce nothing * fix(orchestration): never say to stop while a remote worker runs * Shrink the orchestration guide to the end-state workflow * fix(orchestration): stop reports quote the agent's last words, or the screen for errors and prompts * fix(orchestration): withhold the stop while chat failure mail is off * test: a clean finish quotes the agent's last words * fix(orchestration): stop asking workers for heartbeats Workers are no longer told to send periodic heartbeats. A heartbeat that still arrives from an older worker or peer only records last_heartbeat_at: it is stored already handled, so it never lands in a coordinator inbox and never wakes a coordinator or a check --wait. Removes the stale-heartbeat warning and the heartbeat interval plumbing that only fed the preamble. * fix(settings): remove the worker heartbeat controls The Worker heartbeats switch and Heartbeat interval field only changed the worker preamble text, which no longer mentions heartbeats. Saved values are dropped on load as retired settings. * fix(orchestration): wake a coordinator that reports program status but never sets a title Program status only re-classified a pane that had a title, so a titleless agent (agy) never got a live status and the wake gate refused it. * fix(orchestration): a new Run no longer cuts a coordinator off from its earlier Run * test(orchestration): drop heartbeat-batch cases the handled heartbeat row removed * fix(orchestration): redact capabilities from a stop report's quoted output * fix(orchestration): never wake a mailbox for a heartbeat One rule at the runtime notification entry replaces per-call-site read checks, so mutation replay and federated control-mail import stay silent for heartbeats too. * Shrink the orchestration references and worker preamble to the end-state workflow * Name the older-Orca bind refusal as worker-start prints it * Owner-fence test: a refused foreign ack changes nothing, whatever the worker's own check already handled * Integration: drop the duplicate consumingCheck after merging #34043 and #35293 * Integration: await the worker-start next receipt before naming its Run * Apply review round 1: drain to zero, release without auto-release, retry after stop, Run before a DAG * Apply review round 2: start ready DAG Tasks, block when no failure wake, replay sends by request ID * Apply review round 3: one receipt-based wait rule for starts and wakes * fix(orchestration): a worker stopped without reporting needs action, and stop keeps its output worker-list projected a stop-reported attempt as live, in_progress, no action. It now projects finished_unverified with a worker-read recovery until mail reaches the worker. worker-stop closed the terminal before anything archived it, so release reported the archive unavailable; stop now archives the output first. * Revert "Owner-fence test: a refused foreign ack changes nothing, whatever the worker's own check already handled" This reverts commit |