Skip to content

Commit 7ca7b3a

Browse files
author
StackMemory Bot (CLI)
committed
feat(skills): add parallel agent skill and expand skill registry
Add parallel agent orchestration skill for concurrent task execution. Extend claude-skills registry and skills CLI command.
1 parent c11d981 commit 7ca7b3a

5 files changed

Lines changed: 1239 additions & 2 deletions

File tree

src/cli/commands/skills.ts

Lines changed: 144 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -912,6 +912,125 @@ export function createSkillsCommand(): Command {
912912
}
913913
});
914914

915+
// Parallel agent skill commands
916+
const agentCmd = skillsCmd
917+
.command('agent')
918+
.description('Spawn parallel Claude agents in isolated workspaces');
919+
920+
agentCmd
921+
.command('research <question>')
922+
.description('Explore codebase and save findings as a frame')
923+
.option('--timeout <ms>', 'Agent timeout in milliseconds', '300000')
924+
.action(async (question, options) => {
925+
const spinner = ora('Spawning research agent...').start();
926+
try {
927+
const { context } = await initializeSkillContext();
928+
const { ParallelAgentSkill } =
929+
await import('../../skills/parallel-agent-skill.js');
930+
const agentSkill = new ParallelAgentSkill(context);
931+
const result = await agentSkill.research(question, {
932+
timeout: parseInt(options.timeout),
933+
});
934+
spinner.stop();
935+
if (result.success) {
936+
console.log(chalk.green('✓'), result.message);
937+
if (result.data?.findings) {
938+
console.log(chalk.cyan('\nFindings:\n'));
939+
console.log(result.data.findings);
940+
}
941+
} else {
942+
console.log(chalk.red('✗'), result.message);
943+
}
944+
await context.database.disconnect();
945+
} catch (error: unknown) {
946+
spinner.stop();
947+
console.error(chalk.red('Error:'), (error as Error).message);
948+
process.exit(1);
949+
}
950+
});
951+
952+
agentCmd
953+
.command('maintain <task>')
954+
.description('Low-stakes fix, produces a .patch file')
955+
.option('--timeout <ms>', 'Agent timeout in milliseconds', '300000')
956+
.action(async (task, options) => {
957+
const spinner = ora('Spawning maintenance agent...').start();
958+
try {
959+
const { context } = await initializeSkillContext();
960+
const { ParallelAgentSkill } =
961+
await import('../../skills/parallel-agent-skill.js');
962+
const agentSkill = new ParallelAgentSkill(context);
963+
const result = await agentSkill.maintain(task, {
964+
timeout: parseInt(options.timeout),
965+
});
966+
spinner.stop();
967+
if (result.success) {
968+
console.log(chalk.green('✓'), result.message);
969+
if (result.data) {
970+
console.log(chalk.cyan('\nPatch Details:'));
971+
console.log(` Files changed: ${result.data.filesChanged}`);
972+
console.log(` Additions: +${result.data.additions}`);
973+
console.log(` Deletions: -${result.data.deletions}`);
974+
console.log(chalk.yellow(`\n ${result.action}`));
975+
}
976+
} else {
977+
console.log(chalk.red('✗'), result.message);
978+
}
979+
await context.database.disconnect();
980+
} catch (error: unknown) {
981+
spinner.stop();
982+
console.error(chalk.red('Error:'), (error as Error).message);
983+
process.exit(1);
984+
}
985+
});
986+
987+
agentCmd
988+
.command('spec-run <specPath>')
989+
.description('Implement a spec on a branch, validate with lint+test+build')
990+
.option('--timeout <ms>', 'Agent timeout in milliseconds', '300000')
991+
.action(async (specPath, options) => {
992+
const spinner = ora('Spawning spec agent...').start();
993+
try {
994+
const { context } = await initializeSkillContext();
995+
const { ParallelAgentSkill } =
996+
await import('../../skills/parallel-agent-skill.js');
997+
const agentSkill = new ParallelAgentSkill(context);
998+
const result = await agentSkill.specRun(specPath, {
999+
timeout: parseInt(options.timeout),
1000+
});
1001+
spinner.stop();
1002+
if (result.success) {
1003+
console.log(chalk.green('✓'), result.message);
1004+
} else {
1005+
console.log(chalk.red('✗'), result.message);
1006+
}
1007+
if (result.data) {
1008+
console.log(chalk.cyan('\nResults:'));
1009+
console.log(` Branch: ${result.data.branch}`);
1010+
console.log(` Workspace: ${result.data.workDir}`);
1011+
const v = result.data.validation;
1012+
if (v) {
1013+
console.log(
1014+
` Lint: ${v.lint ? chalk.green('pass') : chalk.red('fail')} ` +
1015+
`Test: ${v.test ? chalk.green('pass') : chalk.red('fail')} ` +
1016+
`Build: ${v.build ? chalk.green('pass') : chalk.red('fail')}`
1017+
);
1018+
}
1019+
if (result.data.diffStat) {
1020+
console.log(chalk.gray(`\n${result.data.diffStat}`));
1021+
}
1022+
if (result.action) {
1023+
console.log(chalk.yellow(`\n ${result.action}`));
1024+
}
1025+
}
1026+
await context.database.disconnect();
1027+
} catch (error: unknown) {
1028+
spinner.stop();
1029+
console.error(chalk.red('Error:'), (error as Error).message);
1030+
process.exit(1);
1031+
}
1032+
});
1033+
9151034
// Help command for skills
9161035
skillsCmd
9171036
.command('help [skill]')
@@ -945,6 +1064,29 @@ Options:
9451064
--security Focus on security vulnerabilities
9461065
--performance Focus on performance issues
9471066
--verbose Show detailed output
1067+
`);
1068+
break;
1069+
case 'agent':
1070+
console.log(`
1071+
agent — Parallel Agent Skill (Willison Patterns)
1072+
1073+
Spawn isolated Claude agents in disposable /tmp workspaces.
1074+
1075+
Subcommands:
1076+
research <question> Explore codebase, save findings as a frame
1077+
maintain <task> Low-stakes fix, produces a .patch file
1078+
spec-run <specPath> Implement spec on branch, validate
1079+
1080+
Options:
1081+
--timeout <ms> Agent timeout (default: 300000)
1082+
1083+
Examples:
1084+
stackmemory skills agent research "How does FTS5 search work?"
1085+
stackmemory skills agent maintain "Fix deprecation warning in webhook.ts"
1086+
stackmemory skills agent spec-run docs/specs/my-feature.md
1087+
1088+
Apply patches: git apply .stackmemory/patches/<file>.patch
1089+
Review specs: cd /tmp/sm-spec-* && git log --oneline
9481090
`);
9491091
break;
9501092
default:
@@ -972,8 +1114,9 @@ Options:
9721114
console.log(
9731115
' spec - Generate iterative spec docs (one-pager, dev-spec, prompt-plan, agents)'
9741116
);
1117+
console.log(' linear-run - Execute Linear tasks via RLM orchestrator');
9751118
console.log(
976-
' linear-run - Execute Linear tasks via RLM orchestrator\n'
1119+
' agent - Spawn parallel agents (research, maintain, spec-run)\n'
9771120
);
9781121
console.log(
9791122
chalk.yellow(

src/skills/__tests__/claude-skills.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,7 @@ describe('Claude Skills', () => {
517517
'dashboard',
518518
'api',
519519
'spec',
520+
'agent',
520521
'repo',
521522
]);
522523

0 commit comments

Comments
 (0)