kodelyth-ecc 1.5.5 → 1.5.6
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/.github/ISSUE_TEMPLATE/bug_report.md +47 -0
- package/.github/ISSUE_TEMPLATE/new_agent.md +52 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +53 -0
- package/CHANGELOG.md +27 -0
- package/README.md +4 -4
- package/VERSION +1 -1
- package/agents/kodelyth-advisor.md +0 -1
- package/commands/doctor.md +75 -0
- package/commands/update.md +92 -0
- package/install.ps1 +16 -11
- package/install.sh +20 -14
- package/package.json +2 -2
- package/rules/common/agents.md +141 -45
- package/rules/elixir/coding-style.md +46 -0
- package/rules/elixir/hooks.md +26 -0
- package/rules/elixir/patterns.md +67 -0
- package/rules/elixir/security.md +58 -0
- package/rules/elixir/testing.md +64 -0
- package/rules/ruby/coding-style.md +41 -0
- package/rules/ruby/hooks.md +23 -0
- package/rules/ruby/patterns.md +71 -0
- package/rules/ruby/security.md +56 -0
- package/rules/ruby/testing.md +65 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Bug report
|
|
3
|
+
about: Something broken in ECC — install failure, agent misbehavior, hook error
|
|
4
|
+
title: '[BUG] '
|
|
5
|
+
labels: bug
|
|
6
|
+
assignees: ''
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## What happened
|
|
10
|
+
|
|
11
|
+
<!-- Describe what went wrong. Include the exact command you ran or behavior you observed. -->
|
|
12
|
+
|
|
13
|
+
## Expected behavior
|
|
14
|
+
|
|
15
|
+
<!-- What should have happened instead. -->
|
|
16
|
+
|
|
17
|
+
## Steps to reproduce
|
|
18
|
+
|
|
19
|
+
1.
|
|
20
|
+
2.
|
|
21
|
+
3.
|
|
22
|
+
|
|
23
|
+
## Environment
|
|
24
|
+
|
|
25
|
+
- **ECC version**: <!-- run: cat ~/.claude/kodelyth-ecc-install-state.json | grep version -->
|
|
26
|
+
- **Install target**: <!-- claude-home / windsurf-home / windsurf-project / cursor-project / codex-home / antigravity / opencode -->
|
|
27
|
+
- **Platform**: <!-- macOS / Linux / Windows -->
|
|
28
|
+
- **AI IDE**: <!-- Claude Code / Windsurf / Cursor / Codex CLI / Antigravity / OpenCode -->
|
|
29
|
+
- **Node.js version**: <!-- run: node --version -->
|
|
30
|
+
|
|
31
|
+
## Doctor output
|
|
32
|
+
|
|
33
|
+
<!-- Run: node scripts/doctor.js or /doctor in your IDE -->
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
paste output here
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Relevant logs or error messages
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
paste here
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Additional context
|
|
46
|
+
|
|
47
|
+
<!-- Screenshots, related issues, anything else. -->
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: New agent proposal
|
|
3
|
+
about: Propose a new specialist agent for ECC
|
|
4
|
+
title: '[AGENT] '
|
|
5
|
+
labels: enhancement, new-agent
|
|
6
|
+
assignees: ''
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Agent name
|
|
10
|
+
|
|
11
|
+
<!-- e.g. `rate-limiter-specialist`, `database-migrator` -->
|
|
12
|
+
|
|
13
|
+
## One-line description
|
|
14
|
+
|
|
15
|
+
<!-- What does this agent do? Max 15 words. -->
|
|
16
|
+
|
|
17
|
+
## Problem it solves
|
|
18
|
+
|
|
19
|
+
<!-- What pain does this agent remove? What does a developer have to do manually today that this agent would handle? -->
|
|
20
|
+
|
|
21
|
+
## Persona
|
|
22
|
+
|
|
23
|
+
<!-- Who is this agent? Describe their experience, scale they've worked at, what makes their advice different from a generic answer. -->
|
|
24
|
+
|
|
25
|
+
## Trigger patterns
|
|
26
|
+
|
|
27
|
+
<!-- When should intent routing auto-invoke this agent? Give 5–10 natural-language phrases a user might type. -->
|
|
28
|
+
|
|
29
|
+
- "..."
|
|
30
|
+
- "..."
|
|
31
|
+
- "..."
|
|
32
|
+
|
|
33
|
+
## Example interaction
|
|
34
|
+
|
|
35
|
+
<!-- Show a realistic input and the kind of response this agent would give. -->
|
|
36
|
+
|
|
37
|
+
**User:** ...
|
|
38
|
+
|
|
39
|
+
**Agent:** ...
|
|
40
|
+
|
|
41
|
+
## Does this overlap with an existing agent?
|
|
42
|
+
|
|
43
|
+
<!-- Check the agent list. If it overlaps with e.g. `debug-detective` or `performance-optimizer`, explain what makes this distinct. -->
|
|
44
|
+
|
|
45
|
+
## Kodelyth Standard checklist
|
|
46
|
+
|
|
47
|
+
- [ ] The agent has a specific, named persona with years of experience and scale context
|
|
48
|
+
- [ ] The agent responds to the human situation, not just the technical question
|
|
49
|
+
- [ ] Responses give exact file paths, before/after code, or specific commands — not abstract advice
|
|
50
|
+
- [ ] No emoji in agent responses
|
|
51
|
+
- [ ] Ends with `> Powered by Kodelyth — [tagline]`
|
|
52
|
+
- [ ] No `model:` field in frontmatter
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
## What this PR does
|
|
2
|
+
|
|
3
|
+
<!-- One paragraph. What was broken or missing, what you changed, and why this is the right approach. -->
|
|
4
|
+
|
|
5
|
+
## Type of change
|
|
6
|
+
|
|
7
|
+
- [ ] Bug fix (broken behavior, wrong count, install failure)
|
|
8
|
+
- [ ] New agent
|
|
9
|
+
- [ ] New skill
|
|
10
|
+
- [ ] New command
|
|
11
|
+
- [ ] New hook
|
|
12
|
+
- [ ] Rule update
|
|
13
|
+
- [ ] Install script change
|
|
14
|
+
- [ ] Documentation
|
|
15
|
+
- [ ] Other: ___
|
|
16
|
+
|
|
17
|
+
## Checklist
|
|
18
|
+
|
|
19
|
+
### All PRs
|
|
20
|
+
- [ ] `npm test` passes (`node tests/run-all.js`)
|
|
21
|
+
- [ ] No hardcoded version numbers or counts that will drift
|
|
22
|
+
- [ ] No `.DS_Store`, `node_modules`, or generated files committed
|
|
23
|
+
|
|
24
|
+
### New agent
|
|
25
|
+
- [ ] File at `agents/<name>.md`
|
|
26
|
+
- [ ] No `model:` field in frontmatter
|
|
27
|
+
- [ ] Has a specific persona with experience/scale context
|
|
28
|
+
- [ ] Responds to human situation, not just the technical question
|
|
29
|
+
- [ ] Ends with `> Powered by Kodelyth — [tagline]`
|
|
30
|
+
- [ ] Trigger patterns added to `rules/common/agent-intent-routing.md`
|
|
31
|
+
- [ ] Agent added to `rules/common/agents.md`
|
|
32
|
+
- [ ] README agent table updated
|
|
33
|
+
|
|
34
|
+
### New skill
|
|
35
|
+
- [ ] File at `skills/<name>/SKILL.md`
|
|
36
|
+
- [ ] Description is accurate and testable
|
|
37
|
+
|
|
38
|
+
### Install script change (`install.sh` / `install.ps1`)
|
|
39
|
+
- [ ] Both `install.sh` and `install.ps1` updated (feature parity)
|
|
40
|
+
- [ ] Tested on at least one platform
|
|
41
|
+
- [ ] No new hardcoded counts (use dynamic `find` instead)
|
|
42
|
+
|
|
43
|
+
### Rule change
|
|
44
|
+
- [ ] Rule is general enough to apply across languages/frameworks
|
|
45
|
+
- [ ] Not duplicating guidance already in another rule file
|
|
46
|
+
|
|
47
|
+
## Testing
|
|
48
|
+
|
|
49
|
+
<!-- How did you verify this works? -->
|
|
50
|
+
|
|
51
|
+
## Related issues
|
|
52
|
+
|
|
53
|
+
<!-- Closes #123 -->
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,33 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to Kodelyth ECC are documented here.
|
|
4
4
|
|
|
5
|
+
## v1.5.6 — Accuracy, Ruby/Elixir, /doctor, /update (May 2026)
|
|
6
|
+
|
|
7
|
+
### Bug Fixes
|
|
8
|
+
|
|
9
|
+
- **Dynamic install counts** — `install.sh` and `install.ps1` now compute agent/skill/command counts from the actual filesystem at install time. Hardcoded numbers like `(58)` and `(79)` that were wrong on every install are gone permanently.
|
|
10
|
+
- **`rules/common/agents.md` rewritten** — listed only 10 agents from an ancient version. Now documents all 62 agents across 10 categories with handoff chains. This file is injected into `.windsurfrules` on every Windsurf session — the AI was being told there were 10 agents when there are 62.
|
|
11
|
+
- **`kodelyth-advisor` model field removed** — `model: sonnet` violated the Kodelyth Standard (`CONTRIBUTING.md` explicitly says no `model:` field). Fixed.
|
|
12
|
+
- **Windsurf post-install rule count** — was hardcoded as "15 coding rules", now computed dynamically.
|
|
13
|
+
- **`install.ps1` `.windsurfrules` path bug** — for `windsurf-home` target, the file was being written to `$HomeDir\.windsurfrules` instead of `$Dest\.windsurfrules`. Fixed.
|
|
14
|
+
- **README agent count** — "All 61 subagents" in the What Gets Installed table corrected to 62.
|
|
15
|
+
- **OpenCode platform description** — README said "Full" support. OpenCode receives rules only (no agents, no skills). Now documented honestly.
|
|
16
|
+
|
|
17
|
+
### New Features
|
|
18
|
+
|
|
19
|
+
- **`/doctor` command** — run a health check on your ECC install from inside your IDE. Wraps `scripts/doctor.js`. Shows OK/WARNING/ERROR per component with a summary.
|
|
20
|
+
- **`/update` command** — upgrade to the latest ECC version without memorizing your original install flags. Reads `kodelyth-ecc-install-state.json`, replays `npx kodelyth-ecc@latest --target <target>` automatically. Never overwrites `~/.kodelyth/memory/` or `tasks/lessons.md`.
|
|
21
|
+
- **Ruby language rules** — `rules/ruby/` with coding-style, patterns, testing (RSpec + FactoryBot), security (Brakeman + bundler-audit), and hooks (RuboCop auto-fix). Installable via `npx kodelyth-ecc ruby` or `./install.sh ruby`.
|
|
22
|
+
- **Elixir language rules** — `rules/elixir/` with coding-style (mix format + Credo), patterns (with/GenServer/Context), testing (ExUnit + Mox + excoveralls), security (Sobelow + mix hex.audit), and hooks. Installable via `npx kodelyth-ecc elixir` or `./install.sh elixir`.
|
|
23
|
+
- **GitHub issue + PR templates** — `.github/ISSUE_TEMPLATE/bug_report.md`, `.github/ISSUE_TEMPLATE/new_agent.md`, `.github/PULL_REQUEST_TEMPLATE.md`. Contribution quality gate built into the repo workflow.
|
|
24
|
+
|
|
25
|
+
### Changes
|
|
26
|
+
|
|
27
|
+
- `package.json` description updated to reflect 90 commands (was 88)
|
|
28
|
+
- `ruby` and `elixir` added to language parser in both `install.sh` and `install.ps1`
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
5
32
|
## v1.5.3 — God-Tier Intent Routing Expansion (May 2026)
|
|
6
33
|
|
|
7
34
|
### The Routing Overhaul
|
package/README.md
CHANGED
|
@@ -299,7 +299,7 @@ Project: **my-app**
|
|
|
299
299
|
|---|---|---|
|
|
300
300
|
| Agents | **62** | Specialist subagents — reviewers, planners, debuggers, architects, incident-commander, load-tester, memory, image-architect |
|
|
301
301
|
| Skills | **188** | Domain knowledge — patterns, testing, security, DevOps, intent routing, memory |
|
|
302
|
-
| Commands | **
|
|
302
|
+
| Commands | **90** | Slash command workflows (`/tdd`, `/plan`, `/memory`, `/doctor`, `/update`, etc.) |
|
|
303
303
|
| Hooks | **20+** | Quality gates, secret scanning, branch checks, memory inject + capture + correction + project DNA |
|
|
304
304
|
| Rules | **17** | Always-on coding standards + intent routing + memory protocol + self-improvement workflow |
|
|
305
305
|
| Memory | **local** | BM25-indexed personal memory at `~/.kodelyth/memory/` (zero deps) |
|
|
@@ -440,7 +440,7 @@ The intent router will route you to the right one. The AI announces who's taking
|
|
|
440
440
|
|
|
441
441
|
| Source | Destination | What it does |
|
|
442
442
|
|---|---|---|
|
|
443
|
-
| `agents/` | `~/.claude/agents/` | All
|
|
443
|
+
| `agents/` | `~/.claude/agents/` | All 62 subagents available globally |
|
|
444
444
|
| `skills/` | `~/.claude/skills/` | All 188 skills loadable via commands |
|
|
445
445
|
| `hooks/hooks.json` | `~/.claude/hooks/` | Automated quality gates |
|
|
446
446
|
| `rules/` | `~/.claude/rules/` | Always-on standards + intent routing |
|
|
@@ -510,7 +510,7 @@ Available profiles:
|
|
|
510
510
|
Or specify languages directly:
|
|
511
511
|
|
|
512
512
|
```bash
|
|
513
|
-
npx kodelyth-ecc typescript python golang rust java kotlin php swift cpp dart
|
|
513
|
+
npx kodelyth-ecc typescript python golang rust java kotlin php swift cpp dart ruby elixir
|
|
514
514
|
```
|
|
515
515
|
|
|
516
516
|
---
|
|
@@ -524,7 +524,7 @@ npx kodelyth-ecc typescript python golang rust java kotlin php swift cpp dart
|
|
|
524
524
|
| Cursor | Full | `cursor-project` | Rules, skills |
|
|
525
525
|
| Codex CLI | Full | `codex-home` | Agents, skills, commands, rules |
|
|
526
526
|
| Google Antigravity | Full | `antigravity` | Agents → skills, commands → workflows, rules |
|
|
527
|
-
| OpenCode |
|
|
527
|
+
| OpenCode | Rules only | `opencode` | Rules (agents + skills not yet supported by OpenCode) |
|
|
528
528
|
|
|
529
529
|
**OS support:** macOS, Linux (`install.sh`), Windows (`install.ps1`), or any OS with Node.js 18+ (`npx`).
|
|
530
530
|
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
1.5.
|
|
1
|
+
1.5.6
|
|
@@ -7,7 +7,6 @@ description: >
|
|
|
7
7
|
direction instantly. No hand-holding, no noise — just the exact answer.
|
|
8
8
|
Use when you need strategic guidance, tool selection, or a clear path forward.
|
|
9
9
|
tools: ["Read", "Grep", "Glob"]
|
|
10
|
-
model: sonnet
|
|
11
10
|
---
|
|
12
11
|
|
|
13
12
|
You are the Kodelyth Advisor — a principal engineer with a decade-plus of building systems that power billions of users at companies valued in the hundreds of billions. You have shipped production code at Google scale, designed distributed systems under real SLA pressure, and mentored engineers who went on to lead their own platforms. You do not write toy code. You do not give junior-level answers. You think in systems, not files.
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Diagnose your Kodelyth ECC install — check for drift, missing files, version mismatches, and confirm everything is healthy
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# /doctor
|
|
6
|
+
|
|
7
|
+
Runs a health check on your ECC install. Detects drift between what was installed and what is currently on disk.
|
|
8
|
+
|
|
9
|
+
## What It Checks
|
|
10
|
+
|
|
11
|
+
- Install state file exists and is readable
|
|
12
|
+
- Installed version vs latest available
|
|
13
|
+
- Agent files present and uncorrupted
|
|
14
|
+
- Skills directory intact
|
|
15
|
+
- Rules loaded correctly
|
|
16
|
+
- Memory store accessible (if applicable)
|
|
17
|
+
- Hooks registered (Claude Code only)
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
/doctor
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Run with no arguments for a full health report on all detected installs.
|
|
26
|
+
|
|
27
|
+
## Implementation
|
|
28
|
+
|
|
29
|
+
Runs the built-in doctor script:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
node scripts/doctor.js
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Or with a specific target:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
node scripts/doctor.js --target claude-home
|
|
39
|
+
node scripts/doctor.js --target windsurf-home
|
|
40
|
+
node scripts/doctor.js --target windsurf-project
|
|
41
|
+
node scripts/doctor.js --target codex-home
|
|
42
|
+
node scripts/doctor.js --target cursor-project
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
For JSON output (useful in CI or scripts):
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
node scripts/doctor.js --json
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Output
|
|
52
|
+
|
|
53
|
+
The doctor report shows:
|
|
54
|
+
|
|
55
|
+
| Field | Meaning |
|
|
56
|
+
|-------|---------|
|
|
57
|
+
| `OK` | Component healthy, no issues |
|
|
58
|
+
| `WARNING` | Potential issue, non-blocking |
|
|
59
|
+
| `ERROR` | Missing or corrupted file, needs attention |
|
|
60
|
+
|
|
61
|
+
A summary line shows total checked, ok, warnings, and errors.
|
|
62
|
+
|
|
63
|
+
## When to Run
|
|
64
|
+
|
|
65
|
+
- After first install to confirm everything landed
|
|
66
|
+
- After upgrading to a new ECC version
|
|
67
|
+
- When an agent or skill isn't behaving as expected
|
|
68
|
+
- Before filing a bug report
|
|
69
|
+
|
|
70
|
+
## Related
|
|
71
|
+
|
|
72
|
+
- `/update` — upgrade to the latest ECC version
|
|
73
|
+
- `use kodelyth-advisor` — if you're not sure where to start
|
|
74
|
+
|
|
75
|
+
> Powered by Kodelyth — trust your install, verify your tools.
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Upgrade Kodelyth ECC to the latest version, preserving your current install target and language profile
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# /update
|
|
6
|
+
|
|
7
|
+
Upgrades your ECC install to the latest version from npm. Reads your existing install state to replay the same target and language options automatically — no flags to remember.
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
/update
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## What It Does
|
|
16
|
+
|
|
17
|
+
1. Reads `kodelyth-ecc-install-state.json` from your install directory to recover the original `target` and `languages`
|
|
18
|
+
2. Runs `npx kodelyth-ecc@latest` with those same flags
|
|
19
|
+
3. Overwrites agents, skills, rules, and commands with the latest versions
|
|
20
|
+
4. Leaves your memory store (`~/.kodelyth/memory/`) and `tasks/lessons.md` untouched — your learned context is never overwritten
|
|
21
|
+
|
|
22
|
+
## Implementation
|
|
23
|
+
|
|
24
|
+
The agent should run the appropriate command based on your platform.
|
|
25
|
+
|
|
26
|
+
### Automatic (reads install state)
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
node -e "
|
|
30
|
+
const fs = require('fs');
|
|
31
|
+
const os = require('os');
|
|
32
|
+
const path = require('path');
|
|
33
|
+
|
|
34
|
+
const candidates = [
|
|
35
|
+
path.join(os.homedir(), '.claude', 'kodelyth-ecc-install-state.json'),
|
|
36
|
+
path.join(os.homedir(), '.codeium', 'windsurf', 'kodelyth-ecc-install-state.json'),
|
|
37
|
+
path.join(os.homedir(), '.codex', 'kodelyth-ecc-install-state.json'),
|
|
38
|
+
path.join(process.cwd(), '.windsurf', 'kodelyth-ecc-install-state.json'),
|
|
39
|
+
path.join(process.cwd(), '.cursor', 'kodelyth-ecc-install-state.json'),
|
|
40
|
+
path.join(process.cwd(), '.agent', 'kodelyth-ecc-install-state.json'),
|
|
41
|
+
path.join(process.cwd(), '.opencode', 'kodelyth-ecc-install-state.json'),
|
|
42
|
+
];
|
|
43
|
+
|
|
44
|
+
let state = null;
|
|
45
|
+
let stateFile = null;
|
|
46
|
+
for (const f of candidates) {
|
|
47
|
+
if (fs.existsSync(f)) { state = JSON.parse(fs.readFileSync(f, 'utf8')); stateFile = f; break; }
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (!state) {
|
|
51
|
+
console.error('No install state found. Run the installer manually:');
|
|
52
|
+
console.error(' npx kodelyth-ecc --target <target>');
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const langs = (state.languages || []).join(' ');
|
|
57
|
+
const cmd = ['npx', 'kodelyth-ecc@latest', '--target', state.target, langs].filter(Boolean).join(' ');
|
|
58
|
+
console.log('Found install state:', stateFile);
|
|
59
|
+
console.log('Previous version:', state.version);
|
|
60
|
+
console.log('Running:', cmd);
|
|
61
|
+
require('child_process').execSync(cmd, { stdio: 'inherit' });
|
|
62
|
+
"
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Manual (if you know your target)
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
npx kodelyth-ecc@latest # Claude Code
|
|
69
|
+
npx kodelyth-ecc@latest --target windsurf-home # Windsurf global
|
|
70
|
+
npx kodelyth-ecc@latest --target windsurf-project # Windsurf project
|
|
71
|
+
npx kodelyth-ecc@latest --target codex-home # Codex CLI
|
|
72
|
+
npx kodelyth-ecc@latest --target cursor-project # Cursor
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## What Is NOT Overwritten
|
|
76
|
+
|
|
77
|
+
| Path | Protected |
|
|
78
|
+
|------|-----------|
|
|
79
|
+
| `~/.kodelyth/memory/` | Your BM25 memory store |
|
|
80
|
+
| `tasks/lessons.md` | Project correction rules |
|
|
81
|
+
| `tasks/todo.md` | Open todos |
|
|
82
|
+
|
|
83
|
+
## After Updating
|
|
84
|
+
|
|
85
|
+
Run `/doctor` to confirm the new version is healthy.
|
|
86
|
+
|
|
87
|
+
## Related
|
|
88
|
+
|
|
89
|
+
- `/doctor` — verify install health
|
|
90
|
+
- `use kodelyth-advisor` — guidance after a major version update
|
|
91
|
+
|
|
92
|
+
> Powered by Kodelyth — stay current, stay sharp.
|
package/install.ps1
CHANGED
|
@@ -21,7 +21,7 @@ $ErrorActionPreference = "Stop"
|
|
|
21
21
|
# ── Banner ────────────────────────────────────────────────────────────────────
|
|
22
22
|
Write-Host ""
|
|
23
23
|
Write-Host " Kodelyth ECC — Production-grade AI coding agent toolkit" -ForegroundColor Cyan
|
|
24
|
-
Write-Host "
|
|
24
|
+
Write-Host " 62 agents · 188 skills · 90 commands · 20+ hooks · intent routing · local memory" -ForegroundColor Gray
|
|
25
25
|
Write-Host ""
|
|
26
26
|
|
|
27
27
|
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
|
@@ -107,6 +107,11 @@ if ($Confirm -and $Confirm -notmatch '^[Yy]$') {
|
|
|
107
107
|
}
|
|
108
108
|
Write-Host ""
|
|
109
109
|
|
|
110
|
+
# ── Dynamic Counts ───────────────────────────────────────────────────────────
|
|
111
|
+
$AgentCount = (Get-ChildItem -Path "$ScriptDir\agents" -Filter "*.md" -File).Count
|
|
112
|
+
$SkillCount = (Get-ChildItem -Path "$ScriptDir\skills" -Recurse -Filter "SKILL.md" -File).Count
|
|
113
|
+
$CmdCount = (Get-ChildItem -Path "$ScriptDir\commands" -Filter "*.md" -File).Count
|
|
114
|
+
|
|
110
115
|
# ── Helpers ───────────────────────────────────────────────────────────────────
|
|
111
116
|
function Install-Dir {
|
|
112
117
|
param([string]$Src, [string]$Dest, [string]$Label)
|
|
@@ -162,12 +167,12 @@ switch ($Target) {
|
|
|
162
167
|
Write-Host " [OK] CLAUDE.md + SOUL.md" -ForegroundColor Green
|
|
163
168
|
}
|
|
164
169
|
{ $_ -in "windsurf-project","windsurf-home" } {
|
|
165
|
-
Install-Dir "$ScriptDir\agents" $AgentsDest "Agents (
|
|
166
|
-
Install-Dir "$ScriptDir\skills" $SkillsDest "Skills (
|
|
170
|
+
Install-Dir "$ScriptDir\agents" $AgentsDest "Agents ($AgentCount)"
|
|
171
|
+
Install-Dir "$ScriptDir\skills" $SkillsDest "Skills ($SkillCount)"
|
|
167
172
|
Install-Flat "$ScriptDir\rules" $RulesDest "Rules"
|
|
168
173
|
|
|
169
174
|
# Generate .windsurfrules from all common rules
|
|
170
|
-
$WindsurfRulesFile = if ($Target -eq "windsurf-project") { "$(Get-Location)\.windsurfrules" } else { "$
|
|
175
|
+
$WindsurfRulesFile = if ($Target -eq "windsurf-project") { "$(Get-Location)\.windsurfrules" } else { "$Dest\.windsurfrules" }
|
|
171
176
|
$CommonRulesDir = "$ScriptDir\rules\common"
|
|
172
177
|
if (Test-Path $CommonRulesDir) {
|
|
173
178
|
$Combined = Get-ChildItem -Path $CommonRulesDir -Filter "*.md" | Sort-Object Name | ForEach-Object { Get-Content $_.FullName }
|
|
@@ -176,18 +181,18 @@ switch ($Target) {
|
|
|
176
181
|
}
|
|
177
182
|
}
|
|
178
183
|
"antigravity" {
|
|
179
|
-
Install-Dir "$ScriptDir\agents" $AgentsDest "Agents -> skills (
|
|
180
|
-
Install-Dir "$ScriptDir\commands" $CommandsDest "Commands -> workflows (
|
|
184
|
+
Install-Dir "$ScriptDir\agents" $AgentsDest "Agents -> skills ($AgentCount)"
|
|
185
|
+
Install-Dir "$ScriptDir\commands" $CommandsDest "Commands -> workflows ($CmdCount)"
|
|
181
186
|
Install-Flat "$ScriptDir\rules" $RulesDest "Rules"
|
|
182
187
|
}
|
|
183
188
|
"cursor-project" {
|
|
184
189
|
Install-Flat "$ScriptDir\rules" $RulesDest "Rules"
|
|
185
|
-
Install-Dir "$ScriptDir\skills" $SkillsDest "Skills (
|
|
190
|
+
Install-Dir "$ScriptDir\skills" $SkillsDest "Skills ($SkillCount)"
|
|
186
191
|
}
|
|
187
192
|
"codex-home" {
|
|
188
|
-
Install-Dir "$ScriptDir\agents" $AgentsDest "Agents (
|
|
189
|
-
Install-Dir "$ScriptDir\skills" $SkillsDest "Skills (
|
|
190
|
-
Install-Dir "$ScriptDir\commands" $CommandsDest "Commands (
|
|
193
|
+
Install-Dir "$ScriptDir\agents" $AgentsDest "Agents ($AgentCount)"
|
|
194
|
+
Install-Dir "$ScriptDir\skills" $SkillsDest "Skills ($SkillCount)"
|
|
195
|
+
Install-Dir "$ScriptDir\commands" $CommandsDest "Commands ($CmdCount)"
|
|
191
196
|
Install-Flat "$ScriptDir\rules" $RulesDest "Rules"
|
|
192
197
|
}
|
|
193
198
|
"opencode" {
|
|
@@ -231,7 +236,7 @@ switch ($Target) {
|
|
|
231
236
|
}
|
|
232
237
|
"codex-home" {
|
|
233
238
|
Write-Host " 1. Restart Codex CLI (codex)"
|
|
234
|
-
Write-Host " 2. All
|
|
239
|
+
Write-Host " 2. All $AgentCount agents and $SkillCount skills are now available"
|
|
235
240
|
Write-Host " 3. Try: use kodelyth-advisor"
|
|
236
241
|
}
|
|
237
242
|
"antigravity" {
|
package/install.sh
CHANGED
|
@@ -87,7 +87,7 @@ while [[ $# -gt 0 ]]; do
|
|
|
87
87
|
TARGET="${1#--target=}"
|
|
88
88
|
shift
|
|
89
89
|
;;
|
|
90
|
-
typescript|python|golang|go|rust|java|kotlin|php|swift|cpp|csharp|dart)
|
|
90
|
+
typescript|python|golang|go|rust|java|kotlin|php|swift|cpp|csharp|dart|ruby|elixir)
|
|
91
91
|
lang="$1"
|
|
92
92
|
[[ "$lang" == "go" ]] && lang="golang"
|
|
93
93
|
LANGUAGE_MODULES+=("$lang")
|
|
@@ -143,7 +143,7 @@ while [[ $# -gt 0 ]]; do
|
|
|
143
143
|
echo " --profile backend Go + Python + Java"
|
|
144
144
|
echo ""
|
|
145
145
|
echo "Languages (manual, installs language-specific rules):"
|
|
146
|
-
echo " typescript python golang rust java kotlin php swift cpp dart"
|
|
146
|
+
echo " typescript python golang rust java kotlin php swift cpp dart ruby elixir"
|
|
147
147
|
echo ""
|
|
148
148
|
echo "Examples:"
|
|
149
149
|
echo " ./install.sh"
|
|
@@ -338,15 +338,20 @@ generate_windsurfrules() {
|
|
|
338
338
|
echo -e " ${GREEN}✓${RESET} .windsurfrules ${BLUE}(→ $dest_file)${RESET}"
|
|
339
339
|
}
|
|
340
340
|
|
|
341
|
+
# ── Dynamic Counts ────────────────────────────────────────────────────────────
|
|
342
|
+
AGENT_COUNT=$(find "$SCRIPT_DIR/agents" -maxdepth 1 -name "*.md" | wc -l | tr -d ' ')
|
|
343
|
+
SKILL_COUNT=$(find "$SCRIPT_DIR/skills" -mindepth 2 -maxdepth 2 -name "SKILL.md" | wc -l | tr -d ' ')
|
|
344
|
+
CMD_COUNT=$(find "$SCRIPT_DIR/commands" -maxdepth 1 -name "*.md" | wc -l | tr -d ' ')
|
|
345
|
+
|
|
341
346
|
# ── Install ───────────────────────────────────────────────────────────────────
|
|
342
347
|
echo -e "${BOLD}Installing components...${RESET}"
|
|
343
348
|
echo ""
|
|
344
349
|
|
|
345
350
|
case "$TARGET" in
|
|
346
351
|
claude-home)
|
|
347
|
-
install_dir "$SCRIPT_DIR/agents" "$AGENTS_DEST" "Agents (
|
|
348
|
-
install_dir "$SCRIPT_DIR/skills" "$SKILLS_DEST" "Skills (
|
|
349
|
-
install_dir "$SCRIPT_DIR/commands" "$COMMANDS_DEST" "Commands (
|
|
352
|
+
install_dir "$SCRIPT_DIR/agents" "$AGENTS_DEST" "Agents ($AGENT_COUNT)"
|
|
353
|
+
install_dir "$SCRIPT_DIR/skills" "$SKILLS_DEST" "Skills ($SKILL_COUNT)"
|
|
354
|
+
install_dir "$SCRIPT_DIR/commands" "$COMMANDS_DEST" "Commands ($CMD_COUNT)"
|
|
350
355
|
install_hooks "$HOOKS_DEST"
|
|
351
356
|
# Rules: install common + selected languages
|
|
352
357
|
mkdir -p "$RULES_DEST"
|
|
@@ -369,9 +374,9 @@ case "$TARGET" in
|
|
|
369
374
|
|
|
370
375
|
antigravity)
|
|
371
376
|
# Agents → .agent/skills/
|
|
372
|
-
install_dir "$SCRIPT_DIR/agents" "$AGENTS_DEST" "Agents → skills (
|
|
377
|
+
install_dir "$SCRIPT_DIR/agents" "$AGENTS_DEST" "Agents → skills ($AGENT_COUNT)"
|
|
373
378
|
# Commands → .agent/workflows/
|
|
374
|
-
install_dir "$SCRIPT_DIR/commands" "$COMMANDS_DEST" "Commands → workflows (
|
|
379
|
+
install_dir "$SCRIPT_DIR/commands" "$COMMANDS_DEST" "Commands → workflows ($CMD_COUNT)"
|
|
375
380
|
# Rules → .agent/rules/ (flattened)
|
|
376
381
|
install_flat "$SCRIPT_DIR/rules" "$RULES_DEST" "Rules (flattened)"
|
|
377
382
|
# Kodelyth skills → .agent/rules/ (flattened — Antigravity has no skills system)
|
|
@@ -387,19 +392,19 @@ case "$TARGET" in
|
|
|
387
392
|
|
|
388
393
|
cursor-project)
|
|
389
394
|
install_flat "$SCRIPT_DIR/rules" "$RULES_DEST" "Rules (flattened)"
|
|
390
|
-
install_dir "$SCRIPT_DIR/skills" "$SKILLS_DEST" "Skills (
|
|
395
|
+
install_dir "$SCRIPT_DIR/skills" "$SKILLS_DEST" "Skills ($SKILL_COUNT)"
|
|
391
396
|
;;
|
|
392
397
|
|
|
393
398
|
codex-home)
|
|
394
|
-
install_dir "$SCRIPT_DIR/agents" "$AGENTS_DEST" "Agents (
|
|
395
|
-
install_dir "$SCRIPT_DIR/skills" "$SKILLS_DEST" "Skills (
|
|
396
|
-
install_dir "$SCRIPT_DIR/commands" "$COMMANDS_DEST" "Commands (
|
|
399
|
+
install_dir "$SCRIPT_DIR/agents" "$AGENTS_DEST" "Agents ($AGENT_COUNT)"
|
|
400
|
+
install_dir "$SCRIPT_DIR/skills" "$SKILLS_DEST" "Skills ($SKILL_COUNT)"
|
|
401
|
+
install_dir "$SCRIPT_DIR/commands" "$COMMANDS_DEST" "Commands ($CMD_COUNT)"
|
|
397
402
|
install_flat "$SCRIPT_DIR/rules" "$RULES_DEST" "Rules (flattened)"
|
|
398
403
|
;;
|
|
399
404
|
|
|
400
405
|
windsurf-project|windsurf-home)
|
|
401
|
-
install_dir "$SCRIPT_DIR/agents" "$AGENTS_DEST" "Agents (
|
|
402
|
-
install_dir "$SCRIPT_DIR/skills" "$SKILLS_DEST" "Skills (
|
|
406
|
+
install_dir "$SCRIPT_DIR/agents" "$AGENTS_DEST" "Agents ($AGENT_COUNT)"
|
|
407
|
+
install_dir "$SCRIPT_DIR/skills" "$SKILLS_DEST" "Skills ($SKILL_COUNT)"
|
|
403
408
|
install_flat "$SCRIPT_DIR/rules" "$RULES_DEST" "Rules (flattened)"
|
|
404
409
|
generate_windsurfrules "$SCRIPT_DIR/rules" "$WINDSURFRULES_DEST"
|
|
405
410
|
;;
|
|
@@ -472,10 +477,11 @@ case "$TARGET" in
|
|
|
472
477
|
echo " use kodelyth-advisor"
|
|
473
478
|
;;
|
|
474
479
|
windsurf-project|windsurf-home)
|
|
480
|
+
RULE_COUNT=$(find "$SCRIPT_DIR/rules/common" -maxdepth 1 -name "*.md" ! -name "agent-intent-routing.md" | wc -l | tr -d ' ')
|
|
475
481
|
echo -e "${BOLD} Windsurf — what to do now:${RESET}"
|
|
476
482
|
echo ""
|
|
477
483
|
echo " Open your project in Windsurf (Cascade)."
|
|
478
|
-
echo " .windsurfrules is active —
|
|
484
|
+
echo " .windsurfrules is active — $RULE_COUNT coding rules + intent routing loaded automatically."
|
|
479
485
|
echo " Agents available in .windsurf/agents/"
|
|
480
486
|
echo ""
|
|
481
487
|
echo " use kodelyth-advisor ← not sure where to start"
|
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 — 62 agents, 188 skills,
|
|
3
|
+
"version": "1.5.6",
|
|
4
|
+
"description": "Production-grade AI coding toolkit — 62 agents, 188 skills, 90 commands, parallel multi-agent commands, semantic intent routing, self-learning memory. Works with Claude Code, Windsurf, Cursor, Codex, Antigravity, and OpenCode.",
|
|
5
5
|
"author": "Kodelyth <github.com/sifxprime>",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
package/rules/common/agents.md
CHANGED
|
@@ -1,50 +1,146 @@
|
|
|
1
1
|
# Agent Orchestration
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
| Agent |
|
|
8
|
-
|
|
9
|
-
|
|
|
10
|
-
|
|
|
11
|
-
|
|
|
12
|
-
|
|
|
13
|
-
|
|
|
14
|
-
|
|
|
15
|
-
|
|
|
16
|
-
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
##
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
3
|
+
62 specialist agents are available. Intent routing is always-on — describe your problem in plain words and the right agent is invoked automatically. You can also invoke explicitly: `use <agent-name>`.
|
|
4
|
+
|
|
5
|
+
## Kodelyth Exclusives
|
|
6
|
+
|
|
7
|
+
| Agent | When to Use |
|
|
8
|
+
|-------|-------------|
|
|
9
|
+
| `kodelyth-advisor` | Not sure where to start — master guide |
|
|
10
|
+
| `pair-programmer` | Before writing code — think through approach first |
|
|
11
|
+
| `debug-detective` | Any bug — evidence-first root cause, never guess-and-check |
|
|
12
|
+
| `silent-failure-hunter` | Bugs that don't throw errors |
|
|
13
|
+
| `incident-commander` | Production incident — P0/P1 triage, contain, postmortem |
|
|
14
|
+
| `load-tester` | Load/stress testing — k6, Locust, Artillery, capacity planning |
|
|
15
|
+
| `kodelyth-memory` | Manage local BM25 memory — recall, capture, review |
|
|
16
|
+
| `image-architect` | AI image generation — Gemini/DALL-E/fal.ai/SVG |
|
|
17
|
+
|
|
18
|
+
## Planning & Architecture
|
|
19
|
+
|
|
20
|
+
| Agent | When to Use |
|
|
21
|
+
|-------|-------------|
|
|
22
|
+
| `planner` | Plan a feature before writing a line of code |
|
|
23
|
+
| `architect` | System-level design, dependency graphs |
|
|
24
|
+
| `code-architect` | Code-level architecture decisions |
|
|
25
|
+
| `chief-of-staff` | Strategic decisions, comms, stakeholder updates |
|
|
26
|
+
| `migration-guide` | Framework/language version upgrades, phase by phase |
|
|
27
|
+
|
|
28
|
+
## Code Review
|
|
29
|
+
|
|
30
|
+
| Agent | When to Use |
|
|
31
|
+
|-------|-------------|
|
|
32
|
+
| `code-reviewer` | General review after writing code |
|
|
33
|
+
| `typescript-reviewer` | TypeScript / React / Next.js |
|
|
34
|
+
| `python-reviewer` | Python |
|
|
35
|
+
| `go-reviewer` | Go |
|
|
36
|
+
| `rust-reviewer` | Rust |
|
|
37
|
+
| `java-reviewer` | Java / Spring Boot |
|
|
38
|
+
| `kotlin-reviewer` | Kotlin / Android / KMP |
|
|
39
|
+
| `cpp-reviewer` | C++ |
|
|
40
|
+
| `csharp-reviewer` | C# / .NET |
|
|
41
|
+
| `flutter-reviewer` | Flutter / Dart |
|
|
42
|
+
| `database-reviewer` | SQL schema, query patterns, indexes |
|
|
43
|
+
| `healthcare-reviewer` | PHI/HIPAA-aware review for healthcare apps |
|
|
44
|
+
|
|
45
|
+
## Build Fixers
|
|
46
|
+
|
|
47
|
+
| Agent | When to Use |
|
|
48
|
+
|-------|-------------|
|
|
49
|
+
| `build-error-resolver` | General build failure |
|
|
50
|
+
| `go-build-resolver` | Go build errors |
|
|
51
|
+
| `rust-build-resolver` | Rust/Cargo build errors |
|
|
52
|
+
| `java-build-resolver` | Java/Maven/Gradle build errors |
|
|
53
|
+
| `kotlin-build-resolver` | Kotlin/Gradle build errors |
|
|
54
|
+
| `cpp-build-resolver` | C++/CMake/Make build errors |
|
|
55
|
+
| `dart-build-resolver` | Dart/Flutter build errors |
|
|
56
|
+
| `pytorch-build-resolver` | PyTorch/CUDA build errors |
|
|
57
|
+
| `dependency-doctor` | npm/pip/cargo/maven dep hell, CVEs, lockfile drift |
|
|
58
|
+
| `env-debugger` | "Works on my machine" — env, config, secrets layers |
|
|
59
|
+
|
|
60
|
+
## Debugging & Testing
|
|
61
|
+
|
|
62
|
+
| Agent | When to Use |
|
|
63
|
+
|-------|-------------|
|
|
64
|
+
| `tdd-guide` | Write tests first — TDD methodology |
|
|
65
|
+
| `e2e-runner` | End-to-end test automation |
|
|
66
|
+
| `pr-test-analyzer` | CI output — root cause failing tests |
|
|
67
|
+
| `flake-hunter` | Flaky test stabilization — never blind retries |
|
|
68
|
+
|
|
69
|
+
## Security & API
|
|
70
|
+
|
|
71
|
+
| Agent | When to Use |
|
|
72
|
+
|-------|-------------|
|
|
73
|
+
| `security-reviewer` | OWASP top 10, secrets, auth, injection vectors |
|
|
74
|
+
| `api-guardian` | Detect breaking API changes before they ship |
|
|
75
|
+
|
|
76
|
+
## Performance & Quality
|
|
77
|
+
|
|
78
|
+
| Agent | When to Use |
|
|
79
|
+
|-------|-------------|
|
|
80
|
+
| `performance-optimizer` | Profiling-first — measure before optimizing |
|
|
81
|
+
| `refactor-cleaner` | Remove code smells, dead code, tech debt |
|
|
82
|
+
| `code-simplifier` | Improve readability without changing behavior |
|
|
83
|
+
| `type-design-analyzer` | TypeScript type system design |
|
|
84
|
+
|
|
85
|
+
## Documentation & Analysis
|
|
86
|
+
|
|
87
|
+
| Agent | When to Use |
|
|
88
|
+
|-------|-------------|
|
|
89
|
+
| `doc-updater` | Update or write documentation |
|
|
90
|
+
| `docs-lookup` | Find docs for a library or API |
|
|
91
|
+
| `comment-analyzer` | Audit code comments for accuracy |
|
|
92
|
+
| `code-explorer` | Explore an unfamiliar codebase |
|
|
93
|
+
| `conversation-analyzer` | Analyze conversation or chat patterns |
|
|
94
|
+
|
|
95
|
+
## Release & Ops
|
|
96
|
+
|
|
97
|
+
| Agent | When to Use |
|
|
98
|
+
|-------|-------------|
|
|
99
|
+
| `release-captain` | Cut a clean release — semver, tagging, rollback plan |
|
|
100
|
+
| `git-rescue` | Broken git state, lost commits, bad rebase — no history loss |
|
|
101
|
+
|
|
102
|
+
## Open Source
|
|
103
|
+
|
|
104
|
+
| Agent | When to Use |
|
|
105
|
+
|-------|-------------|
|
|
106
|
+
| `opensource-forker` | Fork and clean a project for open-source release |
|
|
107
|
+
| `opensource-sanitizer` | Strip secrets, PII, proprietary references |
|
|
108
|
+
| `opensource-packager` | README, license, contribution docs |
|
|
109
|
+
|
|
110
|
+
## Specialized
|
|
111
|
+
|
|
112
|
+
| Agent | When to Use |
|
|
113
|
+
|-------|-------------|
|
|
114
|
+
| `ux-reviewer` | UX behavior + WCAG 2.1 AA accessibility |
|
|
115
|
+
| `seo-specialist` | Technical SEO, structured data, rankings |
|
|
116
|
+
|
|
117
|
+
## GAN Harness (Multi-Agent)
|
|
118
|
+
|
|
119
|
+
| Agent | When to Use |
|
|
120
|
+
|-------|-------------|
|
|
121
|
+
| `gan-planner` | Plan a GAN-style generator/evaluator workflow |
|
|
122
|
+
| `gan-generator` | Generate output in a GAN harness loop |
|
|
123
|
+
| `gan-evaluator` | Evaluate output and provide adversarial feedback |
|
|
124
|
+
| `harness-optimizer` | Optimize agent harness action spaces |
|
|
125
|
+
| `loop-operator` | Operate autonomous agent loops |
|
|
126
|
+
|
|
127
|
+
## Parallel Execution
|
|
128
|
+
|
|
129
|
+
ALWAYS launch independent agents in parallel:
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
# GOOD: parallel
|
|
133
|
+
use code-reviewer + security-reviewer + ux-reviewer simultaneously
|
|
134
|
+
|
|
135
|
+
# BAD: sequential when not needed
|
|
136
|
+
code-reviewer → then security-reviewer → then ux-reviewer
|
|
41
137
|
```
|
|
42
138
|
|
|
43
|
-
##
|
|
139
|
+
## Standard Handoff Chains
|
|
44
140
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
-
|
|
48
|
-
-
|
|
49
|
-
-
|
|
50
|
-
-
|
|
141
|
+
| Workflow | Chain |
|
|
142
|
+
|----------|-------|
|
|
143
|
+
| New feature | `pair-programmer` → `tdd-guide` → `code-reviewer` → `security-reviewer` |
|
|
144
|
+
| Bug fix | `debug-detective` → `tdd-guide` → `refactor-cleaner` |
|
|
145
|
+
| Production incident | `incident-commander` → `debug-detective` → `tdd-guide` |
|
|
146
|
+
| Open-source | `opensource-forker` → `opensource-sanitizer` → `opensource-packager` → `release-captain` |
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/*.ex"
|
|
4
|
+
- "**/*.exs"
|
|
5
|
+
---
|
|
6
|
+
# Elixir Coding Style
|
|
7
|
+
|
|
8
|
+
> This file extends [common/coding-style.md](../common/coding-style.md) with Elixir specific content.
|
|
9
|
+
|
|
10
|
+
## Standards
|
|
11
|
+
|
|
12
|
+
- Follow the official **Elixir Style Guide**
|
|
13
|
+
- Use **mix format** — non-negotiable, always auto-format
|
|
14
|
+
- All public functions must have `@spec` type annotations and `@doc` documentation
|
|
15
|
+
|
|
16
|
+
## Immutability
|
|
17
|
+
|
|
18
|
+
Data is immutable by default in Elixir. Embrace it:
|
|
19
|
+
|
|
20
|
+
```elixir
|
|
21
|
+
# Use the pipe operator for data transformations
|
|
22
|
+
result =
|
|
23
|
+
input
|
|
24
|
+
|> validate()
|
|
25
|
+
|> transform()
|
|
26
|
+
|> persist()
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Function Heads Over Conditionals
|
|
30
|
+
|
|
31
|
+
```elixir
|
|
32
|
+
# Prefer pattern-matched function heads over cond/case at the top level
|
|
33
|
+
def process(%{status: :active} = user), do: activate(user)
|
|
34
|
+
def process(%{status: :banned} = user), do: reject(user)
|
|
35
|
+
def process(_user), do: {:error, :unknown_status}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Formatting
|
|
39
|
+
|
|
40
|
+
- **mix format** — run on every save
|
|
41
|
+
- **Credo** for code quality and style checks
|
|
42
|
+
- Line length: 98 characters (mix format default)
|
|
43
|
+
|
|
44
|
+
## Reference
|
|
45
|
+
|
|
46
|
+
See skill: `elixir-patterns` for comprehensive GenServer, Phoenix, and OTP patterns.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/*.ex"
|
|
4
|
+
- "**/*.exs"
|
|
5
|
+
---
|
|
6
|
+
# Elixir Hooks
|
|
7
|
+
|
|
8
|
+
> This file extends [common/hooks.md](../common/hooks.md) with Elixir specific content.
|
|
9
|
+
|
|
10
|
+
## PostToolUse Hooks
|
|
11
|
+
|
|
12
|
+
Configure in `~/.claude/settings.json`:
|
|
13
|
+
|
|
14
|
+
- **mix format**: Auto-format `.ex` / `.exs` files after edit
|
|
15
|
+
```bash
|
|
16
|
+
mix format <file>
|
|
17
|
+
```
|
|
18
|
+
- **Credo**: Run on edited files for style warnings
|
|
19
|
+
```bash
|
|
20
|
+
mix credo <file>
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Warnings
|
|
24
|
+
|
|
25
|
+
- Warn when `IO.inspect` is left in non-test `.ex` files (use `Logger` instead)
|
|
26
|
+
- Warn when `dbg()` (Elixir 1.14+) is left in production code paths
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/*.ex"
|
|
4
|
+
- "**/*.exs"
|
|
5
|
+
---
|
|
6
|
+
# Elixir Patterns
|
|
7
|
+
|
|
8
|
+
> This file extends [common/patterns.md](../common/patterns.md) with Elixir specific content.
|
|
9
|
+
|
|
10
|
+
## with for Multi-Step Operations
|
|
11
|
+
|
|
12
|
+
```elixir
|
|
13
|
+
def create_user(params) do
|
|
14
|
+
with {:ok, validated} <- validate(params),
|
|
15
|
+
{:ok, user} <- Repo.insert(User.changeset(%User{}, validated)),
|
|
16
|
+
:ok <- send_welcome_email(user) do
|
|
17
|
+
{:ok, user}
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## GenServer Pattern
|
|
23
|
+
|
|
24
|
+
```elixir
|
|
25
|
+
defmodule MyApp.Cache do
|
|
26
|
+
use GenServer
|
|
27
|
+
|
|
28
|
+
def start_link(opts), do: GenServer.start_link(__MODULE__, %{}, opts)
|
|
29
|
+
|
|
30
|
+
def get(pid, key), do: GenServer.call(pid, {:get, key})
|
|
31
|
+
def put(pid, key, value), do: GenServer.cast(pid, {:put, key, value})
|
|
32
|
+
|
|
33
|
+
@impl true
|
|
34
|
+
def init(state), do: {:ok, state}
|
|
35
|
+
|
|
36
|
+
@impl true
|
|
37
|
+
def handle_call({:get, key}, _from, state), do: {:reply, Map.get(state, key), state}
|
|
38
|
+
|
|
39
|
+
@impl true
|
|
40
|
+
def handle_cast({:put, key, value}, state), do: {:noreply, Map.put(state, key, value)}
|
|
41
|
+
end
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Context Modules (Phoenix)
|
|
45
|
+
|
|
46
|
+
```elixir
|
|
47
|
+
defmodule MyApp.Accounts do
|
|
48
|
+
alias MyApp.Accounts.User
|
|
49
|
+
alias MyApp.Repo
|
|
50
|
+
|
|
51
|
+
def get_user!(id), do: Repo.get!(User, id)
|
|
52
|
+
|
|
53
|
+
def create_user(attrs) do
|
|
54
|
+
%User{}
|
|
55
|
+
|> User.changeset(attrs)
|
|
56
|
+
|> Repo.insert()
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Tagged Tuples for Errors
|
|
62
|
+
|
|
63
|
+
Always return `{:ok, result}` or `{:error, reason}` — never bare values from functions that can fail.
|
|
64
|
+
|
|
65
|
+
## Reference
|
|
66
|
+
|
|
67
|
+
See skill: `phoenix-patterns` for Phoenix LiveView, contexts, and Ecto query patterns.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/*.ex"
|
|
4
|
+
- "**/*.exs"
|
|
5
|
+
---
|
|
6
|
+
# Elixir Security
|
|
7
|
+
|
|
8
|
+
> This file extends [common/security.md](../common/security.md) with Elixir specific content.
|
|
9
|
+
|
|
10
|
+
## Secret Management
|
|
11
|
+
|
|
12
|
+
```elixir
|
|
13
|
+
# config/runtime.exs — read from environment at runtime, never compile-time
|
|
14
|
+
config :my_app, :stripe_key,
|
|
15
|
+
System.fetch_env!("STRIPE_SECRET_KEY") # raises if missing
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Never put secrets in `config/config.exs` or `config/dev.exs` committed to git.
|
|
19
|
+
|
|
20
|
+
## SQL Injection
|
|
21
|
+
|
|
22
|
+
Always use Ecto parameterized queries:
|
|
23
|
+
|
|
24
|
+
```elixir
|
|
25
|
+
# UNSAFE — never do this
|
|
26
|
+
Repo.query("SELECT * FROM users WHERE email = '#{email}'")
|
|
27
|
+
|
|
28
|
+
# SAFE
|
|
29
|
+
from(u in User, where: u.email == ^email) |> Repo.one()
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Atom Exhaustion
|
|
33
|
+
|
|
34
|
+
Never convert untrusted user input to atoms — the atom table is not garbage collected:
|
|
35
|
+
|
|
36
|
+
```elixir
|
|
37
|
+
# UNSAFE
|
|
38
|
+
String.to_atom(user_input)
|
|
39
|
+
|
|
40
|
+
# SAFE
|
|
41
|
+
String.to_existing_atom(user_input) # only if atom must already exist
|
|
42
|
+
# or keep it as a string
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Security Scanning
|
|
46
|
+
|
|
47
|
+
- **Sobelow** for Phoenix/Elixir static security analysis:
|
|
48
|
+
```bash
|
|
49
|
+
mix sobelow --config
|
|
50
|
+
```
|
|
51
|
+
- **mix audit** for dependency vulnerability scanning:
|
|
52
|
+
```bash
|
|
53
|
+
mix hex.audit
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Reference
|
|
57
|
+
|
|
58
|
+
See skill: `security-review` for OWASP top 10 and authentication patterns.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/*.ex"
|
|
4
|
+
- "**/*.exs"
|
|
5
|
+
- "**/test/**"
|
|
6
|
+
---
|
|
7
|
+
# Elixir Testing
|
|
8
|
+
|
|
9
|
+
> This file extends [common/testing.md](../common/testing.md) with Elixir specific content.
|
|
10
|
+
|
|
11
|
+
## Framework
|
|
12
|
+
|
|
13
|
+
Use **ExUnit** (built-in). Use **Mox** for behaviour-based mocking.
|
|
14
|
+
|
|
15
|
+
## Structure
|
|
16
|
+
|
|
17
|
+
```elixir
|
|
18
|
+
defmodule MyApp.AccountsTest do
|
|
19
|
+
use MyApp.DataCase
|
|
20
|
+
|
|
21
|
+
alias MyApp.Accounts
|
|
22
|
+
|
|
23
|
+
describe "create_user/1" do
|
|
24
|
+
test "creates a user with valid attrs" do
|
|
25
|
+
attrs = %{name: "Alice", email: "alice@example.com"}
|
|
26
|
+
assert {:ok, user} = Accounts.create_user(attrs)
|
|
27
|
+
assert user.email == "alice@example.com"
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
test "returns error with invalid attrs" do
|
|
31
|
+
assert {:error, changeset} = Accounts.create_user(%{})
|
|
32
|
+
assert "can't be blank" in errors_on(changeset).email
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Coverage
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
mix test --cover
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Use **excoveralls** for detailed coverage reports:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
mix coveralls
|
|
48
|
+
mix coveralls.html
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Async Tests
|
|
52
|
+
|
|
53
|
+
Mark tests as `async: true` when they don't share state:
|
|
54
|
+
|
|
55
|
+
```elixir
|
|
56
|
+
defmodule MyApp.PureTest do
|
|
57
|
+
use ExUnit.Case, async: true
|
|
58
|
+
...
|
|
59
|
+
end
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Reference
|
|
63
|
+
|
|
64
|
+
See skill: `elixir-testing` for ExUnit async patterns, Mox setup, and property-based testing with StreamData.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/*.rb"
|
|
4
|
+
- "**/*.rake"
|
|
5
|
+
- "**/Gemfile"
|
|
6
|
+
- "**/Rakefile"
|
|
7
|
+
---
|
|
8
|
+
# Ruby Coding Style
|
|
9
|
+
|
|
10
|
+
> This file extends [common/coding-style.md](../common/coding-style.md) with Ruby specific content.
|
|
11
|
+
|
|
12
|
+
## Standards
|
|
13
|
+
|
|
14
|
+
- Follow the **Ruby Style Guide** (rubocop default)
|
|
15
|
+
- Use **frozen_string_literal: true** at the top of every file
|
|
16
|
+
- Prefer `do...end` for multi-line blocks, `{ }` for single-line
|
|
17
|
+
|
|
18
|
+
## Immutability
|
|
19
|
+
|
|
20
|
+
```ruby
|
|
21
|
+
# frozen_string_literal: true
|
|
22
|
+
|
|
23
|
+
User = Data.define(:name, :email) # Ruby 3.2+ immutable value object
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Formatting
|
|
27
|
+
|
|
28
|
+
- **RuboCop** for linting and style enforcement
|
|
29
|
+
- **StandardRB** as a zero-config RuboCop config alternative
|
|
30
|
+
- Line length: 120 characters max
|
|
31
|
+
|
|
32
|
+
## Naming
|
|
33
|
+
|
|
34
|
+
- `snake_case` for methods and variables
|
|
35
|
+
- `CamelCase` for classes and modules
|
|
36
|
+
- `SCREAMING_SNAKE_CASE` for constants
|
|
37
|
+
- Predicate methods end with `?`, destructive methods end with `!`
|
|
38
|
+
|
|
39
|
+
## Reference
|
|
40
|
+
|
|
41
|
+
See skill: `ruby-patterns` for comprehensive Ruby idioms, Rails patterns, and concurrency.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/*.rb"
|
|
4
|
+
- "**/*.rake"
|
|
5
|
+
---
|
|
6
|
+
# Ruby Hooks
|
|
7
|
+
|
|
8
|
+
> This file extends [common/hooks.md](../common/hooks.md) with Ruby specific content.
|
|
9
|
+
|
|
10
|
+
## PostToolUse Hooks
|
|
11
|
+
|
|
12
|
+
Configure in `~/.claude/settings.json`:
|
|
13
|
+
|
|
14
|
+
- **RuboCop**: Auto-lint `.rb` files after edit
|
|
15
|
+
```bash
|
|
16
|
+
rubocop --autocorrect <file>
|
|
17
|
+
```
|
|
18
|
+
- **Syntax check**: Run `ruby -c <file>` after editing
|
|
19
|
+
|
|
20
|
+
## Warnings
|
|
21
|
+
|
|
22
|
+
- Warn about `puts` / `p` statements in non-test `.rb` files (use `Rails.logger` or a logger instead)
|
|
23
|
+
- Warn when `binding.pry` or `byebug` is left in edited files
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/*.rb"
|
|
4
|
+
- "**/*.rake"
|
|
5
|
+
---
|
|
6
|
+
# Ruby Patterns
|
|
7
|
+
|
|
8
|
+
> This file extends [common/patterns.md](../common/patterns.md) with Ruby specific content.
|
|
9
|
+
|
|
10
|
+
## Service Objects
|
|
11
|
+
|
|
12
|
+
```ruby
|
|
13
|
+
# frozen_string_literal: true
|
|
14
|
+
|
|
15
|
+
class CreateUserService
|
|
16
|
+
def initialize(params)
|
|
17
|
+
@params = params
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def call
|
|
21
|
+
user = User.new(@params)
|
|
22
|
+
user.save!
|
|
23
|
+
user
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Usage
|
|
28
|
+
result = CreateUserService.new(params).call
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Value Objects
|
|
32
|
+
|
|
33
|
+
```ruby
|
|
34
|
+
# frozen_string_literal: true
|
|
35
|
+
|
|
36
|
+
Address = Data.define(:street, :city, :country)
|
|
37
|
+
|
|
38
|
+
address = Address.new(street: "123 Main St", city: "London", country: "UK")
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Query Objects
|
|
42
|
+
|
|
43
|
+
```ruby
|
|
44
|
+
# frozen_string_literal: true
|
|
45
|
+
|
|
46
|
+
class ActiveUsersQuery
|
|
47
|
+
def initialize(relation = User.all)
|
|
48
|
+
@relation = relation
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def call
|
|
52
|
+
@relation.where(status: :active).order(created_at: :desc)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Modules for Composition
|
|
58
|
+
|
|
59
|
+
Prefer composition over inheritance for shared behavior:
|
|
60
|
+
|
|
61
|
+
```ruby
|
|
62
|
+
module Auditable
|
|
63
|
+
def self.included(base)
|
|
64
|
+
base.before_action :track_activity
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Reference
|
|
70
|
+
|
|
71
|
+
See skill: `rails-patterns` for Rails-specific patterns including concerns, callbacks, and ActiveRecord best practices.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/*.rb"
|
|
4
|
+
- "**/*.rake"
|
|
5
|
+
---
|
|
6
|
+
# Ruby Security
|
|
7
|
+
|
|
8
|
+
> This file extends [common/security.md](../common/security.md) with Ruby specific content.
|
|
9
|
+
|
|
10
|
+
## Secret Management
|
|
11
|
+
|
|
12
|
+
```ruby
|
|
13
|
+
# Never hardcode secrets
|
|
14
|
+
api_key = ENV.fetch("STRIPE_SECRET_KEY") # raises KeyError if missing, not nil
|
|
15
|
+
|
|
16
|
+
# Rails credentials (encrypted)
|
|
17
|
+
Rails.application.credentials.stripe[:secret_key]
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## SQL Injection
|
|
21
|
+
|
|
22
|
+
Always use parameterized queries — never string interpolation:
|
|
23
|
+
|
|
24
|
+
```ruby
|
|
25
|
+
# UNSAFE
|
|
26
|
+
User.where("email = '#{params[:email]}'")
|
|
27
|
+
|
|
28
|
+
# SAFE
|
|
29
|
+
User.where(email: params[:email])
|
|
30
|
+
User.where("email = ?", params[:email])
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Mass Assignment
|
|
34
|
+
|
|
35
|
+
Use strong parameters in Rails controllers:
|
|
36
|
+
|
|
37
|
+
```ruby
|
|
38
|
+
def user_params
|
|
39
|
+
params.require(:user).permit(:name, :email)
|
|
40
|
+
end
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Security Scanning
|
|
44
|
+
|
|
45
|
+
- **Brakeman** for static security analysis of Rails apps:
|
|
46
|
+
```bash
|
|
47
|
+
brakeman -q
|
|
48
|
+
```
|
|
49
|
+
- **bundler-audit** for dependency CVE scanning:
|
|
50
|
+
```bash
|
|
51
|
+
bundle audit check --update
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Reference
|
|
55
|
+
|
|
56
|
+
See skill: `security-review` for OWASP top 10 and auth patterns.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/*.rb"
|
|
4
|
+
- "**/*_spec.rb"
|
|
5
|
+
- "**/spec/**"
|
|
6
|
+
---
|
|
7
|
+
# Ruby Testing
|
|
8
|
+
|
|
9
|
+
> This file extends [common/testing.md](../common/testing.md) with Ruby specific content.
|
|
10
|
+
|
|
11
|
+
## Framework
|
|
12
|
+
|
|
13
|
+
Use **RSpec** as the testing framework. Use **FactoryBot** for fixtures.
|
|
14
|
+
|
|
15
|
+
## Structure
|
|
16
|
+
|
|
17
|
+
```ruby
|
|
18
|
+
# frozen_string_literal: true
|
|
19
|
+
|
|
20
|
+
RSpec.describe CreateUserService do
|
|
21
|
+
subject(:service) { described_class.new(params) }
|
|
22
|
+
|
|
23
|
+
let(:params) { { name: "Alice", email: "alice@example.com" } }
|
|
24
|
+
|
|
25
|
+
describe "#call" do
|
|
26
|
+
context "with valid params" do
|
|
27
|
+
it "creates a user" do
|
|
28
|
+
expect { service.call }.to change(User, :count).by(1)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
context "with invalid params" do
|
|
33
|
+
let(:params) { { name: "", email: "bad" } }
|
|
34
|
+
|
|
35
|
+
it "raises an error" do
|
|
36
|
+
expect { service.call }.to raise_error(ActiveRecord::RecordInvalid)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Coverage
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
COVERAGE=true bundle exec rspec
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Use **SimpleCov** for coverage reporting. Target 90%+ for new code.
|
|
50
|
+
|
|
51
|
+
## Factories
|
|
52
|
+
|
|
53
|
+
```ruby
|
|
54
|
+
FactoryBot.define do
|
|
55
|
+
factory :user do
|
|
56
|
+
sequence(:email) { |n| "user#{n}@example.com" }
|
|
57
|
+
name { Faker::Name.name }
|
|
58
|
+
status { :active }
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Reference
|
|
64
|
+
|
|
65
|
+
See skill: `ruby-testing` for detailed RSpec patterns, shared examples, and Rails request specs.
|