fix(skills): reject execute without explicit confirm
This commit is contained in:
@@ -961,6 +961,33 @@ describe('skills CLI helpers', () => {
|
||||
rmSync(root, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
it('skills install rejects --execute without --confirm', async () => {
|
||||
const root = mkdtempSync(join(tmpdir(), 'flynn-skills-cli-'));
|
||||
const configPath = join(root, 'config.yaml');
|
||||
const managedDir = join(root, 'managed');
|
||||
const bundledDir = join(root, 'bundled');
|
||||
const workspaceDir = join(root, 'workspace');
|
||||
mkdirSync(managedDir, { recursive: true });
|
||||
mkdirSync(bundledDir, { recursive: true });
|
||||
mkdirSync(workspaceDir, { recursive: true });
|
||||
writeSkillsCliConfig(configPath, { managedDir, bundledDir, workspaceDir });
|
||||
|
||||
const program = new Command();
|
||||
registerSkillsCommand(program);
|
||||
|
||||
const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => undefined);
|
||||
process.exitCode = undefined;
|
||||
|
||||
await program.parseAsync(['skills', 'install', '/tmp/any-skill', '--execute', '-c', configPath], { from: 'user' });
|
||||
|
||||
expect(errorSpy).toHaveBeenCalledWith('`--execute` requires `--confirm`. No installer commands were run.');
|
||||
expect(process.exitCode).toBe(1);
|
||||
|
||||
errorSpy.mockRestore();
|
||||
process.exitCode = undefined;
|
||||
rmSync(root, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
it('skills execute parses execute flags and emits execution-enabled JSON receipt', async () => {
|
||||
const root = mkdtempSync(join(tmpdir(), 'flynn-skills-cli-'));
|
||||
const configPath = join(root, 'config.yaml');
|
||||
@@ -1003,4 +1030,42 @@ describe('skills CLI helpers', () => {
|
||||
process.exitCode = undefined;
|
||||
rmSync(root, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
it('skills execute rejects --execute without --confirm', async () => {
|
||||
const root = mkdtempSync(join(tmpdir(), 'flynn-skills-cli-'));
|
||||
const configPath = join(root, 'config.yaml');
|
||||
const managedDir = join(root, 'managed');
|
||||
const bundledDir = join(root, 'bundled');
|
||||
const workspaceDir = join(root, 'workspace');
|
||||
const skillDir = join(managedDir, 'cli-exec-skill');
|
||||
mkdirSync(skillDir, { recursive: true });
|
||||
mkdirSync(bundledDir, { recursive: true });
|
||||
mkdirSync(workspaceDir, { recursive: true });
|
||||
writeSkillsCliConfig(configPath, { managedDir, bundledDir, workspaceDir });
|
||||
writeFileSync(join(skillDir, 'SKILL.md'), '# Execute Skill\nInstructions');
|
||||
writeFileSync(
|
||||
join(skillDir, 'manifest.json'),
|
||||
JSON.stringify({
|
||||
name: 'cli-exec-skill',
|
||||
description: 'CLI execute parse',
|
||||
version: '1.0.0',
|
||||
}),
|
||||
'utf-8',
|
||||
);
|
||||
|
||||
const program = new Command();
|
||||
registerSkillsCommand(program);
|
||||
|
||||
const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => undefined);
|
||||
process.exitCode = undefined;
|
||||
|
||||
await program.parseAsync(['skills', 'execute', 'cli-exec-skill', '--execute', '-c', configPath], { from: 'user' });
|
||||
|
||||
expect(errorSpy).toHaveBeenCalledWith('`--execute` requires `--confirm`. No installer commands were run.');
|
||||
expect(process.exitCode).toBe(1);
|
||||
|
||||
errorSpy.mockRestore();
|
||||
process.exitCode = undefined;
|
||||
rmSync(root, { recursive: true, force: true });
|
||||
});
|
||||
});
|
||||
|
||||
@@ -815,6 +815,12 @@ export function registerSkillsCommand(program: Command): void {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((opts.execute ?? false) && !(opts.confirm ?? false)) {
|
||||
console.error('`--execute` requires `--confirm`. No installer commands were run.');
|
||||
process.exitCode = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
const defaultManagedDir = resolve(homedir(), '.flynn/workspace/skills');
|
||||
const installer = new SkillInstaller(loaded.config.skills.managed_dir ?? defaultManagedDir);
|
||||
|
||||
@@ -952,6 +958,12 @@ export function registerSkillsCommand(program: Command): void {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((opts.execute ?? false) && !(opts.confirm ?? false)) {
|
||||
console.error('`--execute` requires `--confirm`. No installer commands were run.');
|
||||
process.exitCode = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
runSkillExecuteAction(skill, {
|
||||
asJson: opts.json ?? false,
|
||||
confirmed: opts.confirm ?? false,
|
||||
|
||||
Reference in New Issue
Block a user