From 16b47d3dde9007eb27161eeac83184a949463a21 Mon Sep 17 00:00:00 2001 From: Cole Medin Date: Fri, 10 Apr 2026 17:29:25 -0500 Subject: [PATCH 1/2] fix: archon setup --spawn fails on Windows when repo path contains spaces (#1035) The cmd.exe fallback in spawnWindowsTerminal() used shell: true, which caused Bun/Node to flatten args into a single string without proper quoting. Paths with spaces were split at whitespace, breaking the /D argument to start. Changes: - Remove shell: true from cmd.exe fallback spawn options - Remove shell?: boolean from trySpawn options type (no callers need it) Fixes #1035 Co-Authored-By: Claude Opus 4.6 (1M context) --- packages/cli/src/commands/setup.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/cli/src/commands/setup.ts b/packages/cli/src/commands/setup.ts index b94529cd4c..cc0b138a61 100644 --- a/packages/cli/src/commands/setup.ts +++ b/packages/cli/src/commands/setup.ts @@ -1203,7 +1203,7 @@ export function copyArchonSkill(targetPath: string): void { function trySpawn( command: string, args: string[], - options: { detached: boolean; stdio: 'ignore'; shell?: boolean } + options: { detached: boolean; stdio: 'ignore' } ): boolean { try { const child: ChildProcess = spawn(command, args, options); @@ -1238,7 +1238,6 @@ function spawnWindowsTerminal(repoPath: string): SpawnResult { trySpawn('cmd.exe', ['/c', 'start', '""', '/D', repoPath, 'cmd', '/k', 'archon setup'], { detached: true, stdio: 'ignore', - shell: true, }) ) { return { success: true }; From e4555a769bb3dd62122b3e123bb99b75802310a2 Mon Sep 17 00:00:00 2001 From: Cole Medin Date: Fri, 10 Apr 2026 17:47:53 -0500 Subject: [PATCH 2/2] simplify: reduce complexity in changed files - Parallelize checksums + tarball fetch in serve.ts (removes waterfall latency) - Remove redundant existsSync before readFileSync in update-check.ts (catch already handles ENOENT) Co-Authored-By: Claude Sonnet 4.6 --- packages/cli/src/commands/serve.ts | 34 +++++++++++++++++------------- packages/paths/src/update-check.ts | 3 +-- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/packages/cli/src/commands/serve.ts b/packages/cli/src/commands/serve.ts index e24a5526a3..4d0fc10c65 100644 --- a/packages/cli/src/commands/serve.ts +++ b/packages/cli/src/commands/serve.ts @@ -86,29 +86,33 @@ async function downloadWebDist(version: string, targetDir: string): Promise { - throw new Error( - `Network error fetching checksums from ${checksumsUrl}: ${(err as Error).message}` - ); - }); + // Download checksums and tarball in parallel + console.log(`Downloading ${tarballUrl}...`); + const [checksumsRes, tarballRes] = await Promise.all([ + fetch(checksumsUrl).catch((err: unknown) => { + throw new Error( + `Network error fetching checksums from ${checksumsUrl}: ${(err as Error).message}` + ); + }), + fetch(tarballUrl).catch((err: unknown) => { + throw new Error( + `Network error fetching tarball from ${tarballUrl}: ${(err as Error).message}` + ); + }), + ]); if (!checksumsRes.ok) { throw new Error( `Failed to download checksums: ${checksumsRes.status} ${checksumsRes.statusText}` ); } - const checksumsText = await checksumsRes.text(); - const expectedHash = parseChecksum(checksumsText, 'archon-web.tar.gz'); - - // Download tarball - console.log(`Downloading ${tarballUrl}...`); - const tarballRes = await fetch(tarballUrl).catch((err: unknown) => { - throw new Error(`Network error fetching tarball from ${tarballUrl}: ${(err as Error).message}`); - }); if (!tarballRes.ok) { throw new Error(`Failed to download web UI: ${tarballRes.status} ${tarballRes.statusText}`); } - const tarballBuffer = await tarballRes.arrayBuffer(); + const [checksumsText, tarballBuffer] = await Promise.all([ + checksumsRes.text(), + tarballRes.arrayBuffer(), + ]); + const expectedHash = parseChecksum(checksumsText, 'archon-web.tar.gz'); // Verify checksum const hasher = new Bun.CryptoHasher('sha256'); diff --git a/packages/paths/src/update-check.ts b/packages/paths/src/update-check.ts index 46652eb0d8..1e7da7dd41 100644 --- a/packages/paths/src/update-check.ts +++ b/packages/paths/src/update-check.ts @@ -1,5 +1,5 @@ import { join } from 'path'; -import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs'; +import { readFileSync, writeFileSync, mkdirSync } from 'fs'; import { getArchonHome } from './archon-paths'; import { createLogger } from './logger'; @@ -30,7 +30,6 @@ function getCachePath(): string { function readCache(): UpdateCheckCache | null { const cachePath = getCachePath(); try { - if (!existsSync(cachePath)) return null; const raw = readFileSync(cachePath, 'utf-8'); const data = JSON.parse(raw) as UpdateCheckCache; if (!data.latestVersion || !data.releaseUrl || typeof data.checkedAt !== 'number') {