claude-flow-novice 2.5.2 → 2.6.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/.claude/agents/CLAUDE.md +740 -978
- package/.claude/agents/core-agents/cost-savings-cfn-loop-coordinator.md +47 -2
- package/.claude/agents/custom/agent-builder.md +637 -0
- package/.claude/api-configs/config-current-zai-config.env +62 -0
- package/.claude/api-configs/config-test-zai-config.env +62 -0
- package/.claude/api-configs/env-backups/before-anthropic-20251020-025404.env +62 -0
- package/.claude/api-configs/env-backups/before-restore-20251020-025431.env +62 -0
- package/.claude/artifacts/reflection-merge-logs/cli-agent-spawning-v2.5.2-merge-report.md +61 -0
- package/.claude/commands/cfn-loop-epic.md +41 -17
- package/.claude/commands/cfn-loop.md +43 -30
- package/.claude/commands/custom-routing-activate.md +37 -123
- package/.claude/commands/custom-routing-deactivate.md +27 -124
- package/.claude/commands/switch-api.md +41 -16
- package/.claude/skills/agent-execution/execute-agent.sh +126 -0
- package/.claude/skills/redis-coordination/AGENT_LOGGING.md +280 -0
- package/.claude/skills/redis-coordination/agent-log.sh +124 -0
- package/.claude/skills/redis-coordination/init-swarm.sh +6 -1
- package/.claude/skills/redis-coordination/invoke-waiting-mode.sh +62 -5
- package/.claude/skills/redis-coordination/orchestrate-cfn-loop.sh +68 -8
- package/.claude/skills/redis-coordination/orchestrate-cfn-loop.sh.backup-1760949407 +933 -0
- package/.claude/skills/redis-coordination/store-epic-context.sh +123 -0
- package/.claude/skills/redis-coordination/test-iteration-feedback.sh +320 -0
- package/.claude/skills/skill-builder/SKILL.md +910 -0
- package/CLAUDE.md +76 -2
- package/dist/cli/agent-command.js +151 -0
- package/dist/cli/agent-command.js.map +1 -0
- package/dist/cli/agent-definition-parser.js +176 -0
- package/dist/cli/agent-definition-parser.js.map +1 -0
- package/dist/cli/agent-executor.js +176 -0
- package/dist/cli/agent-executor.js.map +1 -0
- package/dist/cli/agent-prompt-builder.js +188 -0
- package/dist/cli/agent-prompt-builder.js.map +1 -0
- package/dist/cli/agent-spawn.js +46 -1
- package/dist/cli/agent-spawn.js.map +1 -1
- package/dist/cli/anthropic-client.js +242 -0
- package/dist/cli/anthropic-client.js.map +1 -0
- package/dist/cli/cli-agent-context.js +353 -0
- package/dist/cli/cli-agent-context.js.map +1 -0
- package/dist/cli/cli-agent-context.test.js +451 -0
- package/dist/cli/cli-agent-context.test.js.map +1 -0
- package/dist/cli/index.js +115 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/iteration-history.js +188 -0
- package/dist/cli/iteration-history.js.map +1 -0
- package/package.json +3 -1
- package/scripts/switch-api.sh +233 -0
|
@@ -0,0 +1,451 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unit Tests for CLI Agent Context Builder
|
|
3
|
+
*
|
|
4
|
+
* Tests the buildCLIAgentSystemPrompt function that creates natural language
|
|
5
|
+
* system prompts for CLI-spawned agents.
|
|
6
|
+
*/ import { buildCLIAgentSystemPrompt, loadContextFromEnv } from './cli-agent-context';
|
|
7
|
+
import fs from 'fs/promises';
|
|
8
|
+
// Mock fs module
|
|
9
|
+
jest.mock('fs/promises');
|
|
10
|
+
describe('CLI Agent Context Builder', ()=>{
|
|
11
|
+
const mockFs = fs;
|
|
12
|
+
beforeEach(()=>{
|
|
13
|
+
// Reset all mocks before each test
|
|
14
|
+
jest.clearAllMocks();
|
|
15
|
+
});
|
|
16
|
+
afterEach(()=>{
|
|
17
|
+
// Clean up environment variables
|
|
18
|
+
delete process.env.AGENT_TYPE;
|
|
19
|
+
delete process.env.TASK_ID;
|
|
20
|
+
delete process.env.ITERATION;
|
|
21
|
+
delete process.env.EPIC_CONTEXT;
|
|
22
|
+
delete process.env.PHASE_CONTEXT;
|
|
23
|
+
delete process.env.SUCCESS_CRITERIA;
|
|
24
|
+
});
|
|
25
|
+
describe('buildCLIAgentSystemPrompt', ()=>{
|
|
26
|
+
it('should build basic system prompt with agent type only', async ()=>{
|
|
27
|
+
// Mock fs.readFile to fail (no CLAUDE.md, no agent template)
|
|
28
|
+
mockFs.readFile.mockRejectedValue(new Error('File not found'));
|
|
29
|
+
const options = {
|
|
30
|
+
agentType: 'researcher'
|
|
31
|
+
};
|
|
32
|
+
const result = await buildCLIAgentSystemPrompt(options);
|
|
33
|
+
expect(result).toBeTruthy();
|
|
34
|
+
expect(result).toContain('Execution Instructions');
|
|
35
|
+
expect(result).toContain('CLI-spawned agent');
|
|
36
|
+
});
|
|
37
|
+
it('should include CLAUDE.md when available', async ()=>{
|
|
38
|
+
const claudeMd = '# Test Project Rules\nRule 1\nRule 2';
|
|
39
|
+
mockFs.readFile.mockImplementation((path)=>{
|
|
40
|
+
if (path.toString().endsWith('CLAUDE.md')) {
|
|
41
|
+
return Promise.resolve(claudeMd);
|
|
42
|
+
}
|
|
43
|
+
return Promise.reject(new Error('File not found'));
|
|
44
|
+
});
|
|
45
|
+
const options = {
|
|
46
|
+
agentType: 'researcher'
|
|
47
|
+
};
|
|
48
|
+
const result = await buildCLIAgentSystemPrompt(options);
|
|
49
|
+
expect(result).toContain('Project Rules (CLAUDE.md)');
|
|
50
|
+
expect(result).toContain('Test Project Rules');
|
|
51
|
+
expect(result).toContain('Rule 1');
|
|
52
|
+
});
|
|
53
|
+
it('should include agent markdown template when available', async ()=>{
|
|
54
|
+
const agentTemplate = '# Researcher Agent\n\nCore responsibilities:\n- Research\n- Analysis';
|
|
55
|
+
mockFs.readFile.mockImplementation((path)=>{
|
|
56
|
+
if (path.toString().includes('researcher.md')) {
|
|
57
|
+
return Promise.resolve(agentTemplate);
|
|
58
|
+
}
|
|
59
|
+
return Promise.reject(new Error('File not found'));
|
|
60
|
+
});
|
|
61
|
+
const options = {
|
|
62
|
+
agentType: 'researcher'
|
|
63
|
+
};
|
|
64
|
+
const result = await buildCLIAgentSystemPrompt(options);
|
|
65
|
+
expect(result).toContain('Agent Definition: researcher');
|
|
66
|
+
expect(result).toContain('Researcher Agent');
|
|
67
|
+
expect(result).toContain('Core responsibilities');
|
|
68
|
+
});
|
|
69
|
+
it('should format epic context from JSON to natural language', async ()=>{
|
|
70
|
+
mockFs.readFile.mockRejectedValue(new Error('File not found'));
|
|
71
|
+
const epicContext = {
|
|
72
|
+
epicGoal: 'Build authentication system',
|
|
73
|
+
inScope: [
|
|
74
|
+
'JWT authentication',
|
|
75
|
+
'User login',
|
|
76
|
+
'Session management'
|
|
77
|
+
],
|
|
78
|
+
outOfScope: [
|
|
79
|
+
'OAuth integration',
|
|
80
|
+
'SAML'
|
|
81
|
+
],
|
|
82
|
+
riskProfile: 'medium'
|
|
83
|
+
};
|
|
84
|
+
const options = {
|
|
85
|
+
agentType: 'researcher',
|
|
86
|
+
epicContext: JSON.stringify(epicContext)
|
|
87
|
+
};
|
|
88
|
+
const result = await buildCLIAgentSystemPrompt(options);
|
|
89
|
+
expect(result).toContain('## Epic Context');
|
|
90
|
+
expect(result).toContain('**Epic Goal:**');
|
|
91
|
+
expect(result).toContain('Build authentication system');
|
|
92
|
+
expect(result).toContain('**In Scope:**');
|
|
93
|
+
expect(result).toContain('- JWT authentication');
|
|
94
|
+
expect(result).toContain('- User login');
|
|
95
|
+
expect(result).toContain('**Out of Scope:**');
|
|
96
|
+
expect(result).toContain('- OAuth integration');
|
|
97
|
+
expect(result).toContain('**Risk Profile:** medium');
|
|
98
|
+
});
|
|
99
|
+
it('should format phase context from JSON to natural language', async ()=>{
|
|
100
|
+
mockFs.readFile.mockRejectedValue(new Error('File not found'));
|
|
101
|
+
const phaseContext = {
|
|
102
|
+
currentPhase: 'Implementation',
|
|
103
|
+
phaseNumber: 2,
|
|
104
|
+
dependencies: [
|
|
105
|
+
'Design complete',
|
|
106
|
+
'API spec approved'
|
|
107
|
+
],
|
|
108
|
+
deliverables: [
|
|
109
|
+
'Working authentication',
|
|
110
|
+
'Unit tests',
|
|
111
|
+
'Documentation'
|
|
112
|
+
]
|
|
113
|
+
};
|
|
114
|
+
const options = {
|
|
115
|
+
agentType: 'researcher',
|
|
116
|
+
phaseContext: JSON.stringify(phaseContext)
|
|
117
|
+
};
|
|
118
|
+
const result = await buildCLIAgentSystemPrompt(options);
|
|
119
|
+
expect(result).toContain('## Current Phase');
|
|
120
|
+
expect(result).toContain('**Phase:** Implementation');
|
|
121
|
+
expect(result).toContain('**Phase Number:** 2');
|
|
122
|
+
expect(result).toContain('**Dependencies:**');
|
|
123
|
+
expect(result).toContain('- Design complete');
|
|
124
|
+
expect(result).toContain('**Deliverables:**');
|
|
125
|
+
expect(result).toContain('- Working authentication');
|
|
126
|
+
});
|
|
127
|
+
it('should format success criteria from JSON to natural language', async ()=>{
|
|
128
|
+
mockFs.readFile.mockRejectedValue(new Error('File not found'));
|
|
129
|
+
const successCriteria = {
|
|
130
|
+
acceptanceCriteria: [
|
|
131
|
+
'All tests pass',
|
|
132
|
+
'Code coverage > 80%',
|
|
133
|
+
'Security review complete'
|
|
134
|
+
],
|
|
135
|
+
gateThreshold: 0.75,
|
|
136
|
+
consensusThreshold: 0.9,
|
|
137
|
+
qualityGates: {
|
|
138
|
+
testCoverage: 80,
|
|
139
|
+
securityScore: 0.9,
|
|
140
|
+
performanceBudget: 200
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
const options = {
|
|
144
|
+
agentType: 'researcher',
|
|
145
|
+
successCriteria: JSON.stringify(successCriteria)
|
|
146
|
+
};
|
|
147
|
+
const result = await buildCLIAgentSystemPrompt(options);
|
|
148
|
+
expect(result).toContain('## Success Criteria');
|
|
149
|
+
expect(result).toContain('**Acceptance Criteria:**');
|
|
150
|
+
expect(result).toContain('- All tests pass');
|
|
151
|
+
expect(result).toContain('- Code coverage > 80%');
|
|
152
|
+
expect(result).toContain('**Quality Gates:**');
|
|
153
|
+
expect(result).toContain('- Gate Threshold (Loop 3): 75%');
|
|
154
|
+
expect(result).toContain('- Consensus Threshold (Loop 2): 90%');
|
|
155
|
+
expect(result).toContain('**Quality Metrics:**');
|
|
156
|
+
expect(result).toContain('- Test Coverage: 80%');
|
|
157
|
+
expect(result).toContain('- Security Score: 90%');
|
|
158
|
+
expect(result).toContain('- Performance Budget: 200ms');
|
|
159
|
+
});
|
|
160
|
+
it('should include iteration context for iteration > 1', async ()=>{
|
|
161
|
+
mockFs.readFile.mockRejectedValue(new Error('File not found'));
|
|
162
|
+
const options = {
|
|
163
|
+
agentType: 'researcher',
|
|
164
|
+
taskId: 'task-123',
|
|
165
|
+
iteration: 3
|
|
166
|
+
};
|
|
167
|
+
const result = await buildCLIAgentSystemPrompt(options);
|
|
168
|
+
expect(result).toContain('## Current Iteration');
|
|
169
|
+
expect(result).toContain('This is **iteration 3** of your task');
|
|
170
|
+
expect(result).toContain('You have completed 2 iterations before this one');
|
|
171
|
+
expect(result).toContain('Address feedback from previous iterations');
|
|
172
|
+
});
|
|
173
|
+
it('should not include iteration context for iteration 1', async ()=>{
|
|
174
|
+
mockFs.readFile.mockRejectedValue(new Error('File not found'));
|
|
175
|
+
const options = {
|
|
176
|
+
agentType: 'researcher',
|
|
177
|
+
taskId: 'task-123',
|
|
178
|
+
iteration: 1
|
|
179
|
+
};
|
|
180
|
+
const result = await buildCLIAgentSystemPrompt(options);
|
|
181
|
+
expect(result).not.toContain('## Current Iteration');
|
|
182
|
+
});
|
|
183
|
+
it('should handle malformed JSON gracefully', async ()=>{
|
|
184
|
+
mockFs.readFile.mockRejectedValue(new Error('File not found'));
|
|
185
|
+
const options = {
|
|
186
|
+
agentType: 'researcher',
|
|
187
|
+
epicContext: '{invalid json}',
|
|
188
|
+
phaseContext: 'not json at all',
|
|
189
|
+
successCriteria: ''
|
|
190
|
+
};
|
|
191
|
+
const result = await buildCLIAgentSystemPrompt(options);
|
|
192
|
+
// Should not throw, and should still build basic prompt
|
|
193
|
+
expect(result).toBeTruthy();
|
|
194
|
+
expect(result).toContain('Execution Instructions');
|
|
195
|
+
});
|
|
196
|
+
it('should handle nil Redis values gracefully', async ()=>{
|
|
197
|
+
mockFs.readFile.mockRejectedValue(new Error('File not found'));
|
|
198
|
+
const options = {
|
|
199
|
+
agentType: 'researcher',
|
|
200
|
+
epicContext: '(nil)',
|
|
201
|
+
phaseContext: '(nil)',
|
|
202
|
+
successCriteria: '(nil)'
|
|
203
|
+
};
|
|
204
|
+
const result = await buildCLIAgentSystemPrompt(options);
|
|
205
|
+
// Should not throw, and should not include empty sections
|
|
206
|
+
expect(result).toBeTruthy();
|
|
207
|
+
expect(result).not.toContain('## Epic Context');
|
|
208
|
+
expect(result).not.toContain('## Current Phase');
|
|
209
|
+
expect(result).not.toContain('## Success Criteria');
|
|
210
|
+
});
|
|
211
|
+
it('should build complete prompt with all sections', async ()=>{
|
|
212
|
+
const claudeMd = '# Project Rules\nRule 1';
|
|
213
|
+
const agentTemplate = '# Researcher\nResponsibilities';
|
|
214
|
+
mockFs.readFile.mockImplementation((path)=>{
|
|
215
|
+
if (path.toString().endsWith('CLAUDE.md')) {
|
|
216
|
+
return Promise.resolve(claudeMd);
|
|
217
|
+
}
|
|
218
|
+
if (path.toString().includes('researcher.md')) {
|
|
219
|
+
return Promise.resolve(agentTemplate);
|
|
220
|
+
}
|
|
221
|
+
return Promise.reject(new Error('File not found'));
|
|
222
|
+
});
|
|
223
|
+
const epicContext = {
|
|
224
|
+
epicGoal: 'Test Epic',
|
|
225
|
+
inScope: [
|
|
226
|
+
'Feature A'
|
|
227
|
+
],
|
|
228
|
+
outOfScope: [
|
|
229
|
+
'Feature B'
|
|
230
|
+
]
|
|
231
|
+
};
|
|
232
|
+
const phaseContext = {
|
|
233
|
+
currentPhase: 'Implementation',
|
|
234
|
+
deliverables: [
|
|
235
|
+
'Code',
|
|
236
|
+
'Tests'
|
|
237
|
+
]
|
|
238
|
+
};
|
|
239
|
+
const successCriteria = {
|
|
240
|
+
acceptanceCriteria: [
|
|
241
|
+
'All tests pass'
|
|
242
|
+
],
|
|
243
|
+
gateThreshold: 0.75
|
|
244
|
+
};
|
|
245
|
+
const options = {
|
|
246
|
+
agentType: 'researcher',
|
|
247
|
+
taskId: 'task-123',
|
|
248
|
+
iteration: 2,
|
|
249
|
+
epicContext: JSON.stringify(epicContext),
|
|
250
|
+
phaseContext: JSON.stringify(phaseContext),
|
|
251
|
+
successCriteria: JSON.stringify(successCriteria)
|
|
252
|
+
};
|
|
253
|
+
const result = await buildCLIAgentSystemPrompt(options);
|
|
254
|
+
// Check all sections are present
|
|
255
|
+
expect(result).toContain('Project Rules (CLAUDE.md)');
|
|
256
|
+
expect(result).toContain('Agent Definition: researcher');
|
|
257
|
+
expect(result).toContain('## Epic Context');
|
|
258
|
+
expect(result).toContain('## Current Phase');
|
|
259
|
+
expect(result).toContain('## Success Criteria');
|
|
260
|
+
expect(result).toContain('## Current Iteration');
|
|
261
|
+
expect(result).toContain('## Execution Instructions');
|
|
262
|
+
// Check separators
|
|
263
|
+
expect(result.split('---').length).toBeGreaterThan(3);
|
|
264
|
+
});
|
|
265
|
+
});
|
|
266
|
+
describe('loadContextFromEnv', ()=>{
|
|
267
|
+
it('should load context from environment variables', ()=>{
|
|
268
|
+
process.env.AGENT_TYPE = 'researcher';
|
|
269
|
+
process.env.TASK_ID = 'task-123';
|
|
270
|
+
process.env.ITERATION = '2';
|
|
271
|
+
process.env.EPIC_CONTEXT = '{"epicGoal":"Test"}';
|
|
272
|
+
process.env.PHASE_CONTEXT = '{"currentPhase":"Implementation"}';
|
|
273
|
+
process.env.SUCCESS_CRITERIA = '{"gateThreshold":0.75}';
|
|
274
|
+
const result = loadContextFromEnv();
|
|
275
|
+
expect(result.agentType).toBe('researcher');
|
|
276
|
+
expect(result.taskId).toBe('task-123');
|
|
277
|
+
expect(result.iteration).toBe(2);
|
|
278
|
+
expect(result.epicContext).toBe('{"epicGoal":"Test"}');
|
|
279
|
+
expect(result.phaseContext).toBe('{"currentPhase":"Implementation"}');
|
|
280
|
+
expect(result.successCriteria).toBe('{"gateThreshold":0.75}');
|
|
281
|
+
});
|
|
282
|
+
it('should handle missing environment variables', ()=>{
|
|
283
|
+
const result = loadContextFromEnv();
|
|
284
|
+
expect(result.agentType).toBe('unknown');
|
|
285
|
+
expect(result.taskId).toBeUndefined();
|
|
286
|
+
expect(result.iteration).toBe(1);
|
|
287
|
+
expect(result.epicContext).toBeUndefined();
|
|
288
|
+
});
|
|
289
|
+
it('should parse iteration as number', ()=>{
|
|
290
|
+
process.env.ITERATION = '5';
|
|
291
|
+
const result = loadContextFromEnv();
|
|
292
|
+
expect(result.iteration).toBe(5);
|
|
293
|
+
expect(typeof result.iteration).toBe('number');
|
|
294
|
+
});
|
|
295
|
+
it('should default iteration to 1 if not provided', ()=>{
|
|
296
|
+
const result = loadContextFromEnv();
|
|
297
|
+
expect(result.iteration).toBe(1);
|
|
298
|
+
});
|
|
299
|
+
});
|
|
300
|
+
describe('Epic Context Formatting', ()=>{
|
|
301
|
+
it('should format epic with phases', async ()=>{
|
|
302
|
+
mockFs.readFile.mockRejectedValue(new Error('File not found'));
|
|
303
|
+
const epicContext = {
|
|
304
|
+
epicGoal: 'Build system',
|
|
305
|
+
phases: [
|
|
306
|
+
'Phase 1: Design',
|
|
307
|
+
'Phase 2: Implementation',
|
|
308
|
+
'Phase 3: Testing'
|
|
309
|
+
]
|
|
310
|
+
};
|
|
311
|
+
const options = {
|
|
312
|
+
agentType: 'researcher',
|
|
313
|
+
epicContext: JSON.stringify(epicContext)
|
|
314
|
+
};
|
|
315
|
+
const result = await buildCLIAgentSystemPrompt(options);
|
|
316
|
+
expect(result).toContain('**Phases:**');
|
|
317
|
+
expect(result).toContain('1. Phase 1: Design');
|
|
318
|
+
expect(result).toContain('2. Phase 2: Implementation');
|
|
319
|
+
expect(result).toContain('3. Phase 3: Testing');
|
|
320
|
+
});
|
|
321
|
+
it('should format epic with stakeholders', async ()=>{
|
|
322
|
+
mockFs.readFile.mockRejectedValue(new Error('File not found'));
|
|
323
|
+
const epicContext = {
|
|
324
|
+
epicGoal: 'Build system',
|
|
325
|
+
stakeholders: [
|
|
326
|
+
'Product Manager',
|
|
327
|
+
'Tech Lead',
|
|
328
|
+
'Security Team'
|
|
329
|
+
]
|
|
330
|
+
};
|
|
331
|
+
const options = {
|
|
332
|
+
agentType: 'researcher',
|
|
333
|
+
epicContext: JSON.stringify(epicContext)
|
|
334
|
+
};
|
|
335
|
+
const result = await buildCLIAgentSystemPrompt(options);
|
|
336
|
+
expect(result).toContain('**Stakeholders:** Product Manager, Tech Lead, Security Team');
|
|
337
|
+
});
|
|
338
|
+
it('should format epic with timeline', async ()=>{
|
|
339
|
+
mockFs.readFile.mockRejectedValue(new Error('File not found'));
|
|
340
|
+
const epicContext = {
|
|
341
|
+
epicGoal: 'Build system',
|
|
342
|
+
timeline: {
|
|
343
|
+
start: '2025-10-01',
|
|
344
|
+
end: '2025-12-31',
|
|
345
|
+
milestones: [
|
|
346
|
+
{
|
|
347
|
+
phase: 'Design',
|
|
348
|
+
date: '2025-10-15'
|
|
349
|
+
},
|
|
350
|
+
{
|
|
351
|
+
phase: 'Implementation',
|
|
352
|
+
date: '2025-11-30'
|
|
353
|
+
}
|
|
354
|
+
]
|
|
355
|
+
}
|
|
356
|
+
};
|
|
357
|
+
const options = {
|
|
358
|
+
agentType: 'researcher',
|
|
359
|
+
epicContext: JSON.stringify(epicContext)
|
|
360
|
+
};
|
|
361
|
+
const result = await buildCLIAgentSystemPrompt(options);
|
|
362
|
+
expect(result).toContain('**Timeline:**');
|
|
363
|
+
expect(result).toContain('- Start: 2025-10-01');
|
|
364
|
+
expect(result).toContain('- End: 2025-12-31');
|
|
365
|
+
expect(result).toContain('- Milestones:');
|
|
366
|
+
expect(result).toContain(' - Design: 2025-10-15');
|
|
367
|
+
expect(result).toContain(' - Implementation: 2025-11-30');
|
|
368
|
+
});
|
|
369
|
+
});
|
|
370
|
+
describe('Phase Context Formatting', ()=>{
|
|
371
|
+
it('should format phase with blockers', async ()=>{
|
|
372
|
+
mockFs.readFile.mockRejectedValue(new Error('File not found'));
|
|
373
|
+
const phaseContext = {
|
|
374
|
+
currentPhase: 'Implementation',
|
|
375
|
+
blockers: [
|
|
376
|
+
'Waiting for API key',
|
|
377
|
+
'Database migration pending'
|
|
378
|
+
]
|
|
379
|
+
};
|
|
380
|
+
const options = {
|
|
381
|
+
agentType: 'researcher',
|
|
382
|
+
phaseContext: JSON.stringify(phaseContext)
|
|
383
|
+
};
|
|
384
|
+
const result = await buildCLIAgentSystemPrompt(options);
|
|
385
|
+
expect(result).toContain('**Current Blockers:**');
|
|
386
|
+
expect(result).toContain('- Waiting for API key');
|
|
387
|
+
expect(result).toContain('- Database migration pending');
|
|
388
|
+
});
|
|
389
|
+
it('should format phase with resources', async ()=>{
|
|
390
|
+
mockFs.readFile.mockRejectedValue(new Error('File not found'));
|
|
391
|
+
const phaseContext = {
|
|
392
|
+
currentPhase: 'Implementation',
|
|
393
|
+
resources: {
|
|
394
|
+
agentCount: 5,
|
|
395
|
+
estimatedDuration: 3,
|
|
396
|
+
costBudget: 2.5
|
|
397
|
+
}
|
|
398
|
+
};
|
|
399
|
+
const options = {
|
|
400
|
+
agentType: 'researcher',
|
|
401
|
+
phaseContext: JSON.stringify(phaseContext)
|
|
402
|
+
};
|
|
403
|
+
const result = await buildCLIAgentSystemPrompt(options);
|
|
404
|
+
expect(result).toContain('**Resources:**');
|
|
405
|
+
expect(result).toContain('- Agents: 5');
|
|
406
|
+
expect(result).toContain('- Duration: 3 hours');
|
|
407
|
+
expect(result).toContain('- Budget: $2.50');
|
|
408
|
+
});
|
|
409
|
+
});
|
|
410
|
+
describe('Success Criteria Formatting', ()=>{
|
|
411
|
+
it('should format success criteria with definition of done', async ()=>{
|
|
412
|
+
mockFs.readFile.mockRejectedValue(new Error('File not found'));
|
|
413
|
+
const successCriteria = {
|
|
414
|
+
definitionOfDone: [
|
|
415
|
+
'All tests pass',
|
|
416
|
+
'Code reviewed',
|
|
417
|
+
'Documentation complete'
|
|
418
|
+
]
|
|
419
|
+
};
|
|
420
|
+
const options = {
|
|
421
|
+
agentType: 'researcher',
|
|
422
|
+
successCriteria: JSON.stringify(successCriteria)
|
|
423
|
+
};
|
|
424
|
+
const result = await buildCLIAgentSystemPrompt(options);
|
|
425
|
+
expect(result).toContain('**Definition of Done:**');
|
|
426
|
+
expect(result).toContain('- [ ] All tests pass');
|
|
427
|
+
expect(result).toContain('- [ ] Code reviewed');
|
|
428
|
+
expect(result).toContain('- [ ] Documentation complete');
|
|
429
|
+
});
|
|
430
|
+
it('should format success criteria with non-functional requirements', async ()=>{
|
|
431
|
+
mockFs.readFile.mockRejectedValue(new Error('File not found'));
|
|
432
|
+
const successCriteria = {
|
|
433
|
+
nonFunctionalRequirements: [
|
|
434
|
+
'Response time < 200ms',
|
|
435
|
+
'Support 1000 concurrent users',
|
|
436
|
+
'WCAG 2.1 AA compliance'
|
|
437
|
+
]
|
|
438
|
+
};
|
|
439
|
+
const options = {
|
|
440
|
+
agentType: 'researcher',
|
|
441
|
+
successCriteria: JSON.stringify(successCriteria)
|
|
442
|
+
};
|
|
443
|
+
const result = await buildCLIAgentSystemPrompt(options);
|
|
444
|
+
expect(result).toContain('**Non-Functional Requirements:**');
|
|
445
|
+
expect(result).toContain('- Response time < 200ms');
|
|
446
|
+
expect(result).toContain('- Support 1000 concurrent users');
|
|
447
|
+
});
|
|
448
|
+
});
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
//# sourceMappingURL=cli-agent-context.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/cli/cli-agent-context.test.ts"],"sourcesContent":["/**\r\n * Unit Tests for CLI Agent Context Builder\r\n *\r\n * Tests the buildCLIAgentSystemPrompt function that creates natural language\r\n * system prompts for CLI-spawned agents.\r\n */\r\n\r\nimport {\r\n buildCLIAgentSystemPrompt,\r\n loadContextFromEnv,\r\n type ContextBuilderOptions,\r\n type EpicContext,\r\n type PhaseContext,\r\n type SuccessCriteria,\r\n} from './cli-agent-context';\r\nimport fs from 'fs/promises';\r\n\r\n// Mock fs module\r\njest.mock('fs/promises');\r\n\r\ndescribe('CLI Agent Context Builder', () => {\r\n const mockFs = fs as jest.Mocked<typeof fs>;\r\n\r\n beforeEach(() => {\r\n // Reset all mocks before each test\r\n jest.clearAllMocks();\r\n });\r\n\r\n afterEach(() => {\r\n // Clean up environment variables\r\n delete process.env.AGENT_TYPE;\r\n delete process.env.TASK_ID;\r\n delete process.env.ITERATION;\r\n delete process.env.EPIC_CONTEXT;\r\n delete process.env.PHASE_CONTEXT;\r\n delete process.env.SUCCESS_CRITERIA;\r\n });\r\n\r\n describe('buildCLIAgentSystemPrompt', () => {\r\n it('should build basic system prompt with agent type only', async () => {\r\n // Mock fs.readFile to fail (no CLAUDE.md, no agent template)\r\n mockFs.readFile.mockRejectedValue(new Error('File not found'));\r\n\r\n const options: ContextBuilderOptions = {\r\n agentType: 'researcher',\r\n };\r\n\r\n const result = await buildCLIAgentSystemPrompt(options);\r\n\r\n expect(result).toBeTruthy();\r\n expect(result).toContain('Execution Instructions');\r\n expect(result).toContain('CLI-spawned agent');\r\n });\r\n\r\n it('should include CLAUDE.md when available', async () => {\r\n const claudeMd = '# Test Project Rules\\nRule 1\\nRule 2';\r\n\r\n mockFs.readFile.mockImplementation((path: any) => {\r\n if (path.toString().endsWith('CLAUDE.md')) {\r\n return Promise.resolve(claudeMd);\r\n }\r\n return Promise.reject(new Error('File not found'));\r\n });\r\n\r\n const options: ContextBuilderOptions = {\r\n agentType: 'researcher',\r\n };\r\n\r\n const result = await buildCLIAgentSystemPrompt(options);\r\n\r\n expect(result).toContain('Project Rules (CLAUDE.md)');\r\n expect(result).toContain('Test Project Rules');\r\n expect(result).toContain('Rule 1');\r\n });\r\n\r\n it('should include agent markdown template when available', async () => {\r\n const agentTemplate = '# Researcher Agent\\n\\nCore responsibilities:\\n- Research\\n- Analysis';\r\n\r\n mockFs.readFile.mockImplementation((path: any) => {\r\n if (path.toString().includes('researcher.md')) {\r\n return Promise.resolve(agentTemplate);\r\n }\r\n return Promise.reject(new Error('File not found'));\r\n });\r\n\r\n const options: ContextBuilderOptions = {\r\n agentType: 'researcher',\r\n };\r\n\r\n const result = await buildCLIAgentSystemPrompt(options);\r\n\r\n expect(result).toContain('Agent Definition: researcher');\r\n expect(result).toContain('Researcher Agent');\r\n expect(result).toContain('Core responsibilities');\r\n });\r\n\r\n it('should format epic context from JSON to natural language', async () => {\r\n mockFs.readFile.mockRejectedValue(new Error('File not found'));\r\n\r\n const epicContext: EpicContext = {\r\n epicGoal: 'Build authentication system',\r\n inScope: ['JWT authentication', 'User login', 'Session management'],\r\n outOfScope: ['OAuth integration', 'SAML'],\r\n riskProfile: 'medium',\r\n };\r\n\r\n const options: ContextBuilderOptions = {\r\n agentType: 'researcher',\r\n epicContext: JSON.stringify(epicContext),\r\n };\r\n\r\n const result = await buildCLIAgentSystemPrompt(options);\r\n\r\n expect(result).toContain('## Epic Context');\r\n expect(result).toContain('**Epic Goal:**');\r\n expect(result).toContain('Build authentication system');\r\n expect(result).toContain('**In Scope:**');\r\n expect(result).toContain('- JWT authentication');\r\n expect(result).toContain('- User login');\r\n expect(result).toContain('**Out of Scope:**');\r\n expect(result).toContain('- OAuth integration');\r\n expect(result).toContain('**Risk Profile:** medium');\r\n });\r\n\r\n it('should format phase context from JSON to natural language', async () => {\r\n mockFs.readFile.mockRejectedValue(new Error('File not found'));\r\n\r\n const phaseContext: PhaseContext = {\r\n currentPhase: 'Implementation',\r\n phaseNumber: 2,\r\n dependencies: ['Design complete', 'API spec approved'],\r\n deliverables: ['Working authentication', 'Unit tests', 'Documentation'],\r\n };\r\n\r\n const options: ContextBuilderOptions = {\r\n agentType: 'researcher',\r\n phaseContext: JSON.stringify(phaseContext),\r\n };\r\n\r\n const result = await buildCLIAgentSystemPrompt(options);\r\n\r\n expect(result).toContain('## Current Phase');\r\n expect(result).toContain('**Phase:** Implementation');\r\n expect(result).toContain('**Phase Number:** 2');\r\n expect(result).toContain('**Dependencies:**');\r\n expect(result).toContain('- Design complete');\r\n expect(result).toContain('**Deliverables:**');\r\n expect(result).toContain('- Working authentication');\r\n });\r\n\r\n it('should format success criteria from JSON to natural language', async () => {\r\n mockFs.readFile.mockRejectedValue(new Error('File not found'));\r\n\r\n const successCriteria: SuccessCriteria = {\r\n acceptanceCriteria: [\r\n 'All tests pass',\r\n 'Code coverage > 80%',\r\n 'Security review complete',\r\n ],\r\n gateThreshold: 0.75,\r\n consensusThreshold: 0.9,\r\n qualityGates: {\r\n testCoverage: 80,\r\n securityScore: 0.9,\r\n performanceBudget: 200,\r\n },\r\n };\r\n\r\n const options: ContextBuilderOptions = {\r\n agentType: 'researcher',\r\n successCriteria: JSON.stringify(successCriteria),\r\n };\r\n\r\n const result = await buildCLIAgentSystemPrompt(options);\r\n\r\n expect(result).toContain('## Success Criteria');\r\n expect(result).toContain('**Acceptance Criteria:**');\r\n expect(result).toContain('- All tests pass');\r\n expect(result).toContain('- Code coverage > 80%');\r\n expect(result).toContain('**Quality Gates:**');\r\n expect(result).toContain('- Gate Threshold (Loop 3): 75%');\r\n expect(result).toContain('- Consensus Threshold (Loop 2): 90%');\r\n expect(result).toContain('**Quality Metrics:**');\r\n expect(result).toContain('- Test Coverage: 80%');\r\n expect(result).toContain('- Security Score: 90%');\r\n expect(result).toContain('- Performance Budget: 200ms');\r\n });\r\n\r\n it('should include iteration context for iteration > 1', async () => {\r\n mockFs.readFile.mockRejectedValue(new Error('File not found'));\r\n\r\n const options: ContextBuilderOptions = {\r\n agentType: 'researcher',\r\n taskId: 'task-123',\r\n iteration: 3,\r\n };\r\n\r\n const result = await buildCLIAgentSystemPrompt(options);\r\n\r\n expect(result).toContain('## Current Iteration');\r\n expect(result).toContain('This is **iteration 3** of your task');\r\n expect(result).toContain('You have completed 2 iterations before this one');\r\n expect(result).toContain('Address feedback from previous iterations');\r\n });\r\n\r\n it('should not include iteration context for iteration 1', async () => {\r\n mockFs.readFile.mockRejectedValue(new Error('File not found'));\r\n\r\n const options: ContextBuilderOptions = {\r\n agentType: 'researcher',\r\n taskId: 'task-123',\r\n iteration: 1,\r\n };\r\n\r\n const result = await buildCLIAgentSystemPrompt(options);\r\n\r\n expect(result).not.toContain('## Current Iteration');\r\n });\r\n\r\n it('should handle malformed JSON gracefully', async () => {\r\n mockFs.readFile.mockRejectedValue(new Error('File not found'));\r\n\r\n const options: ContextBuilderOptions = {\r\n agentType: 'researcher',\r\n epicContext: '{invalid json}',\r\n phaseContext: 'not json at all',\r\n successCriteria: '',\r\n };\r\n\r\n const result = await buildCLIAgentSystemPrompt(options);\r\n\r\n // Should not throw, and should still build basic prompt\r\n expect(result).toBeTruthy();\r\n expect(result).toContain('Execution Instructions');\r\n });\r\n\r\n it('should handle nil Redis values gracefully', async () => {\r\n mockFs.readFile.mockRejectedValue(new Error('File not found'));\r\n\r\n const options: ContextBuilderOptions = {\r\n agentType: 'researcher',\r\n epicContext: '(nil)',\r\n phaseContext: '(nil)',\r\n successCriteria: '(nil)',\r\n };\r\n\r\n const result = await buildCLIAgentSystemPrompt(options);\r\n\r\n // Should not throw, and should not include empty sections\r\n expect(result).toBeTruthy();\r\n expect(result).not.toContain('## Epic Context');\r\n expect(result).not.toContain('## Current Phase');\r\n expect(result).not.toContain('## Success Criteria');\r\n });\r\n\r\n it('should build complete prompt with all sections', async () => {\r\n const claudeMd = '# Project Rules\\nRule 1';\r\n const agentTemplate = '# Researcher\\nResponsibilities';\r\n\r\n mockFs.readFile.mockImplementation((path: any) => {\r\n if (path.toString().endsWith('CLAUDE.md')) {\r\n return Promise.resolve(claudeMd);\r\n }\r\n if (path.toString().includes('researcher.md')) {\r\n return Promise.resolve(agentTemplate);\r\n }\r\n return Promise.reject(new Error('File not found'));\r\n });\r\n\r\n const epicContext: EpicContext = {\r\n epicGoal: 'Test Epic',\r\n inScope: ['Feature A'],\r\n outOfScope: ['Feature B'],\r\n };\r\n\r\n const phaseContext: PhaseContext = {\r\n currentPhase: 'Implementation',\r\n deliverables: ['Code', 'Tests'],\r\n };\r\n\r\n const successCriteria: SuccessCriteria = {\r\n acceptanceCriteria: ['All tests pass'],\r\n gateThreshold: 0.75,\r\n };\r\n\r\n const options: ContextBuilderOptions = {\r\n agentType: 'researcher',\r\n taskId: 'task-123',\r\n iteration: 2,\r\n epicContext: JSON.stringify(epicContext),\r\n phaseContext: JSON.stringify(phaseContext),\r\n successCriteria: JSON.stringify(successCriteria),\r\n };\r\n\r\n const result = await buildCLIAgentSystemPrompt(options);\r\n\r\n // Check all sections are present\r\n expect(result).toContain('Project Rules (CLAUDE.md)');\r\n expect(result).toContain('Agent Definition: researcher');\r\n expect(result).toContain('## Epic Context');\r\n expect(result).toContain('## Current Phase');\r\n expect(result).toContain('## Success Criteria');\r\n expect(result).toContain('## Current Iteration');\r\n expect(result).toContain('## Execution Instructions');\r\n\r\n // Check separators\r\n expect(result.split('---').length).toBeGreaterThan(3);\r\n });\r\n });\r\n\r\n describe('loadContextFromEnv', () => {\r\n it('should load context from environment variables', () => {\r\n process.env.AGENT_TYPE = 'researcher';\r\n process.env.TASK_ID = 'task-123';\r\n process.env.ITERATION = '2';\r\n process.env.EPIC_CONTEXT = '{\"epicGoal\":\"Test\"}';\r\n process.env.PHASE_CONTEXT = '{\"currentPhase\":\"Implementation\"}';\r\n process.env.SUCCESS_CRITERIA = '{\"gateThreshold\":0.75}';\r\n\r\n const result = loadContextFromEnv();\r\n\r\n expect(result.agentType).toBe('researcher');\r\n expect(result.taskId).toBe('task-123');\r\n expect(result.iteration).toBe(2);\r\n expect(result.epicContext).toBe('{\"epicGoal\":\"Test\"}');\r\n expect(result.phaseContext).toBe('{\"currentPhase\":\"Implementation\"}');\r\n expect(result.successCriteria).toBe('{\"gateThreshold\":0.75}');\r\n });\r\n\r\n it('should handle missing environment variables', () => {\r\n const result = loadContextFromEnv();\r\n\r\n expect(result.agentType).toBe('unknown');\r\n expect(result.taskId).toBeUndefined();\r\n expect(result.iteration).toBe(1);\r\n expect(result.epicContext).toBeUndefined();\r\n });\r\n\r\n it('should parse iteration as number', () => {\r\n process.env.ITERATION = '5';\r\n\r\n const result = loadContextFromEnv();\r\n\r\n expect(result.iteration).toBe(5);\r\n expect(typeof result.iteration).toBe('number');\r\n });\r\n\r\n it('should default iteration to 1 if not provided', () => {\r\n const result = loadContextFromEnv();\r\n\r\n expect(result.iteration).toBe(1);\r\n });\r\n });\r\n\r\n describe('Epic Context Formatting', () => {\r\n it('should format epic with phases', async () => {\r\n mockFs.readFile.mockRejectedValue(new Error('File not found'));\r\n\r\n const epicContext: EpicContext = {\r\n epicGoal: 'Build system',\r\n phases: ['Phase 1: Design', 'Phase 2: Implementation', 'Phase 3: Testing'],\r\n };\r\n\r\n const options: ContextBuilderOptions = {\r\n agentType: 'researcher',\r\n epicContext: JSON.stringify(epicContext),\r\n };\r\n\r\n const result = await buildCLIAgentSystemPrompt(options);\r\n\r\n expect(result).toContain('**Phases:**');\r\n expect(result).toContain('1. Phase 1: Design');\r\n expect(result).toContain('2. Phase 2: Implementation');\r\n expect(result).toContain('3. Phase 3: Testing');\r\n });\r\n\r\n it('should format epic with stakeholders', async () => {\r\n mockFs.readFile.mockRejectedValue(new Error('File not found'));\r\n\r\n const epicContext: EpicContext = {\r\n epicGoal: 'Build system',\r\n stakeholders: ['Product Manager', 'Tech Lead', 'Security Team'],\r\n };\r\n\r\n const options: ContextBuilderOptions = {\r\n agentType: 'researcher',\r\n epicContext: JSON.stringify(epicContext),\r\n };\r\n\r\n const result = await buildCLIAgentSystemPrompt(options);\r\n\r\n expect(result).toContain('**Stakeholders:** Product Manager, Tech Lead, Security Team');\r\n });\r\n\r\n it('should format epic with timeline', async () => {\r\n mockFs.readFile.mockRejectedValue(new Error('File not found'));\r\n\r\n const epicContext: EpicContext = {\r\n epicGoal: 'Build system',\r\n timeline: {\r\n start: '2025-10-01',\r\n end: '2025-12-31',\r\n milestones: [\r\n { phase: 'Design', date: '2025-10-15' },\r\n { phase: 'Implementation', date: '2025-11-30' },\r\n ],\r\n },\r\n };\r\n\r\n const options: ContextBuilderOptions = {\r\n agentType: 'researcher',\r\n epicContext: JSON.stringify(epicContext),\r\n };\r\n\r\n const result = await buildCLIAgentSystemPrompt(options);\r\n\r\n expect(result).toContain('**Timeline:**');\r\n expect(result).toContain('- Start: 2025-10-01');\r\n expect(result).toContain('- End: 2025-12-31');\r\n expect(result).toContain('- Milestones:');\r\n expect(result).toContain(' - Design: 2025-10-15');\r\n expect(result).toContain(' - Implementation: 2025-11-30');\r\n });\r\n });\r\n\r\n describe('Phase Context Formatting', () => {\r\n it('should format phase with blockers', async () => {\r\n mockFs.readFile.mockRejectedValue(new Error('File not found'));\r\n\r\n const phaseContext: PhaseContext = {\r\n currentPhase: 'Implementation',\r\n blockers: ['Waiting for API key', 'Database migration pending'],\r\n };\r\n\r\n const options: ContextBuilderOptions = {\r\n agentType: 'researcher',\r\n phaseContext: JSON.stringify(phaseContext),\r\n };\r\n\r\n const result = await buildCLIAgentSystemPrompt(options);\r\n\r\n expect(result).toContain('**Current Blockers:**');\r\n expect(result).toContain('- Waiting for API key');\r\n expect(result).toContain('- Database migration pending');\r\n });\r\n\r\n it('should format phase with resources', async () => {\r\n mockFs.readFile.mockRejectedValue(new Error('File not found'));\r\n\r\n const phaseContext: PhaseContext = {\r\n currentPhase: 'Implementation',\r\n resources: {\r\n agentCount: 5,\r\n estimatedDuration: 3,\r\n costBudget: 2.5,\r\n },\r\n };\r\n\r\n const options: ContextBuilderOptions = {\r\n agentType: 'researcher',\r\n phaseContext: JSON.stringify(phaseContext),\r\n };\r\n\r\n const result = await buildCLIAgentSystemPrompt(options);\r\n\r\n expect(result).toContain('**Resources:**');\r\n expect(result).toContain('- Agents: 5');\r\n expect(result).toContain('- Duration: 3 hours');\r\n expect(result).toContain('- Budget: $2.50');\r\n });\r\n });\r\n\r\n describe('Success Criteria Formatting', () => {\r\n it('should format success criteria with definition of done', async () => {\r\n mockFs.readFile.mockRejectedValue(new Error('File not found'));\r\n\r\n const successCriteria: SuccessCriteria = {\r\n definitionOfDone: [\r\n 'All tests pass',\r\n 'Code reviewed',\r\n 'Documentation complete',\r\n ],\r\n };\r\n\r\n const options: ContextBuilderOptions = {\r\n agentType: 'researcher',\r\n successCriteria: JSON.stringify(successCriteria),\r\n };\r\n\r\n const result = await buildCLIAgentSystemPrompt(options);\r\n\r\n expect(result).toContain('**Definition of Done:**');\r\n expect(result).toContain('- [ ] All tests pass');\r\n expect(result).toContain('- [ ] Code reviewed');\r\n expect(result).toContain('- [ ] Documentation complete');\r\n });\r\n\r\n it('should format success criteria with non-functional requirements', async () => {\r\n mockFs.readFile.mockRejectedValue(new Error('File not found'));\r\n\r\n const successCriteria: SuccessCriteria = {\r\n nonFunctionalRequirements: [\r\n 'Response time < 200ms',\r\n 'Support 1000 concurrent users',\r\n 'WCAG 2.1 AA compliance',\r\n ],\r\n };\r\n\r\n const options: ContextBuilderOptions = {\r\n agentType: 'researcher',\r\n successCriteria: JSON.stringify(successCriteria),\r\n };\r\n\r\n const result = await buildCLIAgentSystemPrompt(options);\r\n\r\n expect(result).toContain('**Non-Functional Requirements:**');\r\n expect(result).toContain('- Response time < 200ms');\r\n expect(result).toContain('- Support 1000 concurrent users');\r\n });\r\n });\r\n});\r\n"],"names":["buildCLIAgentSystemPrompt","loadContextFromEnv","fs","jest","mock","describe","mockFs","beforeEach","clearAllMocks","afterEach","process","env","AGENT_TYPE","TASK_ID","ITERATION","EPIC_CONTEXT","PHASE_CONTEXT","SUCCESS_CRITERIA","it","readFile","mockRejectedValue","Error","options","agentType","result","expect","toBeTruthy","toContain","claudeMd","mockImplementation","path","toString","endsWith","Promise","resolve","reject","agentTemplate","includes","epicContext","epicGoal","inScope","outOfScope","riskProfile","JSON","stringify","phaseContext","currentPhase","phaseNumber","dependencies","deliverables","successCriteria","acceptanceCriteria","gateThreshold","consensusThreshold","qualityGates","testCoverage","securityScore","performanceBudget","taskId","iteration","not","split","length","toBeGreaterThan","toBe","toBeUndefined","phases","stakeholders","timeline","start","end","milestones","phase","date","blockers","resources","agentCount","estimatedDuration","costBudget","definitionOfDone","nonFunctionalRequirements"],"mappings":"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"}
|
package/dist/cli/index.js
CHANGED
|
@@ -1,7 +1,120 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
3
|
* CLI Entry Point - v2.0
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
*
|
|
5
|
+
* Handles agent spawning commands:
|
|
6
|
+
* npx claude-flow-novice agent <type> [options]
|
|
7
|
+
*/ // Load environment variables from .env file
|
|
8
|
+
import 'dotenv/config';
|
|
9
|
+
import { VERSION } from '../core/index.js';
|
|
10
|
+
import { agentCommand } from './agent-command.js';
|
|
11
|
+
/**
|
|
12
|
+
* Parse command line arguments
|
|
13
|
+
*/ function parseArgs(args) {
|
|
14
|
+
const command = args[0] || 'help';
|
|
15
|
+
const agentType = args[1] && !args[1].startsWith('--') ? args[1] : undefined;
|
|
16
|
+
const options = {};
|
|
17
|
+
// Parse options
|
|
18
|
+
for(let i = agentType ? 2 : 1; i < args.length; i++){
|
|
19
|
+
const arg = args[i];
|
|
20
|
+
const value = args[i + 1];
|
|
21
|
+
switch(arg){
|
|
22
|
+
case '--task-id':
|
|
23
|
+
options.taskId = value;
|
|
24
|
+
i++;
|
|
25
|
+
break;
|
|
26
|
+
case '--iteration':
|
|
27
|
+
options.iteration = parseInt(value, 10);
|
|
28
|
+
i++;
|
|
29
|
+
break;
|
|
30
|
+
case '--context':
|
|
31
|
+
options.context = value;
|
|
32
|
+
i++;
|
|
33
|
+
break;
|
|
34
|
+
case '--mode':
|
|
35
|
+
options.mode = value;
|
|
36
|
+
i++;
|
|
37
|
+
break;
|
|
38
|
+
case '--priority':
|
|
39
|
+
options.priority = parseInt(value, 10);
|
|
40
|
+
i++;
|
|
41
|
+
break;
|
|
42
|
+
case '--parent-task-id':
|
|
43
|
+
options.parentTaskId = value;
|
|
44
|
+
i++;
|
|
45
|
+
break;
|
|
46
|
+
case '--list':
|
|
47
|
+
options.list = true;
|
|
48
|
+
break;
|
|
49
|
+
case '--help':
|
|
50
|
+
case '-h':
|
|
51
|
+
options.help = true;
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
command,
|
|
57
|
+
agentType,
|
|
58
|
+
options
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Display main CLI help
|
|
63
|
+
*/ function displayHelp() {
|
|
64
|
+
console.log(`
|
|
65
|
+
Claude Flow Novice CLI v${VERSION}
|
|
66
|
+
|
|
67
|
+
Usage:
|
|
68
|
+
npx claude-flow-novice <command> [options]
|
|
69
|
+
|
|
70
|
+
Commands:
|
|
71
|
+
agent <type> [options] Spawn an agent for task execution
|
|
72
|
+
--version Show version number
|
|
73
|
+
--help Show this help message
|
|
74
|
+
|
|
75
|
+
Examples:
|
|
76
|
+
# Spawn an agent
|
|
77
|
+
npx claude-flow-novice agent coder --context "Implement feature"
|
|
78
|
+
|
|
79
|
+
# List available agents
|
|
80
|
+
npx claude-flow-novice agent --list
|
|
81
|
+
|
|
82
|
+
# Show version
|
|
83
|
+
npx claude-flow-novice --version
|
|
84
|
+
|
|
85
|
+
For more information:
|
|
86
|
+
https://github.com/yourusername/claude-flow-novice
|
|
87
|
+
`);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Main CLI entry point
|
|
91
|
+
*/ async function main() {
|
|
92
|
+
const args = process.argv.slice(2);
|
|
93
|
+
// Handle version flag
|
|
94
|
+
if (args.includes('--version') || args.includes('-v')) {
|
|
95
|
+
console.log(`Claude Flow Novice v${VERSION}`);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
// Handle help flag
|
|
99
|
+
if (args.length === 0 || args.includes('--help') || args.includes('-h')) {
|
|
100
|
+
displayHelp();
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
const { command, agentType, options } = parseArgs(args);
|
|
104
|
+
switch(command){
|
|
105
|
+
case 'agent':
|
|
106
|
+
await agentCommand(agentType, options);
|
|
107
|
+
break;
|
|
108
|
+
default:
|
|
109
|
+
console.error(`Unknown command: ${command}`);
|
|
110
|
+
console.log('Run with --help for usage information');
|
|
111
|
+
process.exit(1);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// Run CLI
|
|
115
|
+
main().catch((error)=>{
|
|
116
|
+
console.error('[claude-flow-novice] Fatal error:', error);
|
|
117
|
+
process.exit(1);
|
|
118
|
+
});
|
|
6
119
|
|
|
7
120
|
//# sourceMappingURL=index.js.map
|
package/dist/cli/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cli/index.ts"],"sourcesContent":["#!/usr/bin/env node\r\n/**\r\n * CLI Entry Point - v2.0\r\n */\r\n\r\nimport { VERSION } from '../core/index.js';\r\n\r\
|
|
1
|
+
{"version":3,"sources":["../../src/cli/index.ts"],"sourcesContent":["#!/usr/bin/env node\r\n/**\r\n * CLI Entry Point - v2.0\r\n *\r\n * Handles agent spawning commands:\r\n * npx claude-flow-novice agent <type> [options]\r\n */\r\n\r\n// Load environment variables from .env file\r\nimport 'dotenv/config';\r\n\r\nimport { VERSION } from '../core/index.js';\r\nimport { agentCommand, AgentCommandOptions } from './agent-command.js';\r\n\r\n/**\r\n * Parse command line arguments\r\n */\r\nfunction parseArgs(args: string[]): { command: string; agentType?: string; options: AgentCommandOptions } {\r\n const command = args[0] || 'help';\r\n const agentType = args[1] && !args[1].startsWith('--') ? args[1] : undefined;\r\n const options: AgentCommandOptions = {};\r\n\r\n // Parse options\r\n for (let i = agentType ? 2 : 1; i < args.length; i++) {\r\n const arg = args[i];\r\n const value = args[i + 1];\r\n\r\n switch (arg) {\r\n case '--task-id':\r\n options.taskId = value;\r\n i++;\r\n break;\r\n case '--iteration':\r\n options.iteration = parseInt(value, 10);\r\n i++;\r\n break;\r\n case '--context':\r\n options.context = value;\r\n i++;\r\n break;\r\n case '--mode':\r\n options.mode = value;\r\n i++;\r\n break;\r\n case '--priority':\r\n options.priority = parseInt(value, 10);\r\n i++;\r\n break;\r\n case '--parent-task-id':\r\n options.parentTaskId = value;\r\n i++;\r\n break;\r\n case '--list':\r\n options.list = true;\r\n break;\r\n case '--help':\r\n case '-h':\r\n options.help = true;\r\n break;\r\n }\r\n }\r\n\r\n return { command, agentType, options };\r\n}\r\n\r\n/**\r\n * Display main CLI help\r\n */\r\nfunction displayHelp(): void {\r\n console.log(`\r\nClaude Flow Novice CLI v${VERSION}\r\n\r\nUsage:\r\n npx claude-flow-novice <command> [options]\r\n\r\nCommands:\r\n agent <type> [options] Spawn an agent for task execution\r\n --version Show version number\r\n --help Show this help message\r\n\r\nExamples:\r\n # Spawn an agent\r\n npx claude-flow-novice agent coder --context \"Implement feature\"\r\n\r\n # List available agents\r\n npx claude-flow-novice agent --list\r\n\r\n # Show version\r\n npx claude-flow-novice --version\r\n\r\nFor more information:\r\n https://github.com/yourusername/claude-flow-novice\r\n`);\r\n}\r\n\r\n/**\r\n * Main CLI entry point\r\n */\r\nasync function main() {\r\n const args = process.argv.slice(2);\r\n\r\n // Handle version flag\r\n if (args.includes('--version') || args.includes('-v')) {\r\n console.log(`Claude Flow Novice v${VERSION}`);\r\n return;\r\n }\r\n\r\n // Handle help flag\r\n if (args.length === 0 || args.includes('--help') || args.includes('-h')) {\r\n displayHelp();\r\n return;\r\n }\r\n\r\n const { command, agentType, options } = parseArgs(args);\r\n\r\n switch (command) {\r\n case 'agent':\r\n await agentCommand(agentType, options);\r\n break;\r\n\r\n default:\r\n console.error(`Unknown command: ${command}`);\r\n console.log('Run with --help for usage information');\r\n process.exit(1);\r\n }\r\n}\r\n\r\n// Run CLI\r\nmain().catch((error) => {\r\n console.error('[claude-flow-novice] Fatal error:', error);\r\n process.exit(1);\r\n});\r\n"],"names":["VERSION","agentCommand","parseArgs","args","command","agentType","startsWith","undefined","options","i","length","arg","value","taskId","iteration","parseInt","context","mode","priority","parentTaskId","list","help","displayHelp","console","log","main","process","argv","slice","includes","error","exit","catch"],"mappings":";AACA;;;;;CAKC,GAED,4CAA4C;AAC5C,OAAO,gBAAgB;AAEvB,SAASA,OAAO,QAAQ,mBAAmB;AAC3C,SAASC,YAAY,QAA6B,qBAAqB;AAEvE;;CAEC,GACD,SAASC,UAAUC,IAAc;IAC/B,MAAMC,UAAUD,IAAI,CAAC,EAAE,IAAI;IAC3B,MAAME,YAAYF,IAAI,CAAC,EAAE,IAAI,CAACA,IAAI,CAAC,EAAE,CAACG,UAAU,CAAC,QAAQH,IAAI,CAAC,EAAE,GAAGI;IACnE,MAAMC,UAA+B,CAAC;IAEtC,gBAAgB;IAChB,IAAK,IAAIC,IAAIJ,YAAY,IAAI,GAAGI,IAAIN,KAAKO,MAAM,EAAED,IAAK;QACpD,MAAME,MAAMR,IAAI,CAACM,EAAE;QACnB,MAAMG,QAAQT,IAAI,CAACM,IAAI,EAAE;QAEzB,OAAQE;YACN,KAAK;gBACHH,QAAQK,MAAM,GAAGD;gBACjBH;gBACA;YACF,KAAK;gBACHD,QAAQM,SAAS,GAAGC,SAASH,OAAO;gBACpCH;gBACA;YACF,KAAK;gBACHD,QAAQQ,OAAO,GAAGJ;gBAClBH;gBACA;YACF,KAAK;gBACHD,QAAQS,IAAI,GAAGL;gBACfH;gBACA;YACF,KAAK;gBACHD,QAAQU,QAAQ,GAAGH,SAASH,OAAO;gBACnCH;gBACA;YACF,KAAK;gBACHD,QAAQW,YAAY,GAAGP;gBACvBH;gBACA;YACF,KAAK;gBACHD,QAAQY,IAAI,GAAG;gBACf;YACF,KAAK;YACL,KAAK;gBACHZ,QAAQa,IAAI,GAAG;gBACf;QACJ;IACF;IAEA,OAAO;QAAEjB;QAASC;QAAWG;IAAQ;AACvC;AAEA;;CAEC,GACD,SAASc;IACPC,QAAQC,GAAG,CAAC,CAAC;wBACS,EAAExB,QAAQ;;;;;;;;;;;;;;;;;;;;;;AAsBlC,CAAC;AACD;AAEA;;CAEC,GACD,eAAeyB;IACb,MAAMtB,OAAOuB,QAAQC,IAAI,CAACC,KAAK,CAAC;IAEhC,sBAAsB;IACtB,IAAIzB,KAAK0B,QAAQ,CAAC,gBAAgB1B,KAAK0B,QAAQ,CAAC,OAAO;QACrDN,QAAQC,GAAG,CAAC,CAAC,oBAAoB,EAAExB,SAAS;QAC5C;IACF;IAEA,mBAAmB;IACnB,IAAIG,KAAKO,MAAM,KAAK,KAAKP,KAAK0B,QAAQ,CAAC,aAAa1B,KAAK0B,QAAQ,CAAC,OAAO;QACvEP;QACA;IACF;IAEA,MAAM,EAAElB,OAAO,EAAEC,SAAS,EAAEG,OAAO,EAAE,GAAGN,UAAUC;IAElD,OAAQC;QACN,KAAK;YACH,MAAMH,aAAaI,WAAWG;YAC9B;QAEF;YACEe,QAAQO,KAAK,CAAC,CAAC,iBAAiB,EAAE1B,SAAS;YAC3CmB,QAAQC,GAAG,CAAC;YACZE,QAAQK,IAAI,CAAC;IACjB;AACF;AAEA,UAAU;AACVN,OAAOO,KAAK,CAAC,CAACF;IACZP,QAAQO,KAAK,CAAC,qCAAqCA;IACnDJ,QAAQK,IAAI,CAAC;AACf"}
|