kodelyth-ecc 2.4.1 → 2.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,70 @@
2
2
 
3
3
  All notable changes to Kodelyth ECC are documented here.
4
4
 
5
+ ## v2.4.3 — Memory recall crash fix (the "still dummy" bug) (July 2026)
6
+
7
+ Found by testing ECC as a real user actually experiences it, not just in the test harness. **Memory recall was silently crashing on every prompt** for any user whose `~/.kodelythecc/memory/index.json` was written by an older/foreign BM25 schema.
8
+
9
+ ### Fixed
10
+
11
+ - **`scripts/memory/store.js` — recall threw `Cannot read properties of undefined (reading '<token>')` on every UserPromptSubmit** when the on-disk `index.json` used the schema `{k1, b, corpusStats, index, documents, docFreq}` (from a prior BM25 implementation) instead of the current `{tokens, docCount, avgDocLength, totalLength}`. `search()` read `index.tokens[token]` where `index.tokens` was undefined.
12
+ - **Root cause was a two-headed bug**:
13
+ 1. `loadIndex()` blindly returned whatever JSON was on disk, with no schema validation
14
+ 2. The canonical `rebuildIndex()` correctly rebuilt + saved a valid index but **returned `{count}` instead of the index object**
15
+ - **Fix**: `loadIndex()` now validates the schema via `isValidIndexSchema()` and, on any mismatch/corruption, rebuilds from the append-only `memories.jsonl` (the source of truth). `rebuildIndex()` now returns the rebuilt index (with a `count` property preserved for its other caller). Recall self-heals on first call — no crash, no manual `index.json` deletion needed.
16
+
17
+ ### Added
18
+
19
+ - **Regression test** in `tests/memory/store.test.js` — writes a foreign-schema `index.json`, asserts `recall()` does not throw and returns results, and asserts the on-disk index is rebuilt to the valid schema. This class of bug can no longer ship silently.
20
+
21
+ ### Impact
22
+
23
+ - Every real user with a stale index had **zero working memory recall** — the hook fired, errored, and returned nothing. Auto-recall now works end-to-end.
24
+ - Verified live: corrupted the index with the foreign schema, ran both `store.recall()` and the actual `hooks/memory/auto-recall.js` hook — both self-heal and return real Stripe/CORS memories.
25
+
26
+ ### Why this matters
27
+
28
+ This is exactly the "is it real or is it dummy" gap. Files were installed, hooks were registered, rules loaded — but one core feature crashed on real input while passing every existing test. The lesson: test the installed experience with real data, not just unit fixtures.
29
+
30
+ ## v2.4.2 — SEO-massive documentation refresh (July 2026)
31
+
32
+ Full documentation rewrite for website-ready SEO. Every doc now ships with YAML frontmatter (title, description, keywords, Open Graph, Twitter card, canonical URL, last_updated, version, category). Six new feature docs cover subsystems shipped since v2.0 that were undocumented until now.
33
+
34
+ ### Added — 8 new docs
35
+
36
+ - **`docs/index.md`** — SEO-optimized hub page with keyword-rich intro, platform support table, quick reference
37
+ - **`docs/getting-started.md`** — one-command install, verify, first agent invocation, CLI commands, filesystem layout
38
+ - **`docs/rtk.md`** — RTK integration deep-dive (auto-install, CLI, per-target flags, dashboard, live proof numbers)
39
+ - **`docs/terse-mode.md`** — output-compression skill, 4-level dial, memory-file compressor, byte-preservation rules, ledger, Caveman attribution
40
+ - **`docs/codebase-graph.md`** — 158-language AST intelligence via DeusData/codebase-memory-mcp, query examples, edge types, performance table
41
+ - **`docs/interactive-cli.md`** — arrow-key menu, update check details, background daemon, TTY-detection rules, env-var reference
42
+ - **`docs/uninstall.md`** — full cleanup procedure, dry-run mode, what gets removed vs preserved, programmatic API
43
+ - **`docs/intent-routing.md`** — 10-tier signal system + 8 new routing dimensions, output-format examples, live routing table
44
+ - **`docs/sitemap.md`** — complete documentation index for site builds
45
+
46
+ ### Changed — SEO frontmatter on all 7 existing docs
47
+
48
+ Added YAML frontmatter with SEO metadata to:
49
+
50
+ - `docs/dashboard.md`
51
+ - `docs/evolve.md`
52
+ - `docs/mcp.md`
53
+ - `docs/mcp-clients.md`
54
+ - `docs/replay.md`
55
+ - `docs/supply-chain.md`
56
+ - `docs/swarm.md`
57
+
58
+ Every frontmatter block includes: `title`, `description`, `keywords[]`, `og_title`, `og_description`, `og_image`, `og_type`, `twitter_card`, `canonical`, `last_updated`, `version`, `category`. Format is SSG-agnostic — works with Astro, Next.js, Docusaurus, VitePress, Hugo without translation.
59
+
60
+ ### SVGs
61
+
62
+ 18 files version-bumped `v2.4.1 → v2.4.2`.
63
+
64
+ ### Doc count
65
+
66
+ - Before: 7 docs, no frontmatter, 1,553 lines total, 4 empty subdirs
67
+ - After: 16 docs (9 new), full SEO frontmatter, ~2,500 lines, still 4 empty subdirs (reserved for future `api/`, `architecture/`, `config/`, `guides/` expansion)
68
+
5
69
  ## v2.4.1 — Intent routing v2 (July 2026)
6
70
 
7
71
  Full design pass on `rules/common/agent-intent-routing.md` — the always-on rule that maps plain-language user intent to specialist agents. Deferred from 2.4.0.
package/VERSION CHANGED
@@ -1 +1 @@
1
- 2.4.1
1
+ 2.4.3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kodelyth-ecc",
3
- "version": "2.4.1",
3
+ "version": "2.4.3",
4
4
  "description": "Production-grade AI coding toolkit — 70 agents (incl. devil-mode adversarial crew), 194 skills, 97 commands, parallel multi-agent commands, semantic intent routing, self-learning memory, and a built-in MCP server (16 tools / 6 prompts / 377 resources) that bridges to Claude Desktop, LangGraph, AutoGen, CrewAI, and OpenAI Agents SDK. Works with Claude Code, Windsurf, Cursor, Codex, Antigravity, OpenCode, Cline, RooCode, Aider, Kimi, and Gemini CLI.",
5
5
  "author": "Kodelyth <github.com/sifxprime>",
6
6
  "license": "MIT",
@@ -72,15 +72,37 @@ function newMemoryId() {
72
72
  }
73
73
 
74
74
  // ── Index ────────────────────────────────────────────────────────────────────
75
+ function emptyIndex() {
76
+ return { tokens: {}, docCount: 0, avgDocLength: 0, totalLength: 0 };
77
+ }
78
+
79
+ // A valid index for the current schema MUST have a `tokens` object and a
80
+ // numeric `docCount`. Older/foreign schemas (e.g. `{index, documents, docFreq}`
81
+ // from a prior BM25 implementation) are unrecognised — we rebuild from the
82
+ // append-only memories.jsonl rather than crash on `index.tokens[token]`.
83
+ function isValidIndexSchema(idx) {
84
+ return !!idx
85
+ && typeof idx === 'object'
86
+ && idx.tokens && typeof idx.tokens === 'object'
87
+ && typeof idx.docCount === 'number';
88
+ }
89
+
75
90
  function loadIndex() {
76
91
  if (!fs.existsSync(PATHS.index)) {
77
- return { tokens: {}, docCount: 0, avgDocLength: 0, totalLength: 0 };
92
+ return rebuildIndex();
78
93
  }
94
+ let parsed;
79
95
  try {
80
- return JSON.parse(fs.readFileSync(PATHS.index, 'utf8'));
96
+ parsed = JSON.parse(fs.readFileSync(PATHS.index, 'utf8'));
81
97
  } catch {
82
- return { tokens: {}, docCount: 0, avgDocLength: 0, totalLength: 0 };
98
+ return rebuildIndex();
99
+ }
100
+ if (!isValidIndexSchema(parsed)) {
101
+ // Stale or foreign schema on disk — rebuild from the source of truth
102
+ // (the canonical rebuildIndex defined below rebuilds AND persists a valid index).
103
+ return rebuildIndex();
83
104
  }
105
+ return parsed;
84
106
  }
85
107
 
86
108
  function saveIndex(index) {
@@ -360,14 +382,19 @@ function autoResolveOnEdit(filePath, projectRoot = null) {
360
382
  return resolved;
361
383
  }
362
384
 
385
+ // Rebuild the inverted index from memories.jsonl, persist it, and RETURN the
386
+ // index object (with a `count` property for callers that want the memory total).
387
+ // Returning the index lets loadIndex() self-heal a stale/foreign on-disk schema
388
+ // in a single pass instead of returning a bare {count} that breaks search().
363
389
  function rebuildIndex() {
364
390
  const memories = readMemories();
365
- let index = { tokens: {}, docCount: 0, avgDocLength: 0, totalLength: 0 };
391
+ let index = emptyIndex();
366
392
  for (const m of memories) {
367
- index = indexMemory(index, m);
393
+ if (m && m.id) index = indexMemory(index, m);
368
394
  }
369
- saveIndex(index);
370
- return { count: memories.length };
395
+ try { saveIndex(index); } catch { /* read-only fs — keep in-memory index */ }
396
+ index.count = memories.length;
397
+ return index;
371
398
  }
372
399
 
373
400
  function stats() {