kodelyth-ecc 1.8.0 → 1.8.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/CLAUDE.md +1 -1
- package/VERSION +1 -1
- package/bin/kodelyth-ecc.js +54 -5
- package/install.ps1 +30 -13
- package/install.sh +11 -4
- package/package.json +1 -1
- package/rules/common/agent-intent-routing.md +96 -195
- package/.github/ISSUE_TEMPLATE/bug_report.md +0 -47
- package/.github/ISSUE_TEMPLATE/config.yml +0 -8
- package/.github/ISSUE_TEMPLATE/feature_request.md +0 -41
- package/.github/ISSUE_TEMPLATE/good_first_issue.md +0 -36
- package/.github/ISSUE_TEMPLATE/new_agent.md +0 -52
- package/.github/PULL_REQUEST_TEMPLATE.md +0 -53
- package/.github/workflows/ci.yml +0 -45
- package/.github/workflows/publish.yml +0 -60
- package/brand/concepts.svg +0 -109
- package/brand/convert.js +0 -161
- package/brand/favicon.svg +0 -7
- package/brand/fb-cover.svg +0 -34
- package/brand/fb-profile.svg +0 -21
- package/brand/kodelyth-dark.svg +0 -24
- package/brand/kodelyth-light.svg +0 -24
- package/brand/kodelyth-mark.svg +0 -20
- package/brand/package.json +0 -12
- package/docs/dashboard.md +0 -211
- package/docs/evolve.md +0 -303
- package/docs/mcp-clients.md +0 -167
- package/docs/mcp.md +0 -178
- package/docs/replay.md +0 -244
- package/docs/supply-chain.md +0 -207
- package/docs/swarm.md +0 -243
- package/skills/skill-comply/tests/test_grader.py +0 -137
- package/skills/skill-comply/tests/test_parser.py +0 -90
- package/social/card-agents.svg +0 -104
- package/social/card-install.svg +0 -58
- package/social/card-main.svg +0 -54
- package/social/facebook-v150.svg +0 -110
- package/social/fb-ad-main.svg +0 -128
- package/social/fb-post-features.svg +0 -118
- package/social/fb-post-launch.svg +0 -144
- package/social/fb-post-platforms.svg +0 -135
- package/social/github-social-preview.svg +0 -151
- package/social/hype-compound-learning.svg +0 -129
- package/social/hype-devil-mode.svg +0 -240
- package/social/hype-mcp-server.svg +0 -148
- package/social/hype-parallel-agents.svg +0 -162
- package/social/hype-stats-hero.svg +0 -138
- package/social/og-image.svg +0 -151
- package/social/readme-agents.svg +0 -138
- package/social/readme-hero.svg +0 -102
- package/social/section-agents.svg +0 -69
- package/social/section-author.svg +0 -66
- package/social/section-dashboard.svg +0 -71
- package/social/section-devil.svg +0 -66
- package/social/section-hooks.svg +0 -63
- package/social/section-install.svg +0 -54
- package/social/section-learning.svg +0 -64
- package/social/section-mcp.svg +0 -58
- package/social/section-memory.svg +0 -69
- package/social/section-parallel.svg +0 -84
- package/social/section-routing.svg +0 -63
- package/social/twitter-threads.md +0 -621
- package/social/x-card-agents-grid.svg +0 -120
- package/social/x-card-free.svg +0 -71
- package/social/x-card-hook.svg +0 -94
- package/tests/dashboard/data.test.js +0 -391
- package/tests/dashboard/server.test.js +0 -257
- package/tests/evolve/analyze.test.js +0 -169
- package/tests/evolve/proposals.test.js +0 -173
- package/tests/evolve/stats.test.js +0 -167
- package/tests/hooks/branch-name-check.test.js +0 -184
- package/tests/hooks/smart-suggest.test.js +0 -149
- package/tests/hooks/test-reminder.test.js +0 -181
- package/tests/mcp/catalog.test.js +0 -98
- package/tests/mcp/client.test.js +0 -113
- package/tests/mcp/resources-prompts.test.js +0 -70
- package/tests/mcp/tools.test.js +0 -159
- package/tests/memory/auto-recall.test.js +0 -132
- package/tests/memory/instincts.test.js +0 -258
- package/tests/memory/store.test.js +0 -203
- package/tests/replay/bundle.test.js +0 -181
- package/tests/replay/replay.test.js +0 -131
- package/tests/router/classify.test.js +0 -164
- package/tests/run-all.js +0 -55
- package/tests/safety/patterns.test.js +0 -94
- package/tests/safety/prompt-injection-guard.test.js +0 -111
- package/tests/safety/token-budget.test.js +0 -119
- package/tests/supply-chain/manifest.test.js +0 -147
- package/tests/supply-chain/sbom.test.js +0 -170
- package/tests/supply-chain/verify.test.js +0 -146
- package/tests/swarm/build-plan.test.js +0 -188
package/docs/dashboard.md
DELETED
|
@@ -1,211 +0,0 @@
|
|
|
1
|
-
# Local observability dashboard
|
|
2
|
-
|
|
3
|
-
> A localhost-only single-page web UI that renders every local data source Kodelyth ECC produces. Zero telemetry. Zero external runtime dependencies. Read-only.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Why it exists
|
|
8
|
-
|
|
9
|
-
ECC produces a lot of local state by default:
|
|
10
|
-
|
|
11
|
-
- BM25 memory captures (`~/.kodelyth/memory/`)
|
|
12
|
-
- Self-evolving memory signals + proposals (`~/.kodelyth/evolve/`)
|
|
13
|
-
- Token-budget hook state (`~/.kodelyth/token-budget/`)
|
|
14
|
-
- Swarm/orchestration session dirs (`.orchestration/<session>/`)
|
|
15
|
-
- The full catalog of shipped agents / skills / commands / rules / bundles
|
|
16
|
-
|
|
17
|
-
The only way to see all of this was to read JSON files by hand or run six different CLI subcommands. The dashboard is the one-glance answer.
|
|
18
|
-
|
|
19
|
-
---
|
|
20
|
-
|
|
21
|
-
## Boot
|
|
22
|
-
|
|
23
|
-
```bash
|
|
24
|
-
npx kodelyth-ecc dashboard # default: 127.0.0.1:5747, auto-opens browser
|
|
25
|
-
npx kodelyth-ecc dashboard --port 8088 # custom port
|
|
26
|
-
npx kodelyth-ecc dashboard --no-open # don't auto-open browser (CI / remote shells)
|
|
27
|
-
npx kodelyth-ecc dashboard --host localhost # explicit localhost binding
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
Press `Ctrl+C` to stop. The server has no daemon mode by design — it lives only as long as your terminal session.
|
|
31
|
-
|
|
32
|
-
---
|
|
33
|
-
|
|
34
|
-
## Localhost lock
|
|
35
|
-
|
|
36
|
-
The dashboard exposes everything the BM25 store and evolve log have ever recorded. Memories may contain code, problem statements, project paths, gotchas. The default bind is `127.0.0.1` and the server **refuses** to start on any other interface unless you explicitly opt out:
|
|
37
|
-
|
|
38
|
-
```bash
|
|
39
|
-
KODELYTH_DASHBOARD_ALLOW_REMOTE=1 \
|
|
40
|
-
npx kodelyth-ecc dashboard --host 0.0.0.0
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
This escape hatch is intentionally inconvenient. Don't use it on a network you don't fully control.
|
|
44
|
-
|
|
45
|
-
Without the env var, attempting any non-localhost host produces:
|
|
46
|
-
|
|
47
|
-
```
|
|
48
|
-
[dashboard] refusing to bind host=0.0.0.0. Dashboard is localhost-only by default.
|
|
49
|
-
To override (UNSAFE — exposes your memory + evolve data), set KODELYTH_DASHBOARD_ALLOW_REMOTE=1.
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
---
|
|
53
|
-
|
|
54
|
-
## What you see
|
|
55
|
-
|
|
56
|
-
### Overview tab
|
|
57
|
-
|
|
58
|
-
A wall of stat cards: agents · skills · commands · rules · bundles · captured memories · surfaces · routing misses · pending proposals · swarm sessions. Plus storage paths and a token-budget snapshot.
|
|
59
|
-
|
|
60
|
-
### Memory tab
|
|
61
|
-
|
|
62
|
-
- Stats: total / projects / language count / tag classes
|
|
63
|
-
- BM25 search box (proxies through `/api/memory/search`)
|
|
64
|
-
- Recent captures table with tags + source
|
|
65
|
-
|
|
66
|
-
### Evolve tab
|
|
67
|
-
|
|
68
|
-
- Reuse + miss + proposal counts
|
|
69
|
-
- Top 10 reused memories with surface count and last-seen
|
|
70
|
-
- Top 10 miss clusters with token tags and a sample prompt
|
|
71
|
-
- Proposals table with status pills (`pending` / `accepted` / `rejected` / `applied`)
|
|
72
|
-
|
|
73
|
-
### Catalog tab
|
|
74
|
-
|
|
75
|
-
- Selector for agents / skills / commands / rules / bundles
|
|
76
|
-
- Free-text filter across name, description, tags
|
|
77
|
-
- Tabular results with up to 200 entries per page
|
|
78
|
-
|
|
79
|
-
### Sessions tab
|
|
80
|
-
|
|
81
|
-
- Lists every swarm session in `.orchestration/`
|
|
82
|
-
- Per-session: workers, modified time, expandable detail with `task.md` + `handoff.md` + `status.md` excerpts
|
|
83
|
-
|
|
84
|
-
---
|
|
85
|
-
|
|
86
|
-
## API surface
|
|
87
|
-
|
|
88
|
-
The frontend is just a consumer of these endpoints. They're curl-friendly:
|
|
89
|
-
|
|
90
|
-
| Endpoint | Returns |
|
|
91
|
-
|---|---|
|
|
92
|
-
| `GET /api/health` | `{ ok: true, time: <iso> }` — liveness probe |
|
|
93
|
-
| `GET /api/overview` | counts + storage paths |
|
|
94
|
-
| `GET /api/memory[?limit=N]` | `{ stats, recent }` |
|
|
95
|
-
| `GET /api/memory/search?q=…[&limit=N]` | `{ query, results }` |
|
|
96
|
-
| `GET /api/evolve[?limit=N]` | `{ reuse, miss, proposals }` |
|
|
97
|
-
| `GET /api/catalog?kind=…[&q=…&limit=N]` | `{ kind, counts, items }` (kind ∈ agents/skills/commands/rules/bundles) |
|
|
98
|
-
| `GET /api/sessions[?limit=N]` | `{ sessions }` |
|
|
99
|
-
| `GET /api/sessions/:name` | `{ session, path, workers }` |
|
|
100
|
-
| `GET /api/token-budget` | `{ sessions, total_tokens }` |
|
|
101
|
-
|
|
102
|
-
### Examples
|
|
103
|
-
|
|
104
|
-
```bash
|
|
105
|
-
# Last 5 captured memories
|
|
106
|
-
curl -s http://127.0.0.1:5747/api/memory?limit=5 | jq '.recent'
|
|
107
|
-
|
|
108
|
-
# Search memory for "tailwind v4"
|
|
109
|
-
curl -s 'http://127.0.0.1:5747/api/memory/search?q=tailwind+v4' | jq '.results'
|
|
110
|
-
|
|
111
|
-
# Pending proposals
|
|
112
|
-
curl -s http://127.0.0.1:5747/api/evolve | jq '.proposals[] | select(.status == "pending")'
|
|
113
|
-
|
|
114
|
-
# All agents whose tags include "security"
|
|
115
|
-
curl -s 'http://127.0.0.1:5747/api/catalog?kind=agents&q=security'
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
---
|
|
119
|
-
|
|
120
|
-
## Hard rules (enforced by the server)
|
|
121
|
-
|
|
122
|
-
1. **GET-only.** Any other method returns `405 method not allowed`. The dashboard CANNOT mutate state.
|
|
123
|
-
2. **Localhost lock.** Non-localhost binds refused without `KODELYTH_DASHBOARD_ALLOW_REMOTE=1`.
|
|
124
|
-
3. **Path-traversal-safe.** Static file resolution is sandboxed under `scripts/dashboard/static/`. `../` and similar are rejected.
|
|
125
|
-
4. **No cache.** Every response carries `Cache-Control: no-store`. Data is always fresh.
|
|
126
|
-
5. **Hardened headers.** `X-Frame-Options: DENY`, `X-Content-Type-Options: nosniff`, `Referrer-Policy: no-referrer` on every response.
|
|
127
|
-
6. **No external assets.** No CDNs, no Google Fonts, no analytics. Works fully offline.
|
|
128
|
-
7. **Defensive aggregation.** Every data-source read is wrapped in try/catch with empty-default fallback. A broken memory store renders empty cards, never a 500.
|
|
129
|
-
|
|
130
|
-
---
|
|
131
|
-
|
|
132
|
-
## Architecture
|
|
133
|
-
|
|
134
|
-
```
|
|
135
|
-
scripts/dashboard/
|
|
136
|
-
├── server.js ← HTTP server. Routes API + static files.
|
|
137
|
-
├── data.js ← Pure aggregators. Reads memory + evolve + catalog + sessions + budget.
|
|
138
|
-
└── static/
|
|
139
|
-
└── index.html ← Single-page UI. Hand-rolled CSS + vanilla JS. No build step.
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
### `data.js`
|
|
143
|
-
|
|
144
|
-
Pure functions only. Every aggregator:
|
|
145
|
-
|
|
146
|
-
- Accepts its data-source paths as explicit arguments OR uses well-defined env-overridable defaults
|
|
147
|
-
- Returns sane empty defaults on failure (never throws)
|
|
148
|
-
- Has no global mutable state
|
|
149
|
-
- Is unit-testable in isolation
|
|
150
|
-
|
|
151
|
-
### `server.js`
|
|
152
|
-
|
|
153
|
-
Uses only Node built-ins:
|
|
154
|
-
|
|
155
|
-
- `http` for the listener
|
|
156
|
-
- `fs`, `path` for static files
|
|
157
|
-
- `child_process.execFileSync` for browser auto-open (`open` / `xdg-open` / `cmd /c start`) — no shell interpolation
|
|
158
|
-
|
|
159
|
-
No `express`, no `koa`, no third-party static-file middleware. All hardening is hand-rolled and auditable in ~290 lines.
|
|
160
|
-
|
|
161
|
-
### `index.html`
|
|
162
|
-
|
|
163
|
-
- Hand-rolled CSS (no Tailwind, no CDN)
|
|
164
|
-
- Vanilla JS with `fetch` → no build step, no transpilation
|
|
165
|
-
- Tabs are simple data-attribute toggles
|
|
166
|
-
- Lazy-loads each tab's data only when shown
|
|
167
|
-
- SSE (`/api/events`) pushes `data-changed` events when watched files change; a `heartbeat` every 10 s keeps the green dot alive without triggering data reloads
|
|
168
|
-
|
|
169
|
-
---
|
|
170
|
-
|
|
171
|
-
## Worked example
|
|
172
|
-
|
|
173
|
-
```bash
|
|
174
|
-
$ npx kodelyth-ecc dashboard --port 5747
|
|
175
|
-
✓ Kodelyth ECC dashboard
|
|
176
|
-
http://127.0.0.1:5747/
|
|
177
|
-
Press Ctrl+C to stop. Localhost only — zero telemetry.
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
In another shell:
|
|
181
|
-
|
|
182
|
-
```bash
|
|
183
|
-
$ curl -s http://127.0.0.1:5747/api/overview | jq '.catalog'
|
|
184
|
-
{
|
|
185
|
-
"agents": 70,
|
|
186
|
-
"skills": 193,
|
|
187
|
-
"commands": 96,
|
|
188
|
-
"rules": 14,
|
|
189
|
-
"bundles": 3
|
|
190
|
-
}
|
|
191
|
-
```
|
|
192
|
-
|
|
193
|
-
---
|
|
194
|
-
|
|
195
|
-
## Composition with other features
|
|
196
|
-
|
|
197
|
-
| Feature | Effect on the dashboard |
|
|
198
|
-
|---|---|
|
|
199
|
-
| **Memory store** | Source of the Memory tab. |
|
|
200
|
-
| **Swarm orchestrator** | Source of the Sessions tab. |
|
|
201
|
-
| **Token-budget hook** | Source of the budget snapshot card. |
|
|
202
|
-
| **Self-evolving memory** | Source of the Evolve tab. Proposals appear automatically as they're generated. |
|
|
203
|
-
|
|
204
|
-
---
|
|
205
|
-
|
|
206
|
-
## See also
|
|
207
|
-
|
|
208
|
-
- `skills/observability-dashboard/SKILL.md` — explicit-invocation skill
|
|
209
|
-
- `commands/dashboard.md` — `/dashboard` slash command
|
|
210
|
-
- `scripts/dashboard/{server,data}.js` — implementation
|
|
211
|
-
- `tests/dashboard/` — aggregator + server smoke tests
|
package/docs/evolve.md
DELETED
|
@@ -1,303 +0,0 @@
|
|
|
1
|
-
# Self-evolving memory
|
|
2
|
-
|
|
3
|
-
> Phase 3.4 of the Devil Roadmap. Closes the learning loop on the BM25 memory system. Repeated memory hits become draft skills. Repeated routing misses become proposed routing-rule additions. Nothing is ever auto-applied.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Why this exists
|
|
8
|
-
|
|
9
|
-
ECC already has:
|
|
10
|
-
|
|
11
|
-
- A BM25 memory store (`scripts/memory/store.js`)
|
|
12
|
-
- An auto-recall hook that surfaces relevant memories on every `UserPromptSubmit`
|
|
13
|
-
|
|
14
|
-
What it didn't have, until 3.4: a way for those signals to feed back into the toolkit's own structure. If the same memory keeps getting surfaced across sessions, that memory is doing real work — it should graduate to a `SKILL.md`. If users keep submitting prompts that match no memory at all, that's a routing gap — the routing rule should grow.
|
|
15
|
-
|
|
16
|
-
The 3.4 surface formalizes both loops while preserving the **never auto-commit** rule.
|
|
17
|
-
|
|
18
|
-
---
|
|
19
|
-
|
|
20
|
-
## Two signal streams
|
|
21
|
-
|
|
22
|
-
### 1. Memory reuse (→ skill-upgrade proposals)
|
|
23
|
-
|
|
24
|
-
Every time `auto-recall.js` surfaces a memory to the user, it bumps a counter:
|
|
25
|
-
|
|
26
|
-
```jsonc
|
|
27
|
-
// ~/.kodelyth/evolve/reuse.json
|
|
28
|
-
{
|
|
29
|
-
"byMemory": {
|
|
30
|
-
"<memoryId>": {
|
|
31
|
-
"count": 7,
|
|
32
|
-
"sessions": ["s1", "s2", "s3", ...],
|
|
33
|
-
"projects": ["/path/to/proj-a", "/path/to/proj-b"],
|
|
34
|
-
"firstSurfaced": "2026-04-30T...",
|
|
35
|
-
"lastSurfaced": "2026-05-10T..."
|
|
36
|
-
}
|
|
37
|
-
},
|
|
38
|
-
"lastUpdated": "2026-05-10T..."
|
|
39
|
-
}
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
Counter semantics:
|
|
43
|
-
|
|
44
|
-
- **Per-memory, per-session**: surfacing the same memory ten times in one session counts ONCE. Matches the existing "never re-surface the same memory twice in a session" rule of `auto-recall.js`.
|
|
45
|
-
- **Cross-session**: each fresh session bumps the count by exactly one.
|
|
46
|
-
- **Idempotent**: replaying a session does not double-count.
|
|
47
|
-
|
|
48
|
-
Default threshold: count ≥ 3 AND sessions ≥ 2 → eligible for skill-upgrade proposal.
|
|
49
|
-
|
|
50
|
-
### 2. Routing misses (→ routing-addition proposals)
|
|
51
|
-
|
|
52
|
-
When `shouldRecall(prompt)` is true (substantive prompt, ≥12 chars, ≥2 meaningful tokens, not a slash command) AND BM25 recall returns zero matches, the prompt is logged:
|
|
53
|
-
|
|
54
|
-
```jsonl
|
|
55
|
-
// ~/.kodelyth/evolve/routing-misses.jsonl (append-only)
|
|
56
|
-
{"hash":"abc...","prompt":"...","tokens":["..."],"session_id":"...","project":"...","recorded_at":"..."}
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
Stored prompts are capped at 1000 chars. Top tokens are extracted at write time so analysis is cheap.
|
|
60
|
-
|
|
61
|
-
Default threshold: cluster count ≥ 3 AND distinct prompts ≥ 2 → eligible for routing-addition proposal.
|
|
62
|
-
|
|
63
|
-
---
|
|
64
|
-
|
|
65
|
-
## CLI
|
|
66
|
-
|
|
67
|
-
### `kodelyth-ecc evolve stats`
|
|
68
|
-
|
|
69
|
-
Snapshot of recorded signals. No proposals generated.
|
|
70
|
-
|
|
71
|
-
```
|
|
72
|
-
Kodelyth ECC — self-evolving memory stats
|
|
73
|
-
reuse:
|
|
74
|
-
memories tracked: 14
|
|
75
|
-
total surfaces: 42
|
|
76
|
-
last updated: 2026-05-10T17:23:00.000Z
|
|
77
|
-
top reused:
|
|
78
|
-
• efe17d650917e445 count=7 sessions=5
|
|
79
|
-
• a91ce2034d8b1234 count=5 sessions=4
|
|
80
|
-
routing misses:
|
|
81
|
-
total: 18
|
|
82
|
-
unique prompts: 11
|
|
83
|
-
top clusters:
|
|
84
|
-
• count=4 tokens=[feature, flag, gradual, rollout]
|
|
85
|
-
• count=3 tokens=[migration, postgres, downtime, zero]
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
### `kodelyth-ecc evolve analyze`
|
|
89
|
-
|
|
90
|
-
Apply thresholds and write proposals. Idempotent — same evidence produces the same proposal ID, so re-running never duplicates.
|
|
91
|
-
|
|
92
|
-
| Flag | Default | Effect |
|
|
93
|
-
|---|---|---|
|
|
94
|
-
| `--reuse-min N` | 3 | minimum total surface count |
|
|
95
|
-
| `--reuse-min-sessions N` | 2 | minimum distinct sessions |
|
|
96
|
-
| `--miss-min N` | 3 | minimum miss-cluster total |
|
|
97
|
-
| `--miss-min-distinct N` | 2 | minimum distinct prompts in cluster |
|
|
98
|
-
| `--json` | off | full report instead of pretty summary |
|
|
99
|
-
|
|
100
|
-
### `kodelyth-ecc evolve list [--status pending|accepted|rejected|applied]`
|
|
101
|
-
|
|
102
|
-
Show proposals. Filter by status. Pretty output uses ⏸ ✓ ✗ ★ marks for the four states.
|
|
103
|
-
|
|
104
|
-
### `kodelyth-ecc evolve show <id>`
|
|
105
|
-
|
|
106
|
-
Print the full proposed file content + evidence. **Always preview before accepting.**
|
|
107
|
-
|
|
108
|
-
### `kodelyth-ecc evolve accept <id> [--root DIR] [--overwrite]`
|
|
109
|
-
|
|
110
|
-
Write the proposed `diff` to its `target_path` under `--root`. Refuses to overwrite an existing file unless `--overwrite` is explicit. Marks the proposal `accepted` with the absolute `applied_path` written to the audit trail.
|
|
111
|
-
|
|
112
|
-
**The CLI does not stage, does not commit, does not push.** Review the draft, edit, commit by hand.
|
|
113
|
-
|
|
114
|
-
### `kodelyth-ecc evolve reject <id> [--note "..."]`
|
|
115
|
-
|
|
116
|
-
Mark a proposal `rejected`. The optional `--note` is preserved in the audit trail for future reference.
|
|
117
|
-
|
|
118
|
-
---
|
|
119
|
-
|
|
120
|
-
## Proposal anatomy
|
|
121
|
-
|
|
122
|
-
Both proposal kinds share a structure:
|
|
123
|
-
|
|
124
|
-
```jsonc
|
|
125
|
-
{
|
|
126
|
-
"id": "skill-2537cb787a", // deterministic over evidence
|
|
127
|
-
"type": "skill-upgrade", // or "routing-addition"
|
|
128
|
-
"evidence": {
|
|
129
|
-
"memoryId": "efe17d650917e445",
|
|
130
|
-
"reuseCount": 7,
|
|
131
|
-
"sessions": ["s1", "s2", "s3", "s4", "s5"],
|
|
132
|
-
"firstSurfaced": "...",
|
|
133
|
-
"lastSurfaced": "..."
|
|
134
|
-
},
|
|
135
|
-
"proposal": {
|
|
136
|
-
"kind": "create-skill", // or "add-routing-entry"
|
|
137
|
-
"target_path": "skills/<slug>/SKILL.md", // for skill-upgrade
|
|
138
|
-
"diff": "<full markdown content>",
|
|
139
|
-
"rationale": "Memory '...' surfaced 7x across 5 sessions ..."
|
|
140
|
-
},
|
|
141
|
-
"status": "pending", // pending | accepted | rejected | applied
|
|
142
|
-
"created_at": "...",
|
|
143
|
-
"timestamp": "...",
|
|
144
|
-
"applied_path": null // set on accept
|
|
145
|
-
}
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
### Skill-upgrade diff (sample)
|
|
149
|
-
|
|
150
|
-
```markdown
|
|
151
|
-
---
|
|
152
|
-
name: <slug-from-problem>
|
|
153
|
-
description: <problem text> (auto-derived from memory <id> after repeated reuse)
|
|
154
|
-
origin: kodelyth-evolve
|
|
155
|
-
language: typescript
|
|
156
|
-
tags:
|
|
157
|
-
- <memory tags>
|
|
158
|
-
---
|
|
159
|
-
|
|
160
|
-
# Skill: <slug>
|
|
161
|
-
|
|
162
|
-
> **Auto-derived draft.** Generated by `kodelyth-ecc evolve` after this memory
|
|
163
|
-
> was surfaced repeatedly across multiple sessions. Review, refine, and rename
|
|
164
|
-
> before committing.
|
|
165
|
-
|
|
166
|
-
## Problem
|
|
167
|
-
<memory.problem>
|
|
168
|
-
|
|
169
|
-
## Approach
|
|
170
|
-
<memory.approach>
|
|
171
|
-
|
|
172
|
-
## Gotchas
|
|
173
|
-
<memory.gotchas if any>
|
|
174
|
-
|
|
175
|
-
## When to invoke
|
|
176
|
-
_Replace this section with explicit trigger conditions._
|
|
177
|
-
|
|
178
|
-
## Origin
|
|
179
|
-
- Memory id: `<id>`
|
|
180
|
-
- Captured at: <timestamp>
|
|
181
|
-
- Auto-promoted by Phase 3.4 self-evolving memory.
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
### Routing-addition diff (sample)
|
|
185
|
-
|
|
186
|
-
```markdown
|
|
187
|
-
<!-- proposed addition to rules/common/agent-intent-routing.md -->
|
|
188
|
-
<!-- review by hand, decide on tier + agent, then merge -->
|
|
189
|
-
|
|
190
|
-
### TODO-agent — covers prompts about <token>, <token>, <token>
|
|
191
|
-
|
|
192
|
-
Trigger if the user mentions `<t1>`, `<t2>`, `<t3>`.
|
|
193
|
-
|
|
194
|
-
| Signal | Real human phrasing |
|
|
195
|
-
|---|---|
|
|
196
|
-
| repeated unrouted prompt cluster | <tokens> |
|
|
197
|
-
|
|
198
|
-
**Origin:** Phase 3.4 self-evolving memory — N prompts in this cluster were
|
|
199
|
-
submitted with no memory match and (presumably) no specialist routing.
|
|
200
|
-
|
|
201
|
-
Recent samples:
|
|
202
|
-
- "<sample 1>"
|
|
203
|
-
- "<sample 2>"
|
|
204
|
-
- "<sample 3>"
|
|
205
|
-
|
|
206
|
-
_(Pick the right tier in `rules/common/agent-intent-routing.md` before merging.
|
|
207
|
-
Do NOT commit this block as-is — replace `TODO-agent` with the real agent name
|
|
208
|
-
and slot under the correct priority tier.)_
|
|
209
|
-
```
|
|
210
|
-
|
|
211
|
-
The `TODO-agent` placeholder is intentional. Even if you accept and commit verbatim, the rule won't route any real traffic — it's a no-op until you fill in the agent name.
|
|
212
|
-
|
|
213
|
-
---
|
|
214
|
-
|
|
215
|
-
## Storage layout
|
|
216
|
-
|
|
217
|
-
```
|
|
218
|
-
~/.kodelyth/evolve/ ← override with $KODELYTH_EVOLVE_DIR
|
|
219
|
-
├── reuse.json ← per-memory reuse counters
|
|
220
|
-
├── routing-misses.jsonl ← append-only miss log
|
|
221
|
-
└── proposals.jsonl ← append-only proposal events
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
`proposals.jsonl` is append-only. Every state transition is a new event. Reading collapses to "latest state per id" while preserving the full history for audit.
|
|
225
|
-
|
|
226
|
-
---
|
|
227
|
-
|
|
228
|
-
## Worked example
|
|
229
|
-
|
|
230
|
-
```bash
|
|
231
|
-
# 1) Use ECC normally for a few weeks. The auto-recall hook records signals.
|
|
232
|
-
# 2) Eventually run:
|
|
233
|
-
$ npx kodelyth-ecc evolve stats
|
|
234
|
-
... shows current signal volume ...
|
|
235
|
-
|
|
236
|
-
# 3) Generate proposals.
|
|
237
|
-
$ npx kodelyth-ecc evolve analyze
|
|
238
|
-
✓ analyzed signals
|
|
239
|
-
reuse entries scanned: 14
|
|
240
|
-
miss entries scanned: 11
|
|
241
|
-
proposals generated: 3
|
|
242
|
-
new proposals (added): 3
|
|
243
|
-
|
|
244
|
-
Run 'kodelyth-ecc evolve list' to review.
|
|
245
|
-
|
|
246
|
-
# 4) See what's pending.
|
|
247
|
-
$ npx kodelyth-ecc evolve list
|
|
248
|
-
Kodelyth ECC — self-evolving memory proposals (3)
|
|
249
|
-
⏸ [pending] skill-2537cb787a skill-upgrade
|
|
250
|
-
target: skills/tailwind-v4-arbitrary-values/SKILL.md
|
|
251
|
-
why: Memory '...' surfaced 7x across 5 sessions ...
|
|
252
|
-
⏸ [pending] route-13d976a554 routing-addition
|
|
253
|
-
target: rules/common/agent-intent-routing.md
|
|
254
|
-
why: 4 substantive prompts (4 distinct) clustered on tokens [...]
|
|
255
|
-
|
|
256
|
-
# 5) Inspect the skill draft.
|
|
257
|
-
$ npx kodelyth-ecc evolve show skill-2537cb787a
|
|
258
|
-
... full markdown + evidence ...
|
|
259
|
-
|
|
260
|
-
# 6) Accept it. Writes to disk. NEVER commits.
|
|
261
|
-
$ npx kodelyth-ecc evolve accept skill-2537cb787a
|
|
262
|
-
✓ accepted skill-2537cb787a
|
|
263
|
-
draft written: /path/to/repo/skills/tailwind-v4-arbitrary-values/SKILL.md
|
|
264
|
-
|
|
265
|
-
Review the draft. When you're happy with it, commit it.
|
|
266
|
-
|
|
267
|
-
# 7) Reject the routing one — already covered.
|
|
268
|
-
$ npx kodelyth-ecc evolve reject route-13d976a554 --note "covered by debug-detective"
|
|
269
|
-
✗ rejected route-13d976a554 (note: covered by debug-detective)
|
|
270
|
-
```
|
|
271
|
-
|
|
272
|
-
---
|
|
273
|
-
|
|
274
|
-
## Hard rules
|
|
275
|
-
|
|
276
|
-
1. **NEVER auto-apply.** `accept` writes a draft. The user reviews, edits, commits.
|
|
277
|
-
2. **NEVER overwrite without `--overwrite`.** Even on accept of a stale proposal.
|
|
278
|
-
3. **NEVER block the recall hook.** All evolve recording is wrapped in try/catch and lazy-required.
|
|
279
|
-
4. **NEVER auto-route a `TODO-agent` proposal.** The placeholder is intentional.
|
|
280
|
-
5. **Idempotent IDs.** Stable evidence → stable proposal ID. Re-running `analyze` never duplicates.
|
|
281
|
-
6. **Append-only proposal log.** Every state change is a new event. Full audit trail preserved.
|
|
282
|
-
|
|
283
|
-
---
|
|
284
|
-
|
|
285
|
-
## Composition with other phases
|
|
286
|
-
|
|
287
|
-
| Pair | Effect |
|
|
288
|
-
|---|---|
|
|
289
|
-
| BM25 memory store | Source of reuse signals. |
|
|
290
|
-
| `/memory remember` | Manually captured memories that get reused → skill proposals. |
|
|
291
|
-
| `rules/common/agent-intent-routing.md` | Direct target for routing-addition proposals. |
|
|
292
|
-
| Phase 2.7 swarm | Repeated swarm tasks reusing the same memories → those memories become skills the swarm picker can choose automatically. |
|
|
293
|
-
| Phase 2.8 replay | Replay bundles re-trigger reuse signals when the same memory is surfaced again. |
|
|
294
|
-
| Phase 2.10 token-budget hook | Promoting memories → skills means cheaper recalls. |
|
|
295
|
-
|
|
296
|
-
---
|
|
297
|
-
|
|
298
|
-
## See also
|
|
299
|
-
|
|
300
|
-
- `skills/self-evolving-memory/SKILL.md` — explicit-invocation skill
|
|
301
|
-
- `commands/memory-evolve.md` — `/memory-evolve` slash command
|
|
302
|
-
- `scripts/evolve/{stats,analyze,proposals}.js` — pure-function implementation
|
|
303
|
-
- `hooks/memory/auto-recall.js` — signal capture (Phase 3.4 augmentation)
|
package/docs/mcp-clients.md
DELETED
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
# Kodelyth ECC — MCP Client Mode
|
|
2
|
-
|
|
3
|
-
The other half of the MCP story. While `npx kodelyth-ecc mcp` (Phase 2.1) **serves** ECC to any MCP-compatible client, MCP client mode lets ECC **consume** any external MCP server — Stripe, GitHub, Postgres, Redis, Brave, Filesystem, Shopify, Sentry, anything.
|
|
4
|
-
|
|
5
|
-
> **Phase 2.5 of the [Devil Roadmap](../README.md).** This makes ECC the MCP **hub**, not just a node. Local-only registry. Zero telemetry. Same SDK as the server side.
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## Quick start
|
|
10
|
-
|
|
11
|
-
### 1. Register an external MCP server
|
|
12
|
-
|
|
13
|
-
```bash
|
|
14
|
-
# Public servers (no env vars needed)
|
|
15
|
-
npx kodelyth-ecc mcp-add brave -- npx -y @modelcontextprotocol/server-brave-search
|
|
16
|
-
npx kodelyth-ecc mcp-add filesystem -- npx -y @modelcontextprotocol/server-filesystem /Users/me/notes
|
|
17
|
-
|
|
18
|
-
# Servers that need credentials
|
|
19
|
-
npx kodelyth-ecc mcp-add github \
|
|
20
|
-
--env GITHUB_PERSONAL_ACCESS_TOKEN=ghp_... \
|
|
21
|
-
--desc "ECC project ops on github" \
|
|
22
|
-
-- npx -y @modelcontextprotocol/server-github
|
|
23
|
-
|
|
24
|
-
npx kodelyth-ecc mcp-add postgres \
|
|
25
|
-
--env DB_URL=postgres://localhost/myapp \
|
|
26
|
-
-- npx -y @modelcontextprotocol/server-postgres
|
|
27
|
-
|
|
28
|
-
npx kodelyth-ecc mcp-add stripe \
|
|
29
|
-
--env STRIPE_API_KEY=sk_... \
|
|
30
|
-
-- npx -y @stripe/mcp
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
The registry is stored at `~/.kodelyth/mcp-clients.json` (override with `KODELYTH_MCP_CLIENT_DIR`).
|
|
34
|
-
|
|
35
|
-
### 2. Inspect a registered server
|
|
36
|
-
|
|
37
|
-
```bash
|
|
38
|
-
npx kodelyth-ecc mcp-list # all registered
|
|
39
|
-
npx kodelyth-ecc mcp-tools github # tools the server exposes
|
|
40
|
-
npx kodelyth-ecc mcp-resources filesystem # resources
|
|
41
|
-
npx kodelyth-ecc mcp-prompts brave # prompts
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
### 3. Call a tool
|
|
45
|
-
|
|
46
|
-
```bash
|
|
47
|
-
# No args:
|
|
48
|
-
npx kodelyth-ecc mcp-call github list_repos
|
|
49
|
-
|
|
50
|
-
# JSON args:
|
|
51
|
-
npx kodelyth-ecc mcp-call github create_issue \
|
|
52
|
-
--json '{"owner":"sifxprime","repo":"kodelyth-ecc","title":"hi from ECC"}'
|
|
53
|
-
|
|
54
|
-
npx kodelyth-ecc mcp-call postgres query \
|
|
55
|
-
--json '{"sql":"SELECT count(*) FROM users"}'
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
### 4. Unregister
|
|
59
|
-
|
|
60
|
-
```bash
|
|
61
|
-
npx kodelyth-ecc mcp-remove github
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
---
|
|
65
|
-
|
|
66
|
-
## CLI surface
|
|
67
|
-
|
|
68
|
-
| Command | Description |
|
|
69
|
-
|---|---|
|
|
70
|
-
| `mcp-add <name> [--env K=V] [--desc "..."] -- <command> [args...]` | Register an external server. |
|
|
71
|
-
| `mcp-list` | List registered servers. |
|
|
72
|
-
| `mcp-remove <name>` | Unregister. |
|
|
73
|
-
| `mcp-tools <name>` | List tools exposed by the server. |
|
|
74
|
-
| `mcp-resources <name>` | List resources. |
|
|
75
|
-
| `mcp-prompts <name>` | List prompts. |
|
|
76
|
-
| `mcp-call <name> <tool> [--json '{"arg":"value"}']` | Call a tool with JSON arguments. |
|
|
77
|
-
|
|
78
|
-
The `--` separator before the command is mandatory in `mcp-add` so the registry can disambiguate flags belonging to ECC from flags meant for the external server.
|
|
79
|
-
|
|
80
|
-
---
|
|
81
|
-
|
|
82
|
-
## Programmatic use
|
|
83
|
-
|
|
84
|
-
The same registry powers in-session agent tool calls. Inside an ECC agent or skill, require the client library:
|
|
85
|
-
|
|
86
|
-
```js
|
|
87
|
-
const client = require('kodelyth-ecc/scripts/mcp/client.js');
|
|
88
|
-
|
|
89
|
-
// Open a stable connection.
|
|
90
|
-
const session = await client.connect('github');
|
|
91
|
-
const out = await session.client.callTool({
|
|
92
|
-
name: 'create_issue',
|
|
93
|
-
arguments: { owner: 'sifxprime', repo: 'kodelyth-ecc', title: 'auto-issue' },
|
|
94
|
-
});
|
|
95
|
-
await session.close();
|
|
96
|
-
|
|
97
|
-
// Or one-shot:
|
|
98
|
-
const tools = await client.listTools('postgres');
|
|
99
|
-
const stats = await client.callTool('redis', 'set', { key: 'k', value: 'v' });
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
Every call spawns a fresh stdio subprocess; there's no long-lived process pool. This is intentional — failed servers don't poison subsequent calls, and credentials live only in the per-call env.
|
|
103
|
-
|
|
104
|
-
---
|
|
105
|
-
|
|
106
|
-
## Registry shape
|
|
107
|
-
|
|
108
|
-
```json
|
|
109
|
-
{
|
|
110
|
-
"servers": {
|
|
111
|
-
"github": {
|
|
112
|
-
"name": "github",
|
|
113
|
-
"command": "npx",
|
|
114
|
-
"args": ["-y", "@modelcontextprotocol/server-github"],
|
|
115
|
-
"env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_..." },
|
|
116
|
-
"description": "ECC project ops on github",
|
|
117
|
-
"added_at": "2026-05-10T10:48:00.690Z"
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
You can hand-edit the file. Reserved name patterns: alphanumeric, dash, underscore.
|
|
124
|
-
|
|
125
|
-
---
|
|
126
|
-
|
|
127
|
-
## Pairing with the rest of ECC
|
|
128
|
-
|
|
129
|
-
| Pairs with | How |
|
|
130
|
-
|---|---|
|
|
131
|
-
| **Phase 2.1 — MCP server** | The two halves complete each other. ECC serves to any framework AND consumes from any provider. |
|
|
132
|
-
| **Phase 2.10 — prompt-injection-guard** | Tool responses from external MCP servers are scanned for indirect injection on `PostToolUse:mcp__*` (opt in via `KODELYTH_PI_GUARD=warn|block`). |
|
|
133
|
-
| **Phase 2.4 — cost-aware model router** | Tool responses are part of the session token-budget when the safety hook is enabled. |
|
|
134
|
-
| **kodelyth-memory** | Capture interesting tool responses as memories with `kodelyth-ecc remember "..." --approach "..."`. |
|
|
135
|
-
|
|
136
|
-
---
|
|
137
|
-
|
|
138
|
-
## Privacy & safety
|
|
139
|
-
|
|
140
|
-
- **No network egress from this client** — it only spawns subprocesses you registered.
|
|
141
|
-
- **Credentials live in the registry file.** Treat `~/.kodelyth/mcp-clients.json` like a secrets file. `chmod 600` is recommended on shared machines.
|
|
142
|
-
- **External servers can do whatever the user gives them permission to do** — register only servers you trust.
|
|
143
|
-
- **Pair with `prompt-injection-guard`** to scan tool responses for indirect injection before agents act on them.
|
|
144
|
-
|
|
145
|
-
---
|
|
146
|
-
|
|
147
|
-
## Troubleshooting
|
|
148
|
-
|
|
149
|
-
**"Kodelyth MCP client requires `@modelcontextprotocol/sdk`"** — run `npm install @modelcontextprotocol/sdk` once, or rerun via `npx -y kodelyth-ecc ...`.
|
|
150
|
-
|
|
151
|
-
**"MCP server X is not registered"** — `mcp-list` shows nothing because the registry lives at `~/.kodelyth/mcp-clients.json` (or `$KODELYTH_MCP_CLIENT_DIR`). Re-run `mcp-add`.
|
|
152
|
-
|
|
153
|
-
**Server hangs on connect** — the external server probably needs env vars you didn't pass. Re-add with `--env KEY=VAL`.
|
|
154
|
-
|
|
155
|
-
**Tool call returns `isError: true`** — the external server rejected the call. Inspect the `content[0].text` for the underlying error message; it's typed exactly as the spec.
|
|
156
|
-
|
|
157
|
-
---
|
|
158
|
-
|
|
159
|
-
## Roadmap interactions
|
|
160
|
-
|
|
161
|
-
- **Phase 2.6 — sandbox layer** will wrap external MCP servers in Docker/firejail isolation by default.
|
|
162
|
-
- **Phase 2.3 — local dashboard** will show live MCP traffic per registered server (count, latency, errors).
|
|
163
|
-
- **Phase 2.9 — SLSA/SBOM** will publish provenance for the ECC server side and let `supply-chain-auditor` verify external server packages.
|
|
164
|
-
|
|
165
|
-
---
|
|
166
|
-
|
|
167
|
-
Built into [Kodelyth ECC](../README.md). MIT licensed. PRs welcome.
|