From 13415c758fcc0d3945ebbb7b30f62dfa63df24b0 Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Mon, 2 Nov 2026 18:52:32 -0800 Subject: [PATCH 1/3] fix(ssh): reuse the desktop-installed CLI during remote setup --- packages/ssh/src/tunnel.test.ts | 24 +++++++++++++----------- packages/ssh/src/tunnel.ts | 4 ++-- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/packages/ssh/src/tunnel.test.ts b/packages/ssh/src/tunnel.test.ts index dc50e01694ec1..bdb92c116d8d9 100644 --- a/packages/ssh/src/tunnel.test.ts +++ b/packages/ssh/src/tunnel.test.ts @@ -83,16 +83,16 @@ function commandArgs(command: ChildProcess.Command): ReadonlyArray { const ARCHIVE = { archiveVersion: "1.2.3-preview.20260911.4" } as const; const runArchiveRunner = Effect.fn("test.runArchiveRunner")( - function* (installedVersion: string) { + function* (installedVersion: string, installDirectory = ".local/bin") { const fs = yield* FileSystem.FileSystem; const root = yield* fs.makeTempDirectoryScoped(); - yield* fs.makeDirectory(`${root}/.local/bin`, { recursive: true }); + yield* fs.makeDirectory(`${root}/${installDirectory}`, { recursive: true }); yield* fs.makeDirectory(`${root}/bin`); yield* fs.writeFileString( - `${root}/.local/bin/t3`, + `${root}/${installDirectory}/t3`, `#!/bin/sh\ncase "$1" in\n--version) echo 't3 v${installedVersion}';;\n__ssh-helper) exit 0;;\n*) printf 'installed:%s\\n' "$*";;\nesac\n`, ); - yield* fs.chmod(`${root}/.local/bin/t3`, 0o700); + yield* fs.chmod(`${root}/${installDirectory}/t3`, 0o700); yield* fs.writeFileString(`${root}/bin/curl`, '#!/bin/sh\necho "HTTP 404" >&2\nexit 22\n'); yield* fs.chmod(`${root}/bin/curl`, 0o700); yield* fs.writeFileString(`${root}/runner.sh`, SshTunnel.buildRemoteT3RunnerScript(ARCHIVE)); @@ -161,13 +161,15 @@ describe("ssh tunnel scripts", () => { }), ); - it.live("reuses an installed CLI only when it matches the exact requested release", () => - Effect.gen(function* () { - const result = yield* runArchiveRunner(ARCHIVE.archiveVersion); - assert.equal(result.exitCode, 0, result.stderr); - assert.equal(result.stdout, "installed:pair --json\n"); - assert.isFalse(result.runtimeExists); - }), + it.live.each([".local/bin", ".t3/bin"])( + "reuses an exact-release installed CLI in %s", + (installDirectory) => + Effect.gen(function* () { + const result = yield* runArchiveRunner(ARCHIVE.archiveVersion, installDirectory); + assert.equal(result.exitCode, 0, result.stderr); + assert.equal(result.stdout, "installed:pair --json\n"); + assert.isFalse(result.runtimeExists); + }), ); it.live.each(["1.2.2", "1.2.3", "1.2.3-nightly.20260911.4", "1.2.3-preview.20260911.3"])( diff --git a/packages/ssh/src/tunnel.ts b/packages/ssh/src/tunnel.ts index efe0fe8cde202..24d76c2ddfbf6 100644 --- a/packages/ssh/src/tunnel.ts +++ b/packages/ssh/src/tunnel.ts @@ -445,9 +445,9 @@ T3_RUNTIME_DIR="$HOME/.t3/runtime/versions/$T3_ARCHIVE_VERSION" t3_runtime_ready() { [ -x "$T3_RUNTIME_DIR/t3" ] && [ "$(cat "$T3_RUNTIME_DIR/.install-complete" 2>/dev/null)" = "$T3_ARCHIVE_VERSION" ] } -# Without the pinned runtime, reuse only an exact-release CLI from install.sh's PATH symlink. +# Reuse only an exact-release CLI from the shell or the standard install locations. if ! t3_runtime_ready; then - for T3_INSTALLED in "$(command -v t3 2>/dev/null || true)" "$HOME/.local/bin/t3"; do + for T3_INSTALLED in "$(command -v t3 2>/dev/null || true)" "$HOME/.local/bin/t3" "$HOME/.t3/bin/t3"; do [ -n "$T3_INSTALLED" ] && [ -x "$T3_INSTALLED" ] || continue T3_INSTALLED_VERSION="$("$T3_INSTALLED" --version 2>/dev/null || true)" case "$T3_INSTALLED_VERSION" in From 313a28cf11fee9047e468bffc0a035ea00d0db97 Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Tue, 3 Nov 2026 01:28:35 -0800 Subject: [PATCH 2/3] fix(ssh): bound installed-CLI probes in the remote runner A wedged candidate stalled remote setup until the outer SSH timeout: a hung --version or __ssh-helper probe blocked forever, and an executable non-regular file (e.g. a FIFO) at a candidate path made the shell's read-as-script fallback block on open. Probe each candidate through a watchdog that falls through to the archive download, require a regular file, and route probe output through a temp file so orphaned children cannot hold the capture open. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- packages/ssh/src/tunnel.test.ts | 47 ++++++++++++++++++++++++++++----- packages/ssh/src/tunnel.ts | 33 ++++++++++++++++++++--- 2 files changed, 71 insertions(+), 9 deletions(-) diff --git a/packages/ssh/src/tunnel.test.ts b/packages/ssh/src/tunnel.test.ts index bdb92c116d8d9..6a7b2c01c93a3 100644 --- a/packages/ssh/src/tunnel.test.ts +++ b/packages/ssh/src/tunnel.test.ts @@ -83,16 +83,29 @@ function commandArgs(command: ChildProcess.Command): ReadonlyArray { const ARCHIVE = { archiveVersion: "1.2.3-preview.20260911.4" } as const; const runArchiveRunner = Effect.fn("test.runArchiveRunner")( - function* (installedVersion: string, installDirectory = ".local/bin") { + function* ( + installedVersion: string, + installDirectory = ".local/bin", + options?: { readonly cliScript?: string; readonly fifo?: boolean }, + ) { const fs = yield* FileSystem.FileSystem; const root = yield* fs.makeTempDirectoryScoped(); yield* fs.makeDirectory(`${root}/${installDirectory}`, { recursive: true }); yield* fs.makeDirectory(`${root}/bin`); - yield* fs.writeFileString( - `${root}/${installDirectory}/t3`, - `#!/bin/sh\ncase "$1" in\n--version) echo 't3 v${installedVersion}';;\n__ssh-helper) exit 0;;\n*) printf 'installed:%s\\n' "$*";;\nesac\n`, - ); - yield* fs.chmod(`${root}/${installDirectory}/t3`, 0o700); + if (options?.fifo) { + const spawner = yield* ChildProcessSpawner.ChildProcessSpawner; + const mkfifo = yield* spawner.spawn( + ChildProcess.make("mkfifo", ["-m", "700", `${root}/${installDirectory}/t3`]), + ); + yield* mkfifo.exitCode; + } else { + yield* fs.writeFileString( + `${root}/${installDirectory}/t3`, + options?.cliScript ?? + `#!/bin/sh\ncase "$1" in\n--version) echo 't3 v${installedVersion}';;\n__ssh-helper) exit 0;;\n*) printf 'installed:%s\\n' "$*";;\nesac\n`, + ); + yield* fs.chmod(`${root}/${installDirectory}/t3`, 0o700); + } yield* fs.writeFileString(`${root}/bin/curl`, '#!/bin/sh\necho "HTTP 404" >&2\nexit 22\n'); yield* fs.chmod(`${root}/bin/curl`, 0o700); yield* fs.writeFileString(`${root}/runner.sh`, SshTunnel.buildRemoteT3RunnerScript(ARCHIVE)); @@ -187,6 +200,28 @@ describe("ssh tunnel scripts", () => { }), ); + it.live( + "skips an installed CLI whose probes hang and falls through to the archive download", + () => + Effect.gen(function* () { + const result = yield* runArchiveRunner(ARCHIVE.archiveVersion, ".t3/bin", { + cliScript: `#!/bin/sh\ncase "$1" in\n--version) sleep 300;;\n__ssh-helper) sleep 300;;\n*) printf 'installed:%s\\n' "$*";;\nesac\n`, + }); + assert.notEqual(result.exitCode, 0); + assert.include(result.stderr, `v${ARCHIVE.archiveVersion}/SHA256SUMS`); + assert.isFalse(result.runtimeExists); + }), + ); + + it.live("skips a non-regular file at the desktop CLI path", () => + Effect.gen(function* () { + const result = yield* runArchiveRunner(ARCHIVE.archiveVersion, ".t3/bin", { fifo: true }); + assert.notEqual(result.exitCode, 0); + assert.include(result.stderr, `v${ARCHIVE.archiveVersion}/SHA256SUMS`); + assert.isFalse(result.runtimeExists); + }), + ); + it("rejects archive versions that are not a single exact version segment", () => { for (const archiveVersion of [ "../other", diff --git a/packages/ssh/src/tunnel.ts b/packages/ssh/src/tunnel.ts index 24d76c2ddfbf6..81ab35d340c2a 100644 --- a/packages/ssh/src/tunnel.ts +++ b/packages/ssh/src/tunnel.ts @@ -58,6 +58,7 @@ const REMOTE_LAUNCH_TIMEOUT_MS = 90_000; const REMOTE_ARCHIVE_CHECKSUMS_SECONDS = 30; const REMOTE_ARCHIVE_DOWNLOAD_SECONDS = 240; const REMOTE_ARCHIVE_LOCK_WAIT_SECONDS = 360; +const REMOTE_INSTALLED_PROBE_SECONDS = 15; const REMOTE_ARCHIVE_LAUNCH_TIMEOUT_MS = 900_000; const REMOTE_REUSE_READY_TIMEOUT_MS = 2_000; @@ -445,14 +446,39 @@ T3_RUNTIME_DIR="$HOME/.t3/runtime/versions/$T3_ARCHIVE_VERSION" t3_runtime_ready() { [ -x "$T3_RUNTIME_DIR/t3" ] && [ "$(cat "$T3_RUNTIME_DIR/.install-complete" 2>/dev/null)" = "$T3_ARCHIVE_VERSION" ] } +# A wedged candidate (a hung CLI, or an executable FIFO whose read-as-script +# fallback blocks on open) must not stall the launch until the SSH timeout; +# bound each probe so a bad candidate falls through to the archive download. +# Output goes through a file, not the caller's pipe, and the watchdog's sleeps +# are detached too: orphaned children could otherwise hold the capture open +# and block it for the full timeout. +t3_probe() { + T3_PROBE_OUT="$(mktemp "\${TMPDIR:-/tmp}/t3-probe.XXXXXX")" + "$@" >"$T3_PROBE_OUT" 2>/dev/null /dev/null + sleep 2 + kill -KILL "$T3_PROBE_PID" 2>/dev/null + ) >/dev/null 2>&1 & + T3_PROBE_DOG=$! + wait "$T3_PROBE_PID" 2>/dev/null + T3_PROBE_RC=$? + kill "$T3_PROBE_DOG" 2>/dev/null + wait "$T3_PROBE_DOG" 2>/dev/null + cat "$T3_PROBE_OUT" + rm -f "$T3_PROBE_OUT" + return "$T3_PROBE_RC" +} # Reuse only an exact-release CLI from the shell or the standard install locations. if ! t3_runtime_ready; then for T3_INSTALLED in "$(command -v t3 2>/dev/null || true)" "$HOME/.local/bin/t3" "$HOME/.t3/bin/t3"; do - [ -n "$T3_INSTALLED" ] && [ -x "$T3_INSTALLED" ] || continue - T3_INSTALLED_VERSION="$("$T3_INSTALLED" --version 2>/dev/null || true)" + [ -n "$T3_INSTALLED" ] && [ -f "$T3_INSTALLED" ] && [ -x "$T3_INSTALLED" ] || continue + T3_INSTALLED_VERSION="$(t3_probe "$T3_INSTALLED" --version 2>/dev/null || true)" case "$T3_INSTALLED_VERSION" in "t3 v$T3_ARCHIVE_VERSION") - if "$T3_INSTALLED" __ssh-helper --help >/dev/null 2>&1; then + if t3_probe "$T3_INSTALLED" __ssh-helper --help >/dev/null 2>&1; then exec "$T3_INSTALLED" "$@" fi ;; @@ -829,6 +855,7 @@ export function buildRemoteT3RunnerScript(input?: RemoteT3RunnerOptions): string T3_ARCHIVE_VERSION: shellSingleQuote(archiveVersion), T3_RELEASE_BASE_URL: shellSingleQuote(releaseBaseUrl), T3_ARCHIVE_LOCK_WAIT_SECONDS: String(REMOTE_ARCHIVE_LOCK_WAIT_SECONDS), + T3_INSTALLED_PROBE_SECONDS: String(REMOTE_INSTALLED_PROBE_SECONDS), T3_ARCHIVE_DOWNLOAD_SECONDS: String(REMOTE_ARCHIVE_DOWNLOAD_SECONDS), T3_ARCHIVE_CHECKSUMS_SECONDS: String(REMOTE_ARCHIVE_CHECKSUMS_SECONDS), T3_NODE_ENV_SCRIPT: buildRemoteNodeEnvScript(input), From 9a04c94e99edd398eb5a15e8fae4a2883838aa11 Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Tue, 3 Nov 2026 01:33:01 -0800 Subject: [PATCH 3/3] refactor(ssh): tighten the installed-CLI probe comment Co-Authored-By: Claude Opus 5.5 --- packages/ssh/src/tunnel.ts | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/packages/ssh/src/tunnel.ts b/packages/ssh/src/tunnel.ts index 81ab35d340c2a..c8c063dc52570 100644 --- a/packages/ssh/src/tunnel.ts +++ b/packages/ssh/src/tunnel.ts @@ -446,12 +446,9 @@ T3_RUNTIME_DIR="$HOME/.t3/runtime/versions/$T3_ARCHIVE_VERSION" t3_runtime_ready() { [ -x "$T3_RUNTIME_DIR/t3" ] && [ "$(cat "$T3_RUNTIME_DIR/.install-complete" 2>/dev/null)" = "$T3_ARCHIVE_VERSION" ] } -# A wedged candidate (a hung CLI, or an executable FIFO whose read-as-script -# fallback blocks on open) must not stall the launch until the SSH timeout; -# bound each probe so a bad candidate falls through to the archive download. -# Output goes through a file, not the caller's pipe, and the watchdog's sleeps -# are detached too: orphaned children could otherwise hold the capture open -# and block it for the full timeout. +# Bound each probe so a hung candidate falls through to the archive download +# instead of stalling until the SSH timeout. Output goes through a file and the +# watchdog is detached: orphaned children holding a pipe would block the capture. t3_probe() { T3_PROBE_OUT="$(mktemp "\${TMPDIR:-/tmp}/t3-probe.XXXXXX")" "$@" >"$T3_PROBE_OUT" 2>/dev/null