Commit Graph
2079 Commits
Author SHA1 Message Date
Jinwoo Hong bad74e1b7c test(sidebar): the desktop window and a phone reading the feed draw the same list (dark) (#30426)
* test(sidebar): the desktop window and a feed reader draw the same list (dark)

* fix(sidebar): a feed reader lists a paired server's folders and nested workspaces as the window does (dark)

* fix(sidebar): the paired-server shadow compares the lineage the server's check keeps (dark)

* fix(sidebar): paired-server rows carry the unread flag Smart Done reads (dark)
2026-10-18 18:01:45 -04:00
Kelvin Amoaba cf7423c8f4 feat(mobile): redesign the chat composer with file attachments and inline skills (#30359)
* refactor(native-chat): move the slash picker builder and upload chunking to shared

Mobile builds the same skill and command list as desktop.

* feat(mobile): redesign the chat composer with file attachments and inline skills

* fix(mobile): the composer field owns its input style

The page's font-size census cannot follow a style passed in as a prop.
2026-10-18 20:03:26 +00:00
Jinwoo HongandClaude 91b696b6cf refactor(sidebar): main keeps sleeping retention only, no order of its own (dark) (#30404)
* refactor(sidebar): the stamp-sorted window list runs no settle, latch or saved order (dark)

With ORCA_SIDEBAR_INPUTS=main the window's sort hook is a pure read of the
rows' stamps: no settled-epoch store listener, no Smart latch, no saved Smart
order writes, no class telemetry over the old attention map. Switch off: the
existing hook, unchanged.

Co-Authored-By: Claude <noreply@anthropic.com>

* test(sidebar): stamp sort hook reads no live sources; stronger switch-on tests

Co-Authored-By: Claude <noreply@anthropic.com>

* test(sidebar): clear the order-save mock between tests

Co-Authored-By: Claude <noreply@anthropic.com>

* wip: main keeps sleeping retention only

* fix(sidebar): stamp sort reads a shared empty-sources constant, not a renderer layout literal

The layout-writer ratchet counts layout field keys written in the renderer;
the empty sources object now lives beside SmartSortSources in shared code.

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor(sidebar): main keeps sleeping retention only; no order of its own (dark)

Clients sort by the owning host's stamps, so main's temporal owner loses its
settle window, Smart latch, create grace and catalog-listing classifier, and
the shadow check stops comparing order. Retention, its clock and its shadow
comparison stay.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(sidebar): every retention listing shares one sequence; publish after the first

Co-Authored-By: Claude <noreply@anthropic.com>

* test(sidebar): the first listing bumps the retention revision

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-18 15:51:52 -04:00
Jinwoo Hong bde20afb1d Only the tabs the window just changed wait for main's answer; the window-wide layout hold goes (dark, layout-owner build only) (#30384)
* chore(layout): the drift check's ignore comment names every main-only kind (dark, layout-owner build only)

* fix(layout): a quit stage retried after a failed one still sends the resume records (dark, layout-owner build only)

* feat(layout): the window's local layout stream reopens after a loss, and its snapshot redraws every workspace (dark, layout-owner build only)

* fix(layout): a command whose target main's copy lacks is a logged refusal, not the window's own change (dark, layout-owner build only)

* feat(layout): frames keep each tab the window drew, closed or moved as drawn until main answers; the global frame hold goes (dark, layout-owner build only)

A refused draw-first terminal create is closed (its terminal stopped) at the refusal. The
activation create no longer draws main's tab itself while the stream is down: the reopened
stream's snapshot does.

* fix(layout): a tab move or drag-out the frame already drew is not placed again by the window (dark, layout-owner build only)

Also holds the group sizes the window drew until main saves them.

* test(layout): with frames flowing, a pin promotes a preview tab once and tab-change bookkeeping runs once (dark, layout-owner build only)

Also states that the held-tab overlay builds frame slices only.

* test(layout): read the rename's title without a cast

* chore(layout): the drift check's header lists the same ignored records as its inline comment
2026-10-18 14:13:15 -04:00
Neil 1938bd055a refactor(ipc): group SSH and runtime-environment IPC handlers into ipc/ssh/ and ipc/runtime-environments/ (#30362)
git mv plus import, vi.mock and path-literal rewrites; e2e route regexes and the Windows host lane
filter follow the moved handlers.
2026-10-18 08:11:52 -07:00
Neil 658953dc23 refactor(ssh): group system-ssh transport, ssh config and remote exec into ssh/{system-transport,config,remote-exec}/ (#30355)
git mv plus import, vi.mock and path-literal rewrites; one e2e route regex follows the moved
dynamic-forward process.
2026-10-18 07:26:10 -07:00
Neil d7aea6dc28 refactor(managed-server): move host state (state locks, Windows host ops, machine homes) into src/main/managed-server/host-state/ (#30347)
orcad-state-*, orcad-windows-host-* and orcad-machine-* leave src/main/ssh. git mv plus import and
path-literal rewrites, including the Windows host lane's test path in its workflow and PowerShell
runner.
2026-10-18 06:39:56 -07:00
Neil 506aa03195 refactor(managed-server): move the managed server's lifecycle into src/main/managed-server/lifecycle/ (#30343)
orcad-managed-*, orcad-runtime-*, orcad-stdio-bridge-*, orcad-decommission-* and orcad-rollback-*
leave src/main/ssh. git mv plus import and path-literal rewrites; two e2e route regexes learn the
new folder. orcad-runtime-maintenance stays for now because open #29834 edits it.
2026-10-18 06:01:46 -07:00
Neil d38299290d refactor(managed-server): move the managed server's install and deploy code into src/main/managed-server/install/ (#30335)
orcad-remote-*, remote-install-*, remote-node-runtime-store-*, remote-versioned-install and
remote-deploy-timing leave src/main/ssh. git mv plus import and path-literal rewrites; one e2e route
regex learns the new folder. orcad-remote-deploy and orcad-remote-node-runtime-report stay for now
because open PRs #29834 and #29829 edit them.
2026-10-18 05:20:19 -07:00
Neil 50c06d572a refactor(ssh): move port forwarding into ssh/port-forwarding/ and hostile-host harnesses into ssh/hostile-host-test-support/ (#30277)
git mv plus import, path-literal and workflow path-filter rewrites only.
2026-10-18 04:35:04 -07:00
Neil aa07d5891a fix(mobile): break the transport and terminal-document import cycles, and gate cycles after mobile's install (#30290)
* fix(mobile): break the transport and terminal-document import cycles and gate them after mobile's install

client-context re-exported the host-client hooks, which import client-context back: the re-export
barrel is gone and importers (and their test mocks) name host-client-hooks directly. In the terminal
document, the cell-metric getters move to a leaf cell-metrics module and select-mode entry/exit to
selection-mode, so fit, transform, overlay and range no longer import each other. pr.yml lints imports
before mobile's install, when mobile's tsconfig can't load, so Mobile verify now runs the same import
rules over mobile after its install with zero warnings allowed.

* fix(mobile): the browser-pane render harness imports useHostClient from host-client-hooks

Its route source is a template string, so no typecheck saw the removed client-context re-export; the mobile web bundle check did.

* fix(ci): the e2e typecheck ratchet counts the same with or without mobile's install

Specs reach mobile/src/transport, whose expo-crypto and async-storage imports resolve only after mobile's install and then load React Native's globals (numeric timers, a required NODE_ENV), adding errors in unrelated specs. An empty stub pins both, so the static job reads 232 either way.
2026-10-18 04:00:24 -07:00
Neil 0627cd2bd6 refactor(managed-server): move orcad activation into src/main/managed-server/activation/ (#30320)
First slice of the desktop side of managed orcad leaving src/main/ssh. git mv plus import and
path-literal rewrites; host-lane workflow filters and the cross-host prefix list gain the new folder.
2026-10-18 03:59:34 -07:00
Neil db17b33ef9 ci: ratchet the legacy relay fence (importers of ssh/legacy-relay/ and COMPAT(legacy-relay-bridge) seams) (#30317)
Both lists may only shrink, so the 2027-01-15 retirement edits a known set of files.
2026-10-18 03:41:49 -07:00
Neil 2d1ec53533 refactor(ssh): fence the legacy relay in ssh/legacy-relay/ and drop the relay name from live deploy primitives (#30292)
Moves legacy-relay-bridge/ plus the relay-only census and endpoint files into ssh/legacy-relay/,
so the 2027-01-15 retirement deletes one folder. Live install, exec and framing modules that only
carried the relay name become remote-*. git mv plus import, path-literal, routing and workflow
path-filter rewrites only; no remote file name or path changes.
2026-10-18 03:17:41 -07:00
Jinwoo Hong fc24ac3715 Window saves stop carrying tab and pane layout; main keeps its own (dark, layout-owner build only) (#30282)
* fix(layout): an SSH pane's terminal binds in its own session partition (dark, layout-owner build only)

Main keeps its own layout over a window save, so a binding only a save carries is lost. A window
or runtime spawn of an SSH pane bound in the local partition; it now binds where the pane's layout
lives.

(cherry picked from commit beb2275b45)

* test(layout): the SSH binding test uses the shared spawn commit dependencies

(cherry picked from commit 672b641897)

* fix(layout): main moves a tab between a local and an SSH workspace itself (dark, layout-owner build only)

moveTabToWorkspace across two partitions was refused as other_partition and left to the window's
save. Main now reads both partitions, moves the tabs as within one, and writes both in one durable
mutation.

(cherry picked from commit ee27a0bb07)

* chore(layout): one binding write for the partition choice; shipped builds keep their exact replaced-binding read

* fix(layout): window saves keep main's layout and give it only the window's view and facts (dark, layout-owner build only)

windowViewSaveForMain/windowViewPatchForMain replace windowSaveForMain: main's own layout joined
with the window's view, facts and carried fields, written only into the records that change. A
paired server's partition passes through. A visited workspace main holds keeps its terminal row
(D1). The P10 pending case is on.

(cherry picked from commit 0c2fc15974)

* fix(layout): the save divergence detector becomes a report-only drift check behind its log (dark, layout-owner build only)

It no longer wraps the write: it compares the window's raw save with main's layout model, and
only when ORCA_LAYOUT_SAVE_DIVERGENCE_LOG is set.

(cherry picked from commit 6bc1e5556f)

* fix(layout): tab reconcile and terminal reconnect stop writing tab structure (dark, layout-owner build only)

Main's frames draw the tab bar and rows: reconcile still returns its counts but writes nothing,
and reconnect still advertises restored terminals but leaves the rows to main.

(cherry picked from commit ef8eb625ca)

* fix(layout): a layout command main cannot apply is a logged refusal, not the window's own change (dark, layout-owner build only)

other_partition, a thrown call, and host_not_owned for a workspace that is not a paired server's
are refused and logged: a window save no longer carries the change, so drawing it would last only
until the next frame. A twin main may route to a paired server keeps today's path, as does the
first terminal's host_not_owned fallback.

(cherry picked from commit 2c513b2d10)

* fix(layout): the window's refusal code type keeps main's host refusals

(cherry picked from commit 36d46bdcc2)

* fix(layout): the quit checkpoint records only the quit capture's resume records in main (dark, layout-owner build only)

Main keeps its own resume records over a window save, so the quit capture's changes, which reach
main as async commands, could miss the quit. The capture now sends only what it changed with the
synchronous stage, and main writes them through the record-only sleep command before staging; a
wake main recorded that the window had not seen stays.

(cherry picked from commit 2a0f433c34)

* test(layout): the quit capture test builds a typed resume record

(cherry picked from commit d92d1246ee)

* chore(layout): one layout write per save handler

* chore(layout): shipped builds keep their exact quit capture

* fix(layout): the drift check compares structure only, not records main writes itself (dark, layout-owner build only)

Pane bindings and resume records, default-tab marks, closed-tab records and terminal row owners
are main's own writes; a save that has not caught up with them asks main for nothing, so they are
no longer reported.

(cherry picked from commit 93e8b2627c)

* test(layout): relaunch first-terminal cases, and the side-by-side resume case moves its tab the way the window does

(cherry picked from commit ab381332b1)

* test(layout): the relaunch case also checks a reopen that cleared read-only

(cherry picked from commit bbf3d040c8)

* docs(layout): the drift check names the record kinds it ignores

* revert(layout): drop the SSH binding partition change; SSH terminal starts are refused before any binding is saved

getProvider refuses every non-local host, so neither spawn path reaches persistPtyBinding for an
SSH pane, with the switch on or off.

* test: run A2's two real-SQLite session tests in the Node runtime project
2026-10-18 02:56:38 -07:00
Neil 10505696a2 ci: ratchet tests/ type errors so a broken spec import can't land unnoticed (#30286)
tests/ is typechecked by nothing in CI, so the Windows CLI matrix spec imported a helper that never existed (#30231). Per-file error counts under tests/ (tsc -p config/tsconfig.e2e.json) may now only go down.
2026-10-18 02:35:04 -07:00
Neil 019417bd86 refactor(ssh): import the system-ssh and ssh -G modules directly, not through re-export shims (#30255)
Deletes ssh-system-fallback.ts and the re-export lines in ssh-config-parser.ts, ssh-connection.ts,
system-ssh-file-binary-transfer.ts and ssh-remote-powershell.ts; importers name the real modules.
SshConnection tests mock each real module, keeping the parser stub that holds ~/.ssh/config out.
2026-10-18 02:34:30 -07:00
Neil acc235187f refactor(runtime): move runtime/browser-host-* into runtime/browser-host/ (#30275)
git mv plus import and path-literal rewrites only.
2026-10-18 01:42:31 -07:00
Neil ecb1d6859c refactor: compatibility folders name their entry modules instead of an index barrel (#30269)
Deletes remote-layout-snapshot/index.ts and workspace-layout/old-client/index.ts. The compat-boundary
check now lists each folder's entry modules, so deleting the folder plus its listed importers'
import lines still removes the path.
2026-10-18 01:36:12 -07:00
Neil 2c12c1edf1 refactor(runtime): move runtime/relay to runtime/mobile-cloud-relay (#30274)
The folder is the cloud relay that reaches phones; under its old name it read as the legacy SSH
relay. git mv plus import and path-literal rewrites only.
2026-10-18 01:35:40 -07:00
Neil a2946f0a65 chore(worktree): composeWorktreeId plus a ratchet on hand-built worktree ids (#30238)
Worktree ids built as `${repo.id}::${path}` by hand are how one worktree got two
spellings (#30150). New code composes them through src/shared/worktree/id.ts; the
ratchet counts the remaining hand-built ids per file (18) and may only go down. Six
byte-identical `${repo.id}::${repo.path}` sites move to getRepoMainWorktreeId.
2026-10-18 00:51:41 -07:00
Neil 1e4d65ea51 ci: path-literal check scans live gate references; historical gate commands move to currentCommand (#30252)
Gate evidence prose and evidence runs record what ran then, so the check reads only each gate's
commands and test files (baseline 53 -> 14). Four evidence-pinned historical commands that named
deleted tests are removed from their gates' commands and their runs point at the successor via
currentCommand, the manifest's existing mechanism. One live command drops a deleted updater test.
The managed-SSH catch-all route is renamed remote-sources and its test joins the route contracts.
2026-10-18 00:35:33 -07:00
Neil a912265d47 ci: start the SSH host lanes for the SSH transport, the WSL orcad lane for orcad's WSL boot code, and cross-version cells for the WebSocket transport (#30239) 2026-10-18 00:23:29 -07:00
Neilandzhangxaochen 720f45c8f7 Fix mobile Source Control rendering for large branches
Render committed branch changes as virtualized SectionList rows for clean and dirty working trees, keeping all files accessible without delaying Back. Share the existing sleek scrollbar rules with mobile web pages and retain explicit hidden-indicator settings.

Fixes #30170. Review reference: #30171; thanks to @zhangxaochen for the diagnosis and initial proposed fix.

Co-authored-by: zhangxaochen <zhangxaochen@163.com>
2026-10-18 00:20:23 -07:00
Neil 262a61703a ci(e2e): start the managed-SSH lane for every helper only its specs import (#30233)
* ci(e2e): route every helper only managed-SSH specs import to their lane, by import graph

* ci(e2e): normalize import-closure paths to / on Windows
2026-10-18 00:06:24 -07:00
Neil 7ede32ec12 ci: fail when CI config, workflows or e2e code name a src/ file that no longer exists (#30224)
* ci: ratchet src/ path literals in CI config, workflows and e2e code that name no file

* ci(path-literal): resolve relative imports exactly

* ci(path-literal): resolve against tracked files only; read ./src imports

* ci(path-literal): scan src/packages and src/types references too

* ci(path-literal): skip paths quoted in comments

* ci(path-literal): keep a recursive glob's boundary

* ci(path-literal): strip comments with a string-aware scan; any import occurrence is exact

* ci(path-literal): imports need a module or index; relative globs and folders stay prefixes
2026-10-18 00:02:58 -07:00
Neil f47337d852 refactor(worktree): one worktree path equality; the ipc copy folded WSL ext4 tails (#30227)
src/main/ipc/worktree-path-comparison.ts kept its own areWorktreePathsEqual and
dedupeWorktreesByPath. Its Windows branch lowercased a WSL UNC path's ext4 tail, so two
case-twin WSL checkouts merged into one row in removal safety, folder-upgrade dedupe and
the SSH listing fallback. Every caller now uses git/worktree-path-comparison, which gains
the macOS /private/tmp fold the ipc copy had. worktreePathComparisonKey keeps its exact
bytes (retirement namespace keys persist it) in worktree-path-comparison-key.ts, and the
worktree-logic re-export goes.
2026-10-18 00:02:29 -07:00
Neil 9085c5bb87 build(packaging): fail when orca serve's serve-selection entry or a chunk it requires is left in app.asar (#27404) (#30228) 2026-10-18 00:01:46 -07:00
Neil 6afbe49c17 chore: delete unimported SSH, renderer and orchestration modules (#30214)
Removes modules with no importers on main (and their tests), the unused
RELAY_DEPLOY_TEARDOWN_TIMEOUT_MS constant, and the ssh-connection-utils
re-export of ssh-auth-resolution that only its own test used.
2026-10-17 23:47:51 -07:00
Neil 932dc1be29 chore(runtime): delete the never-served TLS branch of the LAN WebSocket server (#30220)
No released build ever passed a certificate to WebSocketTransport or set the pairing TLS
fingerprint; only ws-transport's own tests used tls-certificate.ts. The tests now run over ws://.
2026-10-17 23:44:42 -07:00
Neil 9a86d271dc chore(updater): delete the rollout-flag module nothing reads (#30211)
The nudge request parsed and stored a rollout block, but no build ever read a flag from it.
Drops the module, its call site, its tests, and the e2e env that fed it.
2026-10-17 23:38:45 -07:00
Neil d4aa9dcadc revert: restore pinned npx skills installer (#30207)
Reverts #30185 so the separate installer project can proceed. The restored shared command already pins skills@1.7.2 for CLI, desktop updates, and setup commands.
2026-10-17 23:24:02 -07:00
Neil 1e29bd1907 ci(e2e): route remote product sources without a hand-kept route to the managed-SSH lane (#30210) 2026-10-17 23:15:50 -07:00
Neil 553bde347a ci: simplify CocoaPods pin validation (#30208) 2026-10-17 23:09:25 -07:00
Neil 4baacca5c0 fix(startup): shell PATH probe falls back and retries when the shell cannot launch (#30204)
* fix(startup): shell PATH probe falls back and retries when the shell cannot launch

* chore: drop hydrate-shell-path from the process-host direct-import baseline
2026-10-17 22:54:54 -07:00
Neil ffb818bf61 Ship the locked skills installer instead of executing npx (#30185)
* security: ship a locked skills installer instead of running npx

* chore: remove retired skills process import exception

* test: include the locked installer in packaged layout fixtures

* test: reuse the real installer builder for package fixtures
2026-10-17 22:51:14 -07:00
Neil dcfe8c9e6c perf(typecheck): pin Bun as a devDependency and typecheck with it (#30149)
* perf(typecheck): pnpm tc uses the pinned Bun checker when available

bun check (Bun 1.4.3, TypeScript 7.0.2 parity, already used by CI) checks the
node project in ~29 CPU-s / ~2 GB peak vs tsc's ~98 CPU-s / ~16.6 GB. tsc's
incremental cache rarely helps agents: noEmit builds store no declaration
signatures, so the first edit to any file after a cold check re-checks every
transitive importer (a comment in src/shared/constants.ts re-checks all 18k files).

pnpm tc / tc:node / tc:web / tc:cli now pick the Bun from config/.bun-version when
it is on PATH and fall back to tsc with a one-line hint otherwise;
--compiler=native forces tsc. The pinned-Bun probe is shared with the
localization extraction check.

* build: pin Bun as a devDependency and make it the only default checker

The PATH probe left anyone without the exact pinned Bun (including a 1.4.2
global) on tsc's expensive path. bun@1.4.3 is now a devDependency, its
postinstall is allowed, and pnpm tc / typecheck:ci run that binary. A missing
binary is an error pointing at pnpm install rather than a silent fallback;
--compiler=native still selects tsc. A test keeps the devDependency equal to
config/.bun-version.

* ci: link the pinned Bun after the script-free install

--ignore-scripts leaves node_modules/.bin/bun as bun's postinstall stub, so the
typecheck runner found no binary and any pnpm-run script calling bun would hit
the stub before setup-bun's copy. pnpm rebuild bun runs only that allowed build.
2026-10-17 22:43:00 -07:00
Jinwoo Hong b8264e860b Main drops the layout of workspaces the catalog no longer validates (dark, layout-owner build only) (#30177)
* feat(layout): main drops the layout of workspaces the catalog no longer validates (dark, layout-owner build only)

* rename the paired-host check so the switch-off bundle keeps its names

* a repo id two hosts register skips the listing purge
2026-10-17 22:19:35 -07:00
Neil a42049f297 fix(tooling): lock routine dependency audit executables (#30183) 2026-10-17 22:12:03 -07:00
Jinwoo Hong 303c7c91ef fix(sidebar): main's temporal owner reads the catalog the way the window does (dark) (#30166)
* fix(sidebar): main takes its row baseline from the session's catalog and skips unchanged listings

* fix(sidebar): read catalog listings the way the window's merge does

* fix(sidebar): a seeding listing re-samples, and listings compare with the window's equality
2026-10-17 21:32:33 -07:00
Jinwoo Hong bf97836ae0 Pane titles stay layout: the window stops writing tab names as pane titles, and main loads them as the window does (dark, layout-owner build only) (#30136)
* refactor(shared): move the pane title sanitizer to shared, unchanged

So main's layout Loader can apply the same rule the window applies on load.

* fix(layout): pane titles stay layout in a layout-owner build (dark)

The window stops writing a revealed terminal's tab name as its pane title,
and main's Loader drops a lone pane title that only repeats the tab's name,
as the window's load does. Both behind ORCA_LAYOUT_OWNER_IS_MAIN.

* fix(layout): the Loader compares a lone pane title with the tab bar's quick command label too (dark)

As the window's row hydration does when the row has no label.

* fix(layout): the Loader compares a lone pane title with the tab bar label, the live title (dark)
2026-10-17 20:59:57 -07:00
Jinwoo Hong 3aad2b17b0 feat(sidebar): dark phone feed of the sidebar inputs (sidebarInputs.read) (#30161)
* feat(sidebar): dark phone feed of the sidebar inputs (sidebarInputs.read)

* fix(sidebar): feed review: fresh read on ready, notices kept per revision, one flush owner, closed connections never subscribe

* fix(sidebar): feed skips values JSON cannot hold; a failed read forgets its notice

* fix(sidebar): name the feed batch key by where the batch starts from
2026-10-17 20:46:10 -07:00
Neil 1b3113de8e fix(ssh): a tab closed while a managed host is disconnected stays closed; deflake the shared-home spec (#30146)
* fix(ssh): a tab closed while a managed host is disconnected stays closed after Connect

#30130 made a user's Disconnect mark the host's managed server manually
disconnected, so the desktop now answers its calls itself with
runtime_manually_disconnected. The tab close path read that as the host's
answer and dropped the close instead of holding it for replay, so the tab
came back on reconnect. Treat it as an undelivered close, and route the
Disconnect sources to the managed-orcad Docker lane.

* test(e2e): close the disconnected host's tab the way a user does

The journey called the store's bare closeTab, which sends only terminal.close
and holds nothing; it passed only because the disconnected host used to be
redialed in the background, which #30130 stopped. Click the tab's X instead,
the path that holds and replays an undelivered close.

* test(e2e): the shared-home spec tells a host's own server from a PID that only collides

Each Docker host has its own PID namespace, so the PID host A records in the
login-home slot can belong to an unrelated live process on host B; kill -0
alone then read it as B running from A's slot. Count a recorded PID only when
its process runs from that slot.
2026-10-17 20:23:19 -07:00
Neil d71e3e9d45 fix(serve): orca serve on orcad serves the browser client and answers plain HTTP (#30120)
* fix(serve): orca serve on orcad serves the browser client and answers plain HTTP

orcad, the default local orca serve host since the compatibility launcher,
was never handed the app's web client directory, so its HTTP server had no
request listener: every GET hung and no Web client URL was printed (#30100).

The CLI now passes the app's unpacked out/web to orcad via --web-client-root,
a server without a web client answers plain HTTP with 404 instead of hanging,
and packaging fails when the unpacked web client or a file it loads is missing.

* test(serve): pin orca serve handing orcad the app's web client root
2026-10-17 16:51:37 -07:00
Neil 532cad2cb3 fix(renderer): destructive host callers refuse an ambiguous owner instead of reading it as local (#30035) 2026-10-17 16:42:43 -07:00
Neil 299dcb86fc fix(worktrees): a host-scoped purge leaves a surviving twin's tabs and edits alone (#30030) 2026-10-17 16:29:17 -07:00
Jinwoo Hong a039e9064b feat(sidebar): main keeps the list's time rules on one clock, checked against the window (dark) (#30104)
* refactor(sidebar): move the Smart comparator and attention scoring to src/shared/sidebar-list

Main needs them to own the frozen order. Renderer helpers they depend on move with
them; the window imports the shared copies. No behaviour change.

* refactor(sidebar): one shared ranking for the frozen sort order

The window's sort memo and the palette's Smart sort now call rankWorktreesForSort,
so main can produce the same order from its own records. The pure state-history
step moves to shared for the same reason. No behaviour change.

* feat(sidebar): main keeps the list's time rules on one clock, checked against the window in dev and test

* test(sidebar): fake-clock parity of main's temporal owner against the window

* fix(sidebar): main restarts the settle window only where the window's sortEpoch bumps

* test(sidebar): type the owner harness without an assertion

* fix(sidebar): main's temporal owner stays idle until a dev or test window begins a session

* fix(sidebar): main reads Hide sleeping from the field the window persists

* refactor(sidebar): keep the begin params in their own contract module so the snapshot schema compiles out

* chore: restore files the merge's formatter rewrote to their origin/main content
2026-10-17 15:57:54 -07:00
Brennan Benson 285f95c045 fix(mobile): a compact phone queue: shorter header, a capped scrolling list, and an editor that fits the card (#30016)
* fix(mobile): a compact queue: shorter header, a capped scrolling list, and an editor that fits the card

* fix(mobile): keep queue actions visible and reveal new cards

* test(mobile): allow shared SVG host fixture

* fix(mobile): queue header and editor controls grow with large system text instead of clipping

* fix(mobile): at large text sizes the queue header's buttons wrap below its label instead of squeezing it out

* fix(mobile): at large text sizes the queued editor's Cancel and Save wrap below its heading instead of truncating it

* fix(mobile): at large text sizes the queue header's and editor's buttons take a line of their own

* fix(mobile): the large-text button lines wrap when one button is all a small phone's line holds

* test(mobile): the composer tray test's react-native stub reports the text scale

* fix(mobile): while a card is edited at large text, the paused header's button line gives its height to the editor
2026-10-17 13:47:48 -07:00
Jinwoo Hong cf6a5446a6 Show which desktop the mobile Tasks screen is for (#30105)
* feat(mobile): name the desktop under the Tasks title

Tasks can open on any connected desktop, so the header now shows which
one, in the same subtitle line the host screen uses under its title.

* fix(mobile): reserve the Tasks desktop line so the title does not jump

The subtitle line now holds its height before the host profile is read,
a failed read leaves it blank, and the tests cover a desktop switch
while a read is in flight.

* test(mobile): re-measure the page script sweep after the Tasks subtitle

The Tasks route now shares the host screen's styles, so it emits one
script fewer (77 to 76 at its prefix, 80 to 79 for the tree). Re-swept
every route prefix; the worst route step is now 11.
2026-10-17 13:20:33 -07:00
Brennan Benson 216e3e42a6 fix(native-chat): a Codex chat is Working only while Codex holds the send (#29922)
* fix(native-chat): a Codex chat is Working only while Codex holds the send

Working read 'a send still pending delivery', so any echo or idle signal
that never arrived (a hook-blocked prompt, an answer naming no turn, idle
before a timed-out send was written) kept the chat Working, Stop up, the
queue frozen and /compact refused until the agent exited.

Codex now reports which sends it still holds: unanswered, answered into a
turn that has not ended, or answered into none while a status read after
that answer says the thread runs. Replies and statuses are ordered as they
are read, so a stale status cannot release a newer send. The host reads
that set (plus the short window while it hands a send over) for Working,
publishes a send the child stopped holding as in doubt on every page and
frame so older clients agree, and republishes when the set changes with no
row. The Codex idle latch and its release are removed.

* fix(native-chat): name the handover journal type; reverse without mutating

* test(native-chat): a lost Codex answer while idle is no longer the chat's work; run the held-sends test with the database runtime

* fix(native-chat): bound work updates and own command handovers

* refactor(native-chat): reuse session delivery plumbing

* test(native-chat): allow separate ownership restatements

* test(wire): resolve the release tab predicate after relocation

* test(native-chat): reuse existing promise and empty-batch primitives
2026-10-17 13:14:15 -07:00