claude-flow-novice 2.14.18 → 2.14.19
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_EXPERT_UPDATE.md +142 -0
- package/.claude/commands/cfn-docker/CFN_DOCKER_CLI.md +527 -0
- package/.claude/commands/cfn-docker/CFN_DOCKER_LOOP.md +377 -0
- package/.claude/commands/cfn-docker/CFN_DOCKER_TASK.md +490 -0
- package/.claude/commands/cfn-loop-cli.md +220 -46
- package/.claude/commands/deprecated/README.md +55 -0
- package/claude-assets/agents/docker-coordinators/cfn-docker-v3-coordinator.md +199 -0
- package/claude-assets/commands/CFN_EXPERT_UPDATE.md +142 -0
- package/claude-assets/commands/cfn-docker/CFN_DOCKER_CLI.md +527 -0
- package/claude-assets/commands/cfn-docker/CFN_DOCKER_LOOP.md +377 -0
- package/claude-assets/commands/cfn-docker/CFN_DOCKER_TASK.md +490 -0
- package/claude-assets/commands/cfn-loop-cli.md +220 -46
- package/claude-assets/commands/deprecated/README.md +55 -0
- package/claude-assets/skills/cfn-docker-agent-spawning/SKILL.md +394 -0
- package/claude-assets/skills/cfn-docker-agent-spawning/spawn-agent.sh +461 -0
- package/claude-assets/skills/cfn-docker-loop-orchestration/SKILL.md +449 -0
- package/claude-assets/skills/cfn-docker-loop-orchestration/orchestrate.sh +787 -0
- package/claude-assets/skills/cfn-docker-redis-coordination/SKILL.md +435 -0
- package/claude-assets/skills/cfn-docker-redis-coordination/coordinate.sh +635 -0
- package/claude-assets/skills/cfn-docker-skill-mcp-selection/SKILL.md +289 -0
- package/claude-assets/skills/cfn-docker-skill-mcp-selection/skill-mcp-selector.js +472 -0
- package/claude-assets/skills/cfn-expert-update/update-expert.sh +346 -0
- package/dist/agents/agent-loader.js +165 -146
- package/dist/agents/agent-loader.js.map +1 -1
- package/package.json +1 -1
- /package/.claude/commands/{cfn-loop-epic.md → deprecated/cfn-loop-epic.md} +0 -0
- /package/.claude/commands/{cfn-loop-single.md → deprecated/cfn-loop-single.md} +0 -0
- /package/.claude/commands/{cfn-loop-sprints.md → deprecated/cfn-loop-sprints.md} +0 -0
- /package/.claude/commands/{cfn-loop.md → deprecated/cfn-loop.md} +0 -0
- /package/.claude/commands/{cfn/run-tests.md → run-tests.md} +0 -0
- /package/claude-assets/commands/{cfn-loop-epic.md → deprecated/cfn-loop-epic.md} +0 -0
- /package/claude-assets/commands/{cfn-loop-single.md → deprecated/cfn-loop-single.md} +0 -0
- /package/claude-assets/commands/{cfn-loop-sprints.md → deprecated/cfn-loop-sprints.md} +0 -0
- /package/claude-assets/commands/{cfn-loop.md → deprecated/cfn-loop.md} +0 -0
- /package/claude-assets/commands/{cfn/run-tests.md → run-tests.md} +0 -0
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# CFN Expert Update Skill
|
|
4
|
+
# Updates CFN system expert agent with relevant git commits
|
|
5
|
+
|
|
6
|
+
set -euo pipefail
|
|
7
|
+
|
|
8
|
+
# Configuration
|
|
9
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
10
|
+
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)"
|
|
11
|
+
AGENT_FILE="$PROJECT_ROOT/.claude/agents/custom/cfn-system-expert.md"
|
|
12
|
+
STATE_FILE="$PROJECT_ROOT/.claude/state/cfn-expert-last-commit"
|
|
13
|
+
BACKUP_DIR="$PROJECT_ROOT/.claude/backups/cfn-expert"
|
|
14
|
+
|
|
15
|
+
# Ensure directories exist
|
|
16
|
+
mkdir -p "$(dirname "$STATE_FILE")"
|
|
17
|
+
mkdir -p "$BACKUP_DIR"
|
|
18
|
+
|
|
19
|
+
# Parse arguments
|
|
20
|
+
DRY_RUN=false
|
|
21
|
+
FORCE=false
|
|
22
|
+
SINCE_COMMIT=""
|
|
23
|
+
|
|
24
|
+
while [[ $# -gt 0 ]]; do
|
|
25
|
+
case $1 in
|
|
26
|
+
--dry-run)
|
|
27
|
+
DRY_RUN=true
|
|
28
|
+
shift
|
|
29
|
+
;;
|
|
30
|
+
--force)
|
|
31
|
+
FORCE=true
|
|
32
|
+
shift
|
|
33
|
+
;;
|
|
34
|
+
--since=*)
|
|
35
|
+
SINCE_COMMIT="${1#*=}"
|
|
36
|
+
shift
|
|
37
|
+
;;
|
|
38
|
+
*)
|
|
39
|
+
echo "❌ Unknown parameter: $1"
|
|
40
|
+
echo "Usage: $0 [--dry-run] [--force] [--since=commit_hash]"
|
|
41
|
+
exit 1
|
|
42
|
+
;;
|
|
43
|
+
esac
|
|
44
|
+
done
|
|
45
|
+
|
|
46
|
+
# Colors for output
|
|
47
|
+
RED='\033[0;31m'
|
|
48
|
+
GREEN='\033[0;32m'
|
|
49
|
+
YELLOW='\033[1;33m'
|
|
50
|
+
BLUE='\033[0;34m'
|
|
51
|
+
NC='\033[0m' # No Color
|
|
52
|
+
|
|
53
|
+
# Logging functions
|
|
54
|
+
log_info() { echo -e "${BLUE}ℹ️ $1${NC}"; }
|
|
55
|
+
log_success() { echo -e "${GREEN}✅ $1${NC}"; }
|
|
56
|
+
log_warning() { echo -e "${YELLOW}⚠️ $1${NC}"; }
|
|
57
|
+
log_error() { echo -e "${RED}❌ $1${NC}"; }
|
|
58
|
+
|
|
59
|
+
# Get last scanned commit
|
|
60
|
+
get_last_commit() {
|
|
61
|
+
if [[ -n "$SINCE_COMMIT" ]]; then
|
|
62
|
+
echo "$SINCE_COMMIT"
|
|
63
|
+
elif [[ -f "$STATE_FILE" ]] && ! $FORCE; then
|
|
64
|
+
head -n1 "$STATE_FILE"
|
|
65
|
+
else
|
|
66
|
+
# Default to 10 commits back if no tracking
|
|
67
|
+
git log --format="%H" -n 10 | tail -n1
|
|
68
|
+
fi
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
# Update last commit tracking
|
|
72
|
+
update_last_commit() {
|
|
73
|
+
local commit_hash="$1"
|
|
74
|
+
local timestamp="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
75
|
+
echo "$commit_hash" > "$STATE_FILE"
|
|
76
|
+
echo "$timestamp" >> "$STATE_FILE"
|
|
77
|
+
log_success "📝 Last commit updated: $commit_hash"
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
# Create backup of agent file
|
|
81
|
+
create_backup() {
|
|
82
|
+
if [[ -f "$AGENT_FILE" ]]; then
|
|
83
|
+
local timestamp=$(date +%Y%m%d_%H%M%S)
|
|
84
|
+
local backup_file="$BACKUP_DIR/${timestamp}_cfn-system-expert.md"
|
|
85
|
+
cp "$AGENT_FILE" "$backup_file"
|
|
86
|
+
log_success "📁 Backup created: $backup_file"
|
|
87
|
+
echo "$backup_file"
|
|
88
|
+
fi
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
# Check if commit is relevant to CFN system
|
|
92
|
+
is_relevant_commit() {
|
|
93
|
+
local commit_hash="$1"
|
|
94
|
+
local commit_files
|
|
95
|
+
local commit_msg
|
|
96
|
+
|
|
97
|
+
# Get commit message and files
|
|
98
|
+
commit_msg=$(git log --format="%s" -n 1 "$commit_hash")
|
|
99
|
+
commit_files=$(git show --name-only --format="" "$commit_hash" | tr '\n' ' ')
|
|
100
|
+
|
|
101
|
+
# High relevance patterns
|
|
102
|
+
local high_patterns=(
|
|
103
|
+
"CLAUDE\.md"
|
|
104
|
+
"\.claude/commands/cfn/"
|
|
105
|
+
"cfn-loop"
|
|
106
|
+
"CFN Loop"
|
|
107
|
+
"claude-flow-novice"
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
# Medium relevance patterns
|
|
111
|
+
local medium_patterns=(
|
|
112
|
+
"\.claude/skills/cfn-"
|
|
113
|
+
"agent.*coordination"
|
|
114
|
+
"redis.*coordination"
|
|
115
|
+
"cost.*optimization"
|
|
116
|
+
"adaptive.*context"
|
|
117
|
+
"consensus"
|
|
118
|
+
"swarm"
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
# Low relevance patterns
|
|
122
|
+
local low_patterns=(
|
|
123
|
+
"\.claude/agents/cfn-"
|
|
124
|
+
"performance"
|
|
125
|
+
"optimization"
|
|
126
|
+
"debugging"
|
|
127
|
+
"troubleshooting"
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
# Check relevance
|
|
131
|
+
local relevance=0
|
|
132
|
+
local combined_check="$commit_msg $commit_files"
|
|
133
|
+
|
|
134
|
+
# High priority (always relevant)
|
|
135
|
+
for pattern in "${high_patterns[@]}"; do
|
|
136
|
+
if echo "$combined_check" | grep -qE "$pattern"; then
|
|
137
|
+
echo "high"
|
|
138
|
+
return
|
|
139
|
+
fi
|
|
140
|
+
done
|
|
141
|
+
|
|
142
|
+
# Medium priority
|
|
143
|
+
for pattern in "${medium_patterns[@]}"; do
|
|
144
|
+
if echo "$combined_check" | grep -qE "$pattern"; then
|
|
145
|
+
echo "medium"
|
|
146
|
+
return
|
|
147
|
+
fi
|
|
148
|
+
done
|
|
149
|
+
|
|
150
|
+
# Low priority
|
|
151
|
+
for pattern in "${low_patterns[@]}"; do
|
|
152
|
+
if echo "$combined_check" | grep -qE "$pattern"; then
|
|
153
|
+
echo "low"
|
|
154
|
+
return
|
|
155
|
+
fi
|
|
156
|
+
done
|
|
157
|
+
|
|
158
|
+
echo "none"
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
# Extract knowledge from commit
|
|
162
|
+
extract_commit_knowledge() {
|
|
163
|
+
local commit_hash="$1"
|
|
164
|
+
local relevance="$2"
|
|
165
|
+
local commit_msg
|
|
166
|
+
local commit_diff
|
|
167
|
+
local knowledge=""
|
|
168
|
+
|
|
169
|
+
commit_msg=$(git log --format="%s%n%b" -n 1 "$commit_hash")
|
|
170
|
+
commit_diff=$(git show "$commit_hash" -- . | head -200)
|
|
171
|
+
|
|
172
|
+
case "$relevance" in
|
|
173
|
+
"high")
|
|
174
|
+
knowledge="# HIGH PRIORITY UPDATE
|
|
175
|
+
Commit: $commit_hash
|
|
176
|
+
Message: $commit_msg
|
|
177
|
+
|
|
178
|
+
## System Changes
|
|
179
|
+
$commit_diff
|
|
180
|
+
|
|
181
|
+
## Impact
|
|
182
|
+
This commit contains critical system updates that affect CFN Loop methodology, commands, or core rules.
|
|
183
|
+
"
|
|
184
|
+
;;
|
|
185
|
+
"medium")
|
|
186
|
+
knowledge="# MEDIUM PRIORITY UPDATE
|
|
187
|
+
Commit: $commit_hash
|
|
188
|
+
Message: $commit_msg
|
|
189
|
+
|
|
190
|
+
## Process Changes
|
|
191
|
+
$commit_diff
|
|
192
|
+
|
|
193
|
+
## Impact
|
|
194
|
+
This commit updates coordination patterns, skills, or cost optimization strategies.
|
|
195
|
+
"
|
|
196
|
+
;;
|
|
197
|
+
"low")
|
|
198
|
+
knowledge="# LOW PRIORITY UPDATE
|
|
199
|
+
Commit: $commit_hash
|
|
200
|
+
Message: $commit_msg
|
|
201
|
+
|
|
202
|
+
## Informational Changes
|
|
203
|
+
$commit_diff
|
|
204
|
+
|
|
205
|
+
## Impact
|
|
206
|
+
This commit contains improvements or additions that may be useful for reference.
|
|
207
|
+
"
|
|
208
|
+
;;
|
|
209
|
+
esac
|
|
210
|
+
|
|
211
|
+
echo "$knowledge"
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
# Update agent with new knowledge
|
|
215
|
+
update_agent() {
|
|
216
|
+
local new_knowledge="$1"
|
|
217
|
+
local backup_file="$2"
|
|
218
|
+
|
|
219
|
+
if [[ "$DRY_RUN" == "true" ]]; then
|
|
220
|
+
log_info "🔍 DRY RUN: Would update agent with new knowledge"
|
|
221
|
+
echo "$new_knowledge" | head -20
|
|
222
|
+
log_info "🔍 ... (truncated in dry run)"
|
|
223
|
+
return
|
|
224
|
+
fi
|
|
225
|
+
|
|
226
|
+
# Create backup if not already created
|
|
227
|
+
if [[ -z "$backup_file" ]]; then
|
|
228
|
+
backup_file=$(create_backup)
|
|
229
|
+
fi
|
|
230
|
+
|
|
231
|
+
# Find insertion point (before "---" at end of file)
|
|
232
|
+
local temp_file=$(mktemp)
|
|
233
|
+
local inserted=false
|
|
234
|
+
|
|
235
|
+
while IFS= read -r line; do
|
|
236
|
+
echo "$line" >> "$temp_file"
|
|
237
|
+
|
|
238
|
+
# Insert new knowledge before the closing ---
|
|
239
|
+
if [[ "$line" == "---" ]] && [[ "$inserted" == "false" ]]; then
|
|
240
|
+
echo "" >> "$temp_file"
|
|
241
|
+
echo "$new_knowledge" >> "$temp_file"
|
|
242
|
+
echo "" >> "$temp_file"
|
|
243
|
+
inserted=true
|
|
244
|
+
fi
|
|
245
|
+
done < "$AGENT_FILE"
|
|
246
|
+
|
|
247
|
+
# Move temp file to agent location
|
|
248
|
+
mv "$temp_file" "$AGENT_FILE"
|
|
249
|
+
log_success "🔄 Expert agent updated successfully"
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
# Main execution
|
|
253
|
+
main() {
|
|
254
|
+
log_info "🚀 Starting CFN expert update..."
|
|
255
|
+
|
|
256
|
+
# Validate we're in a git repo
|
|
257
|
+
if ! git rev-parse --git-dir >/dev/null 2>&1; then
|
|
258
|
+
log_error "Not in a git repository"
|
|
259
|
+
exit 1
|
|
260
|
+
fi
|
|
261
|
+
|
|
262
|
+
# Check if agent file exists
|
|
263
|
+
if [[ ! -f "$AGENT_FILE" ]]; then
|
|
264
|
+
log_error "CFN system expert agent not found: $AGENT_FILE"
|
|
265
|
+
exit 1
|
|
266
|
+
fi
|
|
267
|
+
|
|
268
|
+
# Get commit range
|
|
269
|
+
local last_commit=$(get_last_commit)
|
|
270
|
+
local current_head=$(git rev-parse HEAD)
|
|
271
|
+
|
|
272
|
+
if [[ "$last_commit" == "$current_head" ]] && [[ "$FORCE" != "true" ]]; then
|
|
273
|
+
log_info "ℹ️ No new commits to scan"
|
|
274
|
+
return
|
|
275
|
+
fi
|
|
276
|
+
|
|
277
|
+
log_info "🔍 Scanning commits since ${last_commit:0:8}..."
|
|
278
|
+
|
|
279
|
+
# Get commits since last scan
|
|
280
|
+
local commits
|
|
281
|
+
if [[ "$FORCE" == "true" ]]; then
|
|
282
|
+
commits=$(git log --format="%H" --since="2 weeks ago" | tac)
|
|
283
|
+
else
|
|
284
|
+
commits=$(git log --format="%H" "$last_commit..HEAD" | tac)
|
|
285
|
+
fi
|
|
286
|
+
|
|
287
|
+
if [[ -z "$commits" ]]; then
|
|
288
|
+
log_info "ℹ️ No new commits found"
|
|
289
|
+
return
|
|
290
|
+
fi
|
|
291
|
+
|
|
292
|
+
local commit_count=$(echo "$commits" | wc -l)
|
|
293
|
+
log_info "📋 Found $commit_count commits to analyze"
|
|
294
|
+
|
|
295
|
+
# Process commits
|
|
296
|
+
local relevant_commits=0
|
|
297
|
+
local total_knowledge=""
|
|
298
|
+
local backup_file=""
|
|
299
|
+
|
|
300
|
+
while read -r commit_hash; do
|
|
301
|
+
[[ -z "$commit_hash" ]] && continue
|
|
302
|
+
|
|
303
|
+
local relevance=$(is_relevant_commit "$commit_hash")
|
|
304
|
+
|
|
305
|
+
if [[ "$relevance" != "none" ]]; then
|
|
306
|
+
((relevant_commits++))
|
|
307
|
+
log_info "🎯 Relevant commit found (${relevance}): ${commit_hash:0:8}"
|
|
308
|
+
|
|
309
|
+
local knowledge=$(extract_commit_knowledge "$commit_hash" "$relevance")
|
|
310
|
+
total_knowledge="${total_knowledge}${knowledge}"$'\n'
|
|
311
|
+
fi
|
|
312
|
+
done <<< "$commits"
|
|
313
|
+
|
|
314
|
+
# Report results
|
|
315
|
+
if [[ "$relevant_commits" == "0" ]]; then
|
|
316
|
+
log_info "ℹ️ No CFN-relevant changes found"
|
|
317
|
+
return
|
|
318
|
+
fi
|
|
319
|
+
|
|
320
|
+
log_info "📊 Found $relevant_commits/$commit_count relevant commits"
|
|
321
|
+
|
|
322
|
+
if [[ "$DRY_RUN" == "true" ]]; then
|
|
323
|
+
log_info "🔍 DRY RUN MODE - No changes will be applied"
|
|
324
|
+
log_info "💡 Run without --dry-run to apply updates"
|
|
325
|
+
echo ""
|
|
326
|
+
echo "Sample of updates that would be applied:"
|
|
327
|
+
echo "$total_knowledge" | head -50
|
|
328
|
+
return
|
|
329
|
+
fi
|
|
330
|
+
|
|
331
|
+
# Create backup before updating
|
|
332
|
+
backup_file=$(create_backup)
|
|
333
|
+
|
|
334
|
+
# Update agent with new knowledge
|
|
335
|
+
update_agent "$total_knowledge" "$backup_file"
|
|
336
|
+
|
|
337
|
+
# Update tracking
|
|
338
|
+
update_last_commit "$current_head"
|
|
339
|
+
|
|
340
|
+
log_success "🎉 Update complete!"
|
|
341
|
+
log_info "📊 Processed $relevant_commits relevant commits"
|
|
342
|
+
log_info "📁 Backup available: $backup_file"
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
# Execute main function
|
|
346
|
+
main "$@"
|
|
@@ -1,12 +1,145 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* Dynamic Agent Loader - Reads agent definitions from .claude/agents/ directory
|
|
3
4
|
* Single source of truth for agent types in the system
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
*/ var __awaiter = this && this.__awaiter || function(thisArg, _arguments, P, generator) {
|
|
6
|
+
function adopt(value) {
|
|
7
|
+
return value instanceof P ? value : new P(function(resolve) {
|
|
8
|
+
resolve(value);
|
|
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");
|
|
8
141
|
// Legacy agent type mapping for backward compatibility
|
|
9
|
-
|
|
142
|
+
var LEGACY_AGENT_MAPPING = {
|
|
10
143
|
analyst: 'code-analyzer',
|
|
11
144
|
coordinator: 'hierarchical-coordinator',
|
|
12
145
|
optimizer: 'perf-analyzer',
|
|
@@ -17,38 +150,40 @@ const LEGACY_AGENT_MAPPING = {
|
|
|
17
150
|
};
|
|
18
151
|
/**
|
|
19
152
|
* Resolve legacy agent types to current equivalents
|
|
20
|
-
*/
|
|
153
|
+
*/ function resolveLegacyAgentType(legacyType) {
|
|
21
154
|
return LEGACY_AGENT_MAPPING[legacyType] || legacyType;
|
|
22
155
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
156
|
+
var AgentLoader = /** @class */ function() {
|
|
157
|
+
function AgentLoader() {
|
|
158
|
+
this.agentCache = new Map();
|
|
159
|
+
this.categoriesCache = [];
|
|
160
|
+
this.lastLoadTime = 0;
|
|
161
|
+
this.CACHE_EXPIRY = 60000; // 1 minute cache
|
|
162
|
+
}
|
|
163
|
+
AgentLoader.prototype.getAgentsDirectory = function() {
|
|
164
|
+
var currentDir = process.cwd();
|
|
30
165
|
while(currentDir !== '/'){
|
|
31
|
-
|
|
32
|
-
if (existsSync(claudeAgentsPath)) {
|
|
166
|
+
var claudeAgentsPath = (0, node_path_1.resolve)(currentDir, '.claude', 'agents');
|
|
167
|
+
if ((0, node_fs_1.existsSync)(claudeAgentsPath)) {
|
|
33
168
|
return claudeAgentsPath;
|
|
34
169
|
}
|
|
35
|
-
currentDir = dirname(currentDir);
|
|
170
|
+
currentDir = (0, node_path_1.dirname)(currentDir);
|
|
36
171
|
}
|
|
37
|
-
return resolve(process.cwd(), '.claude', 'agents');
|
|
38
|
-
}
|
|
39
|
-
parseAgentFile(filePath) {
|
|
172
|
+
return (0, node_path_1.resolve)(process.cwd(), '.claude', 'agents');
|
|
173
|
+
};
|
|
174
|
+
AgentLoader.prototype.parseAgentFile = function(filePath) {
|
|
40
175
|
try {
|
|
41
|
-
|
|
42
|
-
|
|
176
|
+
var content = (0, node_fs_1.readFileSync)(filePath, 'utf-8');
|
|
177
|
+
var frontmatterMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/);
|
|
43
178
|
if (!frontmatterMatch) {
|
|
44
|
-
console.warn(
|
|
179
|
+
console.warn("No frontmatter found in ".concat(filePath));
|
|
45
180
|
return null;
|
|
46
181
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
182
|
+
var yamlContent = frontmatterMatch[1], markdownContent = frontmatterMatch[2];
|
|
183
|
+
var frontmatter = (0, yaml_1.parse)(yamlContent);
|
|
184
|
+
var description = frontmatter.description;
|
|
50
185
|
if (!frontmatter.name || !description) {
|
|
51
|
-
console.warn(
|
|
186
|
+
console.warn("Missing required fields (name, description) in ".concat(filePath));
|
|
52
187
|
return null;
|
|
53
188
|
}
|
|
54
189
|
return {
|
|
@@ -69,129 +204,13 @@ export class AgentLoader {
|
|
|
69
204
|
content: markdownContent.trim()
|
|
70
205
|
};
|
|
71
206
|
} catch (error) {
|
|
72
|
-
console.error(
|
|
207
|
+
console.error("Error parsing agent file ".concat(filePath, ":"), error);
|
|
73
208
|
return null;
|
|
74
209
|
}
|
|
75
|
-
}
|
|
76
|
-
parseTools(frontmatter) {
|
|
77
|
-
|
|
210
|
+
};
|
|
211
|
+
AgentLoader.prototype.parseTools = function(frontmatter) {
|
|
212
|
+
var extractTools = function(input) {
|
|
78
213
|
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);
|
|
195
214
|
if (typeof input === 'string') {
|
|
196
215
|
return input.split(/[,\s]+/).map(function(t) {
|
|
197
216
|
return t.trim();
|