From a4fc2b45363ecc3e8ed13069ab84c4dbf41f7abe Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Wed, 21 Jan 2026 01:17:35 +0000 Subject: [PATCH] fix: handle fetch streams safely --- src/agents/skills-install.ts | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/agents/skills-install.ts b/src/agents/skills-install.ts index 11ad69647..135045936 100644 --- a/src/agents/skills-install.ts +++ b/src/agents/skills-install.ts @@ -34,6 +34,10 @@ export type SkillInstallResult = { code: number | null; }; +function isNodeReadableStream(value: unknown): value is NodeJS.ReadableStream { + return Boolean(value && typeof (value as NodeJS.ReadableStream).pipe === "function"); +} + function summarizeInstallOutput(text: string): string | undefined { const raw = text.trim(); if (!raw) return undefined; @@ -154,13 +158,10 @@ async function downloadFile( } await ensureDir(path.dirname(destPath)); const file = fs.createWriteStream(destPath); - const body = response.body; - // Node's Readable.fromWeb expects the node:stream/web type; cast through unknown for DOM streams. - const nodeStream = body as unknown as NodeJS.ReadableStream; - const readable = - typeof nodeStream.pipe === "function" - ? nodeStream - : Readable.fromWeb(body as unknown as NodeReadableStream); + const body = response.body as unknown; + const readable = isNodeReadableStream(body) + ? body + : Readable.fromWeb(body as NodeReadableStream); await pipeline(readable, file); const stat = await fs.promises.stat(destPath); return { bytes: stat.size };