From e158968e03e78705d828850e1119ce5922d75ca7 Mon Sep 17 00:00:00 2001 From: William Valentin Date: Tue, 17 Feb 2026 10:29:49 -0800 Subject: [PATCH] fix(skills): generate executable download install plans --- docs/plans/state.json | 12 ++++++++++++ src/skills/planner.test.ts | 14 +++++++++++++- src/skills/planner.ts | 7 +++++-- 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/docs/plans/state.json b/docs/plans/state.json index 11b8757..056e103 100644 --- a/docs/plans/state.json +++ b/docs/plans/state.json @@ -3594,6 +3594,18 @@ "docs/plans/state.json" ], "test_status": "pnpm test:run src/agents/registry.test.ts src/config/schema.test.ts src/daemon/routing.test.ts + pnpm typecheck passing" + }, + "installer-download-plan-command-remediation": { + "status": "completed", + "date": "2026-02-17", + "updated": "2026-02-17", + "summary": "Replaced fake download planner output (`download url -> dest`) with executable curl command planning and added explicit skip behavior when destination is missing, including regression coverage.", + "files_modified": [ + "src/skills/planner.ts", + "src/skills/planner.test.ts", + "docs/plans/state.json" + ], + "test_status": "pnpm test:run src/skills/planner.test.ts + pnpm typecheck passing" } }, "overall_progress": { diff --git a/src/skills/planner.test.ts b/src/skills/planner.test.ts index 0102b24..acf248d 100644 --- a/src/skills/planner.test.ts +++ b/src/skills/planner.test.ts @@ -55,8 +55,20 @@ describe('buildInstallerPlan', () => { expect(plan.steps).toEqual([ { installerType: 'go', command: 'go install example.com/tool/a@latest' }, { installerType: 'go', command: 'go install example.com/tool/b@latest' }, - { installerType: 'download', command: 'download https://example.com/tool.tgz -> /tmp/tool.tgz' }, + { installerType: 'download', command: 'curl -fsSL -o /tmp/tool.tgz https://example.com/tool.tgz' }, ]); expect(plan.skipped).toEqual([]); }); + + it('skips download installer when destination is missing', () => { + const plan = buildInstallerPlan( + [{ type: 'download', url: 'https://example.com/tool.tgz' }], + { hasBinary: () => true }, + ); + + expect(plan.steps).toEqual([]); + expect(plan.skipped).toEqual([ + { installerType: 'download', reason: 'download destination is required for executable install plans' }, + ]); + }); }); diff --git a/src/skills/planner.ts b/src/skills/planner.ts index c96c72a..fb0efe9 100644 --- a/src/skills/planner.ts +++ b/src/skills/planner.ts @@ -73,10 +73,13 @@ export function buildInstallerPlan( continue; } - const destination = installer.destination ?? ''; + if (!installer.destination) { + skipped.push({ installerType: 'download', reason: 'download destination is required for executable install plans' }); + continue; + } steps.push({ installerType: 'download', - command: `download ${installer.url} -> ${destination}`, + command: `curl -fsSL -o ${installer.destination} ${installer.url}`, }); }