kodelyth-ecc 1.5.9 → 1.7.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.
Files changed (123) hide show
  1. package/.github/workflows/publish.yml +19 -0
  2. package/AGENTS.md +1 -1
  3. package/CHANGELOG.md +455 -0
  4. package/CLAUDE.md +48 -16
  5. package/README.md +265 -81
  6. package/VERSION +1 -1
  7. package/actions/ecc-review/README.md +243 -0
  8. package/actions/ecc-review/action.yml +158 -0
  9. package/actions/ecc-review/post-comment.js +171 -0
  10. package/actions/ecc-review/run-review.js +285 -0
  11. package/agents/backdoor-hunter.md +260 -0
  12. package/agents/chaos-engineer.md +251 -0
  13. package/agents/code-stealer-detector.md +228 -0
  14. package/agents/jailbreak-tester.md +222 -0
  15. package/agents/license-violation-finder.md +212 -0
  16. package/agents/prompt-injection-hunter.md +126 -0
  17. package/agents/secret-hunter.md +209 -0
  18. package/agents/supply-chain-auditor.md +195 -0
  19. package/bin/kodelyth-ecc.js +875 -1
  20. package/bundles/enterprise.md +172 -0
  21. package/bundles/indie-hacker.md +106 -0
  22. package/bundles/red-team.md +138 -0
  23. package/cat +0 -0
  24. package/commands/dashboard.md +67 -0
  25. package/commands/devil-mode.md +121 -0
  26. package/commands/memory-evolve.md +71 -0
  27. package/commands/replay.md +61 -0
  28. package/commands/route-model.md +48 -0
  29. package/commands/swarm.md +68 -0
  30. package/commands/verify-supply-chain.md +59 -0
  31. package/docs/dashboard.md +211 -0
  32. package/docs/evolve.md +303 -0
  33. package/docs/mcp-clients.md +167 -0
  34. package/docs/mcp.md +178 -0
  35. package/docs/replay.md +244 -0
  36. package/docs/supply-chain.md +207 -0
  37. package/docs/swarm.md +243 -0
  38. package/hooks/hooks.json +52 -0
  39. package/hooks/memory/auto-recall.js +29 -1
  40. package/hooks/safety/README.md +124 -0
  41. package/hooks/safety/lib/patterns.js +179 -0
  42. package/hooks/safety/prompt-injection-guard.js +179 -0
  43. package/hooks/safety/token-budget.js +229 -0
  44. package/install.ps1 +199 -2
  45. package/install.sh +286 -4
  46. package/package.json +30 -4
  47. package/rules/common/agent-intent-routing.md +182 -0
  48. package/rules/common/cost-aware-model-routing.md +152 -0
  49. package/scripts/dashboard/data.js +353 -0
  50. package/scripts/dashboard/server.js +324 -0
  51. package/scripts/dashboard/static/index.html +645 -0
  52. package/scripts/evolve/analyze.js +303 -0
  53. package/scripts/evolve/proposals.js +162 -0
  54. package/scripts/evolve/stats.js +219 -0
  55. package/scripts/mcp/catalog.js +244 -0
  56. package/scripts/mcp/client.js +181 -0
  57. package/scripts/mcp/prompts.js +133 -0
  58. package/scripts/mcp/resources.js +94 -0
  59. package/scripts/mcp/server.js +153 -0
  60. package/scripts/mcp/tools.js +465 -0
  61. package/scripts/replay/bundle.js +191 -0
  62. package/scripts/replay/replay.js +107 -0
  63. package/scripts/router/classify.js +232 -0
  64. package/scripts/supply-chain/manifest.js +154 -0
  65. package/scripts/supply-chain/sbom.js +202 -0
  66. package/scripts/supply-chain/verify.js +102 -0
  67. package/scripts/swarm/build-plan.js +193 -0
  68. package/skills/cost-aware-model-routing/SKILL.md +153 -0
  69. package/skills/kodelyth-quickstart/SKILL.md +7 -0
  70. package/skills/observability-dashboard/SKILL.md +119 -0
  71. package/skills/self-evolving-memory/SKILL.md +175 -0
  72. package/skills/session-replay/SKILL.md +199 -0
  73. package/skills/supply-chain-verification/SKILL.md +201 -0
  74. package/skills/swarm-orchestrator/SKILL.md +177 -0
  75. package/social/card-install.svg +1 -1
  76. package/social/facebook-group/POST.md +121 -0
  77. package/social/facebook-group/fb-1-3am-debug.png +0 -0
  78. package/social/facebook-group/fb-1-3am-debug.svg +97 -0
  79. package/social/facebook-group/fb-2-cpu-upgrade.png +0 -0
  80. package/social/facebook-group/fb-2-cpu-upgrade.svg +132 -0
  81. package/social/facebook-group/fb-3-before-after.png +0 -0
  82. package/social/facebook-group/fb-3-before-after.svg +94 -0
  83. package/social/facebook-v150.svg +5 -5
  84. package/social/github-social-preview.svg +119 -100
  85. package/social/readme-hero.svg +11 -11
  86. package/social/section-agents.svg +57 -0
  87. package/social/section-author.svg +54 -0
  88. package/social/section-dashboard.svg +59 -0
  89. package/social/section-devil.svg +54 -0
  90. package/social/section-hooks.svg +51 -0
  91. package/social/section-install.svg +42 -0
  92. package/social/section-learning.svg +52 -0
  93. package/social/section-mcp.svg +46 -0
  94. package/social/section-memory.svg +57 -0
  95. package/social/section-parallel.svg +72 -0
  96. package/social/section-routing.svg +51 -0
  97. package/social/x-card-agents-grid.svg +6 -6
  98. package/tests/dashboard/data.test.js +235 -0
  99. package/tests/dashboard/server.test.js +240 -0
  100. package/tests/evolve/analyze.test.js +169 -0
  101. package/tests/evolve/proposals.test.js +173 -0
  102. package/tests/evolve/stats.test.js +159 -0
  103. package/tests/mcp/catalog.test.js +98 -0
  104. package/tests/mcp/client.test.js +109 -0
  105. package/tests/mcp/resources-prompts.test.js +70 -0
  106. package/tests/mcp/tools.test.js +159 -0
  107. package/tests/replay/bundle.test.js +181 -0
  108. package/tests/replay/replay.test.js +131 -0
  109. package/tests/router/classify.test.js +164 -0
  110. package/tests/safety/patterns.test.js +94 -0
  111. package/tests/safety/prompt-injection-guard.test.js +111 -0
  112. package/tests/safety/token-budget.test.js +119 -0
  113. package/tests/supply-chain/manifest.test.js +147 -0
  114. package/tests/supply-chain/sbom.test.js +170 -0
  115. package/tests/supply-chain/verify.test.js +146 -0
  116. package/tests/swarm/build-plan.test.js +188 -0
  117. package/wiki/Agent-Reference.md +58 -7
  118. package/wiki/FAQ.md +204 -7
  119. package/wiki/Home.md +104 -28
  120. package/wiki/Hook-Reference.md +1 -1
  121. package/wiki/Installation-Guide.md +109 -6
  122. package/wiki/Platform-Support.md +239 -25
  123. package/wiki/Skill-Reference.md +101 -6
@@ -0,0 +1,229 @@
1
+ #!/usr/bin/env node
2
+ // =============================================================================
3
+ // Kodelyth ECC — Token Budget Enforcer
4
+ //
5
+ // A safety hook that tracks per-session token usage and blocks new turns once
6
+ // a configurable budget is exceeded. Wires into:
7
+ //
8
+ // - Stop (after each AI response — accumulate usage, write state)
9
+ // - SessionStart (before each new turn — block if budget already exhausted)
10
+ //
11
+ // Token estimation:
12
+ // Hooks don't get authoritative token counts from the platform, so we use
13
+ // a 4-chars-per-token heuristic over the visible transcript path supplied
14
+ // in the Stop payload (transcript_path). On UserPromptSubmit we also count
15
+ // the user message; on PostToolUse we count the tool response.
16
+ //
17
+ // Modes (env var KODELYTH_TOKEN_BUDGET):
18
+ // off — never run (default if unset)
19
+ // warn — exit 0; write usage to stderr; never block
20
+ // <number> — hard budget in tokens (e.g. 200000). Warns at WARN_AT_PCT.
21
+ // Blocks SessionStart once usage >= budget.
22
+ //
23
+ // Optional knobs:
24
+ // KODELYTH_TOKEN_BUDGET_DIR=/custom/path default ~/.kodelyth/safety
25
+ // KODELYTH_TOKEN_BUDGET_WARN=0.7 warn threshold (0-1, default 0.7)
26
+ // KODELYTH_TOKEN_BUDGET_RESET=1 wipe usage and exit (admin op)
27
+ //
28
+ // Always exits 0 on internal errors so the hook never blocks accidentally.
29
+ // =============================================================================
30
+
31
+ 'use strict';
32
+
33
+ const fs = require('fs');
34
+ const os = require('os');
35
+ const path = require('path');
36
+
37
+ const RAW_BUDGET = String(process.env.KODELYTH_TOKEN_BUDGET || 'off').toLowerCase();
38
+ const WARN_PCT = Math.max(0, Math.min(1, Number(process.env.KODELYTH_TOKEN_BUDGET_WARN) || 0.7));
39
+ const RESET = !!process.env.KODELYTH_TOKEN_BUDGET_RESET;
40
+
41
+ const STATE_DIR = process.env.KODELYTH_TOKEN_BUDGET_DIR
42
+ || path.join(os.homedir(), '.kodelyth', 'safety');
43
+
44
+ function safeExit(code) {
45
+ try { process.stdout.write(''); } catch {}
46
+ process.exit(code);
47
+ }
48
+
49
+ function readStdinSync() {
50
+ try {
51
+ const chunks = [];
52
+ const tmp = Buffer.alloc(64 * 1024);
53
+ while (true) {
54
+ let n;
55
+ try { n = fs.readSync(0, tmp, 0, tmp.length, null); }
56
+ catch { break; }
57
+ if (!n) break;
58
+ chunks.push(Buffer.from(tmp.subarray(0, n)));
59
+ }
60
+ return Buffer.concat(chunks).toString('utf8');
61
+ } catch {
62
+ return '';
63
+ }
64
+ }
65
+
66
+ function loadState(sessionId) {
67
+ try {
68
+ const file = path.join(STATE_DIR, `budget-${sessionId}.json`);
69
+ if (!fs.existsSync(file)) return { tokens: 0, turns: 0 };
70
+ return JSON.parse(fs.readFileSync(file, 'utf8'));
71
+ } catch {
72
+ return { tokens: 0, turns: 0 };
73
+ }
74
+ }
75
+
76
+ function saveState(sessionId, state) {
77
+ try {
78
+ fs.mkdirSync(STATE_DIR, { recursive: true });
79
+ const file = path.join(STATE_DIR, `budget-${sessionId}.json`);
80
+ fs.writeFileSync(file, JSON.stringify(state, null, 2));
81
+ } catch { /* never block on persistence */ }
82
+ }
83
+
84
+ function resetState(sessionId) {
85
+ try {
86
+ const file = path.join(STATE_DIR, `budget-${sessionId}.json`);
87
+ if (fs.existsSync(file)) fs.unlinkSync(file);
88
+ } catch {}
89
+ }
90
+
91
+ // ── Token estimation ─────────────────────────────────────────────────────────
92
+ // Rough heuristic — 1 token ≈ 4 characters. Good enough for budget guards.
93
+ function estimateTokensFromChars(s) {
94
+ if (typeof s !== 'string' || !s) return 0;
95
+ return Math.ceil(s.length / 4);
96
+ }
97
+
98
+ function estimateTokensFromTranscript(transcriptPath) {
99
+ if (!transcriptPath || typeof transcriptPath !== 'string') return 0;
100
+ try {
101
+ if (!fs.existsSync(transcriptPath)) return 0;
102
+ const stat = fs.statSync(transcriptPath);
103
+ // Each transcript line is JSON with `text` fields. We approximate by
104
+ // file size (proxy for transcript length); rough but stable.
105
+ return Math.ceil(stat.size / 4);
106
+ } catch {
107
+ return 0;
108
+ }
109
+ }
110
+
111
+ function parseBudget() {
112
+ if (RAW_BUDGET === 'off') return { mode: 'off', limit: 0 };
113
+ if (RAW_BUDGET === 'warn') return { mode: 'warn', limit: 0 };
114
+ const n = Number(RAW_BUDGET);
115
+ if (Number.isFinite(n) && n > 0) return { mode: 'block', limit: Math.floor(n) };
116
+ return { mode: 'off', limit: 0 };
117
+ }
118
+
119
+ // ── Main ─────────────────────────────────────────────────────────────────────
120
+ function main() {
121
+ const cfg = parseBudget();
122
+ if (cfg.mode === 'off') return safeExit(0);
123
+
124
+ let raw = '';
125
+ try { raw = readStdinSync(); } catch { return safeExit(0); }
126
+
127
+ let payload = null;
128
+ try { payload = raw ? JSON.parse(raw) : null; } catch { payload = null; }
129
+
130
+ // Echo stdin so chained hooks still see it.
131
+ if (raw) process.stdout.write(raw);
132
+ if (!payload) return safeExit(0);
133
+
134
+ const sessionId =
135
+ payload.session_id ||
136
+ payload.sessionId ||
137
+ process.env.CLAUDE_SESSION_ID ||
138
+ 'default';
139
+
140
+ if (RESET) {
141
+ resetState(sessionId);
142
+ process.stderr.write(`[Kodelyth Safety] token-budget reset for session ${sessionId}\n`);
143
+ return safeExit(0);
144
+ }
145
+
146
+ const event = payload.hook_event_name || '';
147
+
148
+ // ── SessionStart: pre-check, block if already over ─────────────────────────
149
+ if (/SessionStart/i.test(event)) {
150
+ const state = loadState(sessionId);
151
+ if (cfg.mode === 'block' && state.tokens >= cfg.limit) {
152
+ process.stderr.write(
153
+ `\n[Kodelyth Safety] BLOCKED — session token budget exhausted.\n` +
154
+ ` session=${sessionId}\n` +
155
+ ` used=${state.tokens.toLocaleString()} tokens\n` +
156
+ ` budget=${cfg.limit.toLocaleString()} tokens\n` +
157
+ ` • Reset with KODELYTH_TOKEN_BUDGET_RESET=1.\n` +
158
+ ` • Raise budget via KODELYTH_TOKEN_BUDGET=<larger number>.\n` +
159
+ ` • Disable entirely via KODELYTH_TOKEN_BUDGET=off.\n\n`
160
+ );
161
+ return safeExit(2);
162
+ }
163
+ if (cfg.mode === 'warn' || cfg.mode === 'block') {
164
+ process.stderr.write(
165
+ `[Kodelyth Safety] token-budget — session=${sessionId} ` +
166
+ `used=${state.tokens.toLocaleString()} ` +
167
+ (cfg.mode === 'block' ? `budget=${cfg.limit.toLocaleString()}` : '(warn-only)') +
168
+ `\n`
169
+ );
170
+ }
171
+ return safeExit(0);
172
+ }
173
+
174
+ // ── Stop: accumulate usage from transcript path ────────────────────────────
175
+ if (/Stop/i.test(event) || event === 'PostToolUse' || event === 'UserPromptSubmit' || event === '') {
176
+ const state = loadState(sessionId);
177
+ let added = 0;
178
+ if (typeof payload.prompt === 'string') added += estimateTokensFromChars(payload.prompt);
179
+ if (typeof payload.user_message === 'string') added += estimateTokensFromChars(payload.user_message);
180
+ if (typeof payload.message === 'string') added += estimateTokensFromChars(payload.message);
181
+ if (payload.transcript_path) added = Math.max(added, estimateTokensFromTranscript(payload.transcript_path));
182
+ if (payload.tool_response) {
183
+ try { added += estimateTokensFromChars(JSON.stringify(payload.tool_response)); } catch {}
184
+ }
185
+ if (added > 0) {
186
+ state.tokens = (state.tokens || 0) + added;
187
+ state.turns = (state.turns || 0) + 1;
188
+ state.last_updated = new Date().toISOString();
189
+ saveState(sessionId, state);
190
+ }
191
+
192
+ if (cfg.mode === 'block') {
193
+ const pct = state.tokens / cfg.limit;
194
+ if (pct >= 1) {
195
+ process.stderr.write(
196
+ `\n[Kodelyth Safety] token-budget EXCEEDED — ` +
197
+ `used=${state.tokens.toLocaleString()} budget=${cfg.limit.toLocaleString()}. ` +
198
+ `Next SessionStart will be blocked. Use KODELYTH_TOKEN_BUDGET_RESET=1 to clear.\n`
199
+ );
200
+ } else if (pct >= WARN_PCT) {
201
+ process.stderr.write(
202
+ `[Kodelyth Safety] token-budget at ${(pct * 100).toFixed(0)}% — ` +
203
+ `used=${state.tokens.toLocaleString()} budget=${cfg.limit.toLocaleString()}\n`
204
+ );
205
+ }
206
+ } else {
207
+ process.stderr.write(
208
+ `[Kodelyth Safety] token-budget (warn) — session=${sessionId} ` +
209
+ `used=${state.tokens.toLocaleString()} added=${added.toLocaleString()}\n`
210
+ );
211
+ }
212
+ }
213
+
214
+ return safeExit(0);
215
+ }
216
+
217
+ if (require.main === module) {
218
+ try { main(); } catch { safeExit(0); }
219
+ }
220
+
221
+ module.exports = {
222
+ // Exposed for tests
223
+ estimateTokensFromChars,
224
+ estimateTokensFromTranscript,
225
+ parseBudget,
226
+ loadState,
227
+ saveState,
228
+ resetState,
229
+ };
package/install.ps1 CHANGED
@@ -13,15 +13,42 @@
13
13
 
14
14
  param(
15
15
  [string]$Target = "claude-home",
16
+ [string]$Bundle = "",
16
17
  [string[]]$Languages = @()
17
18
  )
18
19
 
19
20
  $ErrorActionPreference = "Stop"
20
21
 
22
+ # ── Bundle handling (audience-tailored cheat sheets) ─────────────────────────
23
+ if ($Bundle) {
24
+ switch ($Bundle.ToLower()) {
25
+ { $_ -in "indie-hacker","indie" } {
26
+ $Bundle = "indie-hacker"
27
+ $Languages += @("typescript","python")
28
+ Write-Host "Bundle: Indie Hacker -> ship-fast workflow + TS/Python" -ForegroundColor Cyan
29
+ }
30
+ { $_ -in "red-team","redteam","security" } {
31
+ $Bundle = "red-team"
32
+ $Languages += @("typescript","python")
33
+ Write-Host "Bundle: Red Team -> adversarial mindset + devil-mode crew" -ForegroundColor Cyan
34
+ }
35
+ { $_ -in "enterprise","compliance" } {
36
+ $Bundle = "enterprise"
37
+ $Languages += @("typescript","java","python")
38
+ Write-Host "Bundle: Enterprise -> compliance + audit + supply chain" -ForegroundColor Cyan
39
+ }
40
+ default {
41
+ Write-Host "Unknown bundle: $Bundle" -ForegroundColor Red
42
+ Write-Host "Available bundles: indie-hacker, red-team, enterprise"
43
+ exit 1
44
+ }
45
+ }
46
+ }
47
+
21
48
  # ── Banner ────────────────────────────────────────────────────────────────────
22
49
  Write-Host ""
23
50
  Write-Host " Kodelyth ECC — Production-grade AI coding agent toolkit" -ForegroundColor Cyan
24
- Write-Host " 62 agents · 188 skills · 90 commands · 20+ hooks · intent routing · local memory" -ForegroundColor Gray
51
+ Write-Host " 70 agents (8 devil-mode) · 194 skills · 97 commands · 22+ hooks · intent routing · local memory" -ForegroundColor Gray
25
52
  Write-Host ""
26
53
 
27
54
  $ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
@@ -86,9 +113,57 @@ switch ($Target) {
86
113
  $HooksDest = ""
87
114
  $RulesDest = "$Dest\rules"
88
115
  }
116
+ "cline" {
117
+ $Dest = "$(Get-Location)\.clinerules"
118
+ $AgentsDest = ""
119
+ $SkillsDest = ""
120
+ $CommandsDest = ""
121
+ $HooksDest = ""
122
+ $RulesDest = $Dest
123
+ }
124
+ "roocode" {
125
+ $Dest = "$(Get-Location)\.roo"
126
+ $AgentsDest = "$Dest\agents"
127
+ $SkillsDest = "$Dest\skills"
128
+ $CommandsDest = "$Dest\commands"
129
+ $HooksDest = ""
130
+ $RulesDest = "$Dest\rules"
131
+ }
132
+ "aider" {
133
+ $Dest = "$(Get-Location)\.aider-ecc"
134
+ $AgentsDest = "$Dest\agents"
135
+ $SkillsDest = "$Dest\skills"
136
+ $CommandsDest = "$Dest\commands"
137
+ $HooksDest = ""
138
+ $RulesDest = "$Dest\rules"
139
+ }
140
+ "kimi" {
141
+ $Dest = "$(Get-Location)\.kimi"
142
+ $AgentsDest = "$Dest\agents"
143
+ $SkillsDest = "$Dest\skills"
144
+ $CommandsDest = "$Dest\commands"
145
+ $HooksDest = ""
146
+ $RulesDest = "$Dest\rules"
147
+ }
148
+ "gemini-project" {
149
+ $Dest = "$(Get-Location)\.gemini"
150
+ $AgentsDest = "$Dest\agents"
151
+ $SkillsDest = "$Dest\skills"
152
+ $CommandsDest = ""
153
+ $HooksDest = ""
154
+ $RulesDest = "$Dest\rules"
155
+ }
156
+ "gemini-home" {
157
+ $Dest = "$HomeDir\.gemini"
158
+ $AgentsDest = "$Dest\agents"
159
+ $SkillsDest = "$Dest\skills"
160
+ $CommandsDest = ""
161
+ $HooksDest = ""
162
+ $RulesDest = "$Dest\rules"
163
+ }
89
164
  default {
90
165
  Write-Host "Unknown target: $Target" -ForegroundColor Red
91
- Write-Host "Valid targets: claude-home, windsurf-project, windsurf-home, antigravity, cursor-project, codex-home, opencode"
166
+ Write-Host "Valid targets: claude-home, windsurf-project, windsurf-home, antigravity, cursor-project, codex-home, opencode, cline, roocode, aider, kimi, gemini-project, gemini-home"
92
167
  exit 1
93
168
  }
94
169
  }
@@ -198,6 +273,80 @@ switch ($Target) {
198
273
  "opencode" {
199
274
  Install-Flat "$ScriptDir\rules" $RulesDest "Rules"
200
275
  }
276
+ "cline" {
277
+ Install-Flat "$ScriptDir\rules" $RulesDest "Rules"
278
+ Install-Flat "$ScriptDir\agents" $RulesDest "Agents (flattened)"
279
+ Install-Flat "$ScriptDir\commands" $RulesDest "Commands (flattened)"
280
+ }
281
+ "roocode" {
282
+ Install-Dir "$ScriptDir\agents" $AgentsDest "Agents ($AgentCount)"
283
+ Install-Dir "$ScriptDir\skills" $SkillsDest "Skills ($SkillCount)"
284
+ Install-Dir "$ScriptDir\commands" $CommandsDest "Commands ($CmdCount)"
285
+ Install-Flat "$ScriptDir\rules" $RulesDest "Rules"
286
+ }
287
+ "aider" {
288
+ Install-Dir "$ScriptDir\agents" $AgentsDest "Agents ($AgentCount)"
289
+ Install-Dir "$ScriptDir\skills" $SkillsDest "Skills ($SkillCount)"
290
+ Install-Dir "$ScriptDir\commands" $CommandsDest "Commands ($CmdCount)"
291
+ Install-Flat "$ScriptDir\rules" $RulesDest "Rules"
292
+ $ConventionsFile = "$(Get-Location)\CONVENTIONS.md"
293
+ if (-not (Test-Path $ConventionsFile)) {
294
+ $aiderText = @'
295
+ # Project Conventions (Aider)
296
+
297
+ This project uses **Kodelyth ECC** for AI agent guidance.
298
+
299
+ Aider auto-loads this file. To bring full ECC context, run Aider with:
300
+
301
+ aider --read .aider-ecc/rules/agent-intent-routing.md
302
+ aider --read .aider-ecc/rules/coding-standards.md
303
+ aider --read .aider-ecc/agents/debug-detective.md
304
+
305
+ Full catalog: `.aider-ecc/agents/`, `.aider-ecc/skills/`, `.aider-ecc/commands/`, `.aider-ecc/rules/`.
306
+
307
+ Powered by Kodelyth ECC — github.com/sifxprime/kodelyth-ecc
308
+ '@
309
+ $aiderText | Out-File -FilePath $ConventionsFile -Encoding UTF8
310
+ Write-Host " [OK] CONVENTIONS.md -> $ConventionsFile" -ForegroundColor Green
311
+ } else {
312
+ Write-Host " [skip] CONVENTIONS.md exists — not overwriting" -ForegroundColor Yellow
313
+ }
314
+ }
315
+ "kimi" {
316
+ Install-Dir "$ScriptDir\agents" $AgentsDest "Agents ($AgentCount)"
317
+ Install-Dir "$ScriptDir\skills" $SkillsDest "Skills ($SkillCount)"
318
+ Install-Dir "$ScriptDir\commands" $CommandsDest "Commands ($CmdCount)"
319
+ Install-Flat "$ScriptDir\rules" $RulesDest "Rules"
320
+ }
321
+ { $_ -in "gemini-project","gemini-home" } {
322
+ Install-Dir "$ScriptDir\agents" $AgentsDest "Agents ($AgentCount)"
323
+ Install-Dir "$ScriptDir\skills" $SkillsDest "Skills ($SkillCount)"
324
+ Install-Flat "$ScriptDir\rules" $RulesDest "Rules"
325
+ $GeminiFile = "$Dest\GEMINI.md"
326
+ if (-not (Test-Path $GeminiFile)) {
327
+ $geminiText = @'
328
+ # Kodelyth ECC — Gemini CLI context
329
+
330
+ This project uses Kodelyth ECC — 70 specialist agents, 194 skills, 97 commands, intent routing, and self-learning memory.
331
+
332
+ The full toolkit is installed under this directory:
333
+
334
+ - agents/ — specialist subagents (debug-detective, security-reviewer, devil-mode crew)
335
+ - skills/ — domain knowledge files
336
+ - rules/ — always-on coding standards + intent routing rule
337
+
338
+ For more: github.com/sifxprime/kodelyth-ecc
339
+ '@
340
+ $geminiText | Out-File -FilePath $GeminiFile -Encoding UTF8
341
+ Write-Host " [OK] GEMINI.md -> $GeminiFile" -ForegroundColor Green
342
+ }
343
+ }
344
+ }
345
+
346
+ # ── Install bundle cheat sheet (if -Bundle was set) ───────────────────────────
347
+ if ($Bundle -and (Test-Path "$ScriptDir\bundles\$Bundle.md")) {
348
+ Copy-Item -Path "$ScriptDir\bundles\$Bundle.md" -Destination "$Dest\BUNDLE.md" -Force
349
+ Write-Host " [OK] Bundle cheat sheet ($Bundle) -> $Dest\BUNDLE.md" -ForegroundColor Green
201
350
  }
202
351
 
203
352
  # ── Write install state ───────────────────────────────────────────────────────
@@ -207,12 +356,35 @@ $State = @{
207
356
  installed_by = "kodelyth-ecc"
208
357
  version = $Version.Trim()
209
358
  target = $Target
359
+ bundle = $Bundle
210
360
  installed_at = (Get-Date -Format "yyyy-MM-ddTHH:mm:ssZ")
211
361
  languages = $Languages
212
362
  } | ConvertTo-Json
213
363
  $State | Out-File -FilePath $StateFile -Encoding UTF8
214
364
  Write-Host " [OK] Install state -> $StateFile" -ForegroundColor Green
215
365
 
366
+ # ── Bundle-specific reminder ──────────────────────────────────────────────────
367
+ if ($Bundle) {
368
+ Write-Host ""
369
+ switch ($Bundle) {
370
+ "indie-hacker" {
371
+ Write-Host " Bundle: Indie Hacker is active." -ForegroundColor Cyan
372
+ Write-Host " Lead with: /project-launch (new) | /tdd | /devil-mode --pre-public (before going public)"
373
+ Write-Host " Read: $Dest\BUNDLE.md for the full ship-fast playbook."
374
+ }
375
+ "red-team" {
376
+ Write-Host " Bundle: Red Team is active." -ForegroundColor Red
377
+ Write-Host " Lead with: /devil-mode (4-agent sweep) | /devil-mode --all (full 8-agent crew)"
378
+ Write-Host " Read: $Dest\BUNDLE.md for the adversarial workflow playbook."
379
+ }
380
+ "enterprise" {
381
+ Write-Host " Bundle: Enterprise is active." -ForegroundColor Cyan
382
+ Write-Host " Lead with: /team-review (per-PR) | /pre-release (per-tag) | /devil-mode --pre-launch"
383
+ Write-Host " Read: $Dest\BUNDLE.md for the compliance + audit playbook."
384
+ }
385
+ }
386
+ }
387
+
216
388
  # ── Done ──────────────────────────────────────────────────────────────────────
217
389
  Write-Host ""
218
390
  Write-Host "Kodelyth ECC installed successfully!" -ForegroundColor Green
@@ -248,6 +420,31 @@ switch ($Target) {
248
420
  Write-Host " 1. Open the project in OpenCode"
249
421
  Write-Host " 2. Rules in .opencode/rules/ are now loaded"
250
422
  }
423
+ "cline" {
424
+ Write-Host " 1. Open the project in VS Code with Cline"
425
+ Write-Host " 2. .clinerules/ auto-loaded by Cline"
426
+ Write-Host " 3. Ask: 'use debug-detective' or 'devil mode the codebase'"
427
+ }
428
+ "roocode" {
429
+ Write-Host " 1. Open the project in VS Code with Roo Code"
430
+ Write-Host " 2. Rules + agents auto-loaded from .roo/"
431
+ Write-Host " 3. Ask: 'use kodelyth-advisor'"
432
+ }
433
+ "aider" {
434
+ Write-Host " 1. CONVENTIONS.md created at project root"
435
+ Write-Host " 2. Run: aider --read .aider-ecc/rules/agent-intent-routing.md"
436
+ Write-Host " 3. Then describe your problem in plain words"
437
+ }
438
+ "kimi" {
439
+ Write-Host " 1. Open the project with Kimi CLI"
440
+ Write-Host " 2. Agents/skills/rules in .kimi/"
441
+ Write-Host " 3. Ask: 'use kodelyth-advisor'"
442
+ }
443
+ { $_ -in "gemini-project","gemini-home" } {
444
+ Write-Host " 1. Run Gemini CLI"
445
+ Write-Host " 2. GEMINI.md auto-loaded from $Dest"
446
+ Write-Host " 3. Ask: 'use debug-detective'"
447
+ }
251
448
  default {
252
449
  Write-Host " 1. Restart your AI coding agent"
253
450
  Write-Host " 2. Agents, skills, and rules are now active"