kodelyth-ecc 1.8.5 → 1.8.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/CHANGELOG.md +20 -0
- package/bin/kodelyth-ecc.js +7 -1
- package/hooks/memory/auto-recall.js +2 -2
- package/hooks/memory/capture-stop.js +2 -2
- package/hooks/safety/token-budget.js +2 -2
- package/package.json +1 -1
- package/scripts/dashboard/data.js +5 -5
- package/scripts/dashboard/server.js +5 -5
- package/scripts/evolve/proposals.js +2 -2
- package/scripts/evolve/stats.js +2 -2
- package/scripts/mcp/client.js +2 -2
- package/scripts/memory/instincts.js +2 -2
- package/scripts/memory/store.js +5 -2
- package/scripts/migrate-legacy.js +110 -0
- package/scripts/router/classify.js +2 -2
- package/tasks/lessons.md +11 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,26 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to Kodelyth ECC are documented here.
|
|
4
4
|
|
|
5
|
+
## v1.8.6 — Memory path rename + auto-migration (July 2026)
|
|
6
|
+
|
|
7
|
+
Renamed the on-disk memory root from `~/.kodelyth/` to `~/.kodelythecc/` across every runtime path. Existing installs auto-migrate on first CLI invocation or hook fire — idempotent, non-destructive, keeps a dated backup of the old directory.
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- All 20 runtime JS files: memory, hooks, dashboard, evolve, MCP, router, tests now point at `~/.kodelythecc/` (42 replacements total)
|
|
12
|
+
- `scripts/memory/store.js` — default `MEMORY_DIR` now `~/.kodelythecc/memory/`; runs migration on `require`
|
|
13
|
+
- `bin/kodelyth-ecc.js` — runs migration on every CLI invocation (no-op after first run)
|
|
14
|
+
- `KODELYTH_MEMORY_DIR` and related env vars kept unchanged for backwards compat
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- `scripts/migrate-legacy.js` — one-shot migrator: merges memories, copies sibling files (index, patterns, projects/, evolve/, safety/, mcp-clients.json), renames old dir to `~/.kodelyth.backup-YYYY-MM-DD`, drops `.migrated-from-kodelyth` marker so it never runs twice
|
|
19
|
+
|
|
20
|
+
### Behavior
|
|
21
|
+
|
|
22
|
+
- **New users**: get `~/.kodelythecc/` from the start
|
|
23
|
+
- **Existing users** (have `~/.kodelyth/`): data migrated on next CLI run or hook fire; original preserved as backup
|
|
24
|
+
|
|
5
25
|
## v1.8.0 — Visual system overhaul + SVG polish (May 2026)
|
|
6
26
|
|
|
7
27
|
Comprehensive overhaul of all 31 social assets. GitHub social preview and OG image rebuilt with two-panel stat card layout. All text overflow issues fixed across the full SVG set. Test counts updated to 373. PNG exports regenerated at 4K only.
|
package/bin/kodelyth-ecc.js
CHANGED
|
@@ -20,6 +20,11 @@ const fs = require('fs');
|
|
|
20
20
|
const os = require('os');
|
|
21
21
|
|
|
22
22
|
const ROOT = path.join(__dirname, '..');
|
|
23
|
+
|
|
24
|
+
// Auto-migrate legacy ~/.kodelyth/ → ~/.kodelythecc/ on first run for existing users.
|
|
25
|
+
// Idempotent; instant no-op if legacy dir is absent or migration marker exists.
|
|
26
|
+
try { require(path.join(ROOT, 'scripts', 'migrate-legacy.js')).main(); } catch { /* best-effort */ }
|
|
27
|
+
|
|
23
28
|
// zsh (unlike bash) passes inline comments as literal args — strip them
|
|
24
29
|
const args = process.argv.slice(2).filter((a, i, arr) => {
|
|
25
30
|
if (a.startsWith('#')) return false; // drop # and everything after
|
|
@@ -863,7 +868,7 @@ if (args.includes('--help') || args.includes('-h')) {
|
|
|
863
868
|
mcp-call <name> <tool> [--json '{"arg":"value"}']
|
|
864
869
|
Call a tool on a registered server. See docs/mcp-clients.md.
|
|
865
870
|
route Recommend trivial/standard/hard model tier for a task. Reads
|
|
866
|
-
.
|
|
871
|
+
.kodelythecc/router.json and KODELYTH_ROUTER_* env vars. Disable with
|
|
867
872
|
KODELYTH_ROUTER=off. Use --json for machine-readable output.
|
|
868
873
|
swarm Run N specialist agents in parallel inside isolated git worktrees +
|
|
869
874
|
a tmux session. Auto-picks agents from --task signals or accepts
|
|
@@ -1010,6 +1015,7 @@ if (isWin) {
|
|
|
1010
1015
|
}
|
|
1011
1016
|
process.exit(result.status ?? 1);
|
|
1012
1017
|
} else {
|
|
1018
|
+
try { require(path.join(ROOT, 'scripts', 'migrate-legacy.js')).main(); } catch {}
|
|
1013
1019
|
const sh = path.join(ROOT, 'install.sh');
|
|
1014
1020
|
if (!fs.existsSync(sh)) {
|
|
1015
1021
|
console.error('Error: install.sh not found in package root:', ROOT);
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
// - Skips on prompts that look like agent commands (`use foo`, `@bar`)
|
|
12
12
|
// - Skips when no memory exists yet
|
|
13
13
|
// - Suppresses repeats: never re-surfaces the same memory twice in a session
|
|
14
|
-
// (state file: ~/.
|
|
14
|
+
// (state file: ~/.kodelythecc/memory/session-surfaced-<sessionId>.json)
|
|
15
15
|
// - Always exits 0 — never blocks the prompt because memory is unavailable
|
|
16
16
|
// =============================================================================
|
|
17
17
|
|
|
@@ -120,7 +120,7 @@ function formatBlock(memories, userPrompt) {
|
|
|
120
120
|
|
|
121
121
|
function surfacedStatePath(sessionId) {
|
|
122
122
|
const dir = process.env.KODELYTH_MEMORY_DIR
|
|
123
|
-
|| path.join(os.homedir(), '.
|
|
123
|
+
|| path.join(os.homedir(), '.kodelythecc', 'memory');
|
|
124
124
|
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
125
125
|
return path.join(dir, `session-surfaced-${sessionId}.json`);
|
|
126
126
|
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
//
|
|
5
5
|
// Runs at the end of a Claude Code session. Locates the session JSONL,
|
|
6
6
|
// extracts memory candidates, writes them to a review queue at:
|
|
7
|
-
// ~/.
|
|
7
|
+
// ~/.kodelythecc/memory/pending-review.jsonl
|
|
8
8
|
//
|
|
9
9
|
// Candidates are NEVER auto-stored. The user reviews via:
|
|
10
10
|
// /memory review-pending
|
|
@@ -51,7 +51,7 @@ function main() {
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
const dir = process.env.KODELYTH_MEMORY_DIR
|
|
54
|
-
|| path.join(os.homedir(), '.
|
|
54
|
+
|| path.join(os.homedir(), '.kodelythecc', 'memory');
|
|
55
55
|
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
56
56
|
|
|
57
57
|
const sessionId = data.session_id || path.basename(sessionJsonl, '.jsonl');
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
// Blocks SessionStart once usage >= budget.
|
|
22
22
|
//
|
|
23
23
|
// Optional knobs:
|
|
24
|
-
// KODELYTH_TOKEN_BUDGET_DIR=/custom/path default ~/.
|
|
24
|
+
// KODELYTH_TOKEN_BUDGET_DIR=/custom/path default ~/.kodelythecc/safety
|
|
25
25
|
// KODELYTH_TOKEN_BUDGET_WARN=0.7 warn threshold (0-1, default 0.7)
|
|
26
26
|
// KODELYTH_TOKEN_BUDGET_RESET=1 wipe usage and exit (admin op)
|
|
27
27
|
//
|
|
@@ -39,7 +39,7 @@ const WARN_PCT = Math.max(0, Math.min(1, Number(process.env.KODELYTH_TOKEN_BUD
|
|
|
39
39
|
const RESET = !!process.env.KODELYTH_TOKEN_BUDGET_RESET;
|
|
40
40
|
|
|
41
41
|
const STATE_DIR = process.env.KODELYTH_TOKEN_BUDGET_DIR
|
|
42
|
-
|| path.join(os.homedir(), '.
|
|
42
|
+
|| path.join(os.homedir(), '.kodelythecc', 'safety');
|
|
43
43
|
|
|
44
44
|
function safeExit(code) {
|
|
45
45
|
try { process.stdout.write(''); } catch {}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kodelyth-ecc",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.6",
|
|
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",
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
//
|
|
5
5
|
// All data the dashboard renders comes from:
|
|
6
6
|
// - The MCP catalog (filesystem reads of agents/, skills/, commands/, rules/, bundles/)
|
|
7
|
-
// - The BM25 memory store (~/.
|
|
8
|
-
// - The evolve signal streams (~/.
|
|
7
|
+
// - The BM25 memory store (~/.kodelythecc/memory/)
|
|
8
|
+
// - The evolve signal streams (~/.kodelythecc/evolve/)
|
|
9
9
|
// - The token-budget hook state (${KODELYTH_TOKEN_BUDGET_DIR})
|
|
10
10
|
// - The orchestration session dirs (.orchestration/<session>/)
|
|
11
11
|
// - Live IDE session activity (Claude Code, Windsurf, Antigravity)
|
|
@@ -35,13 +35,13 @@ const evolveProposals = safeRequire('scripts/evolve/proposals.js');
|
|
|
35
35
|
// ── helpers ──────────────────────────────────────────────────────────────────
|
|
36
36
|
|
|
37
37
|
function defaultMemoryDir() {
|
|
38
|
-
return process.env.KODELYTH_MEMORY_DIR || path.join(os.homedir(), '.
|
|
38
|
+
return process.env.KODELYTH_MEMORY_DIR || path.join(os.homedir(), '.kodelythecc', 'memory');
|
|
39
39
|
}
|
|
40
40
|
function defaultEvolveDir() {
|
|
41
|
-
return process.env.KODELYTH_EVOLVE_DIR || path.join(os.homedir(), '.
|
|
41
|
+
return process.env.KODELYTH_EVOLVE_DIR || path.join(os.homedir(), '.kodelythecc', 'evolve');
|
|
42
42
|
}
|
|
43
43
|
function defaultBudgetDir() {
|
|
44
|
-
return process.env.KODELYTH_TOKEN_BUDGET_DIR || path.join(os.homedir(), '.
|
|
44
|
+
return process.env.KODELYTH_TOKEN_BUDGET_DIR || path.join(os.homedir(), '.kodelythecc', 'token-budget');
|
|
45
45
|
}
|
|
46
46
|
function defaultCoordRoot() {
|
|
47
47
|
return process.env.KODELYTH_COORDINATION_ROOT || path.join(process.cwd(), '.orchestration');
|
|
@@ -37,11 +37,11 @@ const MAX_SSE_CLIENTS = 10;
|
|
|
37
37
|
// IMPORTANT: include both `routing-misses.jsonl` (always present once evolve sees
|
|
38
38
|
// any miss) AND `proposals.jsonl` (created later, after `evolve analyze` runs).
|
|
39
39
|
const WATCH_PATHS = [
|
|
40
|
-
path.join(os.homedir(), '.
|
|
41
|
-
path.join(os.homedir(), '.
|
|
42
|
-
path.join(os.homedir(), '.
|
|
43
|
-
path.join(os.homedir(), '.
|
|
44
|
-
path.join(os.homedir(), '.
|
|
40
|
+
path.join(os.homedir(), '.kodelythecc', 'memory', 'memories.jsonl'),
|
|
41
|
+
path.join(os.homedir(), '.kodelythecc', 'evolve', 'reuse.json'),
|
|
42
|
+
path.join(os.homedir(), '.kodelythecc', 'evolve', 'routing-misses.jsonl'),
|
|
43
|
+
path.join(os.homedir(), '.kodelythecc', 'evolve', 'proposals.jsonl'),
|
|
44
|
+
path.join(os.homedir(), '.kodelythecc', 'token-budget'), // dir mtime — changes when budget files appear
|
|
45
45
|
];
|
|
46
46
|
const lastMtimes = new Map();
|
|
47
47
|
let lastIdeMtime = 0; // max mtime across Claude Code / Windsurf / Antigravity sessions
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
// audit trail is preserved. Reads collapse to "latest state per id".
|
|
13
13
|
//
|
|
14
14
|
// Storage:
|
|
15
|
-
// ${KODELYTH_EVOLVE_DIR:-~/.
|
|
15
|
+
// ${KODELYTH_EVOLVE_DIR:-~/.kodelythecc/evolve}/proposals.jsonl
|
|
16
16
|
//
|
|
17
17
|
// Pure where possible. Public functions accept dir explicitly.
|
|
18
18
|
'use strict';
|
|
@@ -22,7 +22,7 @@ const path = require('path');
|
|
|
22
22
|
const os = require('os');
|
|
23
23
|
|
|
24
24
|
const DEFAULT_DIR = process.env.KODELYTH_EVOLVE_DIR
|
|
25
|
-
|| path.join(os.homedir(), '.
|
|
25
|
+
|| path.join(os.homedir(), '.kodelythecc', 'evolve');
|
|
26
26
|
|
|
27
27
|
const PROPOSALS_FILE = 'proposals.jsonl';
|
|
28
28
|
|
package/scripts/evolve/stats.js
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
// by tokens to surface "we keep getting asked
|
|
15
15
|
// about X but have no agent / skill / memory for it".
|
|
16
16
|
//
|
|
17
|
-
// Storage layout (default ${HOME}/.
|
|
17
|
+
// Storage layout (default ${HOME}/.kodelythecc/evolve/):
|
|
18
18
|
// reuse.json { byMemory: { id: { count, sessions[], lastSurfaced } } }
|
|
19
19
|
// routing-misses.jsonl append-only — one prompt per line
|
|
20
20
|
//
|
|
@@ -31,7 +31,7 @@ const path = require('path');
|
|
|
31
31
|
const crypto = require('crypto');
|
|
32
32
|
|
|
33
33
|
const DEFAULT_DIR = process.env.KODELYTH_EVOLVE_DIR
|
|
34
|
-
|| path.join(os.homedir(), '.
|
|
34
|
+
|| path.join(os.homedir(), '.kodelythecc', 'evolve');
|
|
35
35
|
|
|
36
36
|
const REUSE_FILE = 'reuse.json';
|
|
37
37
|
const MISSES_FILE = 'routing-misses.jsonl';
|
package/scripts/mcp/client.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
// make ECC the MCP HUB: serve to any framework, consume from any provider.
|
|
7
7
|
//
|
|
8
8
|
// Storage:
|
|
9
|
-
// ~/.
|
|
9
|
+
// ~/.kodelythecc/mcp-clients.json registry of named external servers
|
|
10
10
|
//
|
|
11
11
|
// Public API (all functions pure or local file-only):
|
|
12
12
|
// loadRegistry(), saveRegistry(reg)
|
|
@@ -32,7 +32,7 @@ const os = require('os');
|
|
|
32
32
|
const path = require('path');
|
|
33
33
|
|
|
34
34
|
const REGISTRY_DIR = process.env.KODELYTH_MCP_CLIENT_DIR
|
|
35
|
-
|| path.join(os.homedir(), '.
|
|
35
|
+
|| path.join(os.homedir(), '.kodelythecc');
|
|
36
36
|
const REGISTRY_FILE = path.join(REGISTRY_DIR, 'mcp-clients.json');
|
|
37
37
|
|
|
38
38
|
// ── Registry I/O ─────────────────────────────────────────────────────────────
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Kodelyth ECC — Structured Instinct Schema (Improvement B)
|
|
3
3
|
//
|
|
4
4
|
// Stores learned instincts as typed JSON records in:
|
|
5
|
-
// ~/.
|
|
5
|
+
// ~/.kodelythecc/memory/instincts.jsonl
|
|
6
6
|
//
|
|
7
7
|
// Each instinct has: pattern, trigger, confidence, last_used, outcome, decay.
|
|
8
8
|
// This replaces free-form markdown bullets for machine-readable learning.
|
|
@@ -33,7 +33,7 @@ const path = require('path');
|
|
|
33
33
|
const crypto = require('crypto');
|
|
34
34
|
|
|
35
35
|
const MEMORY_DIR = process.env.KODELYTH_MEMORY_DIR
|
|
36
|
-
|| path.join(os.homedir(), '.
|
|
36
|
+
|| path.join(os.homedir(), '.kodelythecc', 'memory');
|
|
37
37
|
|
|
38
38
|
const INSTINCTS_FILE = path.join(MEMORY_DIR, 'instincts.jsonl');
|
|
39
39
|
const STALE_DAYS = 30;
|
package/scripts/memory/store.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Kodelyth ECC — Memory Store
|
|
3
3
|
// Local, zero-dependency, model-agnostic memory for AI coding sessions.
|
|
4
4
|
//
|
|
5
|
-
// Storage layout (all in ~/.
|
|
5
|
+
// Storage layout (all in ~/.kodelythecc/memory/):
|
|
6
6
|
// memories.jsonl Append-only log of every captured memory
|
|
7
7
|
// index.json Inverted index: token -> [memory ids]
|
|
8
8
|
// patterns.json User-level patterns (preferences, conventions)
|
|
@@ -19,8 +19,11 @@ const os = require('os');
|
|
|
19
19
|
const path = require('path');
|
|
20
20
|
const crypto = require('crypto');
|
|
21
21
|
|
|
22
|
+
// Auto-migrate legacy ~/.kodelyth/ → ~/.kodelythecc/ before we touch any path.
|
|
23
|
+
try { require('../migrate-legacy').main(); } catch { /* best-effort */ }
|
|
24
|
+
|
|
22
25
|
const MEMORY_DIR = process.env.KODELYTH_MEMORY_DIR
|
|
23
|
-
|| path.join(os.homedir(), '.
|
|
26
|
+
|| path.join(os.homedir(), '.kodelythecc', 'memory');
|
|
24
27
|
|
|
25
28
|
const PATHS = {
|
|
26
29
|
dir: MEMORY_DIR,
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// One-shot migrator: ~/.kodelyth/ (old canonical) → ~/.kodelythecc/ (1.8.5+ canonical)
|
|
3
|
+
// Idempotent — leaves a marker so it never runs twice.
|
|
4
|
+
// Safe — never deletes source; renames old dir to .backup-<date>.
|
|
5
|
+
|
|
6
|
+
'use strict';
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
const os = require('os');
|
|
11
|
+
|
|
12
|
+
const LEGACY = path.join(os.homedir(), '.kodelyth');
|
|
13
|
+
const NEW = path.join(os.homedir(), '.kodelythecc');
|
|
14
|
+
const MARKER = path.join(NEW, '.migrated-from-kodelyth');
|
|
15
|
+
|
|
16
|
+
function main() {
|
|
17
|
+
if (!fs.existsSync(LEGACY)) return { migrated: false, reason: 'no legacy dir' };
|
|
18
|
+
if (fs.existsSync(MARKER)) return { migrated: false, reason: 'already migrated' };
|
|
19
|
+
|
|
20
|
+
fs.mkdirSync(path.join(NEW, 'memory'), { recursive: true });
|
|
21
|
+
|
|
22
|
+
const legacyMem = path.join(LEGACY, 'memory', 'memories.jsonl');
|
|
23
|
+
const newMem = path.join(NEW, 'memory', 'memories.jsonl');
|
|
24
|
+
let addedLines = 0;
|
|
25
|
+
|
|
26
|
+
if (fs.existsSync(legacyMem)) {
|
|
27
|
+
const existing = new Set(
|
|
28
|
+
fs.existsSync(newMem)
|
|
29
|
+
? fs.readFileSync(newMem, 'utf8').split('\n').filter(Boolean)
|
|
30
|
+
: []
|
|
31
|
+
);
|
|
32
|
+
const legacyLines = fs.readFileSync(legacyMem, 'utf8').split('\n').filter(Boolean);
|
|
33
|
+
const toAppend = legacyLines.filter(l => !existing.has(l));
|
|
34
|
+
if (toAppend.length) {
|
|
35
|
+
fs.appendFileSync(newMem, (existing.size ? '\n' : '') + toAppend.join('\n') + '\n');
|
|
36
|
+
addedLines = toAppend.length;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Copy any sibling files (index.json, session-surfaced-*.json) if not already present.
|
|
41
|
+
const legacyMemDir = path.join(LEGACY, 'memory');
|
|
42
|
+
let copiedFiles = 0;
|
|
43
|
+
if (fs.existsSync(legacyMemDir)) {
|
|
44
|
+
for (const f of fs.readdirSync(legacyMemDir)) {
|
|
45
|
+
if (f === 'memories.jsonl') continue;
|
|
46
|
+
const dst = path.join(NEW, 'memory', f);
|
|
47
|
+
if (!fs.existsSync(dst)) {
|
|
48
|
+
fs.copyFileSync(path.join(legacyMemDir, f), dst);
|
|
49
|
+
copiedFiles++;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Copy other subtrees (evolve, safety, token-budget, mcp-clients.json) if missing.
|
|
55
|
+
const subtrees = ['evolve', 'safety', 'token-budget'];
|
|
56
|
+
for (const sub of subtrees) {
|
|
57
|
+
const src = path.join(LEGACY, sub);
|
|
58
|
+
const dst = path.join(NEW, sub);
|
|
59
|
+
if (fs.existsSync(src) && !fs.existsSync(dst)) {
|
|
60
|
+
copyDirSync(src, dst);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
const legacyMcp = path.join(LEGACY, 'mcp-clients.json');
|
|
64
|
+
const newMcp = path.join(NEW, 'mcp-clients.json');
|
|
65
|
+
if (fs.existsSync(legacyMcp) && !fs.existsSync(newMcp)) {
|
|
66
|
+
fs.copyFileSync(legacyMcp, newMcp);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Rename legacy dir → backup (never delete).
|
|
70
|
+
const stamp = new Date().toISOString().slice(0, 10);
|
|
71
|
+
const backup = path.join(os.homedir(), `.kodelyth.backup-${stamp}`);
|
|
72
|
+
try {
|
|
73
|
+
if (!fs.existsSync(backup)) fs.renameSync(LEGACY, backup);
|
|
74
|
+
} catch { /* best-effort */ }
|
|
75
|
+
|
|
76
|
+
fs.writeFileSync(MARKER, JSON.stringify({
|
|
77
|
+
at: new Date().toISOString(),
|
|
78
|
+
addedLines,
|
|
79
|
+
copiedFiles,
|
|
80
|
+
backupPath: backup,
|
|
81
|
+
}, null, 2));
|
|
82
|
+
|
|
83
|
+
return { migrated: true, addedLines, copiedFiles, backupPath: backup };
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function copyDirSync(src, dst) {
|
|
87
|
+
fs.mkdirSync(dst, { recursive: true });
|
|
88
|
+
for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
|
|
89
|
+
const s = path.join(src, entry.name);
|
|
90
|
+
const d = path.join(dst, entry.name);
|
|
91
|
+
if (entry.isDirectory()) copyDirSync(s, d);
|
|
92
|
+
else fs.copyFileSync(s, d);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (require.main === module) {
|
|
97
|
+
try {
|
|
98
|
+
const r = main();
|
|
99
|
+
if (r.migrated) {
|
|
100
|
+
process.stdout.write(
|
|
101
|
+
`[kodelyth] migrated legacy ~/.kodelyth → ~/.kodelythecc ` +
|
|
102
|
+
`(+${r.addedLines} memories, ${r.copiedFiles} files copied, backup: ${r.backupPath})\n`
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
} catch (e) {
|
|
106
|
+
process.stderr.write(`[kodelyth] migration skipped: ${e.message}\n`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
module.exports = { main };
|
|
@@ -164,13 +164,13 @@ function classify(task, opts = {}) {
|
|
|
164
164
|
return { tier: 'standard', reasons, score, explicit_tier: explicitTier || null };
|
|
165
165
|
}
|
|
166
166
|
|
|
167
|
-
// ── Config loader (env vars + .
|
|
167
|
+
// ── Config loader (env vars + .kodelythecc/router.json) ─────────────────────────
|
|
168
168
|
function loadConfig({ projectRoot = process.cwd() } = {}) {
|
|
169
169
|
const cfg = { ...DEFAULT_MODELS, notes: '' };
|
|
170
170
|
|
|
171
171
|
// 1. Project-level override.
|
|
172
172
|
try {
|
|
173
|
-
const file = path.join(projectRoot, '.
|
|
173
|
+
const file = path.join(projectRoot, '.kodelythecc', 'router.json');
|
|
174
174
|
if (fs.existsSync(file)) {
|
|
175
175
|
const raw = JSON.parse(fs.readFileSync(file, 'utf8'));
|
|
176
176
|
for (const k of ['trivial', 'standard', 'hard', 'default', 'notes']) {
|
package/tasks/lessons.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Claude Lessons
|
|
2
|
+
|
|
3
|
+
Project: **kodelyth-ecc**
|
|
4
|
+
|
|
5
|
+
Auto-generated by Kodelyth ECC. Each entry is a rule Claude learned from a correction.
|
|
6
|
+
Edit freely — add, remove, reword. These are YOUR rules.
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
## 2026-07-03
|
|
10
|
+
|
|
11
|
+
- We need to update our kodelyth ecc ( elite code crew) we build from this - https://github.com/affaan-m/ecc but they are now more advance. So now problem is is our ECC less powerfull then them. We have bm25 memories but not works. We need grab maximum feature from them and attach into ours ( don't te
|