mirror of
https://github.com/stablyai/orca.git
synced 2026-09-23 00:02:29 +00:00
stack-final
18
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
766b5b153c |
fix(relay): release the ConPTY conin handle after teardown, not before it (#18601)
A Windows SSH relay leaked one Windows File handle per terminal, for the life of the relay process, across reconnects. node-pty's `kill()` flips `readable` on the conin and conout sockets and destroys neither; `_cleanUpProcess` destroys `_outSocket`, so only conin is stranded, and it wraps a real named-pipe handle from `fs.openSync(term.conin, 'w')`. The obvious fix -- and the one config/patches/node-pty@1.1.0.patch ships for the desktop -- releases it at the top of the branch, before `_getConsoleProcessList()` forks and before the native kill. Measured against a real Windows SSH host, that is three times worse than leaving the leak alone: teardown aborts partway, the forked console-list agent is never reaped, and both pipe handles stay alive. Releasing it at the end of the branch instead is flat. 20 spawn/kill cycles, handles bucketed by NT object type, identical numbers standalone and through a real relay: published node-pty File +1/terminal, Process flat desktop patch placement File +2/terminal, Process +1/terminal released last (this) File flat, Process flat `windowsTerminal.js` takes the desktop's error-listener hunks verbatim. The conin listener is not what fixes the leak -- adding it alone changed nothing -- but it is what keeps a pipe error retiring one terminal instead of the host. The desktop patch has the early placement and therefore the regression, measured against its exact installed tree. Correcting it there needs its own verification on a Windows desktop build, so the trees diverge on this one hunk deliberately and a test pins that so a future patch sync cannot copy the bug back. |
||
|
|
aa3ae6f56e |
fix(ssh): close the pty master fd leak on relay hosts too (#17920)
* fix(ssh): close the pty master fd leak on Linux relay hosts The app gets the FD_CLOEXEC patch through pnpm patchedDependencies (#17914); the relay installs stock node-pty from npm, where no pnpm patch reaches. Linux is where that matters -- it is the only relay platform that takes forkpty()'s no-atomic-O_CLOEXEC path, and it is also the only one that already compiles node-pty at install time, so the fix costs a second compile rather than a first. Ships the patch as a relay asset applied like the existing Windows console-list one, and rebuilds only after the probe has proven node-pty loadable. The rebuild is non-fatal by construction: the working build is moved aside first and moved back on any failure, a failed attempt drops a skip marker so the compile is attempted at most once per relay directory, and the caller swallows the whole step. macOS and Windows relays never run it. Measured on node:22 with a relay-style npm install: before, the master is cloexec=false and shows up as `26 -> /dev/pts/ptmx` in both a later pty child and a later child_process child; after, cloexec=true and neither child sees it. Closes #17915. * test(ssh): feed the cloexec patch exec to the hand-rolled namespace fixtures These sequences are positional, so the new Linux-only patch exec swallowed the READY slot and every install/repair case timed out waiting for the relay. * fix(ssh): patch the pty master before publishing the shared native-deps tree * fix(ssh): refuse to publish a native-deps tree whose cloexec patch did not take |
||
|
|
19e9ec695b |
perf(windows): ship the native process table to Windows relay hosts (#16598)
* feat(windows): let a relay host bind the native process table directly The CIM fallback from #16550 answers on relay hosts, but it costs a powershell.exe and ~1.4s per scan where the native reader costs ~57ms. It is a parachute, not the destination. Teach the loader a second source: the desktop app keeps resolving the npm package, and a relay host -- which has none of our node_modules -- binds a bare `windows-process-tree.node` staged beside the bundle. The CIM scan stays as the last resort, so a host with neither is unchanged. Bind the addon directly rather than its package wrapper. lib/index.js adds only a queue over getProcessList, and that queue is the wedge this module already defends against: it latches a module-global requestInProgress with no try/catch. We hold our own single-flight and deadline, so going straight to the addon drops the duplicate. Measured on a Windows 11 SSH host with ~1490 processes, running the relay-externals bundle from the deployed relay directory: no addon staged nativeAvailable=false 1247ms (CIM) addon staged nativeAvailable=true 57ms memory restored Degradation was exercised on that host, not just in fakes: a truncated upload, a text file, and a foreign-arch ELF each fall through to the scan rather than throwing, and restoring a good addon recovers. A file that loads but lacks getProcessList is rejected by shape, because binding to it would reject every read forever where falling through still answers. No artifact is staged yet, so this is inert until the packaging change lands: today every relay takes the same CIM path it does now. * build(relay): ship the Windows process-table addon to relay hosts The CIM scan restored correctness on Windows SSH hosts, but it costs a powershell.exe and ~1.4s per read where the native addon costs ~57ms. It was always the floor, not the destination. The addon cannot be npm-installed on a relay host: it carries a binding.gyp, so npm rebuilds from source and the build wants Spectre-mitigated libraries even where MSVC is already present. The binary inside the published tarball loads, but predates our patch and still caps enumeration at 1024 processes -- on a 1486-process host it returned exactly 1024 rows with the querying process among the missing, which reads as unavailable only under load. No published alternative clears the bar either; the one fork with a working prebuild story still carries the same cap. So build it where a compiler exists and ship the result. The build script refuses unpatched source -- checking the source rather than trusting the install, because the Spectre hunk fails loudly while the 1024 hunk fails silently -- and verifies the PE machine field so a cross-build cannot emit host arch for another target. The artifact is optional: hashed when present so a relay carrying it never shares an immutable directory with one that does not, and never probed, since requiring a file only a Windows build machine can produce would make a correct relay read as MISSING and redeploy forever. Builds on any other OS keep using the scan, unchanged. arm64 cross-compiles from the x64 runner but needs the optional MSVC ARM64 toolset, so it stays best-effort: a runner image without that component should cost arm64 relays the fast path, not fail the release the x64 relay is riding on. ORCA_REQUIRE_RELAY_NATIVE_ADDONS is a per-arch list rather than a flag for exactly that reason. * build(relay): require the arm64 process-table addon too The arm64 cross-compile is no longer unproven. On a Windows x64 machine with the MSVC v143 ARM64 build tools component installed, node-gyp --arch=arm64 produces a genuine ARM64 image: x64 machine=0x8664 152064 bytes arm64 machine=0xaa64 139776 bytes So arm64 stops being best-effort and joins x64 in the required list. It was only best-effort because the component is optional and I had not seen it succeed; a runner image without it now fails the build with MSB8020 naming the missing component, and that step runs before the long packaging step so the failure costs seconds rather than twenty minutes. The env var stays a per-arch list rather than reverting to a flag, so a future arch can land best-effort before being promoted the same way. |
||
|
|
a9781a4118 |
STA-4150: client-hosted remote browser (consolidated) (#15448)
Co-authored-by: Jinwoo-H <jinwoo@stably.ai> |
||
|
|
471bc9d8ce | Ship the WSL transcript helper with the Windows relay (STA-4831) (#15529) | ||
|
|
d50adec2d2 |
feat(ai-vault): isolate scanning from terminal workloads (#13411)
* feat(ai-vault): isolate scanning in service processes * fix(ai-vault): retire idle service processes * fix(ai-vault): discard unverified cache processes * fix(ai-vault): clear relay sidecar cancel watchdog on acknowledgement A cancelled relay call is settled before its 2s cancel watchdog is armed, so the acknowledgement path bailed out of settle() before clearing the timer. The watchdog then faulted a healthy sidecar two seconds after every aborted scan, killing whatever request had since become active. * fix(ai-vault): clear the pending restart before scheduling another recordFault overwrote this.timer, stranding a restart that dispose() could no longer cancel. * refactor(ai-vault): drop the orphaned first-prompt IPC wrapper session-first-user-prompt-handler.ts now owns this entry point and routes through the service; the copy left in the read module had no callers. * fix(ai-vault): retry a faulted cold start before surfacing it A slow first start surfaced a raw 'did not become ready' error to the caller even though the supervisor was already respawning. Requeue an unsent call once onto the scheduled respawn instead. Also stop arming the cancellation watchdog for a call the child never received: no acknowledgement is coming, so it killed a healthy service and stalled the lane. Invalidation bookkeeping and ready-waiter construction move to the state module to stay under the max-lines cap. * fix(ai-vault): give relay title reads their own lane Before this branch the relay read title files directly, concurrently with scans. Routing both through one sidecar lane put title resolution behind a list scan that may run up to 130s, so SSH tab titles could lag minutes behind. Split cache and interactive lanes in both the relay client and the sidecar entry, mirroring the desktop service. Also: clear the ready deadline on fault, so a sidecar that dies before ready cannot fault its healthy replacement five seconds later; retry an unsent call once across a respawn; and skip the cancellation watchdog for a call the sidecar never received. Restart/circuit bookkeeping moves to its own module, mirroring the desktop policy, to stay under the max-lines cap. * fix(ai-vault): degrade relay title resolution on sidecar failure listSessions already returns a host issue when the sidecar is unavailable; titles propagated the raw RPC error instead. Return no titles so callers fall back to preview text, and keep cancellation propagating. * fix(ai-vault): scrub the service child environment The children are forked with a 384 MiB heap cap and no loader, but both spawn sites handed them the full parent environment, so an exported NODE_OPTIONS silently raised the cap or --require'd code into them. Allowlist both, following the plugin worker. The desktop child keeps the eleven agent-root overrides it resolves its own roots from; the relay sidecar takes remoteHome and hostPlatform from its init message and so needs none of them. Both children share one priority module while they share this one. * fix(ai-vault): soft-disable relay vault when the service is missing A missing service threw out of the constructor, so a Vault wiring bug would abort relay startup and take every PTY on the host with it. The unsupported-platform branch three lines above already treats a Vault failure as a soft disable; do the same here. Threading the service through the two handlers instead of a field also retires the definite-assignment assertion the throw was propping up. * fix(ai-vault): drain consumed cache invalidations invalidatedPaths was re-applied in every request's finally and never drained, so once N paths had been invalidated every later request paid N evictions for the life of the process; the 4096 cap only bounded how bad that got. The re-apply exists to cover a read that overlapped the invalidation, so drain once nothing is executing. Clearing unconditionally would drop the re-apply for a request still running on the other lane. * fix(ai-vault): keep a busy child through slow invalidation acks invalidate() reused the 5s ready budget as its acknowledgement deadline and killed the child on expiry, so a delete issued during a large scan could kill a healthy process mid-scan and burn a slot toward the restart circuit. Fault only when nothing is executing. Fork IPC ordering already puts the invalidation ahead of any later request, so a busy child owes no ack here, and the 130s/15s request deadlines still catch a wedged one. The start-retry predicate moves to the state module to stay under the line cap, matching the shape the relay client already uses. * fix(ai-vault): report a failed local scan as a host issue A local-scope scan let its error escape to the renderer, which paints it over the session list. Service supervision now produces those errors, so "AI Vault service restart circuit is open." replaced the list. Route local scope through the degradation the all-hosts leg and every SSH leg already use, so it lands as a retryable host issue row instead. Same result shape either way, so no IPC or wire contract changes. * test(ai-vault): cover the relay restart circuit transitions The relay policy shipped without tests. Pin both circuit edges, the aging-out case, the forced-refresh reopen the relay has and the desktop does not, and the backoff schedule. * fix(ai-vault): keep the OpenCode roots in the service child env The scrubbed allowlist dropped XDG_DATA_HOME and OPENCODE_DB, which the child reads to locate the OpenCode store and database. The pre-PR worker thread inherited them, so a user who sets either lost every OpenCode session. * test(ai-vault): anchor the service spawn env assertion |
||
|
|
88c78611b7 |
fix(ssh): patch node-pty helper in Windows relay (#9638)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com> |
||
|
|
4f81dfc128 |
perf(ssh): cut warm high-latency connects from 88.7s to 7.7s (#9015)
Move managed agent-hook filesystem work behind one relay RPC so high-latency SSH connects pay one WAN round trip instead of hundreds. Keep installers serial, lock shared account config across relay processes, and fence cancelled connection generations from replacement state. Co-authored-by: nasagong <zinho2000@gachon.ac.kr> Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com> |
||
|
|
e3c47eff17 |
Fix ssh watcher isolation (#8463)
* fix(ssh): isolate relay filesystem watchers
* Fix relay watcher fault-harness pid file and in-process fallback isolati
- Use exclusive ('wx') creation for the fault-harness pid file so a leaked
ORCA_WATCHER_CHILD_PID_FILE env var can't clobber an existing file, and
have the harness remove the file after reading a replacement pid.
- Force useInProcessVitestFallback to false in the relay watcher pool so a
leaked VITEST env var can never load the native watcher addon in-process
on the relay; fail closed instead when the isolated child is missing.
- Thread an injectable RelayWatcherProcessPool into FsHandler/
RelayFilesystemWatchRegistry for tests, and add coverage for both fixes.
|
||
|
|
f238952be2 |
Agent status over WSL: guest-resident hook relay + WSL-side hook installers (STA-1515) (#7903)
* docs: full design + context for agent status over WSL (STA-1515) Why hooks don't work on Windows+WSL (loopback transport gap + WSL-side installation gap), per-client transport map, the OMP-only fixes that shipped (7642/7641) and why they don't generalize, the recommended guest-resident relay over wsl.exe stdio mirroring the SSH relay plus WSL-side hook installers, alternatives considered, validation facts and gotchas from the 2026-07-08 Windows rig run, and acceptance criteria. Co-authored-by: Orca <help@stably.ai> * feat(agent-hooks): agent status over WSL — guest relay + WSL-side hook installers (STA-1515) Agent hooks have never worked from inside WSL: under default NAT networking, WSL's 127.0.0.1 is its own loopback, so every hook POST to the Windows listener dies silently, and hook configs were only ever written to the Windows home where WSL agents never see them. Transport: a hooks-only guest relay (src/relay/wsl-agent-hook-relay.ts) runs inside the distro, binds WSL loopback on the very port the clients were already given (host-issued token; EADDRINUSE falls back to :0 with endpoint-file re-coordination, which also covers mirrored networking), and forwards parsed envelopes over its own wsl.exe stdio into agentHookServer.ingestRemote — the same shape as the SSH relay. It exits when stdin closes so a freed Windows port can never be forwarded into a dead guest listener. Installation: the unchanged SSH remote hook installers run against an SFTP-shaped adapter whose primitives are home-scoped fs RPCs served by the relay, so all 14 managed agents' hooks land in the WSL home over the already-open channel with zero per-file wsl.exe spawns. Lifecycle: per-distro manager ensured from buildPtyHostEnv on every WSL PTY spawn (covers post-restart daemon reattach re-spawns), stale-bundle reinstall via exit 42, no-node-43 cooldown, bounded retry for wsl.exe 'Catastrophic failure (E_UNEXPECTED)', breadcrumbed failures. Zero per-client transport changes; listener stays Windows-loopback-only. Co-authored-by: Orca <help@stably.ai> * fix(agent-hooks): WSL relay link-death recovery + Codex runtime-home hook install (STA-1515) Follow-ups from the first Windows-rig validation of PR #7903: Link death: a mux protocol error or keepalive timeout could kill the host<->guest link while the guest relay stayed alive returning 204s — the manager stayed 'running' and every later envelope blackholed silently (the exact observed signature: Claude hooks POST 204, store never populates). wsl-hook-relay-link.ts now guarantees exactly-once death handling from either signal (mux dispose OR child exit); the manager breadcrumbs it, kills the child, and self-restarts after a short cooldown since a live agent session produces no new PTY spawns to re-trigger ensure. ORCA_WSL_HOOK_RELAY_DEBUG=1 traces each received envelope pre-ingest. A live integration test pins the full host chain: the real esbuild bundle over real child stdio through the real manager into a real AgentHookServer.ingestRemote, exact Claude POST shape. Codex: Orca launches WSL Codex with CODEX_HOME redirected to the managed runtime home (~/.local/share/orca/codex-runtime-home/home), so hooks installed to ~/.codex were never read. installRemote now accepts an explicit codex home (flat layout), threaded from the relay manager; the config.toml trust write is deferred while the file doesn't exist (the launch path seeds it only-if-absent — creating it first would cancel the seed), and the manager re-runs the byte-equality-idempotent installers on later ensures (30s throttle) to upsert trust once the seed lands. Also: WSL test suites now run on Windows dev hosts (fs-backed suites skip with rig coverage noted; manager suite uses a fixed POSIX home). Co-authored-by: Orca <help@stably.ai> * fix(agent-hooks): renderer ownership gate treats wsl:* connection ids as local (STA-1515) Round-2 rig finding: with the link fixed, WSL hook envelopes reached ingestRemote and the durable cache, but useIpcEvents.applyAgentStatus drops any status whose stamped connectionId differs from the owning repo's — 'wsl:<distro>' !== null for a local repo, so every WSL-relayed status died before setAgentStatus and notifications. wsl:* ids are transport provenance, not ownership: the gate now normalizes them to local via isWslHookRelayConnectionId (shared contract, also used by the relay link when stamping), while still rejecting WSL-stamped events against SSH-owned repos. Provenance stays stamped — it is what made this drop diagnosable. Co-authored-by: Orca <help@stably.ai> * fix(agent-hooks): adversarial-review hardening for the WSL hook relay (STA-1515) Four independent review lenses over the branch; all confirmed findings fixed before the next rig round: Endpoint identity (4/4 reviewers): the guest endpoint dir was keyed by the EPHEMERAL Windows hook port, so a daemon-surviving agent kept sourcing the dead port-P1 file after an Orca restart — breaking the restart-resume acceptance criterion and regressing shipped OMP recovery. Now keyed by a restart-stable instance key (hash of the Windows endpoint file path, crossed via ORCA_WSL_HOOK_INSTANCE): the restarted instance's relay rewrites the SAME file, which is exactly what re-coordinates survivors. Restart policy: every failure arms the restart timer (one failed relaunch no longer ends self-recovery), and the timer probes wsl --list --running first — wsl -d BOOTS a stopped distro, so recovery must never resurrect a VM the user shut down; stopped-distro state is dropped instead. Failure counters reset only after 2min of stable uptime, so connect-then-die loops escalate to the 10-min cap instead of cycling every 10s. Timer policy extracted to wsl-hook-relay-recovery.ts with direct tests. Also: version-namespaced guest install dir (dev+prod instances no longer reinstall over each other; PID-suffixed tmp files), 30s install timeout (a wedged wsl.exe could pin the state machine at 'starting' forever), per-candidate node version probing (apt node 12 on PATH no longer masks nvm node 20 into a false no-node cooldown), WSL_UTF8=1 + NUL-stripped stderr (catastrophic-failure matcher survives UTF-16LE), ordered post-sentinel chunk handoff, port-fallback breadcrumb via the home handshake, bad home reply now fails the connect, missing-bundle warn-once, case-normalized distro keys, disposeAll wired to will-quit, one-shot 60s reinstall timer for single-spawn Codex trust catch-up, escaped + contract-derived spawn command. Co-authored-by: Orca <help@stably.ai> * docs: record round-3 rig validation status for agent status over WSL (STA-1515) Co-authored-by: Orca <help@stably.ai> * fix(agent-hooks): round-4 adversarial-review fixes for the WSL hook relay (STA-1515) - dropState identity race: recovery re-checks state identity after the distro-running probe await, and the manager's dropState only deletes the exact state it was armed for — an ensure() landing mid-probe can no longer have its fresh relay orphaned outside the map. - Distro-running probe fails CLOSED: a probe error no longer reports 'running', so recovery can never wsl-d-boot a distro the user shut down. - Relay spawns use --exec: bypasses the distro's default login shell (fish/nushell chsh) and passes argv verbatim, dropping the $-escape shim; same form as the Codex WSL login spawn. - Post-sentinel chunk handoff rides a microtask so an envelope in the trailing bytes can no longer dispatch before the link's notification handler is registered. - Guest relay mirrors the SSH relay's uncaughtException/unhandledRejection posture. - Replay cache capped at 256 panes with recency eviction (the WSL relay has no per-pane teardown signal); meta map kept in lockstep. - Launch script derives the stale-exit code from the shared contract constant; one-shot reinstall timer refuses to arm after dispose. - New oracles: sentinel unit suite, fs-bridge scoping suite, fixed-token 403/204, EADDRINUSE endpoint-file rewrite, cache-cap eviction, and the recovery/manager race regressions (verified to fail with fixes reverted). - Doc: round-4 review section + revised curl.exe stance (kept as the no-node fallback — Codex is a native binary; fresh distros ship no node). * docs: record round-4 pinned rig validation for agent status over WSL (STA-1515) --------- Co-authored-by: Orca <help@stably.ai> Co-authored-by: Brennan Benson <brennanbenson@Brennans-MacBook-Pro.local> |
||
|
|
f9e18910ae |
chore(lint): adopt unicorn/prefer-import-meta-properties (error) (#6847)
Migrate fileURLToPath(import.meta.url) / dirname(...) boilerplate to the
native import.meta.dirname / import.meta.filename, then enable the rule
at error so new code stays on the native form.
The oxlint autofix rewrites the expression but leaves the now-unused
node:url / node:path imports behind (which the already-enabled
no-unused-vars=error would then flag), so this commit also removes those
34 orphaned imports — trimming the named import where other names are
still used, deleting the line where it was the sole import.
Scope is build scripts + Node-env tests only (config/scripts, tools/
benchmarks, *.test.{ts,mjs}, vitest configs); zero shipped runtime code.
The native properties are exact equivalents (Node >= 20.11; repo is on
24), so behavior is unchanged.
Verified: oxlint 0 errors tree-wide (root + mobile), oxfmt clean,
typecheck (node+cli+web) + mobile tsc pass, root vitest 22825 passed /
0 failed, mobile vitest 1018 passed. Exercised the rewritten scripts
directly: build:relay (6 targets), ensure-native-runtime,
verify-macos-entitlements all run correctly with import.meta.dirname.
|
||
|
|
46646d7ff1 |
chore(lint): upgrade oxlint to 1.71 + enable 7 new rules (autofixed backlog) (#6841)
* chore(lint): upgrade oxlint to 1.71 and enable 7 new rules Upgrade oxlint 1.67.0 -> 1.71.0 (1.72 was blocked by the repo's 3-day minimum-release-age supply-chain guard; nothing here needs it). The bump is a no-op on the existing config. Enable 3 error rules (backlog autofixed to zero in this commit) and 4 warn rules (surface signal without gating CI): error (autofixed, behavior-preserving): - unicorn/prefer-node-protocol (~1531 sites: bare builtin -> node:) - typescript/no-import-type-side-effects (~36: all-inline-type -> import type) - unicorn/no-array-reverse (19: copy-then-reverse -> toReversed) warn (real signal, current fires are test-only/correct): - unicorn/no-array-fill-with-reference-type (aliasing footgun guard) - typescript/no-unsafe-function-type (bans bare Function type) - unicorn/prefer-array-flat-map (map().flat() -> flatMap()) - unicorn/prefer-regexp-test (.match() in bool ctx -> .test()) mobile/.oxlintrc.json extends root, so it inherits all 7; the autofix ran from root and covered mobile/ too. Verification (all green): oxlint 0 errors (root+mobile+aux configs), oxfmt clean, typecheck (node+cli+web), vitest 22795 passed / 0 failed, builds (electron-vite + web + cli) succeed. node: rewrites confirmed to skip embedded SSH/CLI string payloads (AST-only); all toReversed sites verified to operate on fresh copies or write-once locals. * chore(lint): bump mobile oxlint to 1.71 so inherited rules parse mobile/ is a standalone pnpm project pinning its own oxlint@1.67, which lacks unicorn/no-array-fill-with-reference-type (needs >=1.70). Since mobile/.oxlintrc.json extends the root config, mobile CI's 'cd mobile && oxlint' failed to parse the new rule. Bump mobile to match root (1.71). Verified in mobile/: oxlint 0 errors, oxfmt --check clean, tsc --noEmit pass, vitest 978 passed / 0 failed. Co-authored-by: Orca <help@stably.ai> --------- Co-authored-by: Orca <help@stably.ai> |
||
|
|
98d02bca47 |
fix: support windows ssh hosts (#5004)
* feat: add windows ssh relay base support * feat: support windows ssh relay runtime services * fix: default windows ssh pty cwd to user profile * fix: support windows hosts over system ssh * fix: preserve degraded windows relay native deps * fix: gate windows shell args by relay platform * fix: preserve windows relay fallback pipes * test: align windows native deps relay fixture * fix: build valid windows install lock command * fix: address windows SSH relay review findings Resolve correctness, efficiency, and reuse issues found reviewing the Windows SSH native-host support: - GC liveness on Windows now probes the actual named pipe (via node net.connect against markers + deterministic candidates) instead of substring-matching Win32_Process command lines, which could remove a live relay dir. Reports ALIVE conservatively only when there is no liveness signal at all (no markers and no seed pipes). - Resolve the remote node path once per deploy and thread it through install/repair/launch instead of re-resolving 3-7x. - Replace the 200ms node -e poll loop with a single long-lived remote wait process during Windows relay startup. - Skip the no-op executable command on Windows in uploadRelay. - Make the Windows fallback pipe name deterministic and recoverable (drop the global counter), with an extra reconnect attempt. - Normalize the prepended node bin dir to backslashes on Windows PATH. - Batch the system-SSH Windows directory upload into a single streamed JSON package instead of one ssh process per file. - Extract relay endpoint/marker helpers into ssh-relay-endpoints.ts and consolidate the PowerShell EncodedCommand encoding into the shared powershell-command-encoding module. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Support cancellation and timeouts in Windows port scanning - Propagate the request AbortSignal and a 5-second timeout to both PowerShell and netstat child processes during Windows port scanning. - Avoid spawning the netstat fallback process if the port scan has already been aborted. - Wrap the .NET OSArchitecture check in a try/catch block during SSH Windows platform detection to robustly fall back to environment variables if needed. --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com> |
||
|
|
1009ac9083 | chore: update Electron to 42 (#3919) | ||
|
|
d603242766 | fix: address review findings (#2130) | ||
|
|
000d4dc08b | Revert sparse checkout worktree creation (#1290) | ||
|
|
79faafcc98 |
Add sparse checkout worktree creation (#1131)
Co-authored-by: Orca <help@stably.ai> Co-authored-by: Jinwoo-H <jinwoo0825@gmail.com> |
||
|
|
4318f3bfa7 |
chore: reduce root-directory clutter (#1275)
Co-authored-by: Orca <help@stably.ai> |