azclaude-copilot 0.1.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-plugin/marketplace.json +27 -0
- package/.claude-plugin/plugin.json +17 -0
- package/LICENSE +21 -0
- package/README.md +477 -0
- package/bin/cli.js +1027 -0
- package/bin/copilot.js +228 -0
- package/hooks/README.md +3 -0
- package/hooks/hooks.json +40 -0
- package/package.json +41 -0
- package/templates/CLAUDE.md +51 -0
- package/templates/agents/cc-cli-integrator.md +104 -0
- package/templates/agents/cc-template-author.md +109 -0
- package/templates/agents/cc-test-maintainer.md +101 -0
- package/templates/agents/code-reviewer.md +136 -0
- package/templates/agents/loop-controller.md +118 -0
- package/templates/agents/orchestrator-init.md +196 -0
- package/templates/agents/test-writer.md +129 -0
- package/templates/capabilities/evolution/cycle2-knowledge.md +87 -0
- package/templates/capabilities/evolution/cycle3-topology.md +128 -0
- package/templates/capabilities/evolution/detect.md +103 -0
- package/templates/capabilities/evolution/evaluate.md +90 -0
- package/templates/capabilities/evolution/generate.md +123 -0
- package/templates/capabilities/evolution/re-derivation.md +77 -0
- package/templates/capabilities/intelligence/debate.md +104 -0
- package/templates/capabilities/intelligence/elo.md +122 -0
- package/templates/capabilities/intelligence/experiment.md +86 -0
- package/templates/capabilities/intelligence/opro.md +84 -0
- package/templates/capabilities/intelligence/pipeline.md +149 -0
- package/templates/capabilities/level-builders/level1-claudemd.md +52 -0
- package/templates/capabilities/level-builders/level2-mcp.md +58 -0
- package/templates/capabilities/level-builders/level3-skills.md +276 -0
- package/templates/capabilities/level-builders/level4-memory.md +72 -0
- package/templates/capabilities/level-builders/level5-agents.md +123 -0
- package/templates/capabilities/level-builders/level6-hooks.md +119 -0
- package/templates/capabilities/level-builders/level7-extmcp.md +60 -0
- package/templates/capabilities/level-builders/level8-orchestrated.md +98 -0
- package/templates/capabilities/manifest.md +58 -0
- package/templates/capabilities/shared/5-layer-agent.md +206 -0
- package/templates/capabilities/shared/completion-rule.md +44 -0
- package/templates/capabilities/shared/context-artifacts.md +96 -0
- package/templates/capabilities/shared/domain-advisor-generator.md +205 -0
- package/templates/capabilities/shared/friction-log.md +43 -0
- package/templates/capabilities/shared/multi-cli-paths.md +56 -0
- package/templates/capabilities/shared/native-tools.md +199 -0
- package/templates/capabilities/shared/plan-tracker.md +69 -0
- package/templates/capabilities/shared/pressure-test.md +88 -0
- package/templates/capabilities/shared/quality-check.md +83 -0
- package/templates/capabilities/shared/reflexes.md +159 -0
- package/templates/capabilities/shared/review-reception.md +70 -0
- package/templates/capabilities/shared/security.md +174 -0
- package/templates/capabilities/shared/semantic-boundary-check.md +140 -0
- package/templates/capabilities/shared/session-rhythm.md +42 -0
- package/templates/capabilities/shared/tdd.md +54 -0
- package/templates/capabilities/shared/vocabulary-transform.md +63 -0
- package/templates/commands/add.md +152 -0
- package/templates/commands/audit.md +123 -0
- package/templates/commands/blueprint.md +115 -0
- package/templates/commands/copilot.md +157 -0
- package/templates/commands/create.md +156 -0
- package/templates/commands/debate.md +75 -0
- package/templates/commands/deps.md +112 -0
- package/templates/commands/doc.md +100 -0
- package/templates/commands/dream.md +120 -0
- package/templates/commands/evolve.md +170 -0
- package/templates/commands/explain.md +25 -0
- package/templates/commands/find.md +100 -0
- package/templates/commands/fix.md +122 -0
- package/templates/commands/hookify.md +100 -0
- package/templates/commands/level-up.md +48 -0
- package/templates/commands/loop.md +62 -0
- package/templates/commands/migrate.md +119 -0
- package/templates/commands/persist.md +73 -0
- package/templates/commands/pulse.md +87 -0
- package/templates/commands/refactor.md +97 -0
- package/templates/commands/reflect.md +107 -0
- package/templates/commands/reflexes.md +141 -0
- package/templates/commands/setup.md +97 -0
- package/templates/commands/ship.md +131 -0
- package/templates/commands/snapshot.md +70 -0
- package/templates/commands/test.md +86 -0
- package/templates/hooks/post-tool-use.js +175 -0
- package/templates/hooks/stop.js +85 -0
- package/templates/hooks/user-prompt.js +96 -0
- package/templates/scripts/env-scan.sh +46 -0
- package/templates/scripts/import-graph.sh +88 -0
- package/templates/scripts/validate-boundaries.sh +180 -0
- package/templates/skills/agent-creator/SKILL.md +91 -0
- package/templates/skills/agent-creator/examples/sample-agent.md +80 -0
- package/templates/skills/agent-creator/references/agent-engineering-guide.md +596 -0
- package/templates/skills/agent-creator/references/quality-checklist.md +42 -0
- package/templates/skills/agent-creator/scripts/scaffold.sh +144 -0
- package/templates/skills/architecture-advisor/SKILL.md +92 -0
- package/templates/skills/architecture-advisor/references/database-decisions.md +61 -0
- package/templates/skills/architecture-advisor/references/decision-matrices.md +122 -0
- package/templates/skills/architecture-advisor/references/rendering-decisions.md +39 -0
- package/templates/skills/architecture-advisor/scripts/detect-scale.sh +67 -0
- package/templates/skills/debate/SKILL.md +36 -0
- package/templates/skills/debate/references/acemad-protocol.md +72 -0
- package/templates/skills/env-scanner/SKILL.md +41 -0
- package/templates/skills/security/SKILL.md +44 -0
- package/templates/skills/security/references/security-details.md +48 -0
- package/templates/skills/session-guard/SKILL.md +33 -0
- package/templates/skills/skill-creator/SKILL.md +82 -0
- package/templates/skills/skill-creator/examples/sample-skill.md +74 -0
- package/templates/skills/skill-creator/references/quality-checklist.md +36 -0
- package/templates/skills/skill-creator/references/skill-engineering-guide.md +365 -0
- package/templates/skills/skill-creator/scripts/scaffold.sh +75 -0
- package/templates/skills/test-first/SKILL.md +41 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
/**
|
|
4
|
+
* AZCLAUDE — UserPromptSubmit hook
|
|
5
|
+
* Runs on every session's first prompt.
|
|
6
|
+
* Injects goals.md into context so Claude always knows the current thread.
|
|
7
|
+
* If previous session was interrupted (In progress entries remain), warns Claude.
|
|
8
|
+
* Works on: Windows (PowerShell/CMD/Git Bash), macOS, Linux.
|
|
9
|
+
*/
|
|
10
|
+
const fs = require('fs');
|
|
11
|
+
const path = require('path');
|
|
12
|
+
const os = require('os');
|
|
13
|
+
|
|
14
|
+
// ── Hook profile gate ───────────────────────────────────────────────────────
|
|
15
|
+
// AZCLAUDE_HOOK_PROFILE=minimal|standard|strict (default: standard)
|
|
16
|
+
const HOOK_PROFILE = process.env.AZCLAUDE_HOOK_PROFILE || 'standard';
|
|
17
|
+
|
|
18
|
+
// Fire once per session only — keyed by parent PID
|
|
19
|
+
const marker = path.join(os.tmpdir(), `.azclaude-session-${process.ppid || process.pid}`);
|
|
20
|
+
if (fs.existsSync(marker)) process.exit(0);
|
|
21
|
+
try { fs.writeFileSync(marker, ''); } catch (_) {}
|
|
22
|
+
|
|
23
|
+
// Only proceed if this is an AZCLAUDE project (goals.md exists)
|
|
24
|
+
const goalsPath = path.join('.claude', 'memory', 'goals.md');
|
|
25
|
+
if (!fs.existsSync(goalsPath)) process.exit(0);
|
|
26
|
+
|
|
27
|
+
// Ensure required directories exist — only in AZCLAUDE projects
|
|
28
|
+
for (const d of ['.claude/memory', '.claude/memory/checkpoints']) {
|
|
29
|
+
try { fs.mkdirSync(d, { recursive: true }); } catch (_) {}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Strip prompt-injection attempts before outputting into context
|
|
33
|
+
const INJECTION = /ignore.{0,20}previous.{0,20}instructions|curl.{0,10}\|.{0,10}bash|wget.{0,10}\|.{0,10}sh|you are now|system prompt/i;
|
|
34
|
+
const content = fs.readFileSync(goalsPath, 'utf8');
|
|
35
|
+
const filtered = content.split('\n').filter(l => !INJECTION.test(l)).join('\n');
|
|
36
|
+
|
|
37
|
+
// Warn if previous session was interrupted (In progress entries survived)
|
|
38
|
+
const ipMatch = filtered.match(/^## In progress\n((?:- .+\n?)+)/m);
|
|
39
|
+
if (ipMatch) {
|
|
40
|
+
console.log('⚠ PREVIOUS SESSION INTERRUPTED — files were being edited:');
|
|
41
|
+
console.log(ipMatch[1].trimEnd());
|
|
42
|
+
console.log('Resume or discard before starting new work.');
|
|
43
|
+
console.log('');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Cap "Done this session" to last 20 entries — older entries are still on disk
|
|
47
|
+
const doneHeading = '## Done this session';
|
|
48
|
+
const doneIdx = filtered.indexOf(doneHeading);
|
|
49
|
+
let output = filtered;
|
|
50
|
+
if (doneIdx !== -1) {
|
|
51
|
+
const before = filtered.slice(0, doneIdx);
|
|
52
|
+
const afterDone = filtered.slice(doneIdx + doneHeading.length);
|
|
53
|
+
const doneLines = afterDone.split('\n');
|
|
54
|
+
const entries = [];
|
|
55
|
+
const rest = [];
|
|
56
|
+
let pastDone = false;
|
|
57
|
+
for (const line of doneLines) {
|
|
58
|
+
if (pastDone) { rest.push(line); continue; }
|
|
59
|
+
if (line.startsWith('## ') && line.trim() !== '') { pastDone = true; rest.push(line); continue; }
|
|
60
|
+
entries.push(line);
|
|
61
|
+
}
|
|
62
|
+
const MAX_DONE = 20;
|
|
63
|
+
const entryLines = entries.filter(l => l.startsWith('- '));
|
|
64
|
+
if (entryLines.length > MAX_DONE) {
|
|
65
|
+
const trimmed = entryLines.slice(0, MAX_DONE);
|
|
66
|
+
const nonEntries = entries.filter(l => !l.startsWith('- '));
|
|
67
|
+
const omitted = entryLines.length - MAX_DONE;
|
|
68
|
+
output = before + doneHeading + '\n' + trimmed.join('\n') + `\n- ... ${omitted} earlier entries (on disk)\n` + nonEntries.filter(l => l.trim()).join('\n') + '\n' + rest.join('\n');
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
console.log('--- ACTIVE GOALS ---');
|
|
73
|
+
console.log(output);
|
|
74
|
+
console.log('--- END GOALS ---');
|
|
75
|
+
|
|
76
|
+
// Inject latest checkpoint if one exists — captures mid-session reasoning
|
|
77
|
+
const checkpointDir = path.join('.claude', 'memory', 'checkpoints');
|
|
78
|
+
if (fs.existsSync(checkpointDir)) {
|
|
79
|
+
const files = fs.readdirSync(checkpointDir)
|
|
80
|
+
.filter(f => f.endsWith('.md'))
|
|
81
|
+
.sort()
|
|
82
|
+
.reverse(); // latest first
|
|
83
|
+
if (files.length > 0) {
|
|
84
|
+
const latest = path.join(checkpointDir, files[0]);
|
|
85
|
+
const cpContent = fs.readFileSync(latest, 'utf8');
|
|
86
|
+
const cpLines = cpContent.split('\n').filter(l => !INJECTION.test(l));
|
|
87
|
+
const MAX_CP = 50;
|
|
88
|
+
const cpTrimmed = cpLines.length > MAX_CP
|
|
89
|
+
? cpLines.slice(0, MAX_CP).concat([`... ${cpLines.length - MAX_CP} more lines (on disk)`])
|
|
90
|
+
: cpLines;
|
|
91
|
+
console.log('');
|
|
92
|
+
console.log(`--- LAST CHECKPOINT (${files[0]}) ---`);
|
|
93
|
+
console.log(cpTrimmed.join('\n').trim());
|
|
94
|
+
console.log('--- END CHECKPOINT ---');
|
|
95
|
+
}
|
|
96
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# AZCLAUDE Environment Scanner
|
|
3
|
+
# Runs as a single script — output (JSON) is what enters Claude's context.
|
|
4
|
+
# Not 15 separate tool calls. One script, one result, ~200 tokens.
|
|
5
|
+
|
|
6
|
+
FILE_COUNT=$(find . \
|
|
7
|
+
-not -path './node_modules/*' \
|
|
8
|
+
-not -path './.git/*' \
|
|
9
|
+
-not -path './.claude/*' \
|
|
10
|
+
\( -name '*.md' -o -name '*.json' -o -name '*.js' -o -name '*.ts' \
|
|
11
|
+
-o -name '*.py' -o -name '*.rs' -o -name '*.go' \) \
|
|
12
|
+
2>/dev/null | wc -l | tr -d ' ')
|
|
13
|
+
|
|
14
|
+
has_file() { [ -f "$1" ] && echo true || echo false; }
|
|
15
|
+
has_dir() { [ -d "$1" ] && echo true || echo false; }
|
|
16
|
+
count_files() { ls "$1"/*.md 2>/dev/null | wc -l | tr -d ' ' || echo 0; }
|
|
17
|
+
|
|
18
|
+
cat <<EOF
|
|
19
|
+
{
|
|
20
|
+
"file_count": $FILE_COUNT,
|
|
21
|
+
"scale": $(
|
|
22
|
+
if [ "$FILE_COUNT" -lt 100 ]; then echo '"STANDARD"'
|
|
23
|
+
elif [ "$FILE_COUNT" -lt 500 ]; then echo '"SKIM"'
|
|
24
|
+
elif [ "$FILE_COUNT" -lt 2000 ]; then echo '"MINIMAL"'
|
|
25
|
+
else echo '"STRUCTURE-ONLY"'
|
|
26
|
+
fi
|
|
27
|
+
),
|
|
28
|
+
"signals": {
|
|
29
|
+
"has_package_json": $(has_file package.json),
|
|
30
|
+
"has_requirements": $(has_file requirements.txt),
|
|
31
|
+
"has_cargo": $(has_file Cargo.toml),
|
|
32
|
+
"has_gomod": $(has_file go.mod),
|
|
33
|
+
"has_pyproject": $(has_file pyproject.toml),
|
|
34
|
+
"has_knowledge_dir": $(has_dir knowledge),
|
|
35
|
+
"has_claude_md": $(has_file CLAUDE.md),
|
|
36
|
+
"claude_md_count": $(find . -name 'CLAUDE.md' 2>/dev/null | wc -l | tr -d ' '),
|
|
37
|
+
"has_git": $(has_dir .git),
|
|
38
|
+
"has_mcp": $(has_file .mcp.json),
|
|
39
|
+
"has_memory": $(has_file .claude/memory/goals.md),
|
|
40
|
+
"commands_count": $(count_files .claude/commands 2>/dev/null),
|
|
41
|
+
"agents_count": $(count_files .claude/agents 2>/dev/null)
|
|
42
|
+
},
|
|
43
|
+
"git_log": "$(git log --oneline -5 2>/dev/null | head -5 | tr '\n' '|' | sed 's/"/\\"/g' || echo 'none')",
|
|
44
|
+
"readme_head": "$(head -10 README.md 2>/dev/null | tr '\n' '|' | sed 's/"/\\"/g' || echo 'none')"
|
|
45
|
+
}
|
|
46
|
+
EOF
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
# import-graph.sh — Lightweight dependency mapper
|
|
4
|
+
# Purpose: Build import/dependency graph from grep, detect circular deps
|
|
5
|
+
# Usage: bash .claude/scripts/import-graph.sh [project-dir]
|
|
6
|
+
# Output: structured text showing imports per file + circular dependencies
|
|
7
|
+
# Zero dependencies — just grep. No ast-grep, no vector DB, no Docker.
|
|
8
|
+
|
|
9
|
+
ROOT="${1:-.}"
|
|
10
|
+
cd "$ROOT"
|
|
11
|
+
|
|
12
|
+
echo "## Import Graph — $(basename "$(pwd)")"
|
|
13
|
+
echo ""
|
|
14
|
+
|
|
15
|
+
# ── Detect language ──────────────────────────────────────────────────────────
|
|
16
|
+
HAS_TS=$(find . -name "*.ts" -o -name "*.tsx" -not -path "*/node_modules/*" 2>/dev/null | head -1)
|
|
17
|
+
HAS_PY=$(find . -name "*.py" -not -path "*/__pycache__/*" -not -path "*/venv/*" 2>/dev/null | head -1)
|
|
18
|
+
HAS_GO=$(find . -name "*.go" -not -path "*/vendor/*" 2>/dev/null | head -1)
|
|
19
|
+
|
|
20
|
+
# ── Extract imports ──────────────────────────────────────────────────────────
|
|
21
|
+
TMPFILE=$(mktemp)
|
|
22
|
+
trap 'rm -f "$TMPFILE"' EXIT
|
|
23
|
+
|
|
24
|
+
if [ -n "$HAS_TS" ]; then
|
|
25
|
+
echo "Language: TypeScript/JavaScript"
|
|
26
|
+
grep -rn "^import\|^const.*require(" --include="*.ts" --include="*.tsx" --include="*.js" --include="*.jsx" \
|
|
27
|
+
--exclude-dir=node_modules --exclude-dir=.git --exclude-dir=dist . 2>/dev/null | \
|
|
28
|
+
sed 's/:.*//' | sort | uniq -c | sort -rn | head -20 > "$TMPFILE"
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
if [ -n "$HAS_PY" ]; then
|
|
32
|
+
echo "Language: Python"
|
|
33
|
+
grep -rn "^import\|^from.*import" --include="*.py" \
|
|
34
|
+
--exclude-dir=__pycache__ --exclude-dir=venv --exclude-dir=.git . 2>/dev/null | \
|
|
35
|
+
sed 's/:.*//' | sort | uniq -c | sort -rn | head -20 > "$TMPFILE"
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
if [ -n "$HAS_GO" ]; then
|
|
39
|
+
echo "Language: Go"
|
|
40
|
+
grep -rn "^import" --include="*.go" \
|
|
41
|
+
--exclude-dir=vendor --exclude-dir=.git . 2>/dev/null | \
|
|
42
|
+
sed 's/:.*//' | sort | uniq -c | sort -rn | head -20 > "$TMPFILE"
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
echo ""
|
|
46
|
+
echo "### Most-imported files (by import count)"
|
|
47
|
+
if [ -s "$TMPFILE" ]; then
|
|
48
|
+
cat "$TMPFILE"
|
|
49
|
+
else
|
|
50
|
+
echo "(no imports detected)"
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
# ── Circular dependency detection ────────────────────────────────────────────
|
|
54
|
+
echo ""
|
|
55
|
+
echo "### Circular dependency check"
|
|
56
|
+
|
|
57
|
+
CIRCULARS=0
|
|
58
|
+
if [ -n "$HAS_TS" ]; then
|
|
59
|
+
# Find files that import each other (A imports B AND B imports A)
|
|
60
|
+
grep -roh "from ['\"]\..*['\"]" --include="*.ts" --include="*.tsx" --include="*.js" . 2>/dev/null | \
|
|
61
|
+
sed "s/from ['\"]//;s/['\"]//g" | sort | uniq -d | while read -r imp; do
|
|
62
|
+
# Check if the target imports back
|
|
63
|
+
target_file=$(find . -path "*${imp}*" -name "*.ts" -o -path "*${imp}*" -name "*.tsx" 2>/dev/null | head -1)
|
|
64
|
+
if [ -n "$target_file" ]; then
|
|
65
|
+
source_dir=$(dirname "$target_file")
|
|
66
|
+
back_imports=$(grep -l "from.*${source_dir}" "$target_file" 2>/dev/null || true)
|
|
67
|
+
if [ -n "$back_imports" ]; then
|
|
68
|
+
echo " ⚠ Possible circular: $imp ↔ $source_dir"
|
|
69
|
+
CIRCULARS=$((CIRCULARS + 1))
|
|
70
|
+
fi
|
|
71
|
+
fi
|
|
72
|
+
done
|
|
73
|
+
fi
|
|
74
|
+
|
|
75
|
+
if [ "$CIRCULARS" -eq 0 ]; then
|
|
76
|
+
echo " ✓ No circular dependencies detected"
|
|
77
|
+
fi
|
|
78
|
+
|
|
79
|
+
# ── File co-change analysis (for /evolve) ────────────────────────────────────
|
|
80
|
+
echo ""
|
|
81
|
+
echo "### Co-change clusters (files that always commit together)"
|
|
82
|
+
if command -v git &>/dev/null && [ -d .git ]; then
|
|
83
|
+
git log --name-only --format="" --diff-filter=M -50 2>/dev/null | \
|
|
84
|
+
sort | uniq -c | sort -rn | head -15 | \
|
|
85
|
+
awk '{if ($1 >= 3) print " " $1 "x — " $2}'
|
|
86
|
+
else
|
|
87
|
+
echo " (not a git repo — skipping)"
|
|
88
|
+
fi
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
# validate-boundaries.sh — Detect overlap between commands, skills, capabilities, agents
|
|
4
|
+
# Run by: /evolve Cycle 3, doctor --audit, or manually
|
|
5
|
+
# Output: warnings for overlapping descriptions, stale manifest entries, orphaned files
|
|
6
|
+
|
|
7
|
+
ROOT="${1:-.claude}"
|
|
8
|
+
PASS=0
|
|
9
|
+
WARN=0
|
|
10
|
+
|
|
11
|
+
echo "## Boundary Validation"
|
|
12
|
+
echo ""
|
|
13
|
+
|
|
14
|
+
# ── 1. Manifest completeness: every capability file is listed ────────────────
|
|
15
|
+
echo "### Manifest completeness"
|
|
16
|
+
if [ -f "$ROOT/capabilities/manifest.md" ]; then
|
|
17
|
+
for cap in "$ROOT"/capabilities/shared/*.md; do
|
|
18
|
+
[ -f "$cap" ] || continue
|
|
19
|
+
name=$(basename "$cap")
|
|
20
|
+
if ! grep -q "$name" "$ROOT/capabilities/manifest.md" 2>/dev/null; then
|
|
21
|
+
echo " ⚠ $name exists but not in manifest.md"
|
|
22
|
+
WARN=$((WARN + 1))
|
|
23
|
+
else
|
|
24
|
+
PASS=$((PASS + 1))
|
|
25
|
+
fi
|
|
26
|
+
done
|
|
27
|
+
echo " Checked: $((PASS + WARN)) capabilities, $WARN missing from manifest"
|
|
28
|
+
else
|
|
29
|
+
echo " ⚠ No manifest.md found"
|
|
30
|
+
WARN=$((WARN + 1))
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
# ── 2. Description overlap: same trigger words in multiple extensions ────────
|
|
34
|
+
echo ""
|
|
35
|
+
echo "### Description overlap detection"
|
|
36
|
+
OVERLAP_FOUND=0
|
|
37
|
+
|
|
38
|
+
# Extract all description fields from commands, skills, agents
|
|
39
|
+
TMPDIR_V=$(mktemp -d)
|
|
40
|
+
trap 'rm -rf "$TMPDIR_V"' EXIT
|
|
41
|
+
|
|
42
|
+
for cmd in "$ROOT"/commands/*.md; do
|
|
43
|
+
[ -f "$cmd" ] || continue
|
|
44
|
+
name=$(basename "$cmd" .md)
|
|
45
|
+
grep -i "description\|triggers on\|use when" "$cmd" 2>/dev/null | tr '[:upper:]' '[:lower:]' > "$TMPDIR_V/cmd-$name.txt"
|
|
46
|
+
done
|
|
47
|
+
|
|
48
|
+
for skill_dir in "$ROOT"/skills/*/; do
|
|
49
|
+
[ -f "${skill_dir}SKILL.md" ] || continue
|
|
50
|
+
name=$(basename "$skill_dir")
|
|
51
|
+
grep -i "description\|triggers on\|use when" "${skill_dir}SKILL.md" 2>/dev/null | tr '[:upper:]' '[:lower:]' > "$TMPDIR_V/skill-$name.txt"
|
|
52
|
+
done
|
|
53
|
+
|
|
54
|
+
for agent in "$ROOT"/agents/*.md; do
|
|
55
|
+
[ -f "$agent" ] || continue
|
|
56
|
+
name=$(basename "$agent" .md)
|
|
57
|
+
grep -i "description\|triggers on\|use when" "$agent" 2>/dev/null | tr '[:upper:]' '[:lower:]' > "$TMPDIR_V/agent-$name.txt"
|
|
58
|
+
done
|
|
59
|
+
|
|
60
|
+
# Check for files with highly similar trigger words
|
|
61
|
+
for f1 in "$TMPDIR_V"/*; do
|
|
62
|
+
[ -f "$f1" ] || continue
|
|
63
|
+
for f2 in "$TMPDIR_V"/*; do
|
|
64
|
+
[ -f "$f2" ] || continue
|
|
65
|
+
[ "$f1" = "$f2" ] && continue
|
|
66
|
+
# Count shared significant words (> 5 chars)
|
|
67
|
+
shared=$(comm -12 \
|
|
68
|
+
<(tr ' ,.:;|' '\n' < "$f1" | grep -E '^.{5,}$' | sort -u) \
|
|
69
|
+
<(tr ' ,.:;|' '\n' < "$f2" | grep -E '^.{5,}$' | sort -u) \
|
|
70
|
+
2>/dev/null | wc -l | tr -d ' ')
|
|
71
|
+
if [ "$shared" -gt 8 ]; then
|
|
72
|
+
n1=$(basename "$f1" .txt)
|
|
73
|
+
n2=$(basename "$f2" .txt)
|
|
74
|
+
# Only report each pair once (alphabetical order)
|
|
75
|
+
if [ "$n1" \< "$n2" ]; then
|
|
76
|
+
echo " ⚠ Possible overlap: $n1 ↔ $n2 ($shared shared trigger words)"
|
|
77
|
+
OVERLAP_FOUND=$((OVERLAP_FOUND + 1))
|
|
78
|
+
fi
|
|
79
|
+
fi
|
|
80
|
+
done
|
|
81
|
+
done
|
|
82
|
+
|
|
83
|
+
if [ "$OVERLAP_FOUND" -eq 0 ]; then
|
|
84
|
+
echo " ✓ No significant overlaps detected"
|
|
85
|
+
PASS=$((PASS + 1))
|
|
86
|
+
else
|
|
87
|
+
WARN=$((WARN + OVERLAP_FOUND))
|
|
88
|
+
fi
|
|
89
|
+
|
|
90
|
+
# ── 3. Orphaned files: extensions not referenced anywhere ────────────────────
|
|
91
|
+
echo ""
|
|
92
|
+
echo "### Orphan detection"
|
|
93
|
+
ORPHANS=0
|
|
94
|
+
|
|
95
|
+
for agent in "$ROOT"/agents/*.md; do
|
|
96
|
+
[ -f "$agent" ] || continue
|
|
97
|
+
name=$(basename "$agent" .md)
|
|
98
|
+
# Check if agent is referenced in any command, skill, or CLAUDE.md
|
|
99
|
+
refs=$(grep -rl "$name" "$ROOT/commands/" "$ROOT/capabilities/" CLAUDE.md 2>/dev/null | wc -l | tr -d ' ')
|
|
100
|
+
if [ "$refs" -eq 0 ]; then
|
|
101
|
+
echo " ⚠ Agent $name.md not referenced in any command or capability"
|
|
102
|
+
ORPHANS=$((ORPHANS + 1))
|
|
103
|
+
fi
|
|
104
|
+
done
|
|
105
|
+
|
|
106
|
+
if [ "$ORPHANS" -eq 0 ]; then
|
|
107
|
+
echo " ✓ No orphaned agents"
|
|
108
|
+
PASS=$((PASS + 1))
|
|
109
|
+
else
|
|
110
|
+
WARN=$((WARN + ORPHANS))
|
|
111
|
+
fi
|
|
112
|
+
|
|
113
|
+
# ── 4. Command name collision with Claude Code built-ins ─────────────────────
|
|
114
|
+
echo ""
|
|
115
|
+
echo "### Claude Code collision check"
|
|
116
|
+
BUILTINS="clear reset new compact config settings context copy cost desktop app diff doctor effort exit quit export fast feedback bug branch fork help hooks ide init insights keybindings login logout mcp memory model passes permissions plan plugin pr-comments release-notes review rewind checkpoint sandbox security-review skills stats status statusline stickers tasks terminal-setup theme upgrade usage vim voice"
|
|
117
|
+
|
|
118
|
+
COLLISIONS=0
|
|
119
|
+
for cmd in "$ROOT"/commands/*.md; do
|
|
120
|
+
[ -f "$cmd" ] || continue
|
|
121
|
+
name=$(basename "$cmd" .md)
|
|
122
|
+
if echo "$BUILTINS" | tr ' ' '\n' | grep -qx "$name"; then
|
|
123
|
+
echo " ⚠ /$name collides with Claude Code built-in"
|
|
124
|
+
COLLISIONS=$((COLLISIONS + 1))
|
|
125
|
+
fi
|
|
126
|
+
done
|
|
127
|
+
|
|
128
|
+
if [ "$COLLISIONS" -eq 0 ]; then
|
|
129
|
+
echo " ✓ No collisions with Claude Code built-ins"
|
|
130
|
+
PASS=$((PASS + 1))
|
|
131
|
+
else
|
|
132
|
+
WARN=$((WARN + COLLISIONS))
|
|
133
|
+
fi
|
|
134
|
+
|
|
135
|
+
# ── Summary ──────────────────────────────────────────────────────────────────
|
|
136
|
+
echo ""
|
|
137
|
+
echo "### Summary: $PASS passed, $WARN warnings"
|
|
138
|
+
if [ "$WARN" -gt 0 ]; then
|
|
139
|
+
echo " Run /evolve to auto-fix overlaps and orphans"
|
|
140
|
+
fi
|
|
141
|
+
|
|
142
|
+
# ── Machine-readable output (last line, always) ─────────────────────────────
|
|
143
|
+
# Format: BOUNDARY_RESULT:pass=N:warn=N
|
|
144
|
+
# Parsed by doctor --audit instead of counting ⚠ symbols
|
|
145
|
+
echo ""
|
|
146
|
+
echo "BOUNDARY_RESULT:pass=$PASS:warn=$WARN"
|
|
147
|
+
|
|
148
|
+
# ── JSON report (structured, diffable, CI-friendly) ─────────────────────────
|
|
149
|
+
REPORT_DIR="$ROOT/memory/metrics"
|
|
150
|
+
mkdir -p "$REPORT_DIR" 2>/dev/null || true
|
|
151
|
+
REPORT_PATH="$REPORT_DIR/boundaries.json"
|
|
152
|
+
TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
|
153
|
+
|
|
154
|
+
cat > "$REPORT_PATH" << JSONEOF
|
|
155
|
+
{
|
|
156
|
+
"timestamp": "$TIMESTAMP",
|
|
157
|
+
"pass": $PASS,
|
|
158
|
+
"warn": $WARN,
|
|
159
|
+
"manifest_gaps": $([ -f "$ROOT/capabilities/manifest.md" ] && {
|
|
160
|
+
gaps=0
|
|
161
|
+
for cap in "$ROOT"/capabilities/shared/*.md; do
|
|
162
|
+
[ -f "$cap" ] || continue
|
|
163
|
+
grep -q "$(basename "$cap")" "$ROOT/capabilities/manifest.md" 2>/dev/null || gaps=$((gaps + 1))
|
|
164
|
+
done
|
|
165
|
+
echo $gaps
|
|
166
|
+
} || echo 0),
|
|
167
|
+
"orphaned_agents": $(for a in "$ROOT"/agents/*.md; do
|
|
168
|
+
[ -f "$a" ] || continue
|
|
169
|
+
n=$(basename "$a" .md)
|
|
170
|
+
grep -rl "$n" "$ROOT/commands/" "$ROOT/capabilities/" CLAUDE.md 2>/dev/null | wc -l | tr -d ' '
|
|
171
|
+
done | awk '$1==0{c++}END{print c+0}'),
|
|
172
|
+
"collisions": $COLLISIONS,
|
|
173
|
+
"overlaps": $OVERLAP_FOUND
|
|
174
|
+
}
|
|
175
|
+
JSONEOF
|
|
176
|
+
|
|
177
|
+
echo " Report written: $REPORT_PATH"
|
|
178
|
+
|
|
179
|
+
# Exit code: 0 if no warnings, 1 if warnings found
|
|
180
|
+
exit $( [ "$WARN" -eq 0 ] && echo 0 || echo 1 )
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agent-creator
|
|
3
|
+
description: >
|
|
4
|
+
Creates and improves Claude Code agent definitions. Use when the user says
|
|
5
|
+
"create an agent", "add an agent", "new agent", "build an agent", "write
|
|
6
|
+
an agent", "make an agent", "I need an agent for", "agent for", "custom
|
|
7
|
+
agent", "specialized agent", "add a reviewer", "add a builder". Also use
|
|
8
|
+
when an existing agent is incomplete, making mistakes, missing context,
|
|
9
|
+
producing inconsistent results, or needs its 5-layer structure fixed.
|
|
10
|
+
Use when splitting work across multiple agents, defining agent boundaries,
|
|
11
|
+
checking agent overlap, or pairing agents with skills. Even if the user
|
|
12
|
+
doesn't say "agent", use this when they describe a workstream that needs
|
|
13
|
+
isolation, parallelism, or specialized context.
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# Agent Creator
|
|
17
|
+
|
|
18
|
+
Creates production-quality Claude Code agents following the 5-layer structure.
|
|
19
|
+
An agent is an OWNERSHIP BOUNDARY — not a persona. If two agents can do the
|
|
20
|
+
same task, one shouldn't exist.
|
|
21
|
+
|
|
22
|
+
## 5-Minute Checklist
|
|
23
|
+
Before diving into the full workflow, verify these 5 essentials:
|
|
24
|
+
1. Does this workstream genuinely need isolation or parallelism? (If not, a skill is enough)
|
|
25
|
+
2. Is the description pushy enough? (30+ trigger keywords, ends with "even if...")
|
|
26
|
+
3. Are all 5 layers filled? (Persona, Scope, Tools, Constraints, Domain — Domain is largest)
|
|
27
|
+
4. Does Scope have explicit DOES NOT TOUCH boundaries? (Without them, agents drift)
|
|
28
|
+
5. Are constraints positive directives that hold under pressure? ("Always X" not "Don't Y")
|
|
29
|
+
|
|
30
|
+
## When NOT to Create an Agent
|
|
31
|
+
- A skill with direct tool calls can do the same work — agents add coordination overhead
|
|
32
|
+
- The "agent" would just read one file and return its content — that's a tool call, not an agent
|
|
33
|
+
- You're using agents as a routing mechanism — routing belongs in CLAUDE.md, not agents
|
|
34
|
+
- Two existing agents already cover this territory — merge or tighten scope instead
|
|
35
|
+
- The project has < 20 files — CLAUDE.md alone is probably enough
|
|
36
|
+
|
|
37
|
+
## Workflow
|
|
38
|
+
|
|
39
|
+
1. **Determine boundaries.** Run co-change analysis to find what changes together:
|
|
40
|
+
```bash
|
|
41
|
+
bash .claude/skills/agent-creator/scripts/scaffold.sh --analyze
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
2. **Generate the agent file:**
|
|
45
|
+
```bash
|
|
46
|
+
bash .claude/skills/agent-creator/scripts/scaffold.sh AGENT_NAME
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
3. **Write the description.** Follow the pushy formula — 30+ trigger keywords.
|
|
50
|
+
End with: "even if not explicitly mentioned, route to this agent when..."
|
|
51
|
+
|
|
52
|
+
4. **Fill all 5 layers:**
|
|
53
|
+
- Layer 1 PERSONA (5%) — one sentence role, not personality
|
|
54
|
+
- Layer 2 SCOPE (25%) — what it OWNS + what it does NOT touch
|
|
55
|
+
- Layer 3 TOOLS (10%) — restrictions matter more than grants
|
|
56
|
+
- Layer 4 CONSTRAINTS (25%) — positive directives, 5-10 max
|
|
57
|
+
- Layer 5 DOMAIN (35%) — project-specific knowledge, the real value
|
|
58
|
+
|
|
59
|
+
5. **Check framework collision:**
|
|
60
|
+
```bash
|
|
61
|
+
grep -r "langgraph\|crewai\|autogen\|langchain.*agent" pyproject.toml package.json 2>/dev/null
|
|
62
|
+
```
|
|
63
|
+
If found: prefix all agents with `cc-` (e.g., `cc-backend`).
|
|
64
|
+
|
|
65
|
+
6. **Pair with skills.** Add mandatory skill check to agent body:
|
|
66
|
+
"Before writing any code, check if a skill matches this task."
|
|
67
|
+
|
|
68
|
+
7. **Validate.** Read `references/quality-checklist.md` and verify all items pass.
|
|
69
|
+
|
|
70
|
+
## Rules
|
|
71
|
+
- 3-5 agents for most projects (3 focused > 6 overlapping)
|
|
72
|
+
- Layer 5 (Domain) matters more than Layer 1 (Persona) — domain drives correctness
|
|
73
|
+
- Every agent has explicit DOES NOT TOUCH boundaries in scope
|
|
74
|
+
- Positive directives: "Always validate" not "Don't skip validation"
|
|
75
|
+
- Review agents: read-only (planMode), no Write/Edit tools
|
|
76
|
+
- Experiment agents: isolated in git worktree
|
|
77
|
+
- Testing is a responsibility, not a role — agent owns its test files
|
|
78
|
+
- `disable-model-invocation: true` ONLY for dangerous agents
|
|
79
|
+
|
|
80
|
+
## Agent Sizing Guide
|
|
81
|
+
| Project size | Recommended agents |
|
|
82
|
+
|---|---|
|
|
83
|
+
| < 20 files | 1-2 (or none — CLAUDE.md is enough) |
|
|
84
|
+
| 20-100 files | 2-3 |
|
|
85
|
+
| 100-500 files | 3-5 |
|
|
86
|
+
| 500+ files | 4-6 with SKIM mode |
|
|
87
|
+
|
|
88
|
+
## References
|
|
89
|
+
For the complete agent engineering guide: `references/agent-engineering-guide.md`
|
|
90
|
+
For the quality checklist: `references/quality-checklist.md`
|
|
91
|
+
For a sample agent output: `examples/sample-agent.md`
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Example: Backend API Agent
|
|
2
|
+
|
|
3
|
+
## Input
|
|
4
|
+
User asked: "create an agent for the backend API layer"
|
|
5
|
+
|
|
6
|
+
## Output: Generated .claude/agents/cc-backend.md
|
|
7
|
+
|
|
8
|
+
```yaml
|
|
9
|
+
---
|
|
10
|
+
name: cc-backend
|
|
11
|
+
description: >
|
|
12
|
+
Backend API specialist. Route to this agent for: API endpoints, routes,
|
|
13
|
+
middleware, request validation, response formatting, database queries,
|
|
14
|
+
repository pattern, migrations, Alembic, SQLAlchemy, Pydantic models,
|
|
15
|
+
authentication, authorization, JWT, OAuth, session management, rate
|
|
16
|
+
limiting, caching, Redis, background tasks, error handling, logging,
|
|
17
|
+
health checks, OpenAPI schema, FastAPI dependencies, Depends(), testing
|
|
18
|
+
API routes, pytest, httpx, integration tests. Also handles: performance
|
|
19
|
+
issues in API layer, N+1 queries, slow endpoints, connection pooling.
|
|
20
|
+
Even if the user doesn't mention "backend" or "API", route here when
|
|
21
|
+
the task involves any server-side code in src/api/, src/middleware/,
|
|
22
|
+
or src/db/.
|
|
23
|
+
tools: Read, Write, Edit, Bash, Grep, Glob
|
|
24
|
+
model: sonnet
|
|
25
|
+
permissionMode: acceptEdits
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Layer 1: PERSONA
|
|
29
|
+
Backend API specialist. Writes production-quality API code with tests.
|
|
30
|
+
|
|
31
|
+
## Layer 2: SCOPE
|
|
32
|
+
OWNS: src/api/, src/middleware/, src/db/, tests/api/
|
|
33
|
+
DOES NOT TOUCH: src/frontend/, src/workers/, infrastructure/
|
|
34
|
+
|
|
35
|
+
## Layer 3: TOOLS & RESOURCES
|
|
36
|
+
- Read, Write, Edit: for all files in scope
|
|
37
|
+
- Bash: for running tests and scripts only
|
|
38
|
+
- Grep, Glob: for searching codebase
|
|
39
|
+
RESTRICTIONS:
|
|
40
|
+
- Do NOT use Bash for installing packages (ask the user)
|
|
41
|
+
- Do NOT use Write on files outside scope directories
|
|
42
|
+
|
|
43
|
+
## Layer 4: CONSTRAINTS
|
|
44
|
+
- Always write the failing test BEFORE implementation code
|
|
45
|
+
- Always run existing tests after every change: `pytest tests/api/ -x`
|
|
46
|
+
- Always include error handling for every external call
|
|
47
|
+
- Always log structured JSON, never print() or console.log()
|
|
48
|
+
- Always validate inputs on user-facing endpoints
|
|
49
|
+
- Reference the specific requirement being implemented
|
|
50
|
+
|
|
51
|
+
## Layer 5: DOMAIN CONTEXT
|
|
52
|
+
### Architecture
|
|
53
|
+
FastAPI application with:
|
|
54
|
+
- Pydantic v2 for all models (use .model_dump(), not .dict())
|
|
55
|
+
- SQLAlchemy 2.0 async (always use async session)
|
|
56
|
+
- Alembic for migrations (never modify tables directly)
|
|
57
|
+
- Redis for caching (connection pool in src/core/redis.py)
|
|
58
|
+
|
|
59
|
+
### Conventions
|
|
60
|
+
- One router per domain (auth_router, users_router, billing_router)
|
|
61
|
+
- All routes use Depends() for auth and database session
|
|
62
|
+
- Error responses: RFC 7807 format via src/core/errors.py
|
|
63
|
+
- Cursor-based pagination (see src/core/pagination.py)
|
|
64
|
+
|
|
65
|
+
### Patterns
|
|
66
|
+
- Repository pattern for all database access
|
|
67
|
+
- Service layer between routes and repos for business logic
|
|
68
|
+
- Background tasks via FastAPI BackgroundTasks, not Celery
|
|
69
|
+
|
|
70
|
+
### Self-Correction
|
|
71
|
+
If the first attempt fails: re-read the error, try one alternative.
|
|
72
|
+
After 2 attempts: stop. Present what was tried, what the error says,
|
|
73
|
+
what is needed to proceed.
|
|
74
|
+
|
|
75
|
+
## Before Starting Any Task
|
|
76
|
+
1. Read .claude/memory/patterns.md for project conventions
|
|
77
|
+
2. Read .claude/memory/antipatterns.md for known mistakes
|
|
78
|
+
3. Check if a relevant skill matches this task type
|
|
79
|
+
4. If touching auth or payments → load security-review skill
|
|
80
|
+
```
|