mirror of
https://github.com/stablyai/orca.git
synced 2026-10-31 00:57:45 +00:00
9c7654600a2d620d0db9024cdbb8dc6ee6f1d8e9
1595
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
fac8a7454a |
fix(wsl-mover): a moved project's chat opens and answers here; a fenced terminal names its host (#34880)
* fix(wsl-mover): a moved project's chat opens and answers here; a fenced terminal names its host New e2e: a moved project's existing chat still answers after the move, run by this computer's agent, with no host involved. Writing it surfaced two product gaps: - Opening the chat from the moved project's sidebar entry asked its composer for focus before the prompt editor mounted; tiptap threw and the terminal workbench crashed. The editor handle now focuses (and answers contains) only once its view is mounted. - A new terminal in a project its WSL host now owns (one a chat's agent might ask for) was refused with "is moving ... try again when the move finishes". It now names the host and the way back: use the project on this computer again. * test(wsl-mover): wait for the moved chat's composer before typing and sending Like #34573: the composer must be editable before typing, and hold the typed text before Send. |
||
|
|
d20791e522 |
fix(session-search): read --since as an instant, whatever offset it carries (#28329)
Hosts filter with `updated_at >= ?`, comparing text against UTC toISOString() values, so a `+08:00` cutoff was read as if UTC and a whole-second `...00Z` cutoff dropped sessions in that same second (`Z` sorts after `.`). The cursor key also hashed the raw spelling. Normalize `since` to toISOString() in AiVaultSearchFiltersSchema. Every client and host path parses this schema, so new clients send a cutoff older hosts already compare correctly, and new hosts normalize whatever older clients send before filtering or building the cursor key. `Date` keeps milliseconds only, so a cutoff like `...00.0005Z` rounds up to the next millisecond rather than letting in a session from before it. Fixes #28253 Co-authored-by: Neil <4138956+nwparker@users.noreply.github.com> |
||
|
|
bd9455b616 |
test(wsl): cover a WSL-host orcad and the desktop at different versions (#34792)
* test(wsl): cover a WSL-host orcad and the desktop at different versions The desktop and a WSL distro's orcad update independently, and nothing pinned how they meet. - wsl-orcad-update-admission.test.ts: an older desktop keeps the newer orcad another desktop deployed serving, with no Update hint, and deploys over it only on Force; a policy refusal over that host carries orcad_host_newer. A newer desktop updates an older orcad on connect, keeps it serving with a Force hint after a failed update, and treats an orcad from before app provenance as updatable. - cross-version-wire/wsl-host-desktop-downgrade: against the baseline release, a newer desktop withholds the agent-session account env from a WSL orcad that never advertised it (the release's strict schema accepts the call), sends agent.launch's account env the release accepts, and reads the release's errors with no drive refusal; an older desktop reads the Windows-drive refusal as the readable runtime_error it already shows. * test(wsl): type the unused Claude preparation, and read the older orcad's error with the newer desktop's unwrap |
||
|
|
ad8d35eb59 |
feat(wsl): serve saved WSL work behind a closed hosts gate (gate states, kill switch 1/2) (#34683)
* feat(wsl): serve saved WSL work behind a closed hosts gate (serve-only) The WSL hosts gate gains three states. A closed gate with a saved WSL host or a committed move becomes serve-only: saved hosts stay listed and reachable, committed rewrites, retention, interrupted-move recovery and the way back keep running, and the preload API is exposed through a stamped window argument. Adding hosts and starting moves still need the open gate. With nothing saved the gate stays closed exactly as before. * fix(wsl): stamp serve-only into the dashboard popout and Space windows too They load the same preload, so without the argument they hid saved WSL hosts' status and Connect in serve-only. One helper now supplies the argument for every window on the shared preload. * fix(wsl): reviewer follow-ups for the serve-only gate - Refuse wslHosts:add unless the internal gate is open here, so this PR is safe on its own. - Promote on any move journal entry, so recovery can reset an in-flight move whose host record is gone. - List unfinished moves in serve-only. - An unreadable WSL deployment store fails closed in serve-only too, through a shared serving flag main sets at startup. - Report the gate state in wsl_usage_snapshot as an optional field. |
||
|
|
f173998203 |
feat(wsl-host): a chat on a stopped WSL distro says so and offers Start (#34681)
* feat(wsl-host): a chat on a stopped WSL distro says so and offers Start * fix(wsl-host): a chat's Start never cancels a pending WSL host Remove |
||
|
|
1eaaf85e9f |
Land the WSL project mover dark (merges only after verify-15b, the flag-off audit and green CI) (#34059)
* test(orcad-migration): pin the SSH manifest through the real dormant collectors Co-Authored-By: Claude <noreply@anthropic.com> * refactor(orcad-migration): read the dormant-state export through a source-kind scope A local-WSL scope lives on host local and owns only its projects, so host-wide matches stay an SSH whole-host rule. SSH bytes are pinned by the collector golden. Co-Authored-By: Claude <noreply@anthropic.com> * feat(wsl-mover): export a local WSL move's signed manifest with its dormant state (D1b-3c) Collects the scoped projects, their groups and every dormant-state kind through the local-WSL export scope, rewrites UNC paths to the distro's, and returns blockers for anything the collectors can't carry instead of dropping it. Automations move disabled, as the wire requires, and come back as a list to re-enable on the host after commit. Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-mover): reset an interrupted move to zero, or finish it once the host proves a commit Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-mover): abort a move by its identity when its manifest is too large for a request Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-mover): cap a new move's manifest below the request limit, and move forward on a by-reference commit only once the host flushed it Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-mover): remove only the newest move of a distro, so its chain stays readable Co-Authored-By: Claude <noreply@anthropic.com> * feat(runtime): clients read a migrated pane's scrollback from its host (D1b-6d-1) * fix(runtime): hold a remote pane only when its host is known to serve scrollback, and never read bytes in render (D1b-6d-1) * fix(runtime): route the scrollback read by the tab's own host, never the focused one (D1b-6d-1) * fix(runtime): resolve the scrollback host through resolveOwner and use the shared RPC error check, after main moved both (D1b-6d-1) * feat(wsl-mover): a moved project's existing chats stay listed and resumable on this computer (D1b-7a) * fix(wsl-mover): moved-project chats go through the layout owner instead of writing layout directly (D1b-7a) * test(wsl-mover): run the moved-project chat runtime test in the Node runtime (D1b-7a) * test(wsl-mover): read the hidden local row through main's per-host hidden-repo API (D1b-7a) * feat(wsl-mover): rewrite the desktop's routing and seed the host's session after a move (D1b-7c) Registers the main-side desktop rewrite stores ui-routing, session-globals and host-session-seed. Adds a +2 main layout-writer baseline line for wsl-move-main-rewrite-stores.ts: these are one-shot, ledgered move rewrites, and no LayoutCommand can set focus or seed a runtime host's partition. * fix(wsl-mover): finish the main rewrite before the window loads, keep one copy of each moved tab, and copy instead of move (D1b-7c) * feat(wsl-move): rewrite renderer stores for moved projects and keep their UI through catalog prunes (D1b-7d) Registers the renderer-side desktop rewrite stores quick-open-history, file-view-preferences and notebook-environments. The renderer copies each moved workspace's entry to its WSL host key, marks it applied in the same storage, and records the ledger entry; main requests a storage flush first and accepts only the main window. Committed moves are re-listed for re-application at every startup. Catalog prunes keep filters, hook trust and setup-script dismissals of moved repos. * fix(wsl-move): import the migration manifest types from main's orcad-migration folder (D1b-7d) * fix(wsl-move): import wslUncPathToLinux from shared wsl-paths in the manifest exporter, where 7d moved it (D1b-7d) * feat(wsl-mover): rewrite a moved project's orchestration history on the desktop (D1b-7e) Settled local worker dispatches and their worker-terminal rows in a moved project take the WSL host's worktree id, in one ledgered, idempotent store. Chat workers, live rows, federated attachments and JSON receipts stay as written; automations keep their unchanged local copy (the scheduler only advances it). Per-table dispositions for orchestration.db. Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-mover): hold the orchestration store while a worker in scope is live; skip federated rows (D1b-7e review) Co-Authored-By: Claude <noreply@anthropic.com> * feat(wsl-mover): copy in-app browser logins into the WSL host on a move (D1b-7f) A committed WSL move now copies each in-app browser profile's cookies once into the WSL host's stable route partition (owner decision 3a), merging without overwriting what the host jar holds and never touching the source. Where that is infeasible (no deployment link so no stable partition, the destination is not a WSL host or is gone, or the partition name is held by another identity) the host starts fresh and the move journal records why (3b). Registered as the ledgered browser-cookies rewrite store; it runs only once browser sessions and an app window exist. WSL_MOVE_DESKTOP_REWRITE_REGISTRY_COMPLETE stays false. * feat(wsl-mover): retain moved source rows, reconcile them on start, and plan delta moves (D1b-8) * fix(wsl-mover): keep the retained mark out of the WSL move manifest (D1b-8) * feat(wsl-mover): the move driver runs a WSL move end to end, with production gate facts and journaled restore folders One entry point (and preview/start/cancel/listUnfinished IPC for D1b-9) plans the move, gates terminals on the hook server's agent status, the close-tab process probe, running automation runs and live dispatches, pauses and proves exit, stages, sends blobs, commits only from blobs-transferred (#29825), and finishes on the desktop. Any failure resets to zero or goes forward when the host committed. Restore folders and the automations to turn back on are kept in the journal; the host turns those automations back on after commit, retried until it confirms. A real-PTY test pauses daemon shells, and runs on a real distro in the WSL orcad lane. * feat(wsl-mover): move dialog with preview, blockers, progress and result behind the internal WSL hosts gate (D1b-9) * fix(wsl-mover): move dialog hides instead of blocking, follows runs after a reload, and lets a start settle an unfinished move (D1b-9 review) * fix(wsl-mover): word an unfinished earlier move as still finishing (D1b-9) * test(wsl-mover): type the e2e's fake move state instead of reading it through Reflect (D1b-9) * WIP(wsl-mover): 7f-2 registry complete, coverage proof, startup re-apply (D1b-7f-2) * test(wsl-mover): registry-complete lifecycle, stale-focus restart, unload re-apply (D1b-7f-2) * fix(wsl-mover): share the session focus write so the re-apply adds no layout writer (D1b-7f-2) * fix(wsl-mover): redo additive rewrites once at a stale window's unload; behavioural coverage proof (D1b-7f-2 review) * test(wsl-mover): the IPC record test now finishes the rewrite with the registry complete (D1b-7f-2) * fix(wsl-mover): fence worktree-less spawns by cwd and re-prove terminal exit before commit (R46, WIP) * test(wsl-mover): pin the commit re-proof, browser jar identity and repeated move generations (R45, R46, R47) * fix(wsl-mover): fence any spawn by its folder and name the re-proof's reason (R46 review) * fix(wsl-mover): a terminal in a known folder outside the move never blocks it (R46 follow-up) * test(wsl-mover): kill the real move driver at every point against a real host store; abort a reset move's leftover stage on reconnect Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-mover): carry unsaved drafts into the moved project; round-trip every fixture through the real export, driver and host import Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-mover): reset a move waiting on a distro that is proven unregistered; test updates mid-move (R41), lost distros (R38) and two desktops (R39) Co-Authored-By: Claude <noreply@anthropic.com> * test(wsl-mover): list the D1b-10 real-SQLite mover tests Co-Authored-By: Claude <noreply@anthropic.com> * test(wsl-mover): type the fault test's journal hook without a cast Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-mover): reset for a lost distro even when its kept host fails to connect, never for a renamed one; compare filled-in repo keys only where the source lacked them Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-mover): carry markdown frontmatter visibility and closed-terminal-tab tombstones into the moved project Co-Authored-By: Claude <noreply@anthropic.com> * test(wsl-mover): read the persisted stage through a typed record, not Reflect Co-Authored-By: Claude <noreply@anthropic.com> * feat(telemetry): report how WSL moves end, by phase and reason code (R43) Co-Authored-By: Claude <noreply@anthropic.com> * fix(telemetry): report a pause refusal's reason, an outcome for a thrown run, and only real transport errors as unreachable Co-Authored-By: Claude <noreply@anthropic.com> * fix(agent-hooks): a WSL host's orcad never removes the hook entries the WSL bridge shares (R42) Co-Authored-By: Claude <noreply@anthropic.com> * fix(agent-hooks): a WSL host's Codex account-home launch with hooks off skips too; mark the R42 guard to drop with the bridge Co-Authored-By: Claude <noreply@anthropic.com> * feat(wsl-mover): "Use on this computer again" brings a moved project back as it was before the move Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-mover): judge a bridge WSL pane's foreground inside its distro On Windows every live bridge pane's own process is wsl.exe, so the busy-terminal gate read every open WSL terminal as running a program and refused the move. Read the pane's terminal foreground process group inside the distro (processes carry ORCA_PANE_KEY): only shells means idle, anything else blocks, and an unreadable guest stays unverifiable. Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-mover): only the selected projects' session rows can refuse a WSL move The session eligibility check treated host local's whole partition as the move's, as the SSH conversion does. So an agent session or unsaved draft in any other project on this desktop, or in a project an earlier move retained, refused every later WSL move from that distro. Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-mover): sign the manifest as the journal and the host read it The digest was computed over in-memory rows. A value with toJSON (a Date on a row added this session) canonicalized to {} when signing but to its string once written to the journal or sent to the host, so the first move after adding a project reset with orcad_migration_manifest_digest_mismatch until a restart reloaded the row. Normalize through JSON before signing. Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-mover): carry a slept pane's scrollback from its daemon checkpoint The move sleeps every pane first, and a slept pane's history lives only in the daemon's checkpoint, never in a renderer snapshot. The export carried renderer snapshots only, so moved terminals opened empty. After Sleep the driver reads each paused pane's checkpoint (as cold restore would replay it) and the export carries it under the pane's own snapshot ref; the snapshot channel serves those bytes, checked against the signed hash. SSH conversions pass no reader and are unchanged. Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-mover): say why when a move can't be prepared, instead of a bare reset An export or journal failure after the pause (a digest mismatch, on awin) was rethrown and shown as "everything was put back" with no reason. Nothing is journaled yet at that point, so refuse with the error named instead. Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-mover): retry a renderer store main refused to record The renderer applied a store and wrote its marker, but ignored a refused ledger record (gated-off, failed, not-main-window), so a committed move stayed unfinished and refused every later move of the distro until the next app start. Log the reason and retry with backoff until it lands. Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-mover): a WSL pane is idle only when its shell has nothing else Review of #32343: reading only the terminal's foreground group let background jobs, nohup and disowned work, setsid daemons and a script waiting at read pass as idle, and the move's Sleep would end them. Scan the pane shell's subtree, its session and every process carrying its key; any non-shell process, or a shell running a script, blocks. Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-mover): never leave behind an agent whose key may be the selected project Review of #32343: scoping the session check to the selected projects let an unqualified key for a repo id another host also registers fall out of both the transfer and the refusal. Such a key now refuses. Adds tests that fail on the old code: another project's live agent with its tab open and its draft don't refuse, the same kinds of state in the selected project still do. Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-mover): refuse an unreadable slept checkpoint, prefer it, and spool it to disk Review of #32343: - A checkpoint behind an unreadable log (or an unreadable one) refuses with the pane named instead of carrying stale history. - For a pane the move just slept the checkpoint is the newest copy, so it wins over an older renderer buffer or snapshot. - Buffers spool to a per-move folder and only their hashes and sizes stay in memory; the snapshot channel reads them by offset. The folder is removed whatever the outcome. - A journal write that landed before it threw is reset, so no orphan record blocks the next move. awin's checkpoints were 310-615 KB, well inside the 5 MB per-pane cap, so nothing there is trimmed. Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-mover): retry a failed listing, never a record another window was refused Review of #32343: not-main-window can't clear by waiting, while a listing failure is transient. Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-mover): sign the manifest as the host parses it The likelier cause of awin's digest mismatch: the signature covered the exported objects, but the manifest parser keeps only the fields it knows, so a session field it drops (one a sleep can write) left the journal and the host hashing something else. Sign the parsed form, and warn when the parser dropped anything, since such a field does not move. Co-Authored-By: Claude <noreply@anthropic.com> * chore(wsl-mover): split the journal step out of the driver, and format The review fixes took wsl-move-driver.ts past the line limit; the export-and-journal step moves to its own module unchanged. Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-mover): a slept pane passes the busy check; say what each move dropped or lacked Re-run on awin ( |
||
|
|
f150deb226 |
feat(native-chat): show the full date and time when hovering a message timestamp (#32051)
Message timestamps render time-only; the full localized date and time was only exposed via aria-label. Wrap the <time> element in the shared Tooltip so hover and keyboard focus reveal the same full label, without adding a duplicate aria-describedby announcement. Transcript render tests now go through a TooltipProvider harness, matching App's production provider. Co-authored-by: Neil <4138956+nwparker@users.noreply.github.com> |
||
|
|
8d908764dc |
Revert "Keep same-machine folders with matching Git remotes in separate projects (#32272)" (#34662)
* Revert "Keep same-machine folders with matching Git remotes in separate projects (#32272)"
This reverts commit
|
||
|
|
2893d06533 |
test(native-chat): name the stalled step in the live-history watcher test (#34663)
* test(native-chat): name the stalled step in the live-history watcher test A CI run hit the 30 s test timeout with no step named. Each wait now has its own 8 s deadline that reports the stalled step with what the watcher had delivered, and the file sets IS_REACT_ACT_ENVIRONMENT so act() flushes. * test(native-chat): share one 27 s budget across the live-history waits Per-step 8 s deadlines were stricter than the old 30 s test timeout; a shared deadline keeps the total unchanged and only improves the failure message. * test(native-chat): use an AbortSignal budget instead of the wall clock Date.now trips the flaky-test wall-clock rule; AbortSignal.timeout gives the same shared 27 s budget without reading the clock. |
||
|
|
5e9e4c84a3 |
test(wsl-host): type into the WSL host terminal only after its shell prompt (#34607)
On CI the first keystrokes typed right after the WSL host terminal attached were sometimes dropped (the shell received "L HOST TERMINAL ..."), leaving an open quote, so the marker never printed. The spec now waits for the prompt, which names the project folder, before typing. The dropped input itself is a separate follow-up. |
||
|
|
90c713af1f |
fix(wsl): refuse Windows drive folders on a WSL host, offer Add on this computer (#34530)
* fix(wsl): refuse Windows drive folders on a WSL host and offer to add them on this computer A /mnt/<drive> project on a WSL host shows false line-ending changes, misses edits made from Windows, and searches slowly. Add Project refuses typed, picked and dropped Windows drive folders for a WSL host and shows the refusal inline with Add on this computer, which switches the open dialog to this computer. The WSL-host orcad re-checks by /proc/self/mountinfo (after resolving symlinks) in repo.add, repo.create, repo.clone, explicit folderWorkspace.create and the nested scan/import, answering with the existing runtime_error code plus optional data, so older clients still show a readable message. Everything is behind the WSL hosts gate; SSH is untouched. * test(wsl): hold the e2e's this-computer add instead of racing its failure On the Linux CI host the switched local add of a Windows path fails its nested scan and hands off to the Open as Folder modal, closing Add Project before the test looked. The refusal itself already came before any scan. The e2e now records the local add at its scan step and asserts it went to this computer with the Windows path; a unit test pins that a refused pick never reaches the host path step. * test(wsl): type the e2e's held-scan window hooks instead of Reflect |
||
|
|
791502fae4 |
ci: move secondary, scheduled and contract workflows to GitHub-hosted runners (#34568)
* ci: move secondary, scheduled and contract workflows to GitHub-hosted runners Public-repo standard hosted runners are free under Enterprise. Release, build, benchmark, e2e and unit workflows stay on Blacksmith. ci-xterm-cache seeds both cache stores since its PR consumer's pool is undecided. * test(pi): resolve the smoke bundle's external packages from the repo #34148 pulled zod into the commit-message planner graph; the bundle in the OS temp dir could not resolve it on any runner. * ci(unit): use four workers on the hosted four-core x64 runner --------- Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com> |
||
|
|
eb7f4d9c31 |
test(wsl-host): native chat on a WSL host through the fake transport, including a stopped distro (#34573)
* test(wsl-host): native chat on a WSL host through the fake transport, including a stopped distro * test(wsl-host): type the chat spec's focus host id * test(wsl-host): harden the WSL host chat spec and re-run fake-connector specs on change * test(wsl-host): scope the chat reply check to the transcript and test the fake's route Find the prompt only in the transcript so the composer can't stand in for it, re-check the boot-free stop window after unfocusing, right before the focus, give the fake's distros.json temp file its own name so it can't collide with the spec's, and test that the fake connector routes to both WSL host specs. |
||
|
|
e71d4358c1 |
Native chat tabs can hand off work from their right-click menu (#34504)
* Add native chat hand-off menu on main * Fix saved chat hand-off observations and RPC exports * Reuse indexed chat tabs for hand-off subscriptions * Match saved-chat clear fixture to current journal API |
||
|
|
287a34c0e5 |
fix(github-project): show linked PRs and sub-issue progress (#34185)
* fix(github-project): render linked PR and sub-issue progress values * fix(github-project): probe schema support for project column values * fix(github-project): preserve independently supported project fields * Preserve nullable project values and unsupported fetch concurrency * Exercise project relation payloads through unchanged consumers * Combine project coordination test cache imports * Use checked project payload types in consumer tests * Place project provider column contract in cross-layer tests --------- Co-authored-by: Wooseong Kim <innocarpe@gmail.com> |
||
|
|
9a51b9845c |
fix(ssh): start a stopped managed server whose recycled PID hid it on hosts without ps (#34519)
* fix(ssh): prove a recycled server PID exited on hosts without ps On slim Linux images that ship no ps, the managed server's liveness probe could not read the recorded PID's argv, so after a reboot a PID that now named another process read as LIVE (same user) or UNKNOWN (root). The wake then refused to start the stopped server, the update deferred on the terminal census, and the host stayed unreachable. Read argv and the zombie state from /proc when ps is missing. Fixes #34149 Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(ssh): name argv-less PIDs from /proc stat; annotate e2e timeout Kernel threads and zombies have an empty cmdline, so a recycled PID owned by one stayed UNKNOWN on hosts without ps. Quote the stat pattern so the probe also parses inside command substitution on older bash. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(ssh): fall back to the stat line only after cmdline was read A failed tr must stay unproven rather than make a live server's PID look recycled. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
a238091bc0 |
Warn before closing an active native chat (#34236)
* fix(chat): confirm before closing active native chats * Repair native chat close settings and consent coverage * Cover native close consent in workspace and floating tests * Require consent before closing active native chats * Fix close-warning typed values in deferred actions and tests * Preserve admission ownership and reconcile relevant send evidence * Separate chat read lifetime from send settlement and activation effects * Fix required read activation typing |
||
|
|
4b4bcc2e60 |
Revert "Size tabs to titles and preserve floating panel drag space (#34025)" (#34506)
This reverts commit
|
||
|
|
13757d773d |
test(e2e): update four stale e2e specs to match intentional product changes (#30115)
* test(e2e): repair specs that missed intentional product changes Align still-stale e2e expectations with shipped product behavior: - the Cmd+J placeholder names workspaces and tasks - the worktree meta dialog is titled "Workspace details" - OS-opened CSV/TSV files are editable and render as an ARIA grid - the delayed-save notice carries the app toaster's close button Fixes #30114 Co-authored-by: Neil <neil@stably.ai> * test(e2e): stub host Linear status in linear-url-workspace-entry spec Since #33270, Create worktree reads Linear status from the repo's host (linear:status IPC) instead of the store, so the store-only fixture left Linear disconnected in the composer and the pasted URL was never looked up. Stub the linear:status handler with the same connected status. --------- Co-authored-by: Neil <neil@stably.ai> |
||
|
|
46c0a1f453 |
test(e2e): skip contributor git hooks and signing when seeding fixture repos (#31591)
Global setup and the worker-scoped fallback now share one seedTestRepository() that runs its commit and worktree add with per-command `-c core.hooksPath=/dev/null -c commit.gpgsign=false`, so a contributor's global hooks or always-on signing no longer abort e2e before any spec runs, and the test repo's own hook config stays untouched for specs that install hooks. Fixes #31587 Co-authored-by: Neil <neil@stably.ai> |
||
|
|
2a08315494 |
refactor: group Claude structured session lifecycle owners (#34449)
* refactor: group Claude structured session lifecycle owners * refactor: consolidate retargeted Claude state type imports |
||
|
|
e310a63624 |
fix(mobile): use desktop's rules for queued messages, turn status, Stop and the chat composer (#34000)
* refactor(mobile): share the queued-card projection with desktop Image-only queued drafts showed a blank card on the phone. * fix(mobile): honor the host's Queue follow-ups setting With it off, a mid-turn send from the phone still queued while desktop sent it into the running turn. * fix(mobile): keep a queued-card edit when the card leaves the queue The phone closed the editor and dropped the typing; it now goes to the chat box as on desktop. * fix(mobile): hold /clear and /compact for background work and sends The phone fired the command where desktop holds it, showed start failures twice, and left the agent unnamed in failures. * fix(mobile): hand a queued edit back to the chat it came from * fix(mobile): scope a command's send hold to its own chat * fix(mobile): read a published null queue as empty * refactor(mobile): share the returned queued-card caption rule * test(mobile): drop queued-card tests the shared rules already own * refactor(native-chat): share the needs-attention rule and drop leftover wrappers * fix(mobile): type the structured sends mock, drop the moved queued-cards path and ship queued edit copy at boot * fix(native-chat): drop the queued card's unused image-label import after the rebase * fix(mobile): order the phone's queue reorder preview by position, as the shared cards sort * test(mobile): keep the queued-messages test within its line budget * fix(mobile): settle terminal chat working state and turn timing with desktop's rules Move desktop's live-status merge, Stop suppression, hook-state resolver and terminal turn timing to src/shared/native-chat. Mobile reads the transcript lifecycle the host already sends, so a provider turn end settles Working the same way desktop does. Terminal chats now get the turn bar, timer and folding, and the streaming preview uses the shared deriveNativeChatStreamingText. * fix(mobile): send desktop's terminal Stop keys, a second Escape only for OpenCode Desktop sends one Escape on Stop. It adds a paced second Escape only for OpenCode, which confirms an interrupt that way. Claude Code and Codex read Esc-Esc at an idle prompt as rewind. The rule moves to native-chat-agent-support, and the phone now paces the second Escape at desktop's answer step instead of 80ms. * fix(mobile): word Orca-stop and usage-limit notices like desktop Move desktop's Orca-stop sentences to src/shared with an English table that desktop translates. The phone names the Orca host it pairs with, and when that host is unnamed it says "the remote server". Usage-limit rows rebuild desktop's sentence from the failure fact. The usageLimitLineText fallback, which only the phone used, is deleted. * test(mobile): pass the overlay's host name in the prompt controller harness * test(mobile): re-record Stop goldens at desktop's step, split status-notice tests, pin the turn clock and ship notice copy at boot * fix(mobile): offer structured Stop while a send is out and read queue-sends-next as working Move desktop's structured Stop rule, its Stop-joining helpers and the queue-sends-next rule to src/shared. Both sides now use them. The phone counts its in-flight sends, so a conversation-stop host offers Stop before the turn opens. Between queued turns the phone reads as working, and commands that can't wait in line hold like they do on desktop. Untargeted Stops are no longer joined on legacy hosts. * fix(mobile): offer terminal Stop again when its Escape went nowhere Stop hides Working on the phone like it does on desktop. The phone's Escape can fail outright, though, while desktop writes to a local PTY. When no Escape could have landed, the phone now drops that suppression. The streaming preview also treats a pending echo as the transcript's tail, as desktop does, so an earlier reply can't hide a new preview. * fix(mobile): hold structured Stop while a send it covers is in flight On desktop, Stop's held and Stopping state depends on whether the chat can stop, and that includes a send still in flight. The phone now does the same. Once Stop is pressed before the turn opens, the button holds and repeated presses send no more untargeted cancels. * fix(mobile): end the terminal Stop hold when a new message is sent Desktop clears Stop's working suppression on an optimistic send, so a new turn that keeps the same hook epoch (Claude with working subagents) still offers Stop. The phone now does the same when a new pending echo appears. * refactor(mobile): trim chat turn wiring after the desktop rule move Drop the controller's unread nativeChatAgentWorking field. Re-render only when a chat starts or stops having a send out. Keep the structured turn indicator stable across stream frames. Type the Stop test table instead of casting. * refactor(mobile): track structured sends in flight once for Stop and command holds * test(mobile): re-record Stop goldens now that Stop settles with its Escape delivery * fix(mobile): escape terminal image paths like desktop drops * fix(mobile): keep launch-draft prefill over older user turns * fix(mobile): rank @ file matches with desktop's fuzzy Quick Open search * fix(mobile): use desktop's composer triggers for mid-prompt / and $ picks Picked @ files are now quoted when the path has spaces. * fix(mobile): send picked skill paths on structured chats * fix(mobile): list the host's disk-scanned skills in the / and $ menus The phone names the workspace and the host resolves its folder, refusing SSH workspaces as desktop does; hosts without skills.discover-workspace.v1 list none. * fix(mobile): forget a picked skill once its token is deleted * fix(mobile): drop a picked skill as soon as its token is deleted, and retry failed skill scans * fix(mobile): treat a picked leading skill as chat and stop failed skill scans from refiring * test(mobile): drop the menu ranking case the shared picker tests own * refactor(mobile): keep skill picks on the draft record and reuse shared send rules A rejected send now keeps its picks and leading-skill origin on both send paths. * fix(mobile): replace a re-picked skill's file and restore picks with a rejected send * fix(mobile): read the chat agent for the skill catalog from the active resolution * style(native-chat): format the composer autocomplete files * fix(native-chat): import the picker's apply and send-classify rules from the shared composer module * refactor(mobile): import the composer's draft-store hooks once * style(mobile): format the notice row's style import |
||
|
|
16a29bc2fe |
refactor(pty): group IPC test harness and provider fixtures (#34440)
* refactor(pty): colocate IPC test fixtures with PTY owners * test: exclude PTY test constants from credential source census |
||
|
|
f776923c04 |
fix(mobile): use desktop's rules for chat tool rows, pending echoes and session option picks (#33977)
* fix(mobile): resolve terminal chat agents in desktop's order Mobile now uses the shared detected-then-launch precedence and transcript-readability check; the phone's remembered agent only fills in after them. * fix(mobile): hide Codex foreground commands from the background-task strip * refactor(native-chat): share diff-card gutter, basename and task count * fix(mobile): show clipped tool output sizes in KB/MB like desktop * refactor(native-chat): share the tool-run header rules with mobile * fix(native-chat): share tool-line detail rules; skip unsafe-only search hits * fix(mobile): copy message text with desktop's rule Copy now leaves out roster and background-task fallback twins and wordless provider frames. * refactor(native-chat): memoize shared tool-line view and output sizes; share result preview * fix(native-chat): read a lone result's preview from its narrowed body * chore(i18n): ship chat tool and stop copy in the runtime English catalog * refactor(native-chat): move the pending-send echo rule to shared Mobile reuses it instead of its own matcher. * fix(mobile): match chat echoes after their send boundary, sink unmatched ones Uses desktop's rule: rows before the send no longer retire an echo, a send that never lands no longer lets later glued sends retire, and an unmatched echo sits below later turns. * fix(mobile): keep glued photo captions and folded boundaries in echo matching * fix(mobile): give image preview echoes the send time the occurrence rule reads * fix(mobile): match echoes on image-normalized rows and cap open sends at eight Same input and bound as desktop; each open send rescans the transcript. * test(mobile): drop a pending-order case the tail test already covers * refactor(mobile): read the send boundary once and skip echo normalization when idle * test(native-chat): type the occurrence case's pending send * test(mobile): drop the pending-echo wall-clock entry from the flaky-test baseline * refactor(native-chat): share session option labels with mobile Mobile's options pill now shortens effort levels (Med, XHigh, Min) and names choices and options the way desktop does, from one English table that desktop translates. * refactor(native-chat): run mobile terminal chat options on the desktop surface The terminal-chat option surface, its appliers, the option cache and the dispatch types move to src/shared, and the phone builds its pickers from them. Grok and every other agent with a catalog now get model and effort pickers on the phone, picks are saved as the host's launch defaults, the OMP live switch gate and discovery mapping come from one copy, and authoritative discovery retires persisted models it no longer lists. The option stamp moves to shared. * refactor(mobile): merge the session option type imports * fix(mobile): keep terminal chat option picks on their own chat The phone keeps one option surface per chat, so a pick that lands after leaving and returning shows there, and a picker command only switches the chat it came from. Discovered models merge with the seed catalog as on desktop, so Grok keeps its effort picker. A Claude model switch the phone cannot confirm is never saved as a launch default. * fix(mobile): start terminal chat options over when a tab changes agent A tab that runs another agent drops its kept option surfaces, report markers and cached record, so a fresh session shows its own model. A pick that lands after the phone moved to another chat is not saved as a launch default. * fix(mobile): fence retired terminal chat option surfaces A write that lands after its tab started another agent no longer publishes the old agent's record, and a changed OMP switch capability rebuilds the chat's surface from the cache instead of reviving an older one. * refactor(native-chat): simplify the shared session option wiring Desktop translation pieces use literal English defaults so the localization gate can read them, the selected-choice lookup is shared once, and the phone keeps one option surface per tab with the agent change detected from the cached record. * refactor(mobile): return no option surface for an agent without a catalog * test(native-chat): expect the shared Effort label in the startup picker test * test(native-chat): keep only the label cases main still checks after the rebase * refactor(native-chat): import the session option snapshot rules once in the PTY option surface * refactor(native-chat): share structured option pick bookkeeping with mobile Desktop and the phone now track picks per option through one shared book: a repeat of an option on its way waits, other options go together, a lost reply is not a pick done, and a stale reply only commits its own option. The phone also re-reads options each turn and after the provider starts, and shows picks at once while the host is still starting the provider. * refactor(native-chat): share the option pick blocking rule * fix(native-chat): read in-flight option picks from the shared book for launch send options * fix(native-chat): keep the structured options hook within its line budget and pass the phone turn in the e2e harness |
||
|
|
176852ad5a |
fix(terminal): highlight the active IME conversion range (#27903)
Japanese IMEs convert one clause at a time, but the terminal's preedit overlay painted the whole composition uniformly, so the clause the candidate window targets was invisible. Read the IME's selection from xterm's textarea on the insertCompositionText input event (Chromium only updates it there) and paint that range of the preedit in the theme's selection colors. Cell-grid advance corrections are unchanged and nothing reaches the PTY; a collapsed caret or a range outside the preedit highlights nothing. Fixes #27873 Co-authored-by: Neil <neil@stably.ai> |
||
|
|
295ed991dd | refactor: group shared native-chat session options (#34356) | ||
|
|
2327180d12 |
feat(quit): add Quit and Stop All Sessions to the app menu and tray (#32153)
* feat(quit): add Quit and Stop All Sessions to the app menu and tray Quit keeps daemon sessions alive for warm reattach. The new item, placed directly above Quit in the macOS app menu and menu bar icon, the Windows File menu and tray, and the Linux File menu, asks for confirmation, runs Settings' Kill all sessions in the renderer, and quits only when every session stopped. Closing the tabs first means nothing reopens or resumes on the next launch. Serve hosts do not offer the item. * fix(quit): keep Orca open when Kill all cannot prove every session stopped - Kill all no longer reads a daemon generation that failed to list as "no sessions": a failed poll keeps the last confirmed remaining set, and a failed initial listing sets listingIncomplete. - Quit and Stop All Sessions stays open on an incomplete listing or a terminal tab opened during the sweep, logs why it stayed open, and reveals the window before the final quit. - Share the main-window message box helper, stub the request on the web client, and add Portuguese strings. - Cover the windowless path, request expiry, the in-flight guard, and failed listings in tests; bound the E2E exit wait. * fix(terminal): count Kill all per daemon generation within a time window - A poll updates only the daemon generations that answered, so one failing generation no longer hides the kills of the others. - Poll for 6.5 s of wall-clock time instead of 65 attempts, because a wedged generation fails each listing only at the request timeout. - Flag a sweep with no daemon provider as listingIncomplete. - Log the leftover-tab exit, share the one-shot window intent with Open Settings, and cover the sender check, the reveal before the final quit, and retries in tests. * fix(quit): stay open while a newer build's daemon is held - Set listingIncomplete while this build holds a newer protocol's daemon, whose sessions it can neither list nor stop. - Reuse getDaemonAdapters in Kill all, type the shared one-shot helper by its flag factory, and move the app-menu quit handlers next to the tray options so both serve/desktop splits are tested. - Cover a quit that outlasts the request expiry and a failed request pull, and fix the docs lead-in for the new quit-time case. * fix(quit): explain, without stopping anything, while a newer version runs terminals - Check the newer-version daemon hold before the confirmation and show an explanation instead, so Kill all no longer closes every tab and then refuses. listingIncomplete stays as the backstop. - Translate the explanation, describe listingIncomplete generically, and assert the single timed-out poll in the Kill all test. * fix(quit): explain before asking whenever Kill all cannot list every session - Show the explanation instead of the confirmation while the daemon provider is missing (still starting or failed) as well as while a newer version's daemon is held. - Name only the steps that work (wait for terminals to open, reopen a terminal opened in a newer version), avoid stating a hold as fact, and label the dialog's button through the catalog. * fix(quit): add the relaunch step to the explanation and align the ja wording * test(pty): keep a confirmed stop when its generation fails a later poll * test(quit): give the E2E timeout bump its reason * fix(quit): stay open when the daemon still lists a session after Kill all Kill all counts only the sessions of its first listing, so a session started since then, for example from the CLI or an automation before its tab reaches the renderer, would outlive the quit. Main now lists every daemon generation again before quitting, and quits only after a listing in which every generation answers and none lists a session. It polls within Kill all's 6.5 s window so the tab sweep's PTY shutdowns can finish; otherwise the renderer shows the existing error and Orca stays open. ui:quitAfterStoppingAllSessions becomes an invoke that answers whether main quits. * feat(quit): rename to Quit Completely with a macOS hover hint, and explain plain Quit in the confirmation * fix(quit): show progress while Quit Completely runs, and refuse at once when the daemon can't be fully listed --------- Co-authored-by: Neil <neil@stably.ai> |
||
|
|
a0e7fa0619 |
Keep Claude approval choices across model changes without freezing delivery (#34031)
* fix(native-chat): keep Claude approval choices across model changes without freezing delivery A Claude chat saved as "Approve for me" could reopen asking for every approval, because Orca read the folder's saved model list as launch policy, and a model change could keep running in a weaker approval mode Claude opened with. The first fix for this was reverted after it froze the app: restored history left a turn reading as running, a send was refused against it, and delivery retried the same send with nothing changed. - The saved approval choice goes to Claude as-is; the menu offers every mode. - Orca records the mode Claude actually opened in. A send that picks a new model reopens Claude first when that mode differs from the one requested, only when the chat owes no work; Orca mail notices never reopen it. - A message sent while a Claude turn is running joins that turn on its current choices; new choices apply at the next new turn. Nothing is refused. - History catch-up closes every turn it opens, in the thread it opened in. - At startup, a turn reading as running under the new agent that the agent is not running is ended as interrupted. - Delivery goes round again only after a step shows what it changed (a commit, a different child, a start it joined ending, or a wake); otherwise it waits for the next change instead of repeating the same step. Tracked in STA-10953. * fix(native-chat): preserve execution evidence at dispatch * Fix delivery iteration ownership and progress contracts * Correct journal fixture types in delivery regressions * Separate Claude input choices from error correlation |
||
|
|
1c4d4a03bc |
feat: drag to reorder queued messages on desktop and phone (#34026)
* feat: drag to reorder queued messages on desktop and phone * fix: use the queue grip button padding from its primitive * fix: preserve the queue grip touch width with hit slop * test: carry queue animation mocks into the chat view harness * test: complete the shared chat view harness registrations * test: carry the queue move cross-version wire contract * Scope queue move feedback to the issuing chat and preserve phone touch width * Keep queue reorder presentation stable during measurement and pending moves * Keep measured row handoff tokens constant size * Avoid rebuilding queue arrival IDs on unchanged renders * Fix mobile queue regression test fixture boundaries * Share the queued message leading slot with its reorder grip * Fix queue regression fixture quality findings * Check queue icons within the leading slot * Allow every unsettled queued message to reorder * Supply stable scope in queued row test mock |
||
|
|
483573f0b9 |
fix(browser): focus newly opened image tabs (#34127)
* fix(browser): focus newly opened image tabs Focus the window before the webview so Command+W closes the new image tab instead of the original tab after a plain image click. Add tests for focus order, image loading, and close-shortcut forwarding. Fixes #34114 * test(browser): verify image tab focus with native keyboard input * refactor(ci): keep browser E2E routes within registry size limit * fix(ci): enable background launch for native browser regression * test(ci): include browser routes in isolated detector fixture --------- Co-authored-by: Neil <neil@stably.ai> |
||
|
|
bff2843fca |
refactor(shared): organize native chat ask input owners (#34251)
* refactor(shared): group native chat ask input owners * refactor(shared): keep split ask type imports erased |
||
|
|
887b781d72 | Move palette matching utilities into shared modules (#34252) | ||
|
|
3347d47a7d |
fix(mobile): use desktop's PR lanes and status-dot rollup in the workspace list (#33966)
* fix(mobile): ask before running orca.yaml default-tab commands from the phone The host's repo.hooks reply now carries desktop's setup config, so the phone gates the Run/Skip choice and the trust prompt on defaultTabs commands too. * fix(setup): keep the local script in run-both setup config without orca.yaml commands * test(setup): drop the shared duplicate-host trust test desktop already covers * refactor(setup): derive host setup trust from the shared setup config * fix(mobile): count every host's repo rows before honouring repo-wide setup trust * fix(mobile): show desktop's PR lanes and failed/interrupted status dots on the phone The host builds worktree.ps linkedPR with the desktop's PR-lane cache reader and sends the desktop sidebar dot as an optional sidebarStatus field. * fix(mobile): keep uncached PR badges and let finished turns show through working titles * fix(mobile): suppress agent panes' permission and parent titles in the host status dot * test(runtime): expect sidebarStatus on the compact ps summary * test(runtime): keep only host-specific sidebar status cases * refactor(mobile): keep host title suppression and the uncached PR lane in one place each * test(wire): pass the terminal title evidence map to new host builds * fix(runtime): read each workspace's PR through its own host's repo |
||
|
|
284411d893 |
fix(wsl-host): uninstall and startup release WSL holders; a partial Remove keeps the host pending (#33843)
* fix(wsl-host): uninstall and startup release the WSL distro holders Orca left running The detached wsl.exe holder outlives the app, so an uninstall left its distro, orcad and shells running. The uninstaller now runs Orca with --orca-uninstall-release-wsl-holders after killing the app and its daemon; it ends only the holders this profile recorded, each verified by pid, start time and command line, and keeps any it cannot verify. At startup the WSL host service now releases holders whose distro is no longer a host (a failed add or remove), and every holder while WSL hosts are off; a closed gate releases them too. Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-host): a Remove that can't prove the server stopped keeps the host, pending A partial Remove dropped the host anyway, leaving a server whose live terminals block the next add's activation. Remove now drops the host only on a proven stop; otherwise it records a pending stop on the WSL record, keeps the host listed and says why (live or unverifiable). Remove again retries without ever booting a stopped distro (it says to start it); Connect or Add on the same distro keeps the host; a distro that is no longer registered finishes. Nothing reconnects a pending host on its own. Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-host): E11 review — keep holders when records are unreadable; finish removals a stopped or renamed distro proves - Startup keeps every holder when the WSL host records can't all be read (unverifiable), and no longer re-adopts a pending host's holder. - Remove matches a renamed distro by GUID (isWslDistroRegistered), and a stopped distro finishes a pending Remove: the cold probe proves the stop. - Only the user's Connect or Add withdraws a pending Remove; other connects are refused, and re-adding respects startIfStopped. - Settings' Remove carries the kept result, so it warns instead of 'Removed'. - A holder record without a start time is never killed on its command line alone, except the one this process just spawned. Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-host): E11 review 2 — a closed gate keeps live hosts' holders; stop a renamed distro by its current name - With the gate closed, a launch releases only orphan holders (no host record, or a pending Remove), under the same keep rule as startup; a user with no holder records costs one folder check, nothing else. - The keep rule re-reads host records per holder and keeps an Add in flight. - Remove resolves the distro's current name from its GUID and stops it there. - The uninstall command arms its exit timer first and exits 1 if setup throws; NSIS launches it only when a userData holder folder exists. Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-host): never boot a host whose Remove is pending at the next launch Early wake built its host list from every record, so a host focused when its Remove ended pending was booted at each launch, undoing the stop's proof. It now skips pending records, and Remove forgets the host's early wake whatever the outcome. Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-host): no wake for a pending host; the e2e fake stops an unbridged server like the real one - mayWake skips a host whose Remove is pending, so a due automation can't boot it (focus already couldn't). - The e2e fake connector read a host with no bridge as stopped. Since E9 a re-enable connects nothing, so Remove after off/on left the host's shells running. Like the real connector, it now reconnects the always-running fake distro to stop its server. - Status bookkeeping moves to WslHostStatusBoard, and the pending-host connect rule to admitConnectToPendingHost, to keep the service under max-lines. Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
e79235371f | fix: restore main typecheck after concurrent merges (#34202) | ||
|
|
29a5f89b8a |
Keep same-machine folders with matching Git remotes in separate projects (#32272)
* WIP: same-host same-remote checkouts keep their own project id * WIP: claim the shared project id per checkout surface; drop the display-only clone split * WIP: index derived ids by repo in the hydration normalizer * Resolve workspace project affiliation from current checkout owners * fix: preserve concrete project ownership across catalogs and operations * fix: combine recent project selector imports * fix: enforce canonical catalog reads and preserve search continuity * fix: scope catalog lint exceptions to renderer files * Resolve project search ownership before native candidate limits * Combine duplicate session scope imports * fix: derive returned history row ownership on the host * Reconcile full session history replies by content * Require authoritative project catalogs for terminal snapshots * Preserve registered project claims and partial history results * test: check orphaned setup cleanup state without assertions * fix: align catalog callers and native search fixture contracts * test: check full repo shapes in runtime routing fixtures * Fix checked catalog inputs in compiler regression fixtures * Keep checked PTY fixture repos mutable * test: align catalog fixtures with canonical readers * test: check catalog and runtime fixture inputs * test: check catalog fixtures without outer assertions * test: follow persistence harness relocation * Adapt catalog test inputs to integrated main checks * Test History hashing across cached depth revalidation * test(settings): expect host-qualified setup removal * test: capture host split listings and scope relay recovery * ci: regenerate merge ref * test: type host-split listing diagnostics |
||
|
|
7f846fd4f9 |
Codex restarts keep the configured command before a session is recorded (#33629)
* fix(codex): honor configured command on unrecorded restarts * test: update account restart startup consumers |
||
|
|
028f609b5a |
Keep chat thinking before its answer across history loads (#33628)
* fix(chat): preserve transcript source order across history windows * test(chat): use template literal for mobile transcript fixture * test(chat): place composed transcript contracts across project boundaries * test(chat): move reader-to-phone contract across project boundaries * test(chat): reuse transcript input setup and caller contracts * test(chat): align mobile recordings with source-order capability * test(chat): scope phone transforms and await history snapshot |
||
|
|
0f47bb16e8 |
refactor(mobile): organize native chat prompts and permissions (#34189)
* refactor(mobile): organize native chat prompts and permissions * fix(mobile): preserve extensionless test fixture imports |
||
|
|
5b4c77906d |
Revert benchmark-only startup loading study (#33912) (#34162)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com> |
||
|
|
7a9abe48f3 | refactor: group remote runtime client modules (#34133) | ||
|
|
6fe0476443 |
fix(session-tabs): keep the server's per-device tab pick on the tab the desktop shows (#34082)
* fix(session-tabs): keep the server's per-device tab pick on the tab the desktop shows The server hands its remembered pick back whenever the desktop has no tab groups of its own for a workspace. A desktop that kept its groups never reported what it showed, so that pick went stale and such an open landed on the wrong tab. * fix(session-tabs): report only a ready visible pane, and retry after an error answer Name the pane the desktop shows and require it ready, so a report never starts a pending sibling's terminal. A failure envelope no longer marks the pick as reported. * fix(session-tabs): report a desktop's pane once per change and connection Two windows sharing one device id could steer the pick back and forth. Report again only when this desktop's own pane changes, scope the record to the pairing and connection, and resolve the visible tab with the existing helper. * fix(session-tabs): report only the on-screen workspace, compare panes, and remember agreement Reports stay with the workspace on screen, whose pane attaches anyway, so a report never starts a terminal elsewhere. The pick is compared pane for pane, and an agreeing frame records the pane so a later change of this desktop's pane reports again. * fix(session-tabs): settle before reporting, report on opening a workspace, and only to its owner A click records its activation after an async hop, so a report now waits until the pane settles and compares against the latest frame. Opening a workspace reports from its latest frame. A workspace id two servers share is reported only to its owner. The e2e now drives the real flow: a stale pick, then a desktop restart. * fix(session-tabs): keep one outstanding pick check per workspace, fenced to its connection A busy workspace's frames no longer postpone the check. A frame from a replaced pairing or connection is dropped, and a frame without the per-device projection clears the cached one. * fix(session-tabs): bound the pick report caches and clear them on mirror teardown One record per workspace, with the connection in the value. Environment teardown drops reports, frames and timers. The tests use checked types, and the e2e notes why it waits and why it needs more time. * fix(session-tabs): check again when the user moved on before a report finished The host does not order activations, so a report that completes after the user picked another pane may have landed last. Clear its record and recheck from the latest frame. * fix(session-tabs): type the visible pane's leaf as optional * fix(session-tabs): send a browser or chat pick again when a late report landed after it A terminal report that completes after the user picked a browser or chat tab may have had the last word. Re-send that pick the way a click does. * fix(session-tabs): recheck a late report against the host's answer, and fence it to teardown The activate answer is the host's per-device frame after the report, so a late landing is checked against it instead of a cached frame. A report answered after mirror teardown or a new connection does nothing. * test(session-tabs): drop the in-connection suppression check from the restart e2e Whether the desktop repairs a stale pick within the connection depends on which frames settle first; the guarded outcome is the pick after a restart. * fix(session-tabs): reconcile the user's newer pick after any report outcome, timeouts included A report whose answer timed out may still have landed after the user's newer pick. Settle every outcome the same way: retry on failure, then reconcile with what the desktop shows. |
||
|
|
316b1887fd |
Size tabs to titles and preserve floating panel drag space (#34025)
* Size tabs to titles and preserve floating panel drag space * Stabilize agent tab layout during activity changes * Balance tab widths across titles and tab types * Reserve terminal tab icon space before agent detection * Run floating header drag E2E in the isolated headful project * Prevent native text selection on the floating panel drag handle * Cap expanded tab width at 24rem * Let tabs expand to fit titles in available space |
||
|
|
d1f6f6ac83 | fix(mobile): resume history sessions with desktop's resume and host rules (#33943) | ||
|
|
ccedfe312e |
fix(ssh): move enabled SSH automations to the host's Orca server (#34044)
* fix(ssh): move enabled SSH automations to the host's Orca server
Connecting an SSH host moves its saved state to the host's managed Orca
server. An enabled SSH automation refused that move on every Connect
("automations (1), automation runs (4)"), leaving the host unconnectable;
Move anyway connected it but stranded the automation on the desktop, where
it no longer ran.
An enabled automation whose runs have all finished now moves with its run
history. The manifest still carries it disabled, which every server version
accepts; once the move commits the desktop disables its retained copy and
turns the server's copy back on through automation.update, re-sending its
start time so the next run is the next future occurrence. A server that
can't is noted in Settings; an unreachable one is retried on the next
Connect. While a move fences the host, the desktop scheduler, Run now and
the launch re-check write nothing for its automations, so a tick can no
longer break the fenced export; releasing the fence resumes them. A run
still in flight keeps blocking and the refusal now says to wait for it.
Fixes #29083
* test(ssh): mock the server automation enabler in the delta-move handler test
* test(e2e): keep the Move anyway specs refusing now that enabled automations move
The inline Move anyway spec seeded an enabled automation to force a
refusal, which this branch now moves instead. It seeds one pinned to an
earlier registration of the host, which still stays behind. The relay
bridge spec's Move anyway lookup also matched the refusal toast's
button since #34041; it now takes the pane's own.
|
||
|
|
f06f737802 |
Unify Source Control action permissions and card layout (#30449)
* Source control actions start chats and terminals on their saved model A "start an agent" action's model lived only in free-text CLI arguments, which a native chat never reads, so AI Fix opened a chat on the default model. Each action now saves a structured model and effort that both routes apply: chat create options, or the agent's own flags in a terminal (winning over the same flag in CLI arguments). Desktop, dialog, fix-checks and mobile launches carry it; Settings rows get Model/Effort selects and the CLI arguments field says it is terminal-only. Tracked in STA-11102. * Name the model in the repository override note * Type the dialog's model hand-off; keep Agent in English in Japanese copy * fix: preserve action chat model choices through launch * Preserve action selection ownership across chat launches * Keep terminal host contract fixtures aligned with preflight * fix: wait for action Settings agent inventory * fix: consolidate direct agent routing imports * fix: use standard action option labels * fix: align action launch contracts with shared types * fix: sync action option localization metadata * test: provide action Settings inventory in mounted fixtures * Keep action options row height stable while loading * Let each Source Control action choose its chat permission mode An action's saved chat choice may now carry a permission mode, with or without a model; "Same as new chats" saves nothing. A model is replaced only when the action names one, so a permission-only choice keeps the chat's remembered model and options. * fix(native-chat): leave older hosts their own permission mode and keep action options readable - An action's saved permission mode is sent only to hosts that advertise agentSession.create.options-mode.v1. Older hosts get no mode, in create options or a later setOption, so the chat starts on that host's new-chat default, as a phone launch to such a host already does. Hosts from 1.4.225 to 1.4.227 refused a mode their tables lacked (OpenCode, Grok, OMP), leaving the action unable to start. - Settings action rows give Model and Permissions full rows in the options column so saved values are readable; the loading placeholder reserves the same rows. - Remove two unused locale keys; fix two stale comments. - Tests: the older-host create carries no permission mode; a permission mode picked alone keeps the remembered model on an acquired create. * fix(settings): reserve one options row while loading an action with nothing saved Terminal and permissions-only rows no longer shrink when loading ends; a chat agent with a model list may grow by its Model row once known. * fix(native-chat): keep the create options mode a checked literal type * fix(settings): share verified action option fields * fix(settings): keep action selectors on standard typography * Keep the launch files under their length limits after the main merge The structured route imports its result types where they are defined, and the two older-host action-launch tests share one setup helper. * One action settings section for chat and terminal launches A Source Control action's Model, model options and Permissions now apply whether it opens a chat or a terminal; terminals receive them as the agent's own flags, and a repository's own CLI arguments keep the flags it sets. Extra CLI arguments stay terminal-only. * fix(source-control-ai): one terminal projection for saved action choices Ask in a terminal now states its permission instead of leaving it to the user's own config: Claude and Grok pass --permission-mode default, Codex passes -a on-request -s read-only -c approvals_reviewer="user" (the interactive CLI has no untrusted policy, so a read-only sandbox is what asks before edits). Agents whose CLI has no flag for a mode show the existing "Applies to chats only" hint. The strict launch-preferences projection now requires the launch agent at every caller, composes model ids through the resolver's own step, carries a mode only where the agent's terminal has a flag for it, and the local string wire keeps booleans as 'true'/'false', so Cursor Thinking/Fast reach the terminal and an OpenCode permission-only choice is not refused. The argument parser knows flag arity, so removing a boolean permission flag keeps other options' values, following positionals and '--'. Pre-admission and executor share one terminal admission check on the options the terminal will receive. Customize with Save launches the recipe as it will resolve once saved; legacy partial repository overrides are edited as the complete recipe they resolve to. Empty Extra CLI arguments start collapsed. * fix(source-control-ai): an edited repository action saves complete Every Settings edit of a repository action (agent, model, permission, prompt or arguments) now starts from the complete recipe the action resolves to, whether its stored override is owned or a legacy partial. The resolved agent selection is kept (never an agent only detected to run a default), an explicit null args clear stays null, and empty args stay empty instead of being dropped. Clearing the last preference therefore means the action agent's own defaults rather than re-inheriting Global. The action text draft is lossless: unset or cleared prompt and args stay so until the user types, and the inputs show them as empty, so saving a prompt no longer writes empty args that suppress the agent's default flags. Untouched sibling actions are not rewritten by the edit. * fix(settings): style the Extra CLI arguments toggle through Button's own variant and size CI's changed-code quality check refuses restyle classes on Button and CollapsibleContent. Use the ghost variant at size xs with a margin, and put the content spacing on a plain inner wrapper. * fix: keep saved action and restart launch recipes consistent * fix: describe inherited arguments and chat-only permissions accurately * test: check repository action settings fixture type * test: map saved action options into terminal compiler inputs * fix: retain saved action controls during agent detection * fix(i18n): retire obsolete Portuguese action labels * test: align folder launch fallback mock with outcome export * fix: carry resolved connector launch intent and mode together * test: pin shared action launch branches to recorded agent output * test: preserve saved source control choices through detection and migration * test: align launch fixtures with integrated result contract * test: retain recipe and restart contracts after main integration * Unify Source Control action permission settings * Keep native Ask copy with its owning change * Preserve action drafts and old-host permission intent * Consume rejected Source Control action saves * Follow the moved Settings persistence fixture * Keep permission integration contracts in the cross-version test project * Include the action permission inheritance label in English catalogs * Align launch contracts with shared permission recipes * Keep Source Control action controls within their Settings columns * Use primitive variants for compact action settings controls * Show action arguments only for terminal defaults and widen recipe rows * Apply terminal-only action arguments visibility to repository overrides * Align action permission control with model controls * Use shared settings label for action permissions * Hide action model controls until argument migration ships |
||
|
|
86a75e99c6 |
perf(bench): measure startup memory and cold SSH latency (#33912)
* perf(bench): separate historical startup loading evidence * fix(bench): retry owned root identity before teardown * fix(bench): format survivor identities explicitly --------- Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com> |
||
|
|
ad2156c358 |
test: remove 140 low-value cases and 49 suites (#34062)
* test: remove 140 low-value cases and redundant browser probes * fix: remove unused upstream chat menu import * test: pin the host-split layout fixture branch --------- Co-authored-by: Orca Test Audit <test-audit@stably.ai> Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com> |
||
|
|
a93e31a933 |
perf(renderer): keep modal blur with independent source regions (#33799)
* perf(renderer): drop full-window overlay blurs and the idle usage-chip pulse A full-window backdrop-filter is re-blurred on every frame while anything beneath it animates, which held ~370 MB of extra GPU render-pass textures and swapchain buffers while a dialog, sheet, palette or onboarding was open. The 2px scrim blur is barely visible under the black scrim, so keep the dim only (5 points darker to keep the background as recessive) and drop the panel blur that sits under a 96%-opaque background. The status-bar usage chip also pulsed forever before its first fetch (unfocused windows never poll); show it static until a fetch is actually running. * perf(renderer): preserve modal blur with independent source regions * fix(renderer): preserve modal blur recovery and Space coverage * fix(ci): remove stale context-menu import after main merge --------- Co-authored-by: m4air <m4air@Mac.localdomain> Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com> |
||
|
|
9ae33a96f9 |
fix(native-chat): keep damaged chats readable without granting agent actions (#31931)
* fix(native-chat): validate saved next-fence floors before use * WIP: separate saved conversation observations from runtime proof * Consolidate duplicate imports for WIP compiler checkpoint * Preserve saved conversation observations with strict runtime authority * Consolidate session admission and catalog imports * fix: align conversation observation contracts and fixtures * test: update conversation observation and writer fixtures * test: use checked host fixtures for structured workers * fix(native-chat): bound conversation projection work per request * test(native-chat): consolidate scale fixture imports * test(native-chat): use checked scale fixture types * test(native-chat): bound unreadable inventory traversal * Test native CLI admission and durable reference reads * test: bound cold conversation name subscription work * test: distinguish native receipt probes from terminal identity * test: retain exact mutation refusal recovery identity * fix: explain agent conversation preparation refusals * test: adapt remaining conversation readers and document CLI timeout * fix: register preparation refusal English message * test: align conversation fixtures with checked read APIs * test(native-chat): use checked conversation in Codex fixture |