fix(skills): align planner and cli tests on curl download commands

This commit is contained in:
William Valentin
2026-02-17 10:33:58 -08:00
parent 1d9c25a4c6
commit ac29789d89
4 changed files with 50 additions and 39 deletions
+13
View File
@@ -3633,6 +3633,19 @@
"docs/plans/state.json" "docs/plans/state.json"
], ],
"test_status": "pnpm typecheck passing" "test_status": "pnpm typecheck passing"
},
"installer-planner-cli-curl-reconciliation": {
"status": "completed",
"date": "2026-02-17",
"updated": "2026-02-17",
"summary": "Reconciled installer planning and CLI output/tests to use executable curl-based download commands (`curl -fsSL -o <dest> <url>` and `curl -fsSL <url>` when destination is omitted), replacing legacy placeholder command strings while preserving install/execute flow semantics.",
"files_modified": [
"src/skills/planner.ts",
"src/skills/planner.test.ts",
"src/cli/skills.test.ts",
"docs/plans/state.json"
],
"test_status": "pnpm test:run src/skills/planner.test.ts src/cli/skills.test.ts + pnpm typecheck passing"
} }
}, },
"overall_progress": { "overall_progress": {
+30 -30
View File
@@ -426,7 +426,7 @@ describe('skills CLI helpers', () => {
expect(output).toContain('Installer plan mode: dry-run'); expect(output).toContain('Installer plan mode: dry-run');
expect(output).toContain('Installer planned steps:'); expect(output).toContain('Installer planned steps:');
expect(output).toContain('[download] download https://example.com/tool.tgz -> /tmp/tool.tgz'); expect(output).toContain('[download] curl -fsSL -o /tmp/tool.tgz https://example.com/tool.tgz');
}); });
it('builds installer plan view for automation output', () => { it('builds installer plan view for automation output', () => {
@@ -452,13 +452,13 @@ describe('skills CLI helpers', () => {
const output = renderSkillInstallerPlan({ const output = renderSkillInstallerPlan({
skill: { name: 'plan-target', tier: 'bundled', version: '1.0.0' }, skill: { name: 'plan-target', tier: 'bundled', version: '1.0.0' },
mode: 'dry-run', mode: 'dry-run',
steps: [{ installerType: 'download', command: 'download https://example.com/tool -> /tmp/tool' }], steps: [{ installerType: 'download', command: 'curl -fsSL -o /tmp/tool https://example.com/tool' }],
skipped: [{ installerType: 'brew', reason: 'brew not available in PATH' }], skipped: [{ installerType: 'brew', reason: 'brew not available in PATH' }],
}); });
expect(output).toContain("Installer plan for 'plan-target'"); expect(output).toContain("Installer plan for 'plan-target'");
expect(output).toContain('Planned steps:'); expect(output).toContain('Planned steps:');
expect(output).toContain('[download] download https://example.com/tool -> /tmp/tool'); expect(output).toContain('[download] curl -fsSL -o /tmp/tool https://example.com/tool');
expect(output).toContain('Skipped steps:'); expect(output).toContain('Skipped steps:');
expect(output).toContain('[brew] brew not available in PATH'); expect(output).toContain('[brew] brew not available in PATH');
}); });
@@ -504,13 +504,13 @@ describe('skills CLI helpers', () => {
sourcePath: '/tmp/source-skill', sourcePath: '/tmp/source-skill',
skill: { name: 'preflight-skill', tier: 'managed', version: '1.0.0' }, skill: { name: 'preflight-skill', tier: 'managed', version: '1.0.0' },
mode: 'dry-run', mode: 'dry-run',
steps: [{ installerType: 'download', command: 'download https://example.com/tool.tgz -> <default destination>' }], steps: [{ installerType: 'download', command: 'curl -fsSL https://example.com/tool.tgz' }],
skipped: [], skipped: [],
}); });
expect(output).toContain("Install preflight for 'preflight-skill' from /tmp/source-skill"); expect(output).toContain("Install preflight for 'preflight-skill' from /tmp/source-skill");
expect(output).toContain('Planned installer steps:'); expect(output).toContain('Planned installer steps:');
expect(output).toContain('[download] download https://example.com/tool.tgz -> <default destination>'); expect(output).toContain('[download] curl -fsSL https://example.com/tool.tgz');
}); });
it('builds installer execution stub view from skill plan', () => { it('builds installer execution stub view from skill plan', () => {
@@ -535,16 +535,16 @@ describe('skills CLI helpers', () => {
expect(view.attempted.length).toBe(1); expect(view.attempted.length).toBe(1);
expect(view.attempted[0]).toEqual({ expect(view.attempted[0]).toEqual({
installer_type: 'download', installer_type: 'download',
command: expect.stringContaining('download https://example.com/tool.tgz'), command: expect.stringContaining('curl -fsSL https://example.com/tool.tgz'),
}); });
expect(view.results[0]).toEqual({ expect(view.results[0]).toEqual({
installer_type: 'download', installer_type: 'download',
command: expect.stringContaining('download https://example.com/tool.tgz'), command: expect.stringContaining('curl -fsSL https://example.com/tool.tgz'),
status: 'skipped', status: 'skipped',
reason: 'execution_disabled', reason: 'execution_disabled',
}); });
expect(view.wouldRun.length).toBe(1); expect(view.wouldRun.length).toBe(1);
expect(view.wouldRun[0]).toContain('download https://example.com/tool.tgz'); expect(view.wouldRun[0]).toContain('curl -fsSL https://example.com/tool.tgz');
}); });
it('renders installer execution stub output text', () => { it('renders installer execution stub output text', () => {
@@ -613,7 +613,7 @@ describe('skills CLI helpers', () => {
sourcePath: '/tmp/source-skill', sourcePath: '/tmp/source-skill',
skill: { name: 'exec-stub', tier: 'managed' as const, version: '1.0.0' }, skill: { name: 'exec-stub', tier: 'managed' as const, version: '1.0.0' },
mode: 'dry-run' as const, mode: 'dry-run' as const,
steps: [{ installerType: 'download', command: 'download https://example.com/a.tgz -> /tmp/a.tgz' }], steps: [{ installerType: 'download', command: 'curl -fsSL -o /tmp/a.tgz https://example.com/a.tgz' }],
skipped: [], skipped: [],
}; };
@@ -628,18 +628,18 @@ describe('skills CLI helpers', () => {
expect(view.attempted).toEqual([ expect(view.attempted).toEqual([
{ {
installer_type: 'download', installer_type: 'download',
command: 'download https://example.com/a.tgz -> /tmp/a.tgz', command: 'curl -fsSL -o /tmp/a.tgz https://example.com/a.tgz',
}, },
]); ]);
expect(view.results).toEqual([ expect(view.results).toEqual([
{ {
installer_type: 'download', installer_type: 'download',
command: 'download https://example.com/a.tgz -> /tmp/a.tgz', command: 'curl -fsSL -o /tmp/a.tgz https://example.com/a.tgz',
status: 'skipped', status: 'skipped',
reason: 'execution_disabled', reason: 'execution_disabled',
}, },
]); ]);
expect(view.wouldRun).toEqual(['download https://example.com/a.tgz -> /tmp/a.tgz']); expect(view.wouldRun).toEqual(['curl -fsSL -o /tmp/a.tgz https://example.com/a.tgz']);
}); });
it('builds blocked step envelopes when confirmation is required', () => { it('builds blocked step envelopes when confirmation is required', () => {
@@ -720,7 +720,7 @@ describe('skills CLI helpers', () => {
results: [ results: [
{ {
installer_type: 'download', installer_type: 'download',
command: 'download https://example.com/pkg.tgz -> <default destination>', command: 'curl -fsSL https://example.com/pkg.tgz',
status: 'failed', status: 'failed',
reason: 'allowlist_blocked', reason: 'allowlist_blocked',
}, },
@@ -738,14 +738,14 @@ describe('skills CLI helpers', () => {
); );
expect(logger.skillsInstallerCommandResult).toHaveBeenCalledWith( expect(logger.skillsInstallerCommandResult).toHaveBeenCalledWith(
expect.objectContaining({ expect.objectContaining({
command: hashSkillInstallerAuditCommand('download https://example.com/pkg.tgz -> <default destination>'), command: hashSkillInstallerAuditCommand('curl -fsSL https://example.com/pkg.tgz'),
}), }),
); );
expect(logger.skillsInstallerExecutionBlocked).not.toHaveBeenCalled(); expect(logger.skillsInstallerExecutionBlocked).not.toHaveBeenCalled();
}); });
it('hashes audit command values deterministically for non-sensitive commands', () => { it('hashes audit command values deterministically for non-sensitive commands', () => {
const command = 'download https://example.com/tool.tgz -> <default destination>'; const command = 'curl -fsSL https://example.com/tool.tgz';
expect(hashSkillInstallerAuditCommand(command)).toBe(hashSkillInstallerAuditCommand(command)); expect(hashSkillInstallerAuditCommand(command)).toBe(hashSkillInstallerAuditCommand(command));
expect(hashSkillInstallerAuditCommand(command)).toMatch(/^sha256:[a-f0-9]{64}$/); expect(hashSkillInstallerAuditCommand(command)).toMatch(/^sha256:[a-f0-9]{64}$/);
}); });
@@ -819,7 +819,7 @@ describe('skills CLI helpers', () => {
skill_name: 'audit-skill', skill_name: 'audit-skill',
phase: 'install', phase: 'install',
installer_type: 'download', installer_type: 'download',
command: 'download https://example.com/pkg.tgz', command: 'curl -fsSL https://example.com/pkg.tgz',
status: 'failed', status: 'failed',
reason: 'allowlist_blocked', reason: 'allowlist_blocked',
}, },
@@ -1550,13 +1550,13 @@ describe('skills CLI helpers', () => {
expect(payload.execution.attempted).toEqual([ expect(payload.execution.attempted).toEqual([
{ {
installer_type: 'download', installer_type: 'download',
command: 'download https://example.com/plan.tgz -> <default destination>', command: 'curl -fsSL https://example.com/plan.tgz',
}, },
]); ]);
expect(payload.execution.results).toEqual([ expect(payload.execution.results).toEqual([
{ {
installer_type: 'download', installer_type: 'download',
command: 'download https://example.com/plan.tgz -> <default destination>', command: 'curl -fsSL https://example.com/plan.tgz',
status: 'skipped', status: 'skipped',
reason: 'execution_disabled', reason: 'execution_disabled',
}, },
@@ -1599,13 +1599,13 @@ describe('skills CLI helpers', () => {
expect(payload.execution.attempted).toEqual([ expect(payload.execution.attempted).toEqual([
{ {
installer_type: 'download', installer_type: 'download',
command: 'download https://example.com/install.tgz -> <default destination>', command: 'curl -fsSL https://example.com/install.tgz',
}, },
]); ]);
expect(payload.execution.results).toEqual([ expect(payload.execution.results).toEqual([
{ {
installer_type: 'download', installer_type: 'download',
command: 'download https://example.com/install.tgz -> <default destination>', command: 'curl -fsSL https://example.com/install.tgz',
status: 'blocked', status: 'blocked',
reason: 'confirmation_required', reason: 'confirmation_required',
}, },
@@ -1645,7 +1645,7 @@ describe('skills CLI helpers', () => {
expect(payload.execution.results).toEqual([ expect(payload.execution.results).toEqual([
{ {
installer_type: 'download', installer_type: 'download',
command: 'download https://example.com/install-confirmed.tgz -> <default destination>', command: 'curl -fsSL https://example.com/install-confirmed.tgz',
status: 'skipped', status: 'skipped',
reason: 'execution_disabled', reason: 'execution_disabled',
}, },
@@ -1694,11 +1694,11 @@ describe('skills CLI helpers', () => {
const payload = JSON.parse(String(logSpy.mock.calls[logSpy.mock.calls.length - 1]?.[0])); const payload = JSON.parse(String(logSpy.mock.calls[logSpy.mock.calls.length - 1]?.[0]));
expect(payload.execution.execution_enabled).toBe(true); expect(payload.execution.execution_enabled).toBe(true);
expect(payload.execution.reason).toBe('execution_enabled'); expect(payload.execution.reason).toBe('execution_enabled');
expect(payload.execution.executed).toEqual(['download https://example.com/install-exec.tgz -> <default destination>']); expect(payload.execution.executed).toEqual(['curl -fsSL https://example.com/install-exec.tgz']);
expect(payload.execution.results).toEqual([ expect(payload.execution.results).toEqual([
{ {
installer_type: 'download', installer_type: 'download',
command: 'download https://example.com/install-exec.tgz -> <default destination>', command: 'curl -fsSL https://example.com/install-exec.tgz',
status: 'succeeded', status: 'succeeded',
reason: 'runner_reported_success', reason: 'runner_reported_success',
}, },
@@ -1739,7 +1739,7 @@ describe('skills CLI helpers', () => {
expect(runner.run).toHaveBeenCalledTimes(1); expect(runner.run).toHaveBeenCalledTimes(1);
const payload = JSON.parse(String(logSpy.mock.calls[0]?.[0])); const payload = JSON.parse(String(logSpy.mock.calls[0]?.[0]));
expect(payload.execution_enabled).toBe(true); expect(payload.execution_enabled).toBe(true);
expect(payload.executed).toEqual(['download https://example.com/execute.tgz -> <default destination>']); expect(payload.executed).toEqual(['curl -fsSL https://example.com/execute.tgz']);
logSpy.mockRestore(); logSpy.mockRestore();
}); });
@@ -2286,7 +2286,7 @@ describe('skills CLI helpers', () => {
expect(payload.execution.results).toEqual([ expect(payload.execution.results).toEqual([
{ {
installer_type: 'download', installer_type: 'download',
command: 'download https://example.com/cli-install-allowlist-blocked.tgz -> <default destination>', command: 'curl -fsSL https://example.com/cli-install-allowlist-blocked.tgz',
status: 'failed', status: 'failed',
reason: 'allowlist_blocked', reason: 'allowlist_blocked',
}, },
@@ -2379,7 +2379,7 @@ describe('skills CLI helpers', () => {
expect(payload.execution.results).toEqual([ expect(payload.execution.results).toEqual([
{ {
installer_type: 'download', installer_type: 'download',
command: 'download https://example.com/cli-install-no-exec.tgz -> <default destination>', command: 'curl -fsSL https://example.com/cli-install-no-exec.tgz',
status: 'skipped', status: 'skipped',
reason: 'execution_disabled', reason: 'execution_disabled',
}, },
@@ -2428,7 +2428,7 @@ describe('skills CLI helpers', () => {
expect(payload.execution.results).toEqual([ expect(payload.execution.results).toEqual([
{ {
installer_type: 'download', installer_type: 'download',
command: 'download https://example.com/cli-install-no-confirm.tgz -> <default destination>', command: 'curl -fsSL https://example.com/cli-install-no-confirm.tgz',
status: 'blocked', status: 'blocked',
reason: 'confirmation_required', reason: 'confirmation_required',
}, },
@@ -2563,7 +2563,7 @@ describe('skills CLI helpers', () => {
expect(payload.results).toEqual([ expect(payload.results).toEqual([
{ {
installer_type: 'download', installer_type: 'download',
command: 'download https://example.com/cli-exec-policy-disabled.tgz -> <default destination>', command: 'curl -fsSL https://example.com/cli-exec-policy-disabled.tgz',
status: 'skipped', status: 'skipped',
reason: 'execution_policy_disabled', reason: 'execution_policy_disabled',
}, },
@@ -2613,7 +2613,7 @@ describe('skills CLI helpers', () => {
expect(payload.results).toEqual([ expect(payload.results).toEqual([
{ {
installer_type: 'download', installer_type: 'download',
command: 'download https://example.com/cli-exec-no-exec.tgz -> <default destination>', command: 'curl -fsSL https://example.com/cli-exec-no-exec.tgz',
status: 'skipped', status: 'skipped',
reason: 'execution_disabled', reason: 'execution_disabled',
}, },
@@ -2763,7 +2763,7 @@ describe('skills CLI helpers', () => {
expect(payload.results).toEqual([ expect(payload.results).toEqual([
{ {
installer_type: 'download', installer_type: 'download',
command: 'download https://example.com/cli-exec-allowlist-blocked.tgz -> <default destination>', command: 'curl -fsSL https://example.com/cli-exec-allowlist-blocked.tgz',
status: 'failed', status: 'failed',
reason: 'allowlist_blocked', reason: 'allowlist_blocked',
}, },
+4 -4
View File
@@ -60,15 +60,15 @@ describe('buildInstallerPlan', () => {
expect(plan.skipped).toEqual([]); expect(plan.skipped).toEqual([]);
}); });
it('skips download installer when destination is missing', () => { it('plans download installer without destination as stdout curl', () => {
const plan = buildInstallerPlan( const plan = buildInstallerPlan(
[{ type: 'download', url: 'https://example.com/tool.tgz' }], [{ type: 'download', url: 'https://example.com/tool.tgz' }],
{ hasBinary: () => true }, { hasBinary: () => true },
); );
expect(plan.steps).toEqual([]); expect(plan.steps).toEqual([
expect(plan.skipped).toEqual([ { installerType: 'download', command: 'curl -fsSL https://example.com/tool.tgz' },
{ installerType: 'download', reason: 'download destination is required for executable install plans' },
]); ]);
expect(plan.skipped).toEqual([]);
}); });
}); });
+3 -5
View File
@@ -73,13 +73,11 @@ export function buildInstallerPlan(
continue; continue;
} }
if (!installer.destination) {
skipped.push({ installerType: 'download', reason: 'download destination is required for executable install plans' });
continue;
}
steps.push({ steps.push({
installerType: 'download', installerType: 'download',
command: `curl -fsSL -o ${installer.destination} ${installer.url}`, command: installer.destination
? `curl -fsSL -o ${installer.destination} ${installer.url}`
: `curl -fsSL ${installer.url}`,
}); });
} }