Commit Graph
13768 Commits
Author SHA1 Message Date
OrcaWinandm4air 61aaa98eb3 refactor(renderer): remove the keyboard-handlers barrel and partial re-exports (#27986)
Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-12 07:02:24 -07:00
OrcaWinandm4air 0eaa04c045 refactor(renderer): remove the web-terminal-surface-id re-export (#27981)
Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-12 06:41:49 -07:00
OrcaWinandm4air 6be60909c7 refactor(renderer): remove the runtime-git-client barrel (#27977)
Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-12 06:21:07 -07:00
OrcaWinandm4air 5763792718 refactor(renderer): remove the runtime-file-client barrel (#27975)
Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-12 06:05:04 -07:00
OrcaWinandm4air f8daed0d98 refactor(renderer): remove the web-session-tabs-sync barrel (#27969)
Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-12 05:30:29 -07:00
OrcaWinandm4air 41fc9542b3 fix(ssh): never start a hidden orcad shell for a tab the legacy relay bridge serves (#27939)
* fix(ssh): never start a hidden orcad shell for a pane the legacy relay bridge serves

* fix(ssh): a skipped bridged activation still supersedes an earlier tab's pending focus

* fix(ssh): a click on a whole mirrored tab never activates its bridged pane on orcad

* fix(ssh): load the bridge pane list lazily from tab activation

---------

Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-12 04:47:01 -07:00
OrcaWinandm4air bce860fec8 refactor(renderer): remove the web-runtime-session barrel (#27967)
Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-12 04:45:32 -07:00
OrcaWinandm4air 3c49cdf09c refactor(providers): import provider contracts directly (ipc); delete the barrel (#27966)
Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-12 04:44:48 -07:00
OrcaWinandm4air c77bebfb7b refactor(providers): import provider contracts directly (runtime) (#27965)
Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-12 04:18:56 -07:00
OrcaWinandm4air 4ad0129984 refactor(orcad): orcad artifacts live under orcad/ and node-runtime/ (#27963)
Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-12 04:16:28 -07:00
OrcaWinandm4air 7c13365f03 refactor(build): relay survivors named for what they are (#27962)
Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-12 04:09:18 -07:00
OrcaWinandm4air 799ec595ba refactor(ssh): remove the ssh-relay-deploy-helpers re-export module (#27961)
Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-12 03:59:05 -07:00
OrcaWinandm4air 93e0b80be7 refactor(cli): serve children spawn through process-host (#27760)
Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-12 03:23:49 -07:00
OrcaWinandm4air b368ebc7a6 refactor(ssh): delete relay-only GC, takeover and install remnants (#27770)
Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-12 03:23:17 -07:00
OrcaWinandm4air 33ddc1ab7f fix(ssh): an old relay terminal's tab shows output again after a reconnect (#27951)
* fix(ssh): a bridged pane reattaches after a disconnect instead of going deaf

* fix(ssh): a bridged pane asks again when it turns live during an earlier ask

---------

Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-12 03:21:30 -07:00
Neil cfbf3610d5 fix(linux): keep Wayland clipboard text current (#27772)
Publish Linux Wayland text copies with an independent clipboard owner, then clear Chromium's stale source only after publication succeeds. Use data control where available and GTK's clipboard bridge on GNOME. Keep macOS, Windows and X11 on their existing Electron writers.

Temporary workaround for https://github.com/electron/electron/issues/54645, with removal checks documented in the native README.

Verified full build, macOS arm64 packaging, Linux x64/arm64 library floors, clipboard/platform tests, real Wayland copy/paste and CI packaging.

Fixes #26917
Fixes #23229
2026-10-12 02:31:03 -07:00
OrcaWinandm4air 822bd9f972 fix(ssh): keep 1.4.224's running terminals working after the upgrade (legacy relay bridge) (#27787)
* wip: legacy relay bridge client

* Revert "fix(ssh): end an older Orca's relay terminals from the connect refusal (STA-10166) (#27748)"

This reverts commit d4a55f583e.

* feat(ssh): bridge terminals an older relay still runs into their old tabs

* test(ssh): cover the legacy relay bridge client, target bridge, transport and gate

* test(ssh): type the bridge test fakes without assertions

* test(e2e): a 1.4.224 relay's live terminal survives the upgrade on a Docker SSH host

* ci(e2e): route legacy relay bridge changes to its Docker spec

* fix(ssh): bridge delta moves too, and never read a non-exhaustive relay listing as exit

* fix(ssh): keep retrying a bridge for panes that mount before connect; end panes proven gone

* fix(ssh): bridge 1.4.224's detached leases through export preflight; publish every leased pane before the first look

* test(e2e): build the released relay out of process so Playwright never loads ESM build tooling

* fix(renderer): drop the recovery hook main removed from PtyTransport

* test(e2e): show the converted worktree before reading the bridged tab

* test(e2e): reconnect and wait for the converted host before opening the bridged tab

* fix(renderer): match bridged leases to tabs mirrored from the managed server

* test(e2e): find the mirrored relay-era tab under any worktree key

* test(e2e): open the converted worktree before looking for its mirrored tab

* test(e2e): a retired lease is terminated or pruned

* fix(ssh): back off attaches a listed terminal refuses; one pane per bridged shell

---------

Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-12 02:24:12 -07:00
Brennan Benson 564693f176 fix(cli): honor Chat UI setting for worktree agent creation (#27796)
* fix(cli): honor Chat UI setting for worktree agent creation

* fix(cli): preserve older host launch and worktree lineage warnings
2026-10-12 02:14:43 -07:00
Brennan Benson c43ac3fc3c Resume dialog: show a finished resume as a result, not a picker (#27732)
* fix(native-chat): show a finished resume as a result, not a picker

Once a resume starts and no chat is left to choose, the dialog drops the
Select all row and the checkbox column, so each chat's check reads as its
status instead of a ticked box. The Don't-ask-again box only shows while
choosing; a run started by the launch's auto-resume says so and links to
the setting. The finished description is past tense.

* fix(i18n): keep Agent untranslated in the ja resume copy

* fix(native-chat): keep resume results actionable and keyboard accessible

* Fix hidden resume preference replay after run starts

* Consume resume picker preference after applying it

* fix(native-chat): keep Don't ask again after Resume while auto-resume is off

The box now shows on the result view too whenever the setting is off and the
user started the resume, and saves only while it is visible, so a hidden tick
still never replays. Automatic launches keep their 'Resumed automatically'
note instead.
2026-10-12 01:22:21 -07:00
Neil 45fd65ec3e fix(chat): show hook failure details in error cards (#27824)
* fix(chat): show hook failure details in error cards

* test(daemon): pin clock for stable-launch budget assertion
2026-10-12 01:12:17 -07:00
Neil c95da2a8d7 test(daemon): pin clock for stable-launch budget assertion (#27850) 2026-10-12 01:10:36 -07:00
Jinwoo Hong 7cb30b7f8f feat(mobile): let the OTA page send extra top-level request fields (#27815)
* feat(mobile): let the OTA page send extra top-level request fields

A page request could only carry method, params and three fixed options, so any new
top-level wire field needed a new app binary. Requests and subscribes now carry an
optional verbatim `envelope`, gated by a new `rpcEnvelope` grant; nothing sets it yet.

Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb

* refactor(mobile): one envelope merge seam per transport

Review follow-up: the direct tracker and registry now hand frames to a single
sendFrame that adds the credential and envelope, like the relay; page refusals
use one fixed code per error class and an envelope-only options bag posts no options.

Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb

* fix(mobile): refuse a non-object envelope before treating it as empty

null threw synchronously and [] or a Date read as empty and was dropped; the schema
now runs first. The tracker tests settle their requests instead of leaving timers.

Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb

* refactor(mobile): type the direct socket's request as the wire request

The typecheck now proves every direct request carries the transport fields, and the
native-verb fence says why it drops an envelope. No behaviour change.

Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb
2026-10-12 04:02:25 -04:00
Brennan Benson 14ec470146 fix(terminal-pane): a confirmed agent process exit removes the agent from the running list (#27742)
In shells that send no command-finished mark (cmd.exe, Git Bash), quitting
Claude or Codex left the pane's live agent row behind: the pane's process
monitor confirmed the exit, but only the OSC 133;D path ever dropped the row.

The monitor's confirmed exit now arms the same drop and main-side reconcile
pair a confirmed 133;D uses, settled behind the existing host-verifiability
gate: a pane whose owner process the host can verify keeps the host's
decision; every other pane drops the row and keeps its resume identity.
Skipped when a 133;D drop is already armed, for remote panes, and when the
row belongs to another agent.
2026-10-12 01:01:38 -07:00
Brennan Benson 5428bd97b9 fix(tab-bar): offer Resume in New Native Chat only while the tab's agent is running (#27520)
The terminal tab menu found its conversation through the tab-title lookup, which also
falls back to retained and sleeping records an exited agent leaves behind. Pass a
running-agents-only option for the move; tab titles keep the remembered conversation.
2026-10-12 00:59:13 -07:00
Brennan Benson 627716fdc1 perf(ports): stop leaving stuck lsof processes behind on a dead network mount (#27729)
* perf(ports): run lsof without blocking on dead network mounts

Without -b, lsof stat()s every mounted file system before answering. A
hard-mounted network share that stops responding blocks that call in the
kernel, so each port scan left an unkillable lsof behind. Pass -b -w to
the lsof queries that name no file (port list, process cwd, executable
path); their output is unchanged. The -U and +D queries keep stat
because -b makes lsof reject named-file arguments.

Linear: STA-9017, STA-9716

* perf(ports): name the stuck lsof helper in the comment; plain readiness test name

* test: query a known child executable in lsof readiness smoke test
2026-10-12 00:55:43 -07:00
Brennan Benson e3ef95dc04 feat(cli): launch agents in existing workspaces (#27794) 2026-10-12 00:38:00 -07:00
OrcaWinandm4air 88a82c0a7d refactor(providers): import provider contracts directly (main) (#27813)
Move the 52 non-runtime, non-ipc importers of src/main/providers/types.ts
onto the per-domain contract files. The barrel itself stays until the
runtime and ipc importers move (3.4b/3.4c).

Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-12 00:09:13 -07:00
github-actions[bot] 9a648667c3 Update README downloads badge 2026-10-12 07:04:16 +00:00
231cf2c9e7 chore(ratchet): one ratchet baseline library (#27788)
Co-authored-by: m4air <m4air@Mac.localdomain>
Co-authored-by: Claude <noreply@anthropic.com>
2026-10-11 23:52:43 -07:00
OrcaWinandm4air aeffeb4cfb refactor(pty): no ipc/pty.ts barrel (#27798)
* refactor(pty): no ipc/pty.ts barrel

* test(orcad): clarify preflight-order comment

---------

Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-11 23:45:07 -07:00
OrcaWinandm4air 8a1c63b381 refactor(shared): dedupe the local-default connection-to-host conversion and the trim helpers (#27797)
Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-11 23:40:18 -07:00
OrcaWinandm4air d327cc9418 feat(daemon): opt-in OS ceiling on terminal processes, reported per host (#27769)
* feat(daemon): opt-in OS ceiling on terminal processes, reported on or off per host

* fix(daemon): verify the ceiling is enforced, reap its slice with the daemon, and keep terminals starting when systemd-run is unusable

* fix(daemon): stop the ceiling slice before the daemon scope, and report a dropped slice as lost

* test(daemon): expect the pid record's processCeiling field

---------

Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-11 23:31:03 -07:00
Brennan Benson d3182d4bf1 Native chat: every agent launches through one composed launch path (#27204)
* test(chat): snapshot every native-chat agent's spawned child as a parity oracle

Captures the exact child each native-chat agent spawns (Claude, Codex, Grok,
OpenCode, OMP, Pi), worktree and floating, fresh and resumed, plus a registered
worker with visuals off, at the real spawn boundary (the process host's spawn)
and through production's own host dependency wiring. The inherited environment
holds every pane, hook, caller, terminal-handle and visuals key a parent Orca
pane could hand down, so the snapshot records today's per-agent differences as
they are. Each case also records the launch's permission posture, which for
Codex (thread policy) and the ACP agents (full access) acts only after spawn.

Each agent also runs fresh and resumed with every launch setting moved off its
default: a Command setting naming another binary, the permission posture
flipped, an environment overlay over inherited and shell keys, and only named
login-shell variables inherited (the fake login shell carries its own PATH and
a variable no case names).

A second test fails when a registered agent has no snapshot, since the oracle
lists its agents by hand.

Test only: the launch-path refactor that follows must leave both tests and the
snapshot file unchanged.

* refactor(chat): one composed launch for every native-chat agent

Every native-chat agent (Claude, Codex, Grok, OpenCode, OMP, Pi) now builds its
child through one composer instead of six hand-written resolvers. Each agent
contributes only its own part (command, args, agent env, keys it must strip);
the shared composer admits the session record, reads the launch directory,
base environment, launch overrides and visuals once each (memoized, in the
agent's original order), sets cwd, and seals the child.

The seal (sealStructuredSessionChild) is the one place that names a child:
session id, structured marker, worker terminal handle, the Orca CLI env, the
spawn token under one shared constant, and the per-launch list of inherited
keys to delete, minus any key the seal itself sets. Claude's delete list now
reaches its SDK spawn after buildClaudeChildProcessEnv's merge.

Behaviour is unchanged: the parity snapshot from the previous commit passes
byte for byte, including each agent's existing differences (Claude and Codex
keep inherited pane and hook env, Pi has no visuals and always full access,
the ACP history read stays unsealed). Admission refusals keep their reasons;
only log-only wording moved to the shared check.

Drops launch dependencies no production caller wires (resolveLaunchEnv,
resolveCodexOverrides) and folds the per-agent env overlay hooks into the
existing resolveAgentLaunchEnv.

* refactor(chat): only the seal names a native-chat child

Follow-ups from review of the composed launch:

- The spawn token is required on every resolveLaunch. The one read that
  starts no child, ACP's restart-recovery history read, now has its own
  path (composeStructuredLaunchRead, deps.readLaunch) that returns the
  agent's own env unsealed, as before. Agent parts receive the session
  identity only, never the token.
- structuredSessionChildIdentityEnv is gone; the seal is the only way to
  build a child's identity env, and tests go through it.
- A launch's environment is the runtime's resolveAgentEnvironment, so the
  base-plus-overlay rule exists once.
- Claude's connection test now covers a non-empty envToDelete applied
  after the inherited env is merged.

No change to any spawned child: the parity snapshot is unchanged.

* ci: run the login-shell contract job for the renamed child-env seal

The seal moved from structured-session-child-identity-env to
structured-session-child-env, but the PR job classifier still listed the old
path, so a change to only the seal would skip the live login-shell contract
job. The prefix now covers the seal, its test and its test support (which
the login-shell harness imports).
2026-10-11 23:27:04 -07:00
Brennan Benson 5035baac50 Edit agent launch settings on the workspace host (#26479)
* Add host-owned agent launch settings mutations

* Edit agent launch defaults on the selected execution host

* Await durable writes for host agent launch settings

* Fence agent detection by execution-host pairing

* Acknowledge host settings before hook reconciliation

* Preserve Reset after pending agent launch saves

* Simplify agent detection re-pair handling to the clear and the transport fence

A re-pair already clears every detected-agent list, flag and pending probe for
the environment, so the per-record pairing owner keys, the owner-keyed pending
probes, the settle-time pairing checks and the hook's ownership gating were
never reached. Detection now captures the pairing before the capability wait
and fences its RPCs with it; the refresh fallback still refuses after a
re-pair. Pins the fence across a capability wait, the needs-update clear, and
the agent-launch RPC permission levels.

* Open launch settings on the Active Server without the focus-routing helper

Main's new owner-routing ratchet counts getActiveRuntimeTarget calls, and this
pane's no-workspace default added one. It now reads the Active Server field the
way the Agents pane did before host selection, so the default is unchanged.

* Re-probe mounted launch surfaces after a re-pair; rely on the transport fence for the refresh fallback

A re-pair clears an environment's detected-agent lists, but a mounted tab bar,
quick launch or composer that was still waiting for its first list (or whose
first probe had failed) never asked again, leaving "Can't reach this
workspace's host" until another surface mounted. The hook now re-runs its
effect when the target environment's pairing revision changes.

The refresh fallback no longer re-checks the pairing in the renderer: it
already carries the pairing captured before the wait, and main refuses any
mismatch. Pins the Settings host form's remount key on re-pair.
2026-10-11 23:26:30 -07:00
OrcaWinandm4air 57a7c22d03 refactor(terminal): one remote input hold (#27781)
* refactor(terminal): one remote input hold

* fix(terminal): keep restored typing scoped to its terminal until the connect settles

* refactor(terminal): name the restored-input expectation type

---------

Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-11 22:56:15 -07:00
OrcaWinandm4air ae0ff63152 fix(serve): initialize the updater in headless Electron serve so paired clients can update it (#27771)
Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-11 22:39:47 -07:00
OrcaWinandm4air 4275ee3969 test(renderer): one runtime-environment bridge fixture (#27780)
Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-11 22:26:39 -07:00
OrcaWinandm4air 411d5c24cb feat(serve): orca serve service install|status|uninstall (#27744)
* feat(serve): orca serve service install|status|uninstall for launchd and systemd user units

* fix(serve): redact pairing secrets in the supervisor instead of an inherited env, validate the port and launcher at install

* fix(serve): keep the redaction module off a direct child_process import

* fix(serve): redact the JSON readiness offer and survive a closed log pipe

---------

Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-11 22:00:50 -07:00
OrcaWinandm4air d4a55f583e fix(ssh): end an older Orca's relay terminals from the connect refusal (STA-10166) (#27748)
* fix(ssh): end an older Orca's relay terminals from the refusal, and name the command

* test: type confirmation mocks

* fix(ssh): match old relay daemons by argv position; owner-check the Windows command

* fix(ssh): select Windows relay daemons by argv position in the manual command

* fix(ssh): keep the relay daemon marker local so census mocks stay intact

---------

Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-11 21:53:57 -07:00
Brennan Benson 30660086f2 test(launch): pin what the "+" launchers produce on main today (#27691)
* test(launch): pin what the "+" launchers and the AI buttons' window route produce on main

Row 1 ("+": menu, shortcut, dashboard) joins the window-tab table on both halves;
saved-arg tokenize failures before routing, the restart of a never-mounted "+" tab
and the AI-button host gate are pinned at the window planner.

* test(launch): cut "+" pins main already holds and check outcomes, not internals

Drop the AI-button and restart tests and the duplicate \\wsl$ folder and macOS
unclosed-quote rows; the Q5 pair now checks that no tab or startup was made.
2026-10-11 21:42:40 -07:00
OrcaWinandm4air 6c3ce444bc feat(updater): auto-park registered serve supervisors during a desktop install (#27722)
* feat(updater): auto-park registered serve supervisors during a desktop install

* test(serve): drop a type assertion in the bundle park test

* fix(updater): stop any server started during an install hold and re-list blockers right before commit

---------

Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-11 21:11:53 -07:00
Neil bb2d3090ab Share historical test source and add manual cache cleanup (#27743)
* Share immutable historical source across local cross-version test caches

* Add preview-first cleanup of old historical test caches

* Include historical test cache cleanup in worktree space maintenance

* Report and retain read-only Electron installs during cleanup

* Protect read-only installs under root and isolate cleanup CLI fixtures
2026-10-11 21:11:37 -07:00
Jinwoo Hong 2365eea5ed chore(relay): move Asia cell c35 to the general same-cap lists after promotion (#27761) 2026-10-12 00:01:19 -04:00
Neil 8259b1a3e5 refactor(ssh): keep ssh2 types out of the orcad host transport (#27689)
The orcad/remote-install transport now exposes exec as a neutral
RemoteCommandChannel (a Duplex with stdin, stderr, close and exit/close
events) instead of ssh2's ClientChannel, and drops sftp(): the only
consumer was a fallback for doubles without writeFile/uploadDirectory,
which the transport type already requires. SshConnection still satisfies
the type structurally, so the SSH adapter keeps returning the connection
itself and identity-keyed caches are unchanged.

The stdio bridge provider is split: the loopback listener (admission,
queueing, socket piping) now takes a channel factory and knows nothing of
SSH; the SSH provider resolves and checks the bridge over the host
transport and hands the listener a factory. No behavior or wire change.
2026-10-11 20:51:40 -07:00
Neil 1d571e67ec Speed up import checks, localization extraction, and CI typechecking (#27727)
* Skip unnecessary compatibility-boundary parsing and benchmark it in CI

* Use pinned preflight Bun for compatibility checks and localization extraction

* Measure two concurrent Bun projects in full preflight and update its scope test
2026-10-11 20:43:34 -07:00
Neil b4aae49de8 [CI] Replace Codex fixture executables atomically (#27747) 2026-10-11 20:40:53 -07:00
Jinjing af33858235 fix(chat): jump to messages without scrolling animation (#27612)
* fix(chat): jump to messages without scrolling animation

* Jump to chat messages instantly instead of animating the scroll

Smooth scrolling let rows measured mid-animation shift the target, so jumps could land short or cancel near the end of the transcript. Jumps now write the scroll offset directly, and the align hook keeps its target until the row settles. Tests assert no smooth scroll is requested and that a loaded target lands within one frame.
2026-10-11 20:35:31 -07:00
983532a5cb fix(bench): make bench:idle-cpu build, sample CPU and parse the process table on Windows (#27622)
* fix(bench): make the idle-CPU benchmark run and report CPU on Windows

Three independent Windows defects in the idle-CPU benchmark (its report is
what Windows performance work would cite):

- `buildAppIfNeeded` spawned `npx`, which is `npx.cmd` on Windows, so
  execFileSync failed with ENOENT before any sampling. Build through
  `config/scripts/run-electron-vite-build.mjs` instead — the repo's own
  Windows-safe wrapper, which also runs the boot-graph verification.
- `readWindowsProcesses` returned `cpuTimeSeconds: null`, so the sampler's
  per-process CPU delta (idle-cpu-process-sampling.mjs:198) fell back to
  the hardcoded `percentCpu: 0` and every CPU KPI in the report was zero.
  Read `UserModeTime`/`KernelModeTime` from `Win32_Process` (100 ns units)
  and keep `null` when a host does not return them.

Measured on Windows, same options before and after the CPU fix:

| class | mean CPU before | mean CPU after |
| --- | ---: | ---: |
| renderer | 0 | 2.20 |
| gpu | 0 | 2.08 |
| utility | 0 | 0.11 |
| agent-or-node | 0 | 0.06 |
| total | 0 | 4.51 (p95 8.40) |

RSS is unchanged (934 MiB -> 937 MiB), so only the CPU reporting changed.

Refs #25235

* fix(bench): reject a missing Win32_Process time instead of reading it as zero

Review follow-up (CodeRabbit). `Number(null)` is `0`, which is also a real
counter value, so an absent `UserModeTime`/`KernelModeTime` passed the
finite check and the sampler would report a kernel-only delta instead of
taking the fallback. Require an actual number from the CIM payload.

Verified on Windows that the real payload still reports CPU once the check
is tight: total mean 4.40%, p95 14.48%, renderer 3.51%.

* test(bench): cover the Windows CIM CPU time mapping

The mapping was only reachable through Get-CimInstance, so no test ran it.
Lift it into cimCpuSeconds and assert the 100ns-to-seconds sum plus the
missing / string / non-finite cases that must stay null.

* fix(bench): read the Windows process table as UTF-8 so JSON.parse survives

PowerShell writes to a redirected stdout in the OEM code page (437 here),
which best-fits characters such as U+2022 and U+2192 in any running
process's command line to raw 0x07 / 0x1A bytes. ConvertTo-Json had left
them unescaped because they are not control characters in UTF-16, so the
sampler's JSON.parse failed with "Bad control character in string literal"
whenever such a process happened to be alive -- hence intermittent.

Set [Console]::OutputEncoding to UTF-8, as the app's own CIM scan does,
and cover it with a Windows-only test that fails without the fix.

Fixes #25236

* fix(bench): pass the local runtime to fetchRepos in the idle-CPU fixture

fetchRepos now requires a runtimeEnvironmentId, so the fixture's bare call
threw "Cannot read properties of undefined (reading 'runtimeEnvironmentId')"
before sampling on every platform. null selects this app's own catalog, as
the e2e helpers already do.

* ci(bench): run the Windows process-table test in the Windows lane

The UTF-8 regression test self-skips off win32, so it must be registered in
both Windows lists or it runs on no machine.

---------

Co-authored-by: Paolo <paovalletta@hotmail.it>
Co-authored-by: Orca Worker <orca-worker@localhost>
2026-10-11 20:27:15 -07:00
bb12a8a1e4 fix(bench): load benchmark sources as file URLs so they run on Windows (#27621)
* fix(bench): resolve dynamically imported sources as file URLs

`await import(path.join(ROOT, '...ts'))` hands Node a bare Windows path
(`C:\...`), which the ESM loader rejects as an unsupported URL scheme
("Received protocol 'c:'"). The two benchmarks that load production
modules this way crashed on Windows before running a single scenario,
while working on macOS and Linux where an absolute path is a valid
specifier.

Wrap each computed specifier in `pathToFileURL(...).href`, the form the
other benchmark scripts already use for the same purpose.

Verified on Windows: bench:session-write-hot-path and
bench:agent-inspection-cadence now run and print their measurement
tables. The fish mode-2031 trace capture resolves its import too, but its
harness targets macOS/Linux shells and cannot complete on Windows.

Fixes #25235

* style(bench): format the session-write benchmark's file-URL import

---------

Co-authored-by: Paolo <paovalletta@hotmail.it>
Co-authored-by: Orca Worker <orca-worker@localhost>
2026-10-11 20:27:11 -07:00
Jinwoo Hong b9d1b958ee feat(relay): promotion path for Asia spare cell c35 (#27733)
Mirrors #25757 (c34): adds the c35 promotion wave, workflow promote and
canary case entries, the c35 canary evidence entry, tests, and docs.
2026-10-11 23:26:19 -04:00