claude-cli-advanced-starter-pack 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/OVERVIEW.md +597 -0
- package/README.md +439 -0
- package/bin/gtask.js +282 -0
- package/bin/postinstall.js +53 -0
- package/package.json +69 -0
- package/src/agents/phase-dev-templates.js +1011 -0
- package/src/agents/templates.js +668 -0
- package/src/analysis/checklist-parser.js +414 -0
- package/src/analysis/codebase.js +481 -0
- package/src/cli/menu.js +958 -0
- package/src/commands/claude-audit.js +1482 -0
- package/src/commands/claude-settings.js +2243 -0
- package/src/commands/create-agent.js +681 -0
- package/src/commands/create-command.js +337 -0
- package/src/commands/create-hook.js +262 -0
- package/src/commands/create-phase-dev/codebase-analyzer.js +813 -0
- package/src/commands/create-phase-dev/documentation-generator.js +352 -0
- package/src/commands/create-phase-dev/post-completion.js +404 -0
- package/src/commands/create-phase-dev/scale-calculator.js +344 -0
- package/src/commands/create-phase-dev/wizard.js +492 -0
- package/src/commands/create-phase-dev.js +481 -0
- package/src/commands/create-skill.js +313 -0
- package/src/commands/create.js +446 -0
- package/src/commands/decompose.js +392 -0
- package/src/commands/detect-tech-stack.js +768 -0
- package/src/commands/explore-mcp/claude-md-updater.js +252 -0
- package/src/commands/explore-mcp/mcp-installer.js +346 -0
- package/src/commands/explore-mcp/mcp-registry.js +438 -0
- package/src/commands/explore-mcp.js +638 -0
- package/src/commands/gtask-init.js +641 -0
- package/src/commands/help.js +128 -0
- package/src/commands/init.js +1890 -0
- package/src/commands/install.js +250 -0
- package/src/commands/list.js +116 -0
- package/src/commands/roadmap.js +750 -0
- package/src/commands/setup-wizard.js +482 -0
- package/src/commands/setup.js +351 -0
- package/src/commands/sync.js +534 -0
- package/src/commands/test-run.js +456 -0
- package/src/commands/test-setup.js +456 -0
- package/src/commands/validate.js +67 -0
- package/src/config/tech-stack.defaults.json +182 -0
- package/src/config/tech-stack.schema.json +502 -0
- package/src/github/client.js +359 -0
- package/src/index.js +84 -0
- package/src/templates/claude-command.js +244 -0
- package/src/templates/issue-body.js +284 -0
- package/src/testing/config.js +411 -0
- package/src/utils/template-engine.js +398 -0
- package/src/utils/validate-templates.js +223 -0
- package/src/utils.js +396 -0
- package/templates/commands/ccasp-setup.template.md +113 -0
- package/templates/commands/context-audit.template.md +97 -0
- package/templates/commands/create-task-list.template.md +382 -0
- package/templates/commands/deploy-full.template.md +261 -0
- package/templates/commands/github-task-start.template.md +99 -0
- package/templates/commands/github-update.template.md +69 -0
- package/templates/commands/happy-start.template.md +117 -0
- package/templates/commands/phase-track.template.md +142 -0
- package/templates/commands/tunnel-start.template.md +127 -0
- package/templates/commands/tunnel-stop.template.md +106 -0
- package/templates/hooks/context-guardian.template.js +173 -0
- package/templates/hooks/deployment-orchestrator.template.js +219 -0
- package/templates/hooks/github-progress-hook.template.js +197 -0
- package/templates/hooks/happy-checkpoint-manager.template.js +222 -0
- package/templates/hooks/phase-dev-enforcer.template.js +183 -0
|
@@ -0,0 +1,681 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Create Agent Command
|
|
3
|
+
*
|
|
4
|
+
* Master command for creating Claude Code agents (L1/L2/L3)
|
|
5
|
+
* with optional RAG pipeline support
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import chalk from 'chalk';
|
|
9
|
+
import inquirer from 'inquirer';
|
|
10
|
+
import ora from 'ora';
|
|
11
|
+
import { existsSync, mkdirSync, writeFileSync } from 'fs';
|
|
12
|
+
import { join, dirname } from 'path';
|
|
13
|
+
import { showHeader, showSuccess, showError, showWarning, showInfo } from '../cli/menu.js';
|
|
14
|
+
import {
|
|
15
|
+
generateAgentTemplate,
|
|
16
|
+
generateOrchestratorTemplate,
|
|
17
|
+
AGENT_LEVELS,
|
|
18
|
+
} from '../agents/templates.js';
|
|
19
|
+
import { runCreateHook } from './create-hook.js';
|
|
20
|
+
import { runCreateCommand } from './create-command.js';
|
|
21
|
+
import { runCreateSkill } from './create-skill.js';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Run the create-agent wizard
|
|
25
|
+
*/
|
|
26
|
+
export async function runCreateAgent(options) {
|
|
27
|
+
showHeader('Agent Creator');
|
|
28
|
+
|
|
29
|
+
// Show the main menu
|
|
30
|
+
const { mode } = await inquirer.prompt([
|
|
31
|
+
{
|
|
32
|
+
type: 'list',
|
|
33
|
+
name: 'mode',
|
|
34
|
+
message: 'What would you like to create?',
|
|
35
|
+
choices: [
|
|
36
|
+
new inquirer.Separator(chalk.cyan('── AGENTS ──')),
|
|
37
|
+
{
|
|
38
|
+
name: `${chalk.green('1)')} Individual Agent Standalone specialized agent`,
|
|
39
|
+
value: 'individual',
|
|
40
|
+
short: 'Individual Agent',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
name: `${chalk.green('2)')} L2/L3 Sub-Agent Add to orchestrator hierarchy`,
|
|
44
|
+
value: 'subagent',
|
|
45
|
+
short: 'Sub-Agent',
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
name: `${chalk.green('3)')} RAG Pipeline System Full autonomous orchestration`,
|
|
49
|
+
value: 'rag-pipeline',
|
|
50
|
+
short: 'RAG Pipeline',
|
|
51
|
+
},
|
|
52
|
+
new inquirer.Separator(chalk.cyan('── SKILLS & WORKFLOWS ──')),
|
|
53
|
+
{
|
|
54
|
+
name: `${chalk.blue('4)')} Skill Package RAG-enhanced domain expertise`,
|
|
55
|
+
value: 'skill',
|
|
56
|
+
short: 'Skill',
|
|
57
|
+
},
|
|
58
|
+
new inquirer.Separator(chalk.cyan('── ENFORCEMENT & COMMANDS ──')),
|
|
59
|
+
{
|
|
60
|
+
name: `${chalk.yellow('5)')} Hook Event-driven enforcement`,
|
|
61
|
+
value: 'hook',
|
|
62
|
+
short: 'Hook',
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
name: `${chalk.yellow('6)')} Command Slash command definition`,
|
|
66
|
+
value: 'command',
|
|
67
|
+
short: 'Command',
|
|
68
|
+
},
|
|
69
|
+
new inquirer.Separator(),
|
|
70
|
+
{
|
|
71
|
+
name: `${chalk.dim('Q)')} Back / Exit`,
|
|
72
|
+
value: 'exit',
|
|
73
|
+
short: 'Exit',
|
|
74
|
+
},
|
|
75
|
+
],
|
|
76
|
+
pageSize: 12,
|
|
77
|
+
},
|
|
78
|
+
]);
|
|
79
|
+
|
|
80
|
+
if (mode === 'exit') {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Delegate to appropriate handler
|
|
85
|
+
switch (mode) {
|
|
86
|
+
case 'individual':
|
|
87
|
+
return await createIndividualAgent(options);
|
|
88
|
+
case 'subagent':
|
|
89
|
+
return await createSubAgent(options);
|
|
90
|
+
case 'rag-pipeline':
|
|
91
|
+
return await createRagPipeline(options);
|
|
92
|
+
case 'skill':
|
|
93
|
+
return await runCreateSkill(options);
|
|
94
|
+
case 'hook':
|
|
95
|
+
return await runCreateHook(options);
|
|
96
|
+
case 'command':
|
|
97
|
+
return await runCreateCommand(options);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Create an individual agent
|
|
103
|
+
*/
|
|
104
|
+
async function createIndividualAgent(options) {
|
|
105
|
+
showHeader('Create Individual Agent');
|
|
106
|
+
|
|
107
|
+
console.log(chalk.dim('Individual agents are standalone specialists for specific tasks.'));
|
|
108
|
+
console.log(chalk.dim('They can be spawned via the Task tool or referenced by skills.\n'));
|
|
109
|
+
|
|
110
|
+
// Step 1: Agent name
|
|
111
|
+
const { name } = await inquirer.prompt([
|
|
112
|
+
{
|
|
113
|
+
type: 'input',
|
|
114
|
+
name: 'name',
|
|
115
|
+
message: 'Agent name (kebab-case):',
|
|
116
|
+
default: options.name || 'my-agent',
|
|
117
|
+
validate: (input) => {
|
|
118
|
+
if (!/^[a-z][a-z0-9-]*$/.test(input)) {
|
|
119
|
+
return 'Use kebab-case (lowercase letters, numbers, hyphens)';
|
|
120
|
+
}
|
|
121
|
+
return true;
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
]);
|
|
125
|
+
|
|
126
|
+
// Step 2: Description
|
|
127
|
+
const { description } = await inquirer.prompt([
|
|
128
|
+
{
|
|
129
|
+
type: 'input',
|
|
130
|
+
name: 'description',
|
|
131
|
+
message: 'What does this agent do?',
|
|
132
|
+
default: `Specialized agent for ${name} tasks`,
|
|
133
|
+
},
|
|
134
|
+
]);
|
|
135
|
+
|
|
136
|
+
// Step 3: Level
|
|
137
|
+
console.log('');
|
|
138
|
+
console.log(chalk.cyan.bold('Agent Levels:'));
|
|
139
|
+
Object.entries(AGENT_LEVELS).forEach(([key, level]) => {
|
|
140
|
+
console.log(chalk.dim(` ${key}: ${level.description} (${level.tokenLimit})`));
|
|
141
|
+
});
|
|
142
|
+
console.log('');
|
|
143
|
+
|
|
144
|
+
const { level } = await inquirer.prompt([
|
|
145
|
+
{
|
|
146
|
+
type: 'list',
|
|
147
|
+
name: 'level',
|
|
148
|
+
message: 'Agent level:',
|
|
149
|
+
choices: Object.entries(AGENT_LEVELS).map(([key, level]) => ({
|
|
150
|
+
name: `${key} - ${level.description}`,
|
|
151
|
+
value: key,
|
|
152
|
+
short: key,
|
|
153
|
+
})),
|
|
154
|
+
default: 'L2',
|
|
155
|
+
},
|
|
156
|
+
]);
|
|
157
|
+
|
|
158
|
+
// Step 4: Tools
|
|
159
|
+
const { tools } = await inquirer.prompt([
|
|
160
|
+
{
|
|
161
|
+
type: 'checkbox',
|
|
162
|
+
name: 'tools',
|
|
163
|
+
message: 'Which tools should this agent have access to?',
|
|
164
|
+
choices: [
|
|
165
|
+
{ name: 'Read', value: 'Read', checked: true },
|
|
166
|
+
{ name: 'Grep', value: 'Grep', checked: true },
|
|
167
|
+
{ name: 'Glob', value: 'Glob', checked: true },
|
|
168
|
+
{ name: 'Edit', value: 'Edit', checked: level !== 'L3' },
|
|
169
|
+
{ name: 'Write', value: 'Write', checked: level !== 'L3' },
|
|
170
|
+
{ name: 'Bash', value: 'Bash', checked: false },
|
|
171
|
+
{ name: 'Task', value: 'Task', checked: level === 'L1' },
|
|
172
|
+
{ name: 'WebFetch', value: 'WebFetch', checked: false },
|
|
173
|
+
{ name: 'WebSearch', value: 'WebSearch', checked: false },
|
|
174
|
+
],
|
|
175
|
+
validate: (input) => input.length > 0 || 'Select at least one tool',
|
|
176
|
+
},
|
|
177
|
+
]);
|
|
178
|
+
|
|
179
|
+
// Step 5: Model
|
|
180
|
+
const { model } = await inquirer.prompt([
|
|
181
|
+
{
|
|
182
|
+
type: 'list',
|
|
183
|
+
name: 'model',
|
|
184
|
+
message: 'Preferred model:',
|
|
185
|
+
choices: [
|
|
186
|
+
{ name: 'Sonnet (balanced)', value: 'sonnet' },
|
|
187
|
+
{ name: 'Haiku (fast, lightweight)', value: 'haiku' },
|
|
188
|
+
{ name: 'Opus (complex tasks)', value: 'opus' },
|
|
189
|
+
{ name: 'Inherit from parent', value: 'inherit' },
|
|
190
|
+
],
|
|
191
|
+
default: level === 'L3' ? 'haiku' : 'sonnet',
|
|
192
|
+
},
|
|
193
|
+
]);
|
|
194
|
+
|
|
195
|
+
// Step 6: Specialization
|
|
196
|
+
const { specialization } = await inquirer.prompt([
|
|
197
|
+
{
|
|
198
|
+
type: 'input',
|
|
199
|
+
name: 'specialization',
|
|
200
|
+
message: 'Specialization focus (what domain does this agent excel in?):',
|
|
201
|
+
default: `${name} domain tasks`,
|
|
202
|
+
},
|
|
203
|
+
]);
|
|
204
|
+
|
|
205
|
+
// Step 7: When to use
|
|
206
|
+
const { whenToUse } = await inquirer.prompt([
|
|
207
|
+
{
|
|
208
|
+
type: 'input',
|
|
209
|
+
name: 'whenToUse',
|
|
210
|
+
message: 'When should this agent be used? (comma-separated):',
|
|
211
|
+
default: `When ${name} operations are needed, When specialized ${name} expertise is required`,
|
|
212
|
+
filter: (input) =>
|
|
213
|
+
input
|
|
214
|
+
.split(',')
|
|
215
|
+
.map((w) => w.trim())
|
|
216
|
+
.filter(Boolean),
|
|
217
|
+
},
|
|
218
|
+
]);
|
|
219
|
+
|
|
220
|
+
// Step 8: Workflow steps
|
|
221
|
+
const { defineWorkflow } = await inquirer.prompt([
|
|
222
|
+
{
|
|
223
|
+
type: 'confirm',
|
|
224
|
+
name: 'defineWorkflow',
|
|
225
|
+
message: 'Define workflow steps?',
|
|
226
|
+
default: true,
|
|
227
|
+
},
|
|
228
|
+
]);
|
|
229
|
+
|
|
230
|
+
const workflow = [];
|
|
231
|
+
if (defineWorkflow) {
|
|
232
|
+
let addingSteps = true;
|
|
233
|
+
let stepNum = 1;
|
|
234
|
+
|
|
235
|
+
while (addingSteps) {
|
|
236
|
+
const { stepTitle, stepInstructions } = await inquirer.prompt([
|
|
237
|
+
{
|
|
238
|
+
type: 'input',
|
|
239
|
+
name: 'stepTitle',
|
|
240
|
+
message: `Step ${stepNum} title:`,
|
|
241
|
+
default:
|
|
242
|
+
stepNum === 1 ? 'Analyze' : stepNum === 2 ? 'Execute' : stepNum === 3 ? 'Report' : `Step ${stepNum}`,
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
type: 'input',
|
|
246
|
+
name: 'stepInstructions',
|
|
247
|
+
message: `Step ${stepNum} instructions:`,
|
|
248
|
+
default: 'Perform this step.',
|
|
249
|
+
},
|
|
250
|
+
]);
|
|
251
|
+
|
|
252
|
+
workflow.push({ title: stepTitle, instructions: stepInstructions });
|
|
253
|
+
stepNum++;
|
|
254
|
+
|
|
255
|
+
if (stepNum > 3) {
|
|
256
|
+
const { continueAdding } = await inquirer.prompt([
|
|
257
|
+
{
|
|
258
|
+
type: 'confirm',
|
|
259
|
+
name: 'continueAdding',
|
|
260
|
+
message: 'Add another step?',
|
|
261
|
+
default: false,
|
|
262
|
+
},
|
|
263
|
+
]);
|
|
264
|
+
addingSteps = continueAdding;
|
|
265
|
+
} else {
|
|
266
|
+
addingSteps = true;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
if (stepNum === 4 && addingSteps) {
|
|
270
|
+
const { continueAdding } = await inquirer.prompt([
|
|
271
|
+
{
|
|
272
|
+
type: 'confirm',
|
|
273
|
+
name: 'continueAdding',
|
|
274
|
+
message: 'Add another step?',
|
|
275
|
+
default: false,
|
|
276
|
+
},
|
|
277
|
+
]);
|
|
278
|
+
addingSteps = continueAdding;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// Step 9: Output location
|
|
284
|
+
const { outputPath } = await inquirer.prompt([
|
|
285
|
+
{
|
|
286
|
+
type: 'list',
|
|
287
|
+
name: 'outputPath',
|
|
288
|
+
message: 'Where should the agent be created?',
|
|
289
|
+
choices: [
|
|
290
|
+
{ name: '.claude/agents/ (standard location)', value: '.claude/agents' },
|
|
291
|
+
{ name: 'Custom location', value: 'custom' },
|
|
292
|
+
],
|
|
293
|
+
},
|
|
294
|
+
]);
|
|
295
|
+
|
|
296
|
+
let finalPath = join(process.cwd(), outputPath, `${name}.md`);
|
|
297
|
+
if (outputPath === 'custom') {
|
|
298
|
+
const { customPath } = await inquirer.prompt([
|
|
299
|
+
{
|
|
300
|
+
type: 'input',
|
|
301
|
+
name: 'customPath',
|
|
302
|
+
message: 'Custom path:',
|
|
303
|
+
default: `.claude/agents/${name}.md`,
|
|
304
|
+
},
|
|
305
|
+
]);
|
|
306
|
+
finalPath = join(process.cwd(), customPath);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// Generate the agent
|
|
310
|
+
const spinner = ora('Generating agent...').start();
|
|
311
|
+
|
|
312
|
+
const agentContent = generateAgentTemplate({
|
|
313
|
+
name,
|
|
314
|
+
description,
|
|
315
|
+
level,
|
|
316
|
+
tools,
|
|
317
|
+
model,
|
|
318
|
+
specialization,
|
|
319
|
+
whenToUse,
|
|
320
|
+
workflow,
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
// Ensure directory exists
|
|
324
|
+
const dir = dirname(finalPath);
|
|
325
|
+
if (!existsSync(dir)) {
|
|
326
|
+
mkdirSync(dir, { recursive: true });
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
// Write the agent file
|
|
330
|
+
writeFileSync(finalPath, agentContent, 'utf8');
|
|
331
|
+
|
|
332
|
+
spinner.succeed('Agent created');
|
|
333
|
+
|
|
334
|
+
// Summary
|
|
335
|
+
const details = [
|
|
336
|
+
`Name: ${name}`,
|
|
337
|
+
`Level: ${level}`,
|
|
338
|
+
`Tools: ${tools.join(', ')}`,
|
|
339
|
+
`Model: ${model}`,
|
|
340
|
+
`Workflow steps: ${workflow.length}`,
|
|
341
|
+
'',
|
|
342
|
+
`Location: ${finalPath}`,
|
|
343
|
+
];
|
|
344
|
+
|
|
345
|
+
showSuccess('Agent Created!', details);
|
|
346
|
+
|
|
347
|
+
// Instructions
|
|
348
|
+
console.log(chalk.dim('\nTo use this agent:'));
|
|
349
|
+
console.log(chalk.cyan(`
|
|
350
|
+
# Via Task tool (subagent_type must be registered)
|
|
351
|
+
Task tool with subagent_type: "${name}"
|
|
352
|
+
|
|
353
|
+
# Reference in skill workflows
|
|
354
|
+
.claude/skills/{skill}/workflows/${name}-agent.md
|
|
355
|
+
`));
|
|
356
|
+
|
|
357
|
+
return { name, path: finalPath, level, tools };
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* Create a sub-agent (L2/L3)
|
|
362
|
+
*/
|
|
363
|
+
async function createSubAgent(options) {
|
|
364
|
+
showHeader('Create Sub-Agent');
|
|
365
|
+
|
|
366
|
+
console.log(chalk.dim('Sub-agents are specialists (L2) or workers (L3) in an orchestrator hierarchy.'));
|
|
367
|
+
console.log(chalk.dim('They are spawned by parent orchestrators for specific tasks.\n'));
|
|
368
|
+
|
|
369
|
+
// Step 1: Parent skill/orchestrator
|
|
370
|
+
const { parentSkill } = await inquirer.prompt([
|
|
371
|
+
{
|
|
372
|
+
type: 'input',
|
|
373
|
+
name: 'parentSkill',
|
|
374
|
+
message: 'Parent skill name (the skill this agent belongs to):',
|
|
375
|
+
default: 'my-skill',
|
|
376
|
+
},
|
|
377
|
+
]);
|
|
378
|
+
|
|
379
|
+
// Step 2: Agent name
|
|
380
|
+
const { name } = await inquirer.prompt([
|
|
381
|
+
{
|
|
382
|
+
type: 'input',
|
|
383
|
+
name: 'name',
|
|
384
|
+
message: 'Sub-agent name:',
|
|
385
|
+
default: `${parentSkill}-specialist`,
|
|
386
|
+
},
|
|
387
|
+
]);
|
|
388
|
+
|
|
389
|
+
// Step 3: Level
|
|
390
|
+
const { level } = await inquirer.prompt([
|
|
391
|
+
{
|
|
392
|
+
type: 'list',
|
|
393
|
+
name: 'level',
|
|
394
|
+
message: 'Agent level:',
|
|
395
|
+
choices: [
|
|
396
|
+
{ name: 'L2 - Specialist (deep domain expertise, 1-8K tokens)', value: 'L2' },
|
|
397
|
+
{ name: 'L3 - Worker (parallel atomic tasks, 500 tokens)', value: 'L3' },
|
|
398
|
+
],
|
|
399
|
+
default: 'L2',
|
|
400
|
+
},
|
|
401
|
+
]);
|
|
402
|
+
|
|
403
|
+
// Step 4: Specialty
|
|
404
|
+
const { specialty } = await inquirer.prompt([
|
|
405
|
+
{
|
|
406
|
+
type: 'input',
|
|
407
|
+
name: 'specialty',
|
|
408
|
+
message: 'What does this sub-agent specialize in?',
|
|
409
|
+
default: level === 'L2' ? 'Analysis and recommendations' : 'Atomic task execution',
|
|
410
|
+
},
|
|
411
|
+
]);
|
|
412
|
+
|
|
413
|
+
// Step 5: Tools (limited for L3)
|
|
414
|
+
const toolChoices =
|
|
415
|
+
level === 'L3'
|
|
416
|
+
? [
|
|
417
|
+
{ name: 'Read', value: 'Read', checked: true },
|
|
418
|
+
{ name: 'Grep', value: 'Grep', checked: true },
|
|
419
|
+
{ name: 'Glob', value: 'Glob', checked: true },
|
|
420
|
+
]
|
|
421
|
+
: [
|
|
422
|
+
{ name: 'Read', value: 'Read', checked: true },
|
|
423
|
+
{ name: 'Grep', value: 'Grep', checked: true },
|
|
424
|
+
{ name: 'Glob', value: 'Glob', checked: true },
|
|
425
|
+
{ name: 'Edit', value: 'Edit', checked: true },
|
|
426
|
+
{ name: 'Write', value: 'Write', checked: true },
|
|
427
|
+
{ name: 'Bash', value: 'Bash', checked: false },
|
|
428
|
+
{ name: 'Task', value: 'Task', checked: false },
|
|
429
|
+
];
|
|
430
|
+
|
|
431
|
+
const { tools } = await inquirer.prompt([
|
|
432
|
+
{
|
|
433
|
+
type: 'checkbox',
|
|
434
|
+
name: 'tools',
|
|
435
|
+
message: `Tools for this ${level}:`,
|
|
436
|
+
choices: toolChoices,
|
|
437
|
+
},
|
|
438
|
+
]);
|
|
439
|
+
|
|
440
|
+
// Generate the sub-agent
|
|
441
|
+
const spinner = ora('Generating sub-agent...').start();
|
|
442
|
+
|
|
443
|
+
const agentContent = generateAgentTemplate({
|
|
444
|
+
name,
|
|
445
|
+
description: specialty,
|
|
446
|
+
level,
|
|
447
|
+
tools,
|
|
448
|
+
model: level === 'L3' ? 'haiku' : 'sonnet',
|
|
449
|
+
specialization: specialty,
|
|
450
|
+
whenToUse: [`When ${parentSkill} orchestrator needs ${specialty.toLowerCase()}`],
|
|
451
|
+
workflow: [
|
|
452
|
+
{ title: 'Receive Task', instructions: 'Accept task from orchestrator with context.' },
|
|
453
|
+
{ title: 'Execute', instructions: `Perform ${specialty.toLowerCase()}.` },
|
|
454
|
+
{ title: 'Report', instructions: 'Return results to orchestrator.' },
|
|
455
|
+
],
|
|
456
|
+
});
|
|
457
|
+
|
|
458
|
+
// Determine path
|
|
459
|
+
const basePath = join(process.cwd(), '.claude', 'skills', parentSkill, 'workflows');
|
|
460
|
+
if (!existsSync(basePath)) {
|
|
461
|
+
mkdirSync(basePath, { recursive: true });
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
const finalPath = join(basePath, `${name}-agent.md`);
|
|
465
|
+
writeFileSync(finalPath, agentContent, 'utf8');
|
|
466
|
+
|
|
467
|
+
spinner.succeed('Sub-agent created');
|
|
468
|
+
|
|
469
|
+
const details = [
|
|
470
|
+
`Name: ${name}`,
|
|
471
|
+
`Parent: ${parentSkill}`,
|
|
472
|
+
`Level: ${level}`,
|
|
473
|
+
`Specialty: ${specialty}`,
|
|
474
|
+
'',
|
|
475
|
+
`Location: ${finalPath}`,
|
|
476
|
+
];
|
|
477
|
+
|
|
478
|
+
showSuccess('Sub-Agent Created!', details);
|
|
479
|
+
|
|
480
|
+
return { name, path: finalPath, level, parentSkill };
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
/**
|
|
484
|
+
* Create a RAG pipeline system
|
|
485
|
+
*/
|
|
486
|
+
async function createRagPipeline(options) {
|
|
487
|
+
showHeader('Create RAG Pipeline');
|
|
488
|
+
|
|
489
|
+
console.log(chalk.dim('RAG pipelines are autonomous systems with L1 orchestrator + L2 specialists.'));
|
|
490
|
+
console.log(chalk.dim('They include token monitoring, context compaction, and state persistence.\n'));
|
|
491
|
+
|
|
492
|
+
// Step 1: Domain name
|
|
493
|
+
const { domain } = await inquirer.prompt([
|
|
494
|
+
{
|
|
495
|
+
type: 'input',
|
|
496
|
+
name: 'domain',
|
|
497
|
+
message: 'Domain/pipeline name:',
|
|
498
|
+
default: 'my-pipeline',
|
|
499
|
+
},
|
|
500
|
+
]);
|
|
501
|
+
|
|
502
|
+
// Step 2: Description
|
|
503
|
+
const { description } = await inquirer.prompt([
|
|
504
|
+
{
|
|
505
|
+
type: 'input',
|
|
506
|
+
name: 'description',
|
|
507
|
+
message: 'What does this pipeline do?',
|
|
508
|
+
default: `Autonomous ${domain} processing`,
|
|
509
|
+
},
|
|
510
|
+
]);
|
|
511
|
+
|
|
512
|
+
// Step 3: L2 Specialists
|
|
513
|
+
console.log('');
|
|
514
|
+
console.log(chalk.cyan.bold('Define L2 Specialists:'));
|
|
515
|
+
console.log(chalk.dim(' Specialists handle specific aspects of the pipeline.\n'));
|
|
516
|
+
|
|
517
|
+
const specialists = [];
|
|
518
|
+
let addingSpecialists = true;
|
|
519
|
+
|
|
520
|
+
while (addingSpecialists) {
|
|
521
|
+
const { specName, specDesc } = await inquirer.prompt([
|
|
522
|
+
{
|
|
523
|
+
type: 'input',
|
|
524
|
+
name: 'specName',
|
|
525
|
+
message: 'Specialist name:',
|
|
526
|
+
default:
|
|
527
|
+
specialists.length === 0
|
|
528
|
+
? 'researcher'
|
|
529
|
+
: specialists.length === 1
|
|
530
|
+
? 'analyzer'
|
|
531
|
+
: 'implementer',
|
|
532
|
+
},
|
|
533
|
+
{
|
|
534
|
+
type: 'input',
|
|
535
|
+
name: 'specDesc',
|
|
536
|
+
message: 'Specialist focus:',
|
|
537
|
+
default: 'Domain-specific tasks',
|
|
538
|
+
},
|
|
539
|
+
]);
|
|
540
|
+
|
|
541
|
+
specialists.push({
|
|
542
|
+
name: specName,
|
|
543
|
+
file: `${specName}-agent.md`,
|
|
544
|
+
description: specDesc,
|
|
545
|
+
level: 'L2',
|
|
546
|
+
});
|
|
547
|
+
|
|
548
|
+
const { continueAdding } = await inquirer.prompt([
|
|
549
|
+
{
|
|
550
|
+
type: 'confirm',
|
|
551
|
+
name: 'continueAdding',
|
|
552
|
+
message: 'Add another specialist?',
|
|
553
|
+
default: specialists.length < 3,
|
|
554
|
+
},
|
|
555
|
+
]);
|
|
556
|
+
addingSpecialists = continueAdding;
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
// Step 4: Token thresholds
|
|
560
|
+
const { compactThreshold, respawnThreshold } = await inquirer.prompt([
|
|
561
|
+
{
|
|
562
|
+
type: 'number',
|
|
563
|
+
name: 'compactThreshold',
|
|
564
|
+
message: 'Context compaction threshold (%):',
|
|
565
|
+
default: 75,
|
|
566
|
+
validate: (n) => (n > 50 && n < 95 ? true : 'Enter 50-95'),
|
|
567
|
+
},
|
|
568
|
+
{
|
|
569
|
+
type: 'number',
|
|
570
|
+
name: 'respawnThreshold',
|
|
571
|
+
message: 'Respawn threshold (%):',
|
|
572
|
+
default: 90,
|
|
573
|
+
validate: (n) => (n > 75 && n <= 100 ? true : 'Enter 75-100'),
|
|
574
|
+
},
|
|
575
|
+
]);
|
|
576
|
+
|
|
577
|
+
// Generate the pipeline
|
|
578
|
+
const spinner = ora('Generating RAG pipeline...').start();
|
|
579
|
+
|
|
580
|
+
const basePath = join(process.cwd(), '.claude', 'skills', domain);
|
|
581
|
+
const dirs = [basePath, join(basePath, 'context'), join(basePath, 'workflows')];
|
|
582
|
+
|
|
583
|
+
for (const dir of dirs) {
|
|
584
|
+
if (!existsSync(dir)) {
|
|
585
|
+
mkdirSync(dir, { recursive: true });
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
const files = [];
|
|
590
|
+
|
|
591
|
+
// 1. L1 Orchestrator
|
|
592
|
+
const orchestratorContent = generateOrchestratorTemplate({
|
|
593
|
+
name: domain,
|
|
594
|
+
description,
|
|
595
|
+
specialists,
|
|
596
|
+
tokenLimits: { compact: compactThreshold, respawn: respawnThreshold },
|
|
597
|
+
});
|
|
598
|
+
const orchestratorPath = join(basePath, 'workflows', `${domain}-orchestrator.md`);
|
|
599
|
+
writeFileSync(orchestratorPath, orchestratorContent, 'utf8');
|
|
600
|
+
files.push(orchestratorPath);
|
|
601
|
+
|
|
602
|
+
// 2. L2 Specialists
|
|
603
|
+
for (const spec of specialists) {
|
|
604
|
+
const specContent = generateAgentTemplate({
|
|
605
|
+
name: `${domain}-${spec.name}`,
|
|
606
|
+
description: spec.description,
|
|
607
|
+
level: 'L2',
|
|
608
|
+
tools: ['Read', 'Grep', 'Glob', 'Edit', 'Write'],
|
|
609
|
+
model: 'sonnet',
|
|
610
|
+
specialization: spec.description,
|
|
611
|
+
whenToUse: [`When ${domain} orchestrator needs ${spec.name}`],
|
|
612
|
+
workflow: [
|
|
613
|
+
{ title: 'Receive', instructions: 'Accept task from orchestrator.' },
|
|
614
|
+
{ title: 'Execute', instructions: `Perform ${spec.name} operations.` },
|
|
615
|
+
{ title: 'Report', instructions: 'Return results to orchestrator.' },
|
|
616
|
+
],
|
|
617
|
+
});
|
|
618
|
+
const specPath = join(basePath, 'workflows', spec.file);
|
|
619
|
+
writeFileSync(specPath, specContent, 'utf8');
|
|
620
|
+
files.push(specPath);
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
// 3. SKILL.md
|
|
624
|
+
const skillContent = `---
|
|
625
|
+
name: ${domain}
|
|
626
|
+
description: ${description}
|
|
627
|
+
version: 1.0.0
|
|
628
|
+
type: rag-pipeline
|
|
629
|
+
---
|
|
630
|
+
|
|
631
|
+
# ${domain} RAG Pipeline
|
|
632
|
+
|
|
633
|
+
${description}
|
|
634
|
+
|
|
635
|
+
## Architecture
|
|
636
|
+
|
|
637
|
+
- **L1 Orchestrator**: Routes, monitors, aggregates
|
|
638
|
+
- **L2 Specialists**: ${specialists.map((s) => s.name).join(', ')}
|
|
639
|
+
|
|
640
|
+
## Token Management
|
|
641
|
+
|
|
642
|
+
| Threshold | Action |
|
|
643
|
+
|-----------|--------|
|
|
644
|
+
| ${compactThreshold}% | Compact context |
|
|
645
|
+
| ${respawnThreshold}% | Spawn continuation |
|
|
646
|
+
|
|
647
|
+
## Usage
|
|
648
|
+
|
|
649
|
+
\`\`\`markdown
|
|
650
|
+
skill: "${domain}"
|
|
651
|
+
|
|
652
|
+
[Your request]
|
|
653
|
+
\`\`\`
|
|
654
|
+
|
|
655
|
+
---
|
|
656
|
+
*RAG Pipeline created by gtask*
|
|
657
|
+
`;
|
|
658
|
+
const skillPath = join(basePath, 'SKILL.md');
|
|
659
|
+
writeFileSync(skillPath, skillContent, 'utf8');
|
|
660
|
+
files.push(skillPath);
|
|
661
|
+
|
|
662
|
+
spinner.succeed('RAG pipeline created');
|
|
663
|
+
|
|
664
|
+
const details = [
|
|
665
|
+
`Domain: ${domain}`,
|
|
666
|
+
`Orchestrator: L1`,
|
|
667
|
+
`Specialists: ${specialists.length} (L2)`,
|
|
668
|
+
`Compact: ${compactThreshold}%`,
|
|
669
|
+
`Respawn: ${respawnThreshold}%`,
|
|
670
|
+
'',
|
|
671
|
+
'Files created:',
|
|
672
|
+
...files.map((f) => ` ${f.replace(process.cwd(), '.')}`),
|
|
673
|
+
];
|
|
674
|
+
|
|
675
|
+
showSuccess('RAG Pipeline Created!', details);
|
|
676
|
+
|
|
677
|
+
console.log(chalk.dim('\nTo use this pipeline:'));
|
|
678
|
+
console.log(chalk.cyan(` skill: "${domain}"`));
|
|
679
|
+
|
|
680
|
+
return { domain, path: basePath, specialists, files };
|
|
681
|
+
}
|