claude-flow-novice 2.14.16 → 2.14.17
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/commands/cfn-loop-cli.md +135 -99
- package/claude-assets/agents/custom/cfn-system-expert.md +262 -0
- package/claude-assets/commands/cfn-loop-cli.md +135 -99
- package/dist/agents/agent-loader.js +146 -165
- package/dist/agents/agent-loader.js.map +1 -1
- package/dist/cli/config-manager.js +109 -91
- package/package.json +1 -1
|
@@ -15,7 +15,7 @@ Execute CFN Loop using CLI spawning for maximum cost savings (95-98% vs Task too
|
|
|
15
15
|
## What is CLI Mode?
|
|
16
16
|
|
|
17
17
|
**CLI Mode Architecture v3.0 (Enhanced):**
|
|
18
|
-
- Main Chat spawns **single coordinator agent**
|
|
18
|
+
- Main Chat spawns **single coordinator agent**
|
|
19
19
|
- Enhanced coordinator spawns **all workers via CLI** with protocol compliance
|
|
20
20
|
- CLI agents use **Z.ai custom routing** (when enabled)
|
|
21
21
|
- **Real-time monitoring** with automatic recovery from stuck agents
|
|
@@ -77,23 +77,121 @@ Savings: 64% with custom routing, 95-98% vs all-Task
|
|
|
77
77
|
| Standard | ≥0.75 | ≥0.90 | 10 | 3-4 | Production features |
|
|
78
78
|
| Enterprise | ≥0.85 | ≥0.95 | 15 | 5 | Security, compliance, critical systems |
|
|
79
79
|
|
|
80
|
-
##
|
|
80
|
+
## How CLI Mode Works
|
|
81
81
|
|
|
82
|
-
**
|
|
82
|
+
1. **Main Chat** spawns a single `cfn-v3-coordinator` agent
|
|
83
|
+
2. **Coordinator** orchestrates the entire CFN Loop workflow
|
|
84
|
+
3. **Loop 3** agents implement the solution and validate against quality gates
|
|
85
|
+
4. **Loop 2** agents review and provide validation feedback
|
|
86
|
+
5. **Product Owner** makes the final decision on deliverables
|
|
87
|
+
6. **Background execution** with Redis coordination for scalability
|
|
83
88
|
|
|
84
|
-
|
|
85
|
-
**DO NOT spawn Loop 2 agents (reviewer, tester, etc.)**
|
|
86
|
-
**DO NOT spawn product-owner**
|
|
89
|
+
The coordinator handles all agent spawning internally using optimized CLI processes.
|
|
87
90
|
|
|
88
|
-
|
|
91
|
+
## CLI Mode Benefits
|
|
92
|
+
|
|
93
|
+
**Cost Savings:**
|
|
94
|
+
- 64% savings with Z.ai routing vs all-Anthropic
|
|
95
|
+
- 95-98% savings vs Task tool spawning
|
|
96
|
+
- Scales linearly with iterations (Task mode scales exponentially)
|
|
97
|
+
|
|
98
|
+
**Production Features v3.0:**
|
|
99
|
+
- Background execution (no timeout issues)
|
|
100
|
+
- Redis state persistence (crash recovery)
|
|
101
|
+
- Zero-token waiting (BLPOP blocks without API calls)
|
|
102
|
+
- Web portal visibility (http://localhost:3000)
|
|
103
|
+
- **Enhanced monitoring**: Real-time agent progress tracking
|
|
104
|
+
- **Automatic recovery**: Dead process cleanup and agent restart
|
|
105
|
+
- **Protocol compliance**: Prevents "consensus on vapor" anti-patterns
|
|
106
|
+
- **Progress visibility**: Detailed reports with timestamps and health status
|
|
107
|
+
|
|
108
|
+
**Performance:**
|
|
109
|
+
- Parallel agent spawning (no sequential bottleneck)
|
|
110
|
+
- Instant wake-up (<100ms latency)
|
|
111
|
+
- Scalable (10+ agents, indefinite cycles)
|
|
112
|
+
|
|
113
|
+
## When to Use CLI Mode
|
|
114
|
+
|
|
115
|
+
**Use CLI Mode for:**
|
|
116
|
+
- ✅ Production features
|
|
117
|
+
- ✅ Long-running tasks (>10 min)
|
|
118
|
+
- ✅ Multi-iteration workflows
|
|
119
|
+
- ✅ Cost-sensitive projects
|
|
120
|
+
- ✅ Background execution
|
|
121
|
+
|
|
122
|
+
**Use Task Mode for:**
|
|
123
|
+
- Debugging (full visibility needed)
|
|
124
|
+
- Learning CFN Loop workflow
|
|
125
|
+
- Short prototypes (<5 min)
|
|
126
|
+
- Single-iteration tasks
|
|
127
|
+
|
|
128
|
+
## Troubleshooting
|
|
129
|
+
|
|
130
|
+
**Custom routing not working:**
|
|
131
|
+
```bash
|
|
132
|
+
/switch-api status # Check current provider
|
|
133
|
+
/switch-api zai # Enable Z.ai routing
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
**Coordinator timeout:**
|
|
137
|
+
- Expected for long tasks (>10 min)
|
|
138
|
+
- Check web portal for progress: http://localhost:3000
|
|
139
|
+
- Query Redis: `redis-cli HGETALL "cfn_loop:task:$TASK_ID:context"`
|
|
140
|
+
|
|
141
|
+
**No deliverables created:**
|
|
142
|
+
- Orchestrator validates deliverables before PROCEED
|
|
143
|
+
- Will force ITERATE if git diff shows zero changes
|
|
144
|
+
- Check coordinator output for validation failures
|
|
145
|
+
|
|
146
|
+
**Web Portal Access:**
|
|
147
|
+
- Monitor real-time agent progress at http://localhost:3000
|
|
148
|
+
- View detailed execution logs and health status
|
|
149
|
+
- Track iteration progress and confidence scores
|
|
150
|
+
|
|
151
|
+
## Usage Examples
|
|
152
|
+
|
|
153
|
+
**Simple API Development:**
|
|
154
|
+
```bash
|
|
155
|
+
/cfn-loop-cli "Build REST API with user authentication"
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
**Complex Feature with High Quality Requirements:**
|
|
159
|
+
```bash
|
|
160
|
+
/cfn-loop-cli "Implement payment processing with PCI compliance" --mode=enterprise --max-iterations=15
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
**Quick Prototype:**
|
|
164
|
+
```bash
|
|
165
|
+
/cfn-loop-cli "Build MVP landing page" --mode=mvp
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
**Infrastructure Deployment:**
|
|
169
|
+
```bash
|
|
170
|
+
/cfn-loop-cli "Set up CI/CD pipeline for microservices"
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## Related Commands
|
|
174
|
+
|
|
175
|
+
- **Task Mode**: `/cfn-loop-task` (debugging, full visibility)
|
|
176
|
+
- **Frontend**: `/cfn-loop-frontend` (visual iteration workflow)
|
|
177
|
+
- **Documentation**: `/cfn-loop-document` (generate docs)
|
|
178
|
+
|
|
179
|
+
## Related Documentation
|
|
180
|
+
|
|
181
|
+
- Task Mode Guide: `.claude/commands/cfn/CFN_LOOP_TASK_MODE.md`
|
|
182
|
+
- Coordinator Parameters: `.claude/commands/cfn/CFN_COORDINATOR_PARAMETERS.md`
|
|
183
|
+
- Redis Coordination: `.claude/skills/cfn-redis-coordination/SKILL.md`
|
|
184
|
+
- Orchestration: `.claude/skills/cfn-loop-orchestration/SKILL.md`
|
|
89
185
|
|
|
90
186
|
---
|
|
91
187
|
|
|
92
|
-
|
|
188
|
+
## 🚨 EXECUTION INSTRUCTIONS (Internal Use)
|
|
189
|
+
|
|
190
|
+
**Main Chat: Execute this Task() call after slash command processing:**
|
|
93
191
|
|
|
94
192
|
```javascript
|
|
95
193
|
Task("cfn-v3-coordinator", `
|
|
96
|
-
CFN LOOP CLI MODE -
|
|
194
|
+
CFN LOOP CLI MODE v3.0 - PRODUCTION EXECUTION WITH ENHANCED MONITORING
|
|
97
195
|
|
|
98
196
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
99
197
|
TASK SPECIFICATION
|
|
@@ -103,6 +201,8 @@ Task("cfn-v3-coordinator", `
|
|
|
103
201
|
Task ID: cfn-cli-$(date +%s%N | tail -c 7)-${RANDOM}
|
|
104
202
|
Mode: ${mode.toUpperCase()}
|
|
105
203
|
|
|
204
|
+
Enhanced Monitoring: Real-time agent tracking, automatic recovery, protocol compliance
|
|
205
|
+
|
|
106
206
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
107
207
|
SUCCESS CRITERIA
|
|
108
208
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
@@ -129,6 +229,7 @@ Task("cfn-v3-coordinator", `
|
|
|
129
229
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
130
230
|
|
|
131
231
|
Mode: ${mode.toUpperCase()}
|
|
232
|
+
Enhanced Features: Real-time monitoring, automatic recovery, protocol compliance
|
|
132
233
|
|
|
133
234
|
Loop 3 Agents (Implementation) - SELECT BASED ON TASK:
|
|
134
235
|
Examples:
|
|
@@ -145,10 +246,10 @@ Task("cfn-v3-coordinator", `
|
|
|
145
246
|
Product Owner: product-owner
|
|
146
247
|
|
|
147
248
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
148
|
-
|
|
249
|
+
EXECUTION INSTRUCTIONS (Enhanced v3.0)
|
|
149
250
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
150
251
|
|
|
151
|
-
1. INVOKE ENHANCED ORCHESTRATOR (CLI spawning
|
|
252
|
+
1. INVOKE ENHANCED ORCHESTRATOR (CLI spawning with monitoring):
|
|
152
253
|
|
|
153
254
|
TASK_ID="cfn-cli-$(date +%s%N | tail -c 7)-${RANDOM}"
|
|
154
255
|
MODE="${mode}"
|
|
@@ -164,16 +265,15 @@ Task("cfn-v3-coordinator", `
|
|
|
164
265
|
--max-iterations ${maxIterations}
|
|
165
266
|
|
|
166
267
|
2. ENHANCED ORCHESTRATOR HANDLES v3.0:
|
|
167
|
-
-
|
|
168
|
-
-
|
|
169
|
-
-
|
|
170
|
-
-
|
|
171
|
-
-
|
|
172
|
-
- Loop
|
|
173
|
-
-
|
|
174
|
-
-
|
|
175
|
-
-
|
|
176
|
-
- Returns structured result to Main Chat
|
|
268
|
+
- ✅ Spawns all agents via CLI (background) with protocol compliance
|
|
269
|
+
- ✅ Real-time agent progress monitoring and stuck detection
|
|
270
|
+
- ✅ Automatic recovery from dead processes
|
|
271
|
+
- ✅ Enhanced context validation prevents "consensus on vapor"
|
|
272
|
+
- ✅ Loop 3: Gate check (≥threshold) → PASS/ITERATE with health verification
|
|
273
|
+
- ✅ Loop 2: Consensus check (≥threshold) → COMPLETE/ITERATE
|
|
274
|
+
- ✅ Product Owner: PROCEED/ITERATE/ABORT decision with deliverable validation
|
|
275
|
+
- ✅ Git commit/push on PROCEED
|
|
276
|
+
- ✅ Returns structured result to Main Chat
|
|
177
277
|
|
|
178
278
|
3. RETURN STRUCTURED RESULT:
|
|
179
279
|
{
|
|
@@ -186,90 +286,26 @@ Task("cfn-v3-coordinator", `
|
|
|
186
286
|
"pending": [...]
|
|
187
287
|
},
|
|
188
288
|
"deliverables": [...],
|
|
289
|
+
"enhancedMonitoring": {
|
|
290
|
+
"agentHealth": "healthy|recovered",
|
|
291
|
+
"processRecovery": true,
|
|
292
|
+
"protocolCompliance": true
|
|
293
|
+
},
|
|
189
294
|
"recommendations": [...]
|
|
190
295
|
}
|
|
191
296
|
|
|
192
297
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
193
|
-
CRITICAL RULES
|
|
298
|
+
CRITICAL ENHANCED RULES v3.0
|
|
194
299
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
195
300
|
|
|
196
|
-
-
|
|
197
|
-
- ALL agents run in background via npx claude-flow-novice
|
|
198
|
-
- USE Redis BLPOP for loop dependencies
|
|
199
|
-
- AGENTS use Z.ai routing automatically (when enabled)
|
|
200
|
-
-
|
|
201
|
-
-
|
|
301
|
+
- ✅ USE enhanced orchestration script with real-time monitoring
|
|
302
|
+
- ✅ ALL agents run in background via npx claude-flow-novice (enhanced v3.0)
|
|
303
|
+
- ✅ USE Redis BLPOP for loop dependencies (zero-token coordination)
|
|
304
|
+
- ✅ AGENTS use Z.ai routing automatically (when enabled)
|
|
305
|
+
- ✅ ENFORCE protocol compliance (prevent "consensus on vapor")
|
|
306
|
+
- ✅ MONITOR agent health and auto-recover stuck processes
|
|
307
|
+
- ✅ RETURN structured result with enhanced monitoring data
|
|
202
308
|
`, "cfn-v3-coordinator")
|
|
203
309
|
```
|
|
204
310
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
**Cost Savings:**
|
|
208
|
-
- 64% savings with Z.ai routing vs all-Anthropic
|
|
209
|
-
- 95-98% savings vs Task tool spawning
|
|
210
|
-
- Scales linearly with iterations (Task mode scales exponentially)
|
|
211
|
-
|
|
212
|
-
**Production Features v3.0:**
|
|
213
|
-
- Background execution (no timeout issues)
|
|
214
|
-
- Redis state persistence (crash recovery)
|
|
215
|
-
- Zero-token waiting (BLPOP blocks without API calls)
|
|
216
|
-
- Web portal visibility (http://localhost:3000)
|
|
217
|
-
- **Enhanced monitoring**: Real-time agent progress tracking
|
|
218
|
-
- **Automatic recovery**: Dead process cleanup and agent restart
|
|
219
|
-
- **Protocol compliance**: Prevents "consensus on vapor" anti-patterns
|
|
220
|
-
- **Progress visibility**: Detailed reports with timestamps and health status
|
|
221
|
-
|
|
222
|
-
**Performance:**
|
|
223
|
-
- Parallel agent spawning (no sequential bottleneck)
|
|
224
|
-
- Instant wake-up (<100ms latency)
|
|
225
|
-
- Scalable (10+ agents, indefinite cycles)
|
|
226
|
-
|
|
227
|
-
## When to Use CLI Mode
|
|
228
|
-
|
|
229
|
-
**Use CLI Mode for:**
|
|
230
|
-
- ✅ Production features
|
|
231
|
-
- ✅ Long-running tasks (>10 min)
|
|
232
|
-
- ✅ Multi-iteration workflows
|
|
233
|
-
- ✅ Cost-sensitive projects
|
|
234
|
-
- ✅ Background execution
|
|
235
|
-
|
|
236
|
-
**Use Task Mode for:**
|
|
237
|
-
- Debugging (full visibility needed)
|
|
238
|
-
- Learning CFN Loop workflow
|
|
239
|
-
- Short prototypes (<5 min)
|
|
240
|
-
- Single-iteration tasks
|
|
241
|
-
|
|
242
|
-
## Troubleshooting
|
|
243
|
-
|
|
244
|
-
**Custom routing not working:**
|
|
245
|
-
```bash
|
|
246
|
-
/switch-api status # Check current provider
|
|
247
|
-
/switch-api zai # Enable Z.ai routing
|
|
248
|
-
```
|
|
249
|
-
|
|
250
|
-
**Coordinator timeout:**
|
|
251
|
-
- Expected for long tasks (>10 min)
|
|
252
|
-
- Check web portal for progress: http://localhost:3000
|
|
253
|
-
- Query Redis: `redis-cli HGETALL "cfn_loop:task:$TASK_ID:context"`
|
|
254
|
-
|
|
255
|
-
**No deliverables created:**
|
|
256
|
-
- Orchestrator validates deliverables before PROCEED
|
|
257
|
-
- Will force ITERATE if git diff shows zero changes
|
|
258
|
-
- Check coordinator output for validation failures
|
|
259
|
-
|
|
260
|
-
## Related Commands
|
|
261
|
-
|
|
262
|
-
- **Task Mode**: `/cfn-loop-task` (debugging, full visibility)
|
|
263
|
-
- **Frontend**: `/cfn-loop-frontend` (visual iteration workflow)
|
|
264
|
-
- **Documentation**: `/cfn-loop-document` (generate docs)
|
|
265
|
-
|
|
266
|
-
## Related Documentation
|
|
267
|
-
|
|
268
|
-
- Task Mode Guide: `.claude/commands/cfn/CFN_LOOP_TASK_MODE.md`
|
|
269
|
-
- Coordinator Parameters: `.claude/commands/cfn/CFN_COORDINATOR_PARAMETERS.md`
|
|
270
|
-
- Redis Coordination: `.claude/skills/cfn-redis-coordination/SKILL.md`
|
|
271
|
-
- Orchestration: `.claude/skills/cfn-loop-orchestration/SKILL.md`
|
|
272
|
-
|
|
273
|
-
---
|
|
274
|
-
|
|
275
|
-
**Version:** 1.0.0 (2025-10-31) - CLI mode: production execution, cost-optimized, background processing
|
|
311
|
+
**Version:** 3.0.0 (2025-11-05) - Enhanced CLI mode: production execution with real-time monitoring, automatic recovery, and protocol compliance
|
|
@@ -1,145 +1,12 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Dynamic Agent Loader - Reads agent definitions from .claude/agents/ directory
|
|
4
3
|
* Single source of truth for agent types in the system
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
});
|
|
10
|
-
}
|
|
11
|
-
return new (P || (P = Promise))(function(resolve, reject) {
|
|
12
|
-
function fulfilled(value) {
|
|
13
|
-
try {
|
|
14
|
-
step(generator.next(value));
|
|
15
|
-
} catch (e) {
|
|
16
|
-
reject(e);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
function rejected(value) {
|
|
20
|
-
try {
|
|
21
|
-
step(generator["throw"](value));
|
|
22
|
-
} catch (e) {
|
|
23
|
-
reject(e);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
function step(result) {
|
|
27
|
-
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
28
|
-
}
|
|
29
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
30
|
-
});
|
|
31
|
-
};
|
|
32
|
-
var __generator = this && this.__generator || function(thisArg, body) {
|
|
33
|
-
var _ = {
|
|
34
|
-
label: 0,
|
|
35
|
-
sent: function() {
|
|
36
|
-
if (t[0] & 1) throw t[1];
|
|
37
|
-
return t[1];
|
|
38
|
-
},
|
|
39
|
-
trys: [],
|
|
40
|
-
ops: []
|
|
41
|
-
}, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
42
|
-
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() {
|
|
43
|
-
return this;
|
|
44
|
-
}), g;
|
|
45
|
-
function verb(n) {
|
|
46
|
-
return function(v) {
|
|
47
|
-
return step([
|
|
48
|
-
n,
|
|
49
|
-
v
|
|
50
|
-
]);
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
function step(op) {
|
|
54
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
55
|
-
while(g && (g = 0, op[0] && (_ = 0)), _)try {
|
|
56
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
57
|
-
if (y = 0, t) op = [
|
|
58
|
-
op[0] & 2,
|
|
59
|
-
t.value
|
|
60
|
-
];
|
|
61
|
-
switch(op[0]){
|
|
62
|
-
case 0:
|
|
63
|
-
case 1:
|
|
64
|
-
t = op;
|
|
65
|
-
break;
|
|
66
|
-
case 4:
|
|
67
|
-
_.label++;
|
|
68
|
-
return {
|
|
69
|
-
value: op[1],
|
|
70
|
-
done: false
|
|
71
|
-
};
|
|
72
|
-
case 5:
|
|
73
|
-
_.label++;
|
|
74
|
-
y = op[1];
|
|
75
|
-
op = [
|
|
76
|
-
0
|
|
77
|
-
];
|
|
78
|
-
continue;
|
|
79
|
-
case 7:
|
|
80
|
-
op = _.ops.pop();
|
|
81
|
-
_.trys.pop();
|
|
82
|
-
continue;
|
|
83
|
-
default:
|
|
84
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
|
|
85
|
-
_ = 0;
|
|
86
|
-
continue;
|
|
87
|
-
}
|
|
88
|
-
if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
|
|
89
|
-
_.label = op[1];
|
|
90
|
-
break;
|
|
91
|
-
}
|
|
92
|
-
if (op[0] === 6 && _.label < t[1]) {
|
|
93
|
-
_.label = t[1];
|
|
94
|
-
t = op;
|
|
95
|
-
break;
|
|
96
|
-
}
|
|
97
|
-
if (t && _.label < t[2]) {
|
|
98
|
-
_.label = t[2];
|
|
99
|
-
_.ops.push(op);
|
|
100
|
-
break;
|
|
101
|
-
}
|
|
102
|
-
if (t[2]) _.ops.pop();
|
|
103
|
-
_.trys.pop();
|
|
104
|
-
continue;
|
|
105
|
-
}
|
|
106
|
-
op = body.call(thisArg, _);
|
|
107
|
-
} catch (e) {
|
|
108
|
-
op = [
|
|
109
|
-
6,
|
|
110
|
-
e
|
|
111
|
-
];
|
|
112
|
-
y = 0;
|
|
113
|
-
} finally{
|
|
114
|
-
f = t = 0;
|
|
115
|
-
}
|
|
116
|
-
if (op[0] & 5) throw op[1];
|
|
117
|
-
return {
|
|
118
|
-
value: op[0] ? op[1] : void 0,
|
|
119
|
-
done: true
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
};
|
|
123
|
-
var __spreadArray = this && this.__spreadArray || function(to, from, pack) {
|
|
124
|
-
if (pack || arguments.length === 2) for(var i = 0, l = from.length, ar; i < l; i++){
|
|
125
|
-
if (ar || !(i in from)) {
|
|
126
|
-
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
127
|
-
ar[i] = from[i];
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
return to.concat(ar || Array.prototype.slice.call(from));
|
|
131
|
-
};
|
|
132
|
-
Object.defineProperty(exports, "__esModule", {
|
|
133
|
-
value: true
|
|
134
|
-
});
|
|
135
|
-
exports.refreshAgents = exports.getAgentsByCategory = exports.isValidAgentType = exports.searchAgents = exports.getAgentCategories = exports.getAllAgents = exports.getAgent = exports.getAvailableAgentTypes = exports.agentLoader = exports.AgentLoader = void 0;
|
|
136
|
-
exports.resolveLegacyAgentType = resolveLegacyAgentType;
|
|
137
|
-
var node_fs_1 = require("node:fs");
|
|
138
|
-
var glob_1 = require("glob");
|
|
139
|
-
var node_path_1 = require("node:path");
|
|
140
|
-
var yaml_1 = require("yaml");
|
|
4
|
+
*/ import { readFileSync, existsSync } from 'node:fs';
|
|
5
|
+
import { glob } from 'glob';
|
|
6
|
+
import { resolve, dirname } from 'node:path';
|
|
7
|
+
import { parse as parseYaml } from 'yaml';
|
|
141
8
|
// Legacy agent type mapping for backward compatibility
|
|
142
|
-
|
|
9
|
+
const LEGACY_AGENT_MAPPING = {
|
|
143
10
|
analyst: 'code-analyzer',
|
|
144
11
|
coordinator: 'hierarchical-coordinator',
|
|
145
12
|
optimizer: 'perf-analyzer',
|
|
@@ -150,40 +17,38 @@ var LEGACY_AGENT_MAPPING = {
|
|
|
150
17
|
};
|
|
151
18
|
/**
|
|
152
19
|
* Resolve legacy agent types to current equivalents
|
|
153
|
-
*/ function resolveLegacyAgentType(legacyType) {
|
|
20
|
+
*/ export function resolveLegacyAgentType(legacyType) {
|
|
154
21
|
return LEGACY_AGENT_MAPPING[legacyType] || legacyType;
|
|
155
22
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
AgentLoader.prototype.getAgentsDirectory = function() {
|
|
164
|
-
var currentDir = process.cwd();
|
|
23
|
+
export class AgentLoader {
|
|
24
|
+
agentCache = new Map();
|
|
25
|
+
categoriesCache = [];
|
|
26
|
+
lastLoadTime = 0;
|
|
27
|
+
CACHE_EXPIRY = 60_000;
|
|
28
|
+
getAgentsDirectory() {
|
|
29
|
+
let currentDir = process.cwd();
|
|
165
30
|
while(currentDir !== '/'){
|
|
166
|
-
|
|
167
|
-
if (
|
|
31
|
+
const claudeAgentsPath = resolve(currentDir, '.claude', 'agents');
|
|
32
|
+
if (existsSync(claudeAgentsPath)) {
|
|
168
33
|
return claudeAgentsPath;
|
|
169
34
|
}
|
|
170
|
-
currentDir =
|
|
35
|
+
currentDir = dirname(currentDir);
|
|
171
36
|
}
|
|
172
|
-
return
|
|
173
|
-
}
|
|
174
|
-
|
|
37
|
+
return resolve(process.cwd(), '.claude', 'agents');
|
|
38
|
+
}
|
|
39
|
+
parseAgentFile(filePath) {
|
|
175
40
|
try {
|
|
176
|
-
|
|
177
|
-
|
|
41
|
+
const content = readFileSync(filePath, 'utf-8');
|
|
42
|
+
const frontmatterMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/);
|
|
178
43
|
if (!frontmatterMatch) {
|
|
179
|
-
console.warn(
|
|
44
|
+
console.warn(`No frontmatter found in ${filePath}`);
|
|
180
45
|
return null;
|
|
181
46
|
}
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
47
|
+
const [, yamlContent, markdownContent] = frontmatterMatch;
|
|
48
|
+
const frontmatter = parseYaml(yamlContent);
|
|
49
|
+
const description = frontmatter.description;
|
|
185
50
|
if (!frontmatter.name || !description) {
|
|
186
|
-
console.warn(
|
|
51
|
+
console.warn(`Missing required fields (name, description) in ${filePath}`);
|
|
187
52
|
return null;
|
|
188
53
|
}
|
|
189
54
|
return {
|
|
@@ -204,13 +69,129 @@ var AgentLoader = /** @class */ function() {
|
|
|
204
69
|
content: markdownContent.trim()
|
|
205
70
|
};
|
|
206
71
|
} catch (error) {
|
|
207
|
-
console.error(
|
|
72
|
+
console.error(`Error parsing agent file ${filePath}:`, error);
|
|
208
73
|
return null;
|
|
209
74
|
}
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
|
|
75
|
+
}
|
|
76
|
+
parseTools(frontmatter) {
|
|
77
|
+
const extractTools = (input)=>{
|
|
213
78
|
if (Array.isArray(input)) return input.map(String);
|
|
79
|
+
if (typeof input === 'string') {
|
|
80
|
+
return input.split(/[,\s]+/).map((t)=>t.trim()).filter((t)=>t.length > 0);
|
|
81
|
+
}
|
|
82
|
+
return [];
|
|
83
|
+
};
|
|
84
|
+
// Safely handle tools and capabilities.tools
|
|
85
|
+
const toolsFromFrontmatter = frontmatter.tools ? extractTools(frontmatter.tools) : [];
|
|
86
|
+
const toolsFromCapabilities = frontmatter.capabilities && typeof frontmatter.capabilities === 'object' ? extractTools(Object(frontmatter.capabilities).tools) : [];
|
|
87
|
+
return [
|
|
88
|
+
...toolsFromFrontmatter,
|
|
89
|
+
...toolsFromCapabilities
|
|
90
|
+
];
|
|
91
|
+
}
|
|
92
|
+
async loadAgents() {
|
|
93
|
+
const agentsDir = this.getAgentsDirectory();
|
|
94
|
+
if (!existsSync(agentsDir)) {
|
|
95
|
+
console.warn(`Agents directory not found: ${agentsDir}`);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
const agentFiles = await new Promise((resolve, reject)=>{
|
|
99
|
+
glob('**/*.md', {
|
|
100
|
+
cwd: agentsDir,
|
|
101
|
+
ignore: [
|
|
102
|
+
'**/README.md',
|
|
103
|
+
'**/MIGRATION_SUMMARY.md'
|
|
104
|
+
],
|
|
105
|
+
absolute: true
|
|
106
|
+
}, (err, matches)=>{
|
|
107
|
+
if (err) reject(err);
|
|
108
|
+
else resolve(matches);
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
this.agentCache.clear();
|
|
112
|
+
this.categoriesCache = [];
|
|
113
|
+
const categoryMap = new Map();
|
|
114
|
+
for (const filePath of agentFiles){
|
|
115
|
+
const agent = this.parseAgentFile(filePath);
|
|
116
|
+
if (agent) {
|
|
117
|
+
this.agentCache.set(agent.name, agent);
|
|
118
|
+
const relativePath = filePath.replace(agentsDir, '');
|
|
119
|
+
const pathParts = relativePath.split('/');
|
|
120
|
+
const category = pathParts[1] || 'uncategorized';
|
|
121
|
+
if (!categoryMap.has(category)) {
|
|
122
|
+
categoryMap.set(category, []);
|
|
123
|
+
}
|
|
124
|
+
categoryMap.get(category).push(agent);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
this.categoriesCache = Array.from(categoryMap.entries()).map(([name, agents])=>({
|
|
128
|
+
name,
|
|
129
|
+
agents: agents.sort((a, b)=>a.name.localeCompare(b.name))
|
|
130
|
+
}));
|
|
131
|
+
this.lastLoadTime = Date.now();
|
|
132
|
+
}
|
|
133
|
+
// Rest of the methods remain similar to the original implementation
|
|
134
|
+
needsRefresh() {
|
|
135
|
+
return Date.now() - this.lastLoadTime > this.CACHE_EXPIRY;
|
|
136
|
+
}
|
|
137
|
+
async ensureLoaded() {
|
|
138
|
+
if (this.agentCache.size === 0 || this.needsRefresh()) {
|
|
139
|
+
await this.loadAgents();
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
async getAvailableAgentTypes() {
|
|
143
|
+
await this.ensureLoaded();
|
|
144
|
+
const currentTypes = Array.from(this.agentCache.keys());
|
|
145
|
+
const legacyTypes = Object.keys(LEGACY_AGENT_MAPPING);
|
|
146
|
+
return Array.from(new Set([
|
|
147
|
+
...currentTypes,
|
|
148
|
+
...legacyTypes
|
|
149
|
+
])).sort();
|
|
150
|
+
}
|
|
151
|
+
async getAgent(name) {
|
|
152
|
+
await this.ensureLoaded();
|
|
153
|
+
return this.agentCache.get(name) || this.agentCache.get(resolveLegacyAgentType(name)) || null;
|
|
154
|
+
}
|
|
155
|
+
async getAllAgents() {
|
|
156
|
+
await this.ensureLoaded();
|
|
157
|
+
return Array.from(this.agentCache.values()).sort((a, b)=>a.name.localeCompare(b.name));
|
|
158
|
+
}
|
|
159
|
+
async getAgentCategories() {
|
|
160
|
+
await this.ensureLoaded();
|
|
161
|
+
return this.categoriesCache;
|
|
162
|
+
}
|
|
163
|
+
async searchAgents(query) {
|
|
164
|
+
await this.ensureLoaded();
|
|
165
|
+
const lowerQuery = query.toLowerCase();
|
|
166
|
+
return Array.from(this.agentCache.values()).filter((agent)=>agent.name.toLowerCase().includes(lowerQuery) || agent.description.toLowerCase().includes(lowerQuery) || agent.capabilities?.some((cap)=>cap.toLowerCase().includes(lowerQuery)));
|
|
167
|
+
}
|
|
168
|
+
async isValidAgentType(name) {
|
|
169
|
+
await this.ensureLoaded();
|
|
170
|
+
return this.agentCache.has(name) || this.agentCache.has(resolveLegacyAgentType(name));
|
|
171
|
+
}
|
|
172
|
+
async getAgentsByCategory(category) {
|
|
173
|
+
const categories = await this.getAgentCategories();
|
|
174
|
+
const found = categories.find((cat)=>cat.name === category);
|
|
175
|
+
return found?.agents || [];
|
|
176
|
+
}
|
|
177
|
+
async refresh() {
|
|
178
|
+
this.lastLoadTime = 0;
|
|
179
|
+
await this.loadAgents();
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
// Singleton instance
|
|
183
|
+
export const agentLoader = new AgentLoader();
|
|
184
|
+
// Convenience exports for use in other modules
|
|
185
|
+
export const getAvailableAgentTypes = ()=>agentLoader.getAvailableAgentTypes();
|
|
186
|
+
export const getAgent = (name)=>agentLoader.getAgent(name);
|
|
187
|
+
export const getAllAgents = ()=>agentLoader.getAllAgents();
|
|
188
|
+
export const getAgentCategories = ()=>agentLoader.getAgentCategories();
|
|
189
|
+
export const searchAgents = (query)=>agentLoader.searchAgents(query);
|
|
190
|
+
export const isValidAgentType = (name)=>agentLoader.isValidAgentType(name);
|
|
191
|
+
export const getAgentsByCategory = (category)=>agentLoader.getAgentsByCategory(category);
|
|
192
|
+
export const refreshAgents = ()=>agentLoader.refresh();
|
|
193
|
+
|
|
194
|
+
//# sourceMappingURL=agent-loader.js.map.isArray(input)) return input.map(String);
|
|
214
195
|
if (typeof input === 'string') {
|
|
215
196
|
return input.split(/[,\s]+/).map(function(t) {
|
|
216
197
|
return t.trim();
|