diff --git a/packages/coding-agent/CHANGELOG.md b/packages/coding-agent/CHANGELOG.md index 4229072c..ca39e488 100644 --- a/packages/coding-agent/CHANGELOG.md +++ b/packages/coding-agent/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +### Fixed + +- Fixed fd/rg download failing on Windows due to `unzip` not being available; now uses `tar` for both `.tar.gz` and `.zip` extraction, with proper error reporting ([#1348](https://github.com/badlogic/pi-mono/issues/1348)) + ## [0.52.8] - 2026-02-07 ### New Features diff --git a/packages/coding-agent/src/utils/tools-manager.ts b/packages/coding-agent/src/utils/tools-manager.ts index 53d2c513..8f5853fc 100644 --- a/packages/coding-agent/src/utils/tools-manager.ts +++ b/packages/coding-agent/src/utils/tools-manager.ts @@ -153,10 +153,18 @@ async function downloadTool(tool: "fd" | "rg"): Promise { mkdirSync(extractDir, { recursive: true }); try { - if (assetName.endsWith(".tar.gz")) { - spawnSync("tar", ["xzf", archivePath, "-C", extractDir], { stdio: "pipe" }); - } else if (assetName.endsWith(".zip")) { - spawnSync("unzip", ["-o", archivePath, "-d", extractDir], { stdio: "pipe" }); + // Use tar for both .tar.gz and .zip extraction. Windows 10+ ships bsdtar + // which handles both formats, avoiding the need for `unzip` (not available + // on Windows by default). + const extractResult = assetName.endsWith(".tar.gz") + ? spawnSync("tar", ["xzf", archivePath, "-C", extractDir], { stdio: "pipe" }) + : assetName.endsWith(".zip") + ? spawnSync("tar", ["xf", archivePath, "-C", extractDir], { stdio: "pipe" }) + : null; + + if (!extractResult || extractResult.error || extractResult.status !== 0) { + const errMsg = extractResult?.error?.message ?? extractResult?.stderr?.toString().trim() ?? "unknown error"; + throw new Error(`Failed to extract ${assetName}: ${errMsg}`); } // Find the binary in extracted files