kodelyth-ecc 1.5.0 → 1.5.2
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/CHANGELOG.md +110 -0
- package/README.md +106 -11
- package/SECURITY.md +6 -2
- package/VERSION +1 -1
- package/agents/image-architect.md +190 -0
- package/commands/lessons.md +92 -0
- package/commands/project-launch.md +74 -0
- package/commands/team-review.md +90 -0
- package/hooks/hooks.json +28 -2
- package/hooks/memory/capture-correction.js +185 -0
- package/hooks/memory/read-lessons.js +190 -0
- package/install.sh +1 -1
- package/package.json +7 -3
- package/rules/common/agent-intent-routing.md +61 -0
- package/rules/common/self-improvement-workflow.md +141 -0
- package/social/facebook-v150.svg +119 -0
- package/wiki/Agent-Reference.md +398 -397
- package/wiki/FAQ.md +229 -228
- package/wiki/Home.md +114 -113
- package/wiki/Hook-Reference.md +197 -196
- package/wiki/Installation-Guide.md +208 -207
- package/wiki/Platform-Support.md +187 -186
- package/wiki/Skill-Reference.md +211 -210
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Parallel full-team audit for existing projects. Fires code-reviewer + security-reviewer + performance-optimizer + api-guardian simultaneously. One command, complete audit at once.
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# /team-review — Parallel Full-Team Audit
|
|
6
|
+
|
|
7
|
+
Run a full audit of your existing codebase with 4 specialist agents firing simultaneously. What would take an hour sequentially takes 15 minutes in parallel.
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
/team-review # full audit — all 4 agents on entire codebase
|
|
13
|
+
/team-review src/auth/ # focus all agents on a specific directory
|
|
14
|
+
/team-review --changed # audit only files changed since last commit
|
|
15
|
+
/team-review --pre-release # adds release-captain for release readiness check
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## What Gets Launched in Parallel
|
|
19
|
+
|
|
20
|
+
| Agent | Focus |
|
|
21
|
+
|---|---|
|
|
22
|
+
| `code-reviewer` | Quality, patterns, dead code, naming, complexity, maintainability |
|
|
23
|
+
| `security-reviewer` | OWASP Top 10, secrets, injection, auth gaps, CVEs in deps |
|
|
24
|
+
| `performance-optimizer` | N+1 queries, unbounded loops, missing indexes, memory leaks, bundle size |
|
|
25
|
+
| `api-guardian` | Breaking changes, missing validation, versioning gaps, contract drift |
|
|
26
|
+
|
|
27
|
+
With `--pre-release`, also adds:
|
|
28
|
+
- `release-captain` — release readiness: changelog, semver, rollback plan, smoke test coverage
|
|
29
|
+
|
|
30
|
+
## How It Works
|
|
31
|
+
|
|
32
|
+
1. Identify the target scope (whole repo, directory, or changed files)
|
|
33
|
+
2. Spawn all 4 agents simultaneously with `run_in_background: true`
|
|
34
|
+
3. Each agent scans its assigned concern independently
|
|
35
|
+
4. Wait for all to complete
|
|
36
|
+
5. Aggregate into a structured **Team Review Report**:
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
## TEAM REVIEW REPORT
|
|
40
|
+
|
|
41
|
+
### Code Quality (code-reviewer)
|
|
42
|
+
CRITICAL: [list]
|
|
43
|
+
HIGH: [list]
|
|
44
|
+
MEDIUM: [list]
|
|
45
|
+
|
|
46
|
+
### Security (security-reviewer)
|
|
47
|
+
CRITICAL: [list]
|
|
48
|
+
HIGH: [list]
|
|
49
|
+
|
|
50
|
+
### Performance (performance-optimizer)
|
|
51
|
+
HIGH: [list]
|
|
52
|
+
MEDIUM: [list]
|
|
53
|
+
|
|
54
|
+
### API Contracts (api-guardian)
|
|
55
|
+
BREAKING: [list]
|
|
56
|
+
WARN: [list]
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
TOTAL: X critical, Y high, Z medium
|
|
60
|
+
RECOMMENDATION: [ship / fix critical first / block]
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
6. After report: "Which finding do you want to fix first?"
|
|
64
|
+
|
|
65
|
+
## Severity Levels
|
|
66
|
+
|
|
67
|
+
| Level | Meaning | Action |
|
|
68
|
+
|---|---|---|
|
|
69
|
+
| CRITICAL | Security vulnerability, data loss, production breakage | Block — fix before merge |
|
|
70
|
+
| HIGH | Bug, broken contract, significant perf regression | Fix before shipping |
|
|
71
|
+
| MEDIUM | Maintainability debt, minor perf, code smell | Fix when convenient |
|
|
72
|
+
| LOW | Style, suggestion | Optional |
|
|
73
|
+
|
|
74
|
+
## When to Use
|
|
75
|
+
|
|
76
|
+
- Before any major PR merge
|
|
77
|
+
- Pre-release audit
|
|
78
|
+
- Onboarding to an unfamiliar codebase (run `/team-review` to get the full picture fast)
|
|
79
|
+
- After a large refactor
|
|
80
|
+
- Monthly health check on long-running projects
|
|
81
|
+
|
|
82
|
+
## Time and Token Efficiency
|
|
83
|
+
|
|
84
|
+
Sequential audit (4 agents one by one): ~40–60 minutes, full context per agent.
|
|
85
|
+
`/team-review` parallel: ~10–15 minutes, narrow focused context per agent.
|
|
86
|
+
System prompt cached across all agents → each pays 10% on that prefix.
|
|
87
|
+
|
|
88
|
+
## Arguments
|
|
89
|
+
|
|
90
|
+
$ARGUMENTS
|
package/hooks/hooks.json
CHANGED
|
@@ -168,6 +168,19 @@
|
|
|
168
168
|
}
|
|
169
169
|
],
|
|
170
170
|
"SessionStart": [
|
|
171
|
+
{
|
|
172
|
+
"matcher": "*",
|
|
173
|
+
"hooks": [
|
|
174
|
+
{
|
|
175
|
+
"type": "command",
|
|
176
|
+
"command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/memory/read-lessons.js\"",
|
|
177
|
+
"async": false,
|
|
178
|
+
"timeout": 4
|
|
179
|
+
}
|
|
180
|
+
],
|
|
181
|
+
"description": "Kodelyth ECC: inject project lessons (tasks/lessons.md) and project DNA as hard rules at session start",
|
|
182
|
+
"id": "kodelyth:session:start:read-lessons"
|
|
183
|
+
},
|
|
171
184
|
{
|
|
172
185
|
"matcher": "*",
|
|
173
186
|
"hooks": [
|
|
@@ -340,6 +353,19 @@
|
|
|
340
353
|
}
|
|
341
354
|
],
|
|
342
355
|
"Stop": [
|
|
356
|
+
{
|
|
357
|
+
"matcher": "*",
|
|
358
|
+
"hooks": [
|
|
359
|
+
{
|
|
360
|
+
"type": "command",
|
|
361
|
+
"command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/memory/capture-correction.js\"",
|
|
362
|
+
"async": true,
|
|
363
|
+
"timeout": 8
|
|
364
|
+
}
|
|
365
|
+
],
|
|
366
|
+
"description": "Kodelyth ECC: detect user corrections in session and encode them as hard rules to tasks/lessons.md (Self-Improvement Loop)",
|
|
367
|
+
"id": "kodelyth:stop:capture-correction"
|
|
368
|
+
},
|
|
343
369
|
{
|
|
344
370
|
"matcher": "*",
|
|
345
371
|
"hooks": [
|
|
@@ -375,7 +401,7 @@
|
|
|
375
401
|
"timeout": 300
|
|
376
402
|
}
|
|
377
403
|
],
|
|
378
|
-
"description": "Batch format (Biome/Prettier) and typecheck (tsc) all JS/TS files edited this response
|
|
404
|
+
"description": "Batch format (Biome/Prettier) and typecheck (tsc) all JS/TS files edited this response \u2014 runs once at Stop instead of after every Edit",
|
|
379
405
|
"id": "stop:format-typecheck"
|
|
380
406
|
},
|
|
381
407
|
{
|
|
@@ -458,4 +484,4 @@
|
|
|
458
484
|
}
|
|
459
485
|
]
|
|
460
486
|
}
|
|
461
|
-
}
|
|
487
|
+
}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// =============================================================================
|
|
3
|
+
// Kodelyth ECC — Correction Capture Hook (Stop)
|
|
4
|
+
//
|
|
5
|
+
// Runs at the end of every Claude Code session. Scans the session JSONL for
|
|
6
|
+
// user messages that contain corrections (e.g. "no don't", "use X instead",
|
|
7
|
+
// "stop doing Y", "wrong approach"). Extracts them as hard rules and appends
|
|
8
|
+
// them to tasks/lessons.md in the project root.
|
|
9
|
+
//
|
|
10
|
+
// This is the engine behind the Self-Improvement Loop:
|
|
11
|
+
// User corrects Claude → rule encoded → next session it doesn't repeat it
|
|
12
|
+
//
|
|
13
|
+
// Output contract: always pass stdin through to stdout. Never block a session.
|
|
14
|
+
// =============================================================================
|
|
15
|
+
|
|
16
|
+
'use strict';
|
|
17
|
+
|
|
18
|
+
const fs = require('fs');
|
|
19
|
+
const path = require('path');
|
|
20
|
+
|
|
21
|
+
// ── Correction signal patterns ─────────────────────────────────────────────
|
|
22
|
+
const CORRECTION_SIGNALS = [
|
|
23
|
+
/\bno[,.]?\s+(don'?t|do not|never|stop|that'?s)/i,
|
|
24
|
+
/\bthat'?s?\s+(wrong|incorrect|not right|not what I|not how I)/i,
|
|
25
|
+
/\b(don'?t|do not|never)\s+(do that|use that|write that|add that|put that)/i,
|
|
26
|
+
/\b(stop|avoid)\s+(doing|using|writing|adding|calling)/i,
|
|
27
|
+
/\binstead[,\s]\s*(use|do|write|call|import|prefer)/i,
|
|
28
|
+
/\b(wrong approach|bad approach|hacky|not the right way|not how we do)/i,
|
|
29
|
+
/\b(I said|I told you|I asked you)\s+(not to|to not|don'?t|to use|to avoid)/i,
|
|
30
|
+
/\b(always|never)\s+(use|do|write|prefer|avoid|import|call)\b/i,
|
|
31
|
+
/\buse\s+\w[\w-]*\s+(not|instead of|rather than)\s+\w/i,
|
|
32
|
+
/\b(we use|we prefer|we don'?t use|we never|we always)\b/i,
|
|
33
|
+
/\b(please don'?t|please use|please avoid|please stop)\b/i,
|
|
34
|
+
/\bthat'?s not (what|how|the way)/i,
|
|
35
|
+
];
|
|
36
|
+
|
|
37
|
+
// ── Messages that look like corrections but are questions ──────────────────
|
|
38
|
+
const EXCLUDE_PATTERNS = [
|
|
39
|
+
/\?$/,
|
|
40
|
+
/^(what|how|why|when|where|which|who|can you|could you|would you|should I)/i,
|
|
41
|
+
];
|
|
42
|
+
|
|
43
|
+
// ── Minimum message length to bother with ─────────────────────────────────
|
|
44
|
+
const MIN_LEN = 8;
|
|
45
|
+
|
|
46
|
+
// ── Entry point ───────────────────────────────────────────────────────────
|
|
47
|
+
let raw = '';
|
|
48
|
+
process.stdin.setEncoding('utf8');
|
|
49
|
+
process.stdin.on('data', chunk => { raw += chunk; });
|
|
50
|
+
process.stdin.on('end', run);
|
|
51
|
+
setTimeout(() => { if (!process.stdin.readableEnded) run(); }, 150);
|
|
52
|
+
|
|
53
|
+
function run() {
|
|
54
|
+
// Always pass stdin through — never block a session
|
|
55
|
+
if (raw) process.stdout.write(raw);
|
|
56
|
+
|
|
57
|
+
try {
|
|
58
|
+
const payload = raw ? JSON.parse(raw) : {};
|
|
59
|
+
const sessionJsonl = payload.session_path
|
|
60
|
+
|| payload.transcript_path
|
|
61
|
+
|| findLatestSession(payload.cwd || process.cwd());
|
|
62
|
+
|
|
63
|
+
if (!sessionJsonl || !fs.existsSync(sessionJsonl)) return;
|
|
64
|
+
|
|
65
|
+
const corrections = extractCorrections(sessionJsonl);
|
|
66
|
+
if (corrections.length === 0) return;
|
|
67
|
+
|
|
68
|
+
writeToLessons(corrections, payload.cwd || process.cwd());
|
|
69
|
+
} catch (err) {
|
|
70
|
+
process.stderr.write(`[ecc:correction-capture] ${err.message}\n`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// ── Extract corrections from session JSONL ─────────────────────────────────
|
|
75
|
+
function extractCorrections(sessionJsonl) {
|
|
76
|
+
const lines = fs.readFileSync(sessionJsonl, 'utf8').split('\n').filter(Boolean);
|
|
77
|
+
const corrections = [];
|
|
78
|
+
|
|
79
|
+
for (const line of lines) {
|
|
80
|
+
let event;
|
|
81
|
+
try { event = JSON.parse(line); } catch { continue; }
|
|
82
|
+
|
|
83
|
+
// Only process user turns
|
|
84
|
+
if (event.type !== 'user') continue;
|
|
85
|
+
|
|
86
|
+
const text = extractText(event);
|
|
87
|
+
if (!text || text.length < MIN_LEN) continue;
|
|
88
|
+
|
|
89
|
+
// Skip if it looks like a question
|
|
90
|
+
if (EXCLUDE_PATTERNS.some(p => p.test(text.trim()))) continue;
|
|
91
|
+
|
|
92
|
+
// Check for correction signals
|
|
93
|
+
if (!CORRECTION_SIGNALS.some(p => p.test(text))) continue;
|
|
94
|
+
|
|
95
|
+
// Clean up and cap length
|
|
96
|
+
const cleaned = text.trim().replace(/\s+/g, ' ').slice(0, 300);
|
|
97
|
+
corrections.push(cleaned);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Deduplicate
|
|
101
|
+
return [...new Set(corrections)];
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// ── Pull plain text from an event ─────────────────────────────────────────
|
|
105
|
+
function extractText(event) {
|
|
106
|
+
const content = event.message?.content ?? event.content ?? '';
|
|
107
|
+
if (typeof content === 'string') return content;
|
|
108
|
+
if (Array.isArray(content)) {
|
|
109
|
+
return content
|
|
110
|
+
.filter(b => b.type === 'text')
|
|
111
|
+
.map(b => b.text || '')
|
|
112
|
+
.join(' ')
|
|
113
|
+
.trim();
|
|
114
|
+
}
|
|
115
|
+
return '';
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// ── Write lessons to tasks/lessons.md ─────────────────────────────────────
|
|
119
|
+
function writeToLessons(corrections, cwd) {
|
|
120
|
+
const tasksDir = path.join(cwd, 'tasks');
|
|
121
|
+
const lessonsFile = path.join(tasksDir, 'lessons.md');
|
|
122
|
+
|
|
123
|
+
try {
|
|
124
|
+
fs.mkdirSync(tasksDir, { recursive: true });
|
|
125
|
+
|
|
126
|
+
const isNew = !fs.existsSync(lessonsFile);
|
|
127
|
+
const date = new Date().toISOString().split('T')[0];
|
|
128
|
+
const project = path.basename(cwd);
|
|
129
|
+
|
|
130
|
+
let header = '';
|
|
131
|
+
if (isNew) {
|
|
132
|
+
header = [
|
|
133
|
+
'# Claude Lessons',
|
|
134
|
+
'',
|
|
135
|
+
`Project: **${project}**`,
|
|
136
|
+
'',
|
|
137
|
+
'Auto-generated by Kodelyth ECC. Each entry is a rule Claude learned from a correction.',
|
|
138
|
+
'Edit freely — add, remove, reword. These are YOUR rules.',
|
|
139
|
+
'',
|
|
140
|
+
'---',
|
|
141
|
+
'',
|
|
142
|
+
].join('\n');
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const block = [
|
|
146
|
+
`## ${date}`,
|
|
147
|
+
'',
|
|
148
|
+
...corrections.map(c => `- ${c}`),
|
|
149
|
+
'',
|
|
150
|
+
].join('\n');
|
|
151
|
+
|
|
152
|
+
fs.appendFileSync(lessonsFile, header + block, 'utf8');
|
|
153
|
+
|
|
154
|
+
process.stderr.write(
|
|
155
|
+
`[ecc:correction-capture] ${corrections.length} lesson(s) written to tasks/lessons.md\n`
|
|
156
|
+
);
|
|
157
|
+
} catch (err) {
|
|
158
|
+
process.stderr.write(`[ecc:correction-capture] Could not write lessons: ${err.message}\n`);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// ── Find the latest session JSONL for this project ────────────────────────
|
|
163
|
+
function findLatestSession(cwd) {
|
|
164
|
+
try {
|
|
165
|
+
const os = require('os');
|
|
166
|
+
const projectsDir = path.join(os.homedir(), '.claude', 'projects');
|
|
167
|
+
if (!fs.existsSync(projectsDir)) return null;
|
|
168
|
+
|
|
169
|
+
const encoded = cwd.replace(/\//g, '-');
|
|
170
|
+
const dirs = fs.readdirSync(projectsDir)
|
|
171
|
+
.filter(d => encoded.endsWith(d.slice(-20)) || d.endsWith(encoded.slice(-30)));
|
|
172
|
+
|
|
173
|
+
if (dirs.length === 0) return null;
|
|
174
|
+
|
|
175
|
+
const projectDir = path.join(projectsDir, dirs[0]);
|
|
176
|
+
const sessions = fs.readdirSync(projectDir)
|
|
177
|
+
.filter(f => f.endsWith('.jsonl'))
|
|
178
|
+
.map(f => ({ f, mtime: fs.statSync(path.join(projectDir, f)).mtimeMs }))
|
|
179
|
+
.sort((a, b) => b.mtime - a.mtime);
|
|
180
|
+
|
|
181
|
+
return sessions[0] ? path.join(projectDir, sessions[0].f) : null;
|
|
182
|
+
} catch {
|
|
183
|
+
return null;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// =============================================================================
|
|
3
|
+
// Kodelyth ECC — Lessons + Project DNA Hook (SessionStart)
|
|
4
|
+
//
|
|
5
|
+
// Runs at the start of every Claude Code session. Does two things:
|
|
6
|
+
//
|
|
7
|
+
// 1. LESSONS: Reads tasks/lessons.md from the project root (if it exists)
|
|
8
|
+
// and injects the encoded rules as high-priority context. These are
|
|
9
|
+
// corrections the user made in past sessions — hard rules, not soft
|
|
10
|
+
// suggestions. Claude MUST follow them for this session.
|
|
11
|
+
//
|
|
12
|
+
// 2. PROJECT DNA: Detects the tech stack, package manager, and key
|
|
13
|
+
// conventions from the project root (package.json, go.mod, Cargo.toml,
|
|
14
|
+
// etc.) and injects a concise project brief so Claude doesn't need to
|
|
15
|
+
// re-discover basics each session.
|
|
16
|
+
//
|
|
17
|
+
// Output contract: emit { additionalContext: "..." } to stdout.
|
|
18
|
+
// Never block a session — exit 0 even on any error.
|
|
19
|
+
// =============================================================================
|
|
20
|
+
|
|
21
|
+
'use strict';
|
|
22
|
+
|
|
23
|
+
const fs = require('fs');
|
|
24
|
+
const path = require('path');
|
|
25
|
+
|
|
26
|
+
let raw = '';
|
|
27
|
+
process.stdin.setEncoding('utf8');
|
|
28
|
+
process.stdin.on('data', chunk => { raw += chunk; });
|
|
29
|
+
process.stdin.on('end', run);
|
|
30
|
+
setTimeout(() => { if (!process.stdin.readableEnded) run(); }, 150);
|
|
31
|
+
|
|
32
|
+
function run() {
|
|
33
|
+
try {
|
|
34
|
+
const payload = raw ? JSON.parse(raw) : {};
|
|
35
|
+
const projectRoot = payload.cwd || payload.project_root || process.cwd();
|
|
36
|
+
|
|
37
|
+
const parts = [];
|
|
38
|
+
|
|
39
|
+
const lessons = readLessons(projectRoot);
|
|
40
|
+
if (lessons) parts.push(lessons);
|
|
41
|
+
|
|
42
|
+
const dna = buildProjectDNA(projectRoot);
|
|
43
|
+
if (dna) parts.push(dna);
|
|
44
|
+
|
|
45
|
+
if (parts.length === 0) {
|
|
46
|
+
process.exit(0);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
process.stdout.write(JSON.stringify({
|
|
50
|
+
additionalContext: parts.join('\n\n---\n\n'),
|
|
51
|
+
meta: { source: 'kodelyth-ecc:read-lessons', hasLessons: !!lessons, hasDNA: !!dna },
|
|
52
|
+
}));
|
|
53
|
+
process.exit(0);
|
|
54
|
+
} catch (err) {
|
|
55
|
+
process.stderr.write(`[ecc:read-lessons] ${err.message}\n`);
|
|
56
|
+
process.exit(0);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// ── Read tasks/lessons.md and format as hard rules ────────────────────────
|
|
61
|
+
function readLessons(projectRoot) {
|
|
62
|
+
const lessonsFile = path.join(projectRoot, 'tasks', 'lessons.md');
|
|
63
|
+
if (!fs.existsSync(lessonsFile)) return null;
|
|
64
|
+
|
|
65
|
+
const content = fs.readFileSync(lessonsFile, 'utf8').trim();
|
|
66
|
+
if (!content) return null;
|
|
67
|
+
|
|
68
|
+
// Extract all bullet rules across all dated sections
|
|
69
|
+
const rules = content
|
|
70
|
+
.split('\n')
|
|
71
|
+
.filter(line => line.match(/^-\s+.{5,}/))
|
|
72
|
+
.map(line => line.trim())
|
|
73
|
+
.filter(Boolean);
|
|
74
|
+
|
|
75
|
+
if (rules.length === 0) return null;
|
|
76
|
+
|
|
77
|
+
return [
|
|
78
|
+
'## PROJECT LESSONS — HARD RULES (from past corrections)',
|
|
79
|
+
'',
|
|
80
|
+
'These rules were encoded from corrections made in previous sessions.',
|
|
81
|
+
'You MUST follow them for this entire session. They override generic defaults.',
|
|
82
|
+
'',
|
|
83
|
+
rules.join('\n'),
|
|
84
|
+
].join('\n');
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// ── Detect project tech stack and conventions ─────────────────────────────
|
|
88
|
+
function buildProjectDNA(projectRoot) {
|
|
89
|
+
const facts = [];
|
|
90
|
+
|
|
91
|
+
// Node / JS / TS
|
|
92
|
+
const pkgPath = path.join(projectRoot, 'package.json');
|
|
93
|
+
if (fs.existsSync(pkgPath)) {
|
|
94
|
+
try {
|
|
95
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
96
|
+
const name = pkg.name || path.basename(projectRoot);
|
|
97
|
+
facts.push(`Project: ${name} (Node.js / JavaScript)`);
|
|
98
|
+
|
|
99
|
+
// Package manager
|
|
100
|
+
if (fs.existsSync(path.join(projectRoot, 'pnpm-lock.yaml'))) {
|
|
101
|
+
facts.push('Package manager: pnpm');
|
|
102
|
+
} else if (fs.existsSync(path.join(projectRoot, 'bun.lockb')) || fs.existsSync(path.join(projectRoot, 'bun.lock'))) {
|
|
103
|
+
facts.push('Package manager: bun');
|
|
104
|
+
} else if (fs.existsSync(path.join(projectRoot, 'yarn.lock'))) {
|
|
105
|
+
facts.push('Package manager: yarn');
|
|
106
|
+
} else {
|
|
107
|
+
facts.push('Package manager: npm');
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Framework detection
|
|
111
|
+
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
112
|
+
const frameworks = [];
|
|
113
|
+
if (deps.next) frameworks.push(`Next.js ${deps.next}`);
|
|
114
|
+
if (deps.react) frameworks.push(`React ${deps.react}`);
|
|
115
|
+
if (deps.vue) frameworks.push(`Vue ${deps.vue}`);
|
|
116
|
+
if (deps.svelte) frameworks.push(`Svelte`);
|
|
117
|
+
if (deps.express) frameworks.push(`Express ${deps.express}`);
|
|
118
|
+
if (deps.fastify) frameworks.push(`Fastify`);
|
|
119
|
+
if (deps.nestjs || deps['@nestjs/core']) frameworks.push('NestJS');
|
|
120
|
+
if (deps.typescript || deps['ts-node']) frameworks.push('TypeScript');
|
|
121
|
+
if (deps.prisma || deps['@prisma/client']) frameworks.push('Prisma');
|
|
122
|
+
if (deps.drizzle) frameworks.push('Drizzle ORM');
|
|
123
|
+
if (frameworks.length > 0) facts.push(`Stack: ${frameworks.join(', ')}`);
|
|
124
|
+
|
|
125
|
+
// Test runner
|
|
126
|
+
if (deps.jest) facts.push('Test runner: Jest');
|
|
127
|
+
else if (deps.vitest) facts.push('Test runner: Vitest');
|
|
128
|
+
else if (deps.mocha) facts.push('Test runner: Mocha');
|
|
129
|
+
} catch {}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Go
|
|
133
|
+
const goModPath = path.join(projectRoot, 'go.mod');
|
|
134
|
+
if (fs.existsSync(goModPath)) {
|
|
135
|
+
try {
|
|
136
|
+
const goMod = fs.readFileSync(goModPath, 'utf8');
|
|
137
|
+
const moduleLine = goMod.match(/^module (.+)/m);
|
|
138
|
+
const goVersion = goMod.match(/^go (.+)/m);
|
|
139
|
+
facts.push(`Project: ${moduleLine?.[1] || 'Go module'} (Go${goVersion ? ' ' + goVersion[1] : ''})`);
|
|
140
|
+
} catch {}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Rust
|
|
144
|
+
const cargoPath = path.join(projectRoot, 'Cargo.toml');
|
|
145
|
+
if (fs.existsSync(cargoPath)) {
|
|
146
|
+
try {
|
|
147
|
+
const cargo = fs.readFileSync(cargoPath, 'utf8');
|
|
148
|
+
const name = cargo.match(/^name\s*=\s*"(.+)"/m);
|
|
149
|
+
facts.push(`Project: ${name?.[1] || 'Rust crate'} (Rust / Cargo)`);
|
|
150
|
+
} catch {}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Python
|
|
154
|
+
const reqPath = path.join(projectRoot, 'requirements.txt');
|
|
155
|
+
const pyprojPath = path.join(projectRoot, 'pyproject.toml');
|
|
156
|
+
if (fs.existsSync(reqPath) || fs.existsSync(pyprojPath)) {
|
|
157
|
+
facts.push('Language: Python');
|
|
158
|
+
if (fs.existsSync(path.join(projectRoot, 'poetry.lock'))) facts.push('Package manager: Poetry');
|
|
159
|
+
else if (fs.existsSync(path.join(projectRoot, 'Pipfile.lock'))) facts.push('Package manager: Pipenv');
|
|
160
|
+
else facts.push('Package manager: pip');
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Java / Kotlin
|
|
164
|
+
if (fs.existsSync(path.join(projectRoot, 'build.gradle')) || fs.existsSync(path.join(projectRoot, 'build.gradle.kts'))) {
|
|
165
|
+
facts.push('Build: Gradle (Java / Kotlin)');
|
|
166
|
+
}
|
|
167
|
+
if (fs.existsSync(path.join(projectRoot, 'pom.xml'))) {
|
|
168
|
+
facts.push('Build: Maven (Java)');
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Existing tasks/todo.md
|
|
172
|
+
const todoPath = path.join(projectRoot, 'tasks', 'todo.md');
|
|
173
|
+
if (fs.existsSync(todoPath)) {
|
|
174
|
+
const todo = fs.readFileSync(todoPath, 'utf8').trim();
|
|
175
|
+
const openItems = todo.split('\n').filter(l => l.match(/^-\s*\[ \]/)).slice(0, 5);
|
|
176
|
+
if (openItems.length > 0) {
|
|
177
|
+
facts.push('');
|
|
178
|
+
facts.push('Open tasks (from tasks/todo.md):');
|
|
179
|
+
openItems.forEach(item => facts.push(item.trim()));
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if (facts.length === 0) return null;
|
|
184
|
+
|
|
185
|
+
return [
|
|
186
|
+
'## PROJECT DNA (auto-detected)',
|
|
187
|
+
'',
|
|
188
|
+
facts.join('\n'),
|
|
189
|
+
].join('\n');
|
|
190
|
+
}
|
package/install.sh
CHANGED
|
@@ -47,7 +47,7 @@ echo -e "${RED}${BOLD} ║ DANGER LEVEL: GOD TIER · NOT FOR JUNIOR DEV
|
|
|
47
47
|
echo -e "${RED}${BOLD} ╚══════════════════════════════════════════════════════════════╝${RESET}"
|
|
48
48
|
echo ""
|
|
49
49
|
echo -e "${BOLD} Kodelyth ECC — The most dangerous AI coding toolkit on the planet${RESET}"
|
|
50
|
-
echo -e "${CYAN}
|
|
50
|
+
echo -e "${CYAN} 61 specialist agents · 188 skills · 80 commands · 20+ hooks · intent routing · compound memory${RESET}"
|
|
51
51
|
echo -e "${CYAN} Any language · Any framework · Any scale · 300B-level quality${RESET}"
|
|
52
52
|
echo ""
|
|
53
53
|
echo -e " github.com/sifxprime/kodelyth-ecc"
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kodelyth-ecc",
|
|
3
|
-
"version": "1.5.
|
|
4
|
-
"description": "Production-grade AI coding toolkit
|
|
3
|
+
"version": "1.5.2",
|
|
4
|
+
"description": "Production-grade AI coding toolkit \u2014 61 agents, 188 skills, 80 commands, god-tier intent routing, local self-learning memory with auto chat detection, incident response, load testing. Works with Claude Code, Windsurf, Cursor, Codex, Antigravity, and OpenCode.",
|
|
5
5
|
"author": "Kodelyth <github.com/sifxprime>",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
@@ -24,7 +24,11 @@
|
|
|
24
24
|
"auto-recall",
|
|
25
25
|
"incident-response",
|
|
26
26
|
"load-testing",
|
|
27
|
-
"kodelyth"
|
|
27
|
+
"kodelyth",
|
|
28
|
+
"image-generation",
|
|
29
|
+
"parallel-agents",
|
|
30
|
+
"multi-agent",
|
|
31
|
+
"project-launch"
|
|
28
32
|
],
|
|
29
33
|
"bin": {
|
|
30
34
|
"kodelyth-ecc": "bin/kodelyth-ecc.js"
|
|
@@ -313,11 +313,66 @@ Use the chain: `forker` → `sanitizer` → `packager`.
|
|
|
313
313
|
| `load-tester` (bottleneck found) | `performance-optimizer` to fix the code |
|
|
314
314
|
| `incident-commander` (incident resolved) | `debug-detective` for deeper root cause, then postmortem |
|
|
315
315
|
|
|
316
|
+
### `image-architect` — Image and visual generation
|
|
317
|
+
|
|
318
|
+
Trigger if the user wants any visual asset generated:
|
|
319
|
+
|
|
320
|
+
| Signal | Examples |
|
|
321
|
+
|---|---|
|
|
322
|
+
| Hero / banner | "generate a hero image", "I need a banner", "create a header image" |
|
|
323
|
+
| Social / OG | "OG image", "social preview", "GitHub card", "Twitter card", "Facebook post image" |
|
|
324
|
+
| Thumbnails | "product thumbnail", "feature image", "cover image" |
|
|
325
|
+
| Landing page | "visuals for landing page", "marketing images", "I need graphics" |
|
|
326
|
+
| General | "generate an image", "create artwork", "I need a picture", "make a visual" |
|
|
327
|
+
|
|
328
|
+
Platform routing inside `image-architect`:
|
|
329
|
+
- Google Antigravity → Gemini Imagen 3 (native, no key needed)
|
|
330
|
+
- Codex CLI → DALL-E 3 (native, no key needed)
|
|
331
|
+
- Claude Code → fal.ai MCP → SVG fallback
|
|
332
|
+
- Windsurf / Cursor → native model image gen → fal.ai → SVG fallback
|
|
333
|
+
|
|
334
|
+
### `/project-launch` — New project parallel founding team
|
|
335
|
+
|
|
336
|
+
Trigger when starting something new and needing full team analysis at once:
|
|
337
|
+
|
|
338
|
+
| Signal | Examples |
|
|
339
|
+
|---|---|
|
|
340
|
+
| New project | "I'm starting a new project", "planning a new app", "building from scratch" |
|
|
341
|
+
| Pre-code analysis | "analyse this before I start coding", "what should I think about first" |
|
|
342
|
+
| Multiple concerns at once | Architecture + security + UX + tests all in one ask |
|
|
343
|
+
|
|
344
|
+
Route to `/project-launch` — fires `architect` + `pair-programmer` + `security-reviewer` + `tdd-guide` + `ux-reviewer` simultaneously.
|
|
345
|
+
|
|
346
|
+
### `/team-review` — Existing project parallel full audit
|
|
347
|
+
|
|
348
|
+
Trigger when the user wants comprehensive review of existing code:
|
|
349
|
+
|
|
350
|
+
| Signal | Examples |
|
|
351
|
+
|---|---|
|
|
352
|
+
| Full audit | "full audit of my codebase", "review everything", "complete code review" |
|
|
353
|
+
| Pre-release | "before I ship", "is this ready to release", "pre-launch review" |
|
|
354
|
+
| Parallel review | "check security AND performance AND code quality at once" |
|
|
355
|
+
|
|
356
|
+
Route to `/team-review` — fires `code-reviewer` + `security-reviewer` + `performance-optimizer` + `api-guardian` simultaneously.
|
|
357
|
+
|
|
358
|
+
### `/lessons` — Project lessons management
|
|
359
|
+
|
|
360
|
+
Trigger when the user wants to work with project-level learned rules:
|
|
361
|
+
|
|
362
|
+
| Signal | Examples |
|
|
363
|
+
|---|---|
|
|
364
|
+
| Load lessons | "load my lessons", "what rules do we have for this project", "apply lessons" |
|
|
365
|
+
| Save corrections | "save what I corrected", "encode today's corrections", "write to lessons" |
|
|
366
|
+
| Add a rule | "remember we always use pnpm", "add a rule: never use var" |
|
|
367
|
+
|
|
316
368
|
### Parallel suggestions
|
|
317
369
|
|
|
318
370
|
If the user has a multi-faceted concern, name the parallel agents:
|
|
319
371
|
- "I'm building a payment endpoint" → `pair-programmer` + `security-reviewer` + `api-guardian`
|
|
320
372
|
- "Refactoring the auth module" → `refactor-cleaner` + `security-reviewer` + `tdd-guide`
|
|
373
|
+
- "Starting a new project" → `/project-launch`
|
|
374
|
+
- "Is this ready to ship?" → `/team-review`
|
|
375
|
+
- "I need visuals for my landing page" → `image-architect`
|
|
321
376
|
|
|
322
377
|
---
|
|
323
378
|
|
|
@@ -353,6 +408,12 @@ If the user has a multi-faceted concern, name the parallel agents:
|
|
|
353
408
|
| "will this hold under 10k concurrent users" | `load-tester` | Capacity / load testing question |
|
|
354
409
|
| "run a load test before launch" | `load-tester` | Pre-launch load validation |
|
|
355
410
|
| "postmortem for yesterday's outage" | `incident-commander` | Postmortem workflow |
|
|
411
|
+
| "generate a hero image for my landing page" | `image-architect` | Image generation request |
|
|
412
|
+
| "I need an OG image / GitHub social card" | `image-architect` | Social preview asset |
|
|
413
|
+
| "create visuals for the app" | `image-architect` | Marketing asset generation |
|
|
414
|
+
| "I'm starting a new SaaS project, help me plan it" | `/project-launch` | New project, all concerns at once |
|
|
415
|
+
| "full audit before we ship v2" | `/team-review` | Pre-release parallel audit |
|
|
416
|
+
| "load my project lessons" | `/lessons` | Cross-platform lesson loading |
|
|
356
417
|
|
|
357
418
|
---
|
|
358
419
|
|