claude-flow 3.22.0 → 3.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/helpers/.helpers-version +1 -0
- package/.claude/helpers/auto-memory-hook.mjs +59 -274
- package/.claude/helpers/helpers.manifest.json +12 -0
- package/.claude/helpers/hook-handler.cjs +132 -112
- package/.claude/helpers/intelligence.cjs +992 -196
- package/package.json +1 -1
- package/v3/@claude-flow/cli/dist/src/commands/memory-backup.d.ts +11 -0
- package/v3/@claude-flow/cli/dist/src/commands/memory-backup.js +46 -0
- package/v3/@claude-flow/cli/dist/src/commands/memory.js +2 -1
- package/v3/@claude-flow/cli/dist/src/config/harness-feedback-applier.d.ts +50 -0
- package/v3/@claude-flow/cli/dist/src/config/harness-feedback-applier.js +122 -0
- package/v3/@claude-flow/cli/dist/src/config/proven-config-refresh.d.ts +39 -0
- package/v3/@claude-flow/cli/dist/src/config/proven-config-refresh.js +154 -0
- package/v3/@claude-flow/cli/dist/src/config/proven-config-rvfa.d.ts +23 -0
- package/v3/@claude-flow/cli/dist/src/config/proven-config-rvfa.js +73 -0
- package/v3/@claude-flow/cli/dist/src/config/proven-config.d.ts +86 -0
- package/v3/@claude-flow/cli/dist/src/config/proven-config.js +176 -0
- package/v3/@claude-flow/cli/dist/src/index.js +35 -0
- package/v3/@claude-flow/cli/dist/src/mcp-tools/neural-tools.d.ts +10 -0
- package/v3/@claude-flow/cli/dist/src/mcp-tools/neural-tools.js +107 -18
- package/v3/@claude-flow/cli/dist/src/services/daemon-autostart.d.ts +17 -0
- package/v3/@claude-flow/cli/dist/src/services/daemon-autostart.js +79 -0
- package/v3/@claude-flow/cli/dist/src/services/evolve-proof.d.ts +247 -0
- package/v3/@claude-flow/cli/dist/src/services/evolve-proof.js +341 -0
- package/v3/@claude-flow/cli/dist/src/services/harness-benchmark.d.ts +68 -0
- package/v3/@claude-flow/cli/dist/src/services/harness-benchmark.js +94 -0
- package/v3/@claude-flow/cli/dist/src/services/harness-canary.d.ts +60 -0
- package/v3/@claude-flow/cli/dist/src/services/harness-canary.js +69 -0
- package/v3/@claude-flow/cli/dist/src/services/harness-corpus-harvester.d.ts +51 -0
- package/v3/@claude-flow/cli/dist/src/services/harness-corpus-harvester.js +74 -0
- package/v3/@claude-flow/cli/dist/src/services/harness-flywheel-generations.d.ts +111 -0
- package/v3/@claude-flow/cli/dist/src/services/harness-flywheel-generations.js +354 -0
- package/v3/@claude-flow/cli/dist/src/services/harness-flywheel-runtime.d.ts +25 -0
- package/v3/@claude-flow/cli/dist/src/services/harness-flywheel-runtime.js +101 -0
- package/v3/@claude-flow/cli/dist/src/services/harness-flywheel.d.ts +48 -0
- package/v3/@claude-flow/cli/dist/src/services/harness-flywheel.js +207 -0
- package/v3/@claude-flow/cli/dist/src/services/harness-hosts.d.ts +40 -0
- package/v3/@claude-flow/cli/dist/src/services/harness-hosts.js +88 -0
- package/v3/@claude-flow/cli/dist/src/services/harness-improvement-ledger.d.ts +63 -0
- package/v3/@claude-flow/cli/dist/src/services/harness-improvement-ledger.js +101 -0
- package/v3/@claude-flow/cli/dist/src/services/harness-loop.d.ts +53 -0
- package/v3/@claude-flow/cli/dist/src/services/harness-loop.js +85 -0
- package/v3/@claude-flow/cli/dist/src/services/harness-qualification.d.ts +66 -0
- package/v3/@claude-flow/cli/dist/src/services/harness-qualification.js +143 -0
- package/v3/@claude-flow/cli/dist/src/services/harness-replay.d.ts +37 -0
- package/v3/@claude-flow/cli/dist/src/services/harness-replay.js +92 -0
- package/v3/@claude-flow/cli/dist/src/services/harness-verify.d.ts +33 -0
- package/v3/@claude-flow/cli/dist/src/services/harness-verify.js +26 -0
- package/v3/@claude-flow/cli/dist/src/services/harness-worker.d.ts +23 -0
- package/v3/@claude-flow/cli/dist/src/services/harness-worker.js +66 -0
- package/v3/@claude-flow/cli/dist/src/services/memory-backup.d.ts +24 -0
- package/v3/@claude-flow/cli/dist/src/services/memory-backup.js +94 -0
- package/v3/@claude-flow/cli/dist/src/services/worker-daemon.d.ts +16 -1
- package/v3/@claude-flow/cli/dist/src/services/worker-daemon.js +84 -0
- package/v3/@claude-flow/cli/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.23.0
|
|
@@ -27,16 +27,29 @@ const CYAN = '\x1b[0;36m';
|
|
|
27
27
|
const DIM = '\x1b[2m';
|
|
28
28
|
const RESET = '\x1b[0m';
|
|
29
29
|
|
|
30
|
+
const YELLOW = '\x1b[0;33m';
|
|
30
31
|
const log = (msg) => console.log(`${CYAN}[AutoMemory] ${msg}${RESET}`);
|
|
31
32
|
const success = (msg) => console.log(`${GREEN}[AutoMemory] ✓ ${msg}${RESET}`);
|
|
32
33
|
const dim = (msg) => console.log(` ${DIM}${msg}${RESET}`);
|
|
33
34
|
|
|
35
|
+
// #2545: fail LOUD instead of a silent dim skip. When @claude-flow/memory cannot
|
|
36
|
+
// be resolved, self-learning imports are a no-op — the user must see this and be
|
|
37
|
+
// told exactly how to fix it (on both stdout, so it shows in the Claude Code hook
|
|
38
|
+
// transcript, and stderr, per the issue's requested channel).
|
|
39
|
+
function warnMemoryUnavailable() {
|
|
40
|
+
const line1 = `[AutoMemory] @claude-flow/memory not resolvable from ${PROJECT_ROOT} — self-learning imports are DISABLED.`;
|
|
41
|
+
const line2 = ' Fix: npm i -D @claude-flow/memory (or re-run: npx ruflo@latest init, then npx ruflo@latest doctor --fix)';
|
|
42
|
+
console.log(`${YELLOW}${line1}${RESET}`);
|
|
43
|
+
console.log(`${YELLOW}${line2}${RESET}`);
|
|
44
|
+
process.stderr.write(`${line1}\n${line2}\n`);
|
|
45
|
+
}
|
|
46
|
+
|
|
34
47
|
const DEBUG = !!(process.env.RUFLO_DEBUG || process.env.DEBUG);
|
|
35
48
|
|
|
36
49
|
// ── Graceful shutdown (FIX 3) ───────────────────────────────────────────────
|
|
37
|
-
// Track the backend
|
|
38
|
-
//
|
|
39
|
-
//
|
|
50
|
+
// Track the backend in use so a SIGTERM/SIGINT mid-run can still flush it
|
|
51
|
+
// (the JSON backend persists; a SQLite-backed one closes/flushes WAL) instead
|
|
52
|
+
// of leaving a half-written store or a stale lock behind.
|
|
40
53
|
let activeBackend = null;
|
|
41
54
|
let shuttingDown = false;
|
|
42
55
|
function trackBackend(b) { activeBackend = b; return b; }
|
|
@@ -151,77 +164,31 @@ class JsonFileBackend {
|
|
|
151
164
|
// Resolve memory package path (local dev or npm installed)
|
|
152
165
|
// ============================================================================
|
|
153
166
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
* 5. Global npm prefix — checks the ruflo / claude-flow / @claude-flow/cli
|
|
161
|
-
* bundles, AND the package installed globally on its own
|
|
162
|
-
*
|
|
163
|
-
* Returns the resolved absolute path, or null. See issue #2285.
|
|
164
|
-
*/
|
|
165
|
-
async function resolveBundledFile(pkg, relativeFile) {
|
|
166
|
-
const monorepo = join(PROJECT_ROOT, 'v3', pkg, relativeFile);
|
|
167
|
-
if (existsSync(monorepo)) return monorepo;
|
|
168
|
-
|
|
169
|
-
const cwd = process.env.CLAUDE_FLOW_CWD || process.cwd();
|
|
170
|
-
const inCwd = join(cwd, 'node_modules', pkg, relativeFile);
|
|
171
|
-
if (existsSync(inCwd)) return inCwd;
|
|
172
|
-
|
|
173
|
-
const walkUp = (start) => {
|
|
174
|
-
let dir = start;
|
|
175
|
-
while (dir && dir !== dirname(dir)) {
|
|
176
|
-
const candidate = join(dir, 'node_modules', pkg, relativeFile);
|
|
177
|
-
if (existsSync(candidate)) return candidate;
|
|
178
|
-
dir = dirname(dir);
|
|
179
|
-
}
|
|
180
|
-
return null;
|
|
181
|
-
};
|
|
182
|
-
|
|
183
|
-
const fromProject = walkUp(PROJECT_ROOT);
|
|
184
|
-
if (fromProject) return fromProject;
|
|
185
|
-
|
|
186
|
-
const fromCwd = walkUp(cwd);
|
|
187
|
-
if (fromCwd) return fromCwd;
|
|
188
|
-
|
|
189
|
-
// Global npm prefix fallback — handles `npm i -g ruflo` and friends, where
|
|
190
|
-
// the marketplace clone (PROJECT_ROOT) has no access to the bundled deps.
|
|
167
|
+
async function loadMemoryPackage() {
|
|
168
|
+
// Strategy 0 (#2545): sidecar recorded by `init` / `doctor --fix`. On the
|
|
169
|
+
// documented `npx ruflo` path @claude-flow/memory (an optionalDependency of
|
|
170
|
+
// the CLI) lands in the npx cache, which is NOT on the walk-up path from the
|
|
171
|
+
// project — so init resolves it from the CLI's own context and records the
|
|
172
|
+
// absolute path here. This is the only strategy that works on that install.
|
|
191
173
|
try {
|
|
192
|
-
const
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
if (npmPrefix) {
|
|
198
|
-
// Both Unix (<prefix>/lib/node_modules) and Windows (<prefix>/node_modules)
|
|
199
|
-
const roots = [join(npmPrefix, 'lib', 'node_modules'), join(npmPrefix, 'node_modules')];
|
|
200
|
-
const wrappers = ['ruflo', 'claude-flow', join('@claude-flow', 'cli')];
|
|
201
|
-
for (const root of roots) {
|
|
202
|
-
for (const wrapper of wrappers) {
|
|
203
|
-
const candidate = join(root, wrapper, 'node_modules', pkg, relativeFile);
|
|
204
|
-
if (existsSync(candidate)) return candidate;
|
|
205
|
-
}
|
|
206
|
-
const direct = join(root, pkg, relativeFile);
|
|
207
|
-
if (existsSync(direct)) return direct;
|
|
174
|
+
const sidecar = join(PROJECT_ROOT, '.claude-flow', 'memory-package.json');
|
|
175
|
+
if (existsSync(sidecar)) {
|
|
176
|
+
const rec = JSON.parse(readFileSync(sidecar, 'utf-8'));
|
|
177
|
+
if (rec?.distPath && existsSync(rec.distPath)) {
|
|
178
|
+
return await import(`file://${rec.distPath}`);
|
|
208
179
|
}
|
|
209
180
|
}
|
|
210
|
-
} catch { /*
|
|
211
|
-
|
|
212
|
-
return null;
|
|
213
|
-
}
|
|
181
|
+
} catch { /* fall through */ }
|
|
214
182
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
if (resolved) {
|
|
183
|
+
// Strategy 1: Local dev (built dist)
|
|
184
|
+
const localDist = join(PROJECT_ROOT, 'v3/@claude-flow/memory/dist/index.js');
|
|
185
|
+
if (existsSync(localDist)) {
|
|
219
186
|
try {
|
|
220
|
-
return await import(`file://${
|
|
187
|
+
return await import(`file://${localDist}`);
|
|
221
188
|
} catch { /* fall through */ }
|
|
222
189
|
}
|
|
223
190
|
|
|
224
|
-
// Strategy
|
|
191
|
+
// Strategy 2: Use createRequire for CJS-style resolution (handles nested node_modules
|
|
225
192
|
// when installed as a transitive dependency via npx ruflo / npx claude-flow)
|
|
226
193
|
try {
|
|
227
194
|
const { createRequire } = await import('module');
|
|
@@ -229,11 +196,24 @@ async function loadMemoryPackage() {
|
|
|
229
196
|
return require('@claude-flow/memory');
|
|
230
197
|
} catch { /* fall through */ }
|
|
231
198
|
|
|
232
|
-
// Strategy
|
|
199
|
+
// Strategy 3: ESM import (works when @claude-flow/memory is a direct dependency)
|
|
233
200
|
try {
|
|
234
201
|
return await import('@claude-flow/memory');
|
|
235
202
|
} catch { /* fall through */ }
|
|
236
203
|
|
|
204
|
+
// Strategy 4: Walk up from PROJECT_ROOT looking for @claude-flow/memory in any node_modules
|
|
205
|
+
let searchDir = PROJECT_ROOT;
|
|
206
|
+
const { parse } = await import('path');
|
|
207
|
+
while (searchDir !== parse(searchDir).root) {
|
|
208
|
+
const candidate = join(searchDir, 'node_modules', '@claude-flow', 'memory', 'dist', 'index.js');
|
|
209
|
+
if (existsSync(candidate)) {
|
|
210
|
+
try {
|
|
211
|
+
return await import(`file://${candidate}`);
|
|
212
|
+
} catch { /* fall through */ }
|
|
213
|
+
}
|
|
214
|
+
searchDir = dirname(searchDir);
|
|
215
|
+
}
|
|
216
|
+
|
|
237
217
|
return null;
|
|
238
218
|
}
|
|
239
219
|
|
|
@@ -283,7 +263,7 @@ async function doImport() {
|
|
|
283
263
|
|
|
284
264
|
const memPkg = await loadMemoryPackage();
|
|
285
265
|
if (!memPkg || !memPkg.AutoMemoryBridge) {
|
|
286
|
-
|
|
266
|
+
warnMemoryUnavailable();
|
|
287
267
|
return;
|
|
288
268
|
}
|
|
289
269
|
|
|
@@ -292,10 +272,7 @@ async function doImport() {
|
|
|
292
272
|
await backend.initialize();
|
|
293
273
|
|
|
294
274
|
const bridgeConfig = {
|
|
295
|
-
|
|
296
|
-
// — PROJECT_ROOT resolves to the plugin clone when this hook runs from
|
|
297
|
-
// ~/.claude/plugins/marketplaces/ruflo/. See issue #2284.
|
|
298
|
-
workingDir: process.env.CLAUDE_FLOW_CWD || process.cwd(),
|
|
275
|
+
workingDir: PROJECT_ROOT,
|
|
299
276
|
syncMode: 'on-session-end',
|
|
300
277
|
};
|
|
301
278
|
|
|
@@ -327,36 +304,6 @@ async function doImport() {
|
|
|
327
304
|
dim(`├─ Learning: ${config.learningBridge.enabled ? 'active' : 'disabled'}`);
|
|
328
305
|
dim(`├─ Graph: ${config.memoryGraph.enabled ? 'active' : 'disabled'}`);
|
|
329
306
|
dim(`└─ Agent scopes: ${config.agentScopes.enabled ? 'active' : 'disabled'}`);
|
|
330
|
-
|
|
331
|
-
// Bridge to AgentDB: store entries with ONNX vector embeddings for semantic search
|
|
332
|
-
let vectorized = 0;
|
|
333
|
-
try {
|
|
334
|
-
const cliDistPath = await resolveBundledFile('@claude-flow/cli', 'dist/src/memory/memory-initializer.js');
|
|
335
|
-
if (cliDistPath) {
|
|
336
|
-
const memInit = await import(`file://${cliDistPath}`);
|
|
337
|
-
await memInit.initializeMemoryDatabase({ force: false, verbose: false });
|
|
338
|
-
|
|
339
|
-
const entries = await backend.query({});
|
|
340
|
-
for (const entry of entries) {
|
|
341
|
-
if (!entry.content || entry.content.length < 10) continue;
|
|
342
|
-
try {
|
|
343
|
-
await memInit.storeEntry({
|
|
344
|
-
key: entry.key || entry.id,
|
|
345
|
-
value: entry.content,
|
|
346
|
-
namespace: entry.namespace || 'auto-memory',
|
|
347
|
-
generateEmbeddingFlag: true,
|
|
348
|
-
});
|
|
349
|
-
vectorized++;
|
|
350
|
-
} catch { /* skip entries that fail to embed */ }
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
if (vectorized > 0) {
|
|
354
|
-
success(`Vectorized ${vectorized} entries into AgentDB (ONNX 384-dim)`);
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
} catch (vecErr) {
|
|
358
|
-
dim(`AgentDB vectorization skipped: ${vecErr.message?.slice(0, 60)}`);
|
|
359
|
-
}
|
|
360
307
|
} catch (err) {
|
|
361
308
|
dim(`Import failed (non-critical): ${err.message}`);
|
|
362
309
|
}
|
|
@@ -369,7 +316,7 @@ async function doSync() {
|
|
|
369
316
|
|
|
370
317
|
const memPkg = await loadMemoryPackage();
|
|
371
318
|
if (!memPkg || !memPkg.AutoMemoryBridge) {
|
|
372
|
-
|
|
319
|
+
warnMemoryUnavailable();
|
|
373
320
|
return;
|
|
374
321
|
}
|
|
375
322
|
|
|
@@ -385,8 +332,7 @@ async function doSync() {
|
|
|
385
332
|
}
|
|
386
333
|
|
|
387
334
|
const bridgeConfig = {
|
|
388
|
-
|
|
389
|
-
workingDir: process.env.CLAUDE_FLOW_CWD || process.cwd(),
|
|
335
|
+
workingDir: PROJECT_ROOT,
|
|
390
336
|
syncMode: 'on-session-end',
|
|
391
337
|
};
|
|
392
338
|
|
|
@@ -416,21 +362,6 @@ async function doSync() {
|
|
|
416
362
|
// Curate MEMORY.md index with graph-aware ordering
|
|
417
363
|
await bridge.curateIndex();
|
|
418
364
|
success('Curated MEMORY.md index');
|
|
419
|
-
|
|
420
|
-
// Flush intelligence patterns to disk (SONA + ReasoningBank)
|
|
421
|
-
try {
|
|
422
|
-
const intPath = await resolveBundledFile('@claude-flow/cli', 'dist/src/memory/intelligence.js');
|
|
423
|
-
if (intPath) {
|
|
424
|
-
const intelligence = await import(`file://${intPath}`);
|
|
425
|
-
if (intelligence.flushPatterns) {
|
|
426
|
-
intelligence.flushPatterns();
|
|
427
|
-
const stats = intelligence.getIntelligenceStats?.();
|
|
428
|
-
if (stats && stats.patternsLearned > 0) {
|
|
429
|
-
success(`Flushed ${stats.patternsLearned} learned patterns to disk`);
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
} catch { /* non-critical */ }
|
|
434
365
|
} catch (err) {
|
|
435
366
|
dim(`Sync failed (non-critical): ${err.message}`);
|
|
436
367
|
}
|
|
@@ -443,8 +374,12 @@ async function doStatus() {
|
|
|
443
374
|
const memPkg = await loadMemoryPackage();
|
|
444
375
|
const config = readConfig();
|
|
445
376
|
|
|
377
|
+
const sidecar = join(PROJECT_ROOT, '.claude-flow', 'memory-package.json');
|
|
378
|
+
const hasSidecar = existsSync(sidecar);
|
|
379
|
+
|
|
446
380
|
console.log('\n=== Auto Memory Bridge Status ===\n');
|
|
447
|
-
console.log(` Package: ${memPkg ? '✅ Available' : '❌ Not found'}`);
|
|
381
|
+
console.log(` Package: ${memPkg ? '✅ Available' : '❌ Not found — self-learning DISABLED (fix: npm i -D @claude-flow/memory)'}`);
|
|
382
|
+
console.log(` Resolver: ${hasSidecar ? '✅ .claude-flow/memory-package.json' : '⏸ no sidecar (run: npx ruflo@latest doctor --fix)'}`);
|
|
448
383
|
console.log(` Store: ${existsSync(STORE_PATH) ? '✅ ' + STORE_PATH : '⏸ Not initialized'}`);
|
|
449
384
|
console.log(` LearningBridge: ${config.learningBridge.enabled ? '✅ Enabled' : '⏸ Disabled'}`);
|
|
450
385
|
console.log(` MemoryGraph: ${config.memoryGraph.enabled ? '✅ Enabled' : '⏸ Disabled'}`);
|
|
@@ -457,158 +392,9 @@ async function doStatus() {
|
|
|
457
392
|
} catch { /* ignore */ }
|
|
458
393
|
}
|
|
459
394
|
|
|
460
|
-
// AgentDB vector status
|
|
461
|
-
try {
|
|
462
|
-
const dbPath = join(PROJECT_ROOT, '.claude-flow', 'memory', 'memory.db');
|
|
463
|
-
const swarmDbPath = join(PROJECT_ROOT, '.swarm', 'memory.db');
|
|
464
|
-
const hasDb = existsSync(dbPath) || existsSync(swarmDbPath);
|
|
465
|
-
console.log(` AgentDB: ${hasDb ? '✅ sql.js database exists' : '⏸ Not initialized'}`);
|
|
466
|
-
|
|
467
|
-
const intPath = await resolveBundledFile('@claude-flow/cli', 'dist/src/memory/intelligence.js');
|
|
468
|
-
if (intPath) {
|
|
469
|
-
const intelligence = await import(`file://${intPath}`);
|
|
470
|
-
const stats = intelligence.getIntelligenceStats?.();
|
|
471
|
-
if (stats) {
|
|
472
|
-
console.log(` SONA: ${stats.sonaEnabled ? '✅ Active' : '⏸ Not initialized'}`);
|
|
473
|
-
console.log(` Patterns: ${stats.patternsLearned} learned`);
|
|
474
|
-
console.log(` Trajectories: ${stats.trajectoriesRecorded} recorded`);
|
|
475
|
-
}
|
|
476
|
-
}
|
|
477
|
-
} catch { /* ignore */ }
|
|
478
|
-
|
|
479
395
|
console.log('');
|
|
480
396
|
}
|
|
481
397
|
|
|
482
|
-
// ============================================================================
|
|
483
|
-
// Import ALL Claude Code memories from all projects into AgentDB
|
|
484
|
-
// ============================================================================
|
|
485
|
-
|
|
486
|
-
async function doImportAll() {
|
|
487
|
-
log('Importing ALL Claude Code memories into AgentDB...');
|
|
488
|
-
|
|
489
|
-
const { homedir } = await import('os');
|
|
490
|
-
const { readdirSync } = await import('fs');
|
|
491
|
-
const claudeProjectsDir = join(homedir(), '.claude', 'projects');
|
|
492
|
-
|
|
493
|
-
if (!existsSync(claudeProjectsDir)) {
|
|
494
|
-
dim('No Claude Code projects found at ' + claudeProjectsDir);
|
|
495
|
-
return;
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
// Find all memory files across all projects
|
|
499
|
-
const memoryFiles = [];
|
|
500
|
-
try {
|
|
501
|
-
const projects = readdirSync(claudeProjectsDir, { withFileTypes: true });
|
|
502
|
-
for (const project of projects) {
|
|
503
|
-
if (!project.isDirectory()) continue;
|
|
504
|
-
const memDir = join(claudeProjectsDir, project.name, 'memory');
|
|
505
|
-
if (!existsSync(memDir)) continue;
|
|
506
|
-
const files = readdirSync(memDir).filter(f => f.endsWith('.md'));
|
|
507
|
-
for (const file of files) {
|
|
508
|
-
memoryFiles.push({
|
|
509
|
-
path: join(memDir, file),
|
|
510
|
-
project: project.name,
|
|
511
|
-
file,
|
|
512
|
-
});
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
} catch (err) {
|
|
516
|
-
dim('Error scanning projects: ' + err.message);
|
|
517
|
-
return;
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
if (memoryFiles.length === 0) {
|
|
521
|
-
dim('No memory files found');
|
|
522
|
-
return;
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
log(`Found ${memoryFiles.length} memory files across ${new Set(memoryFiles.map(f => f.project)).size} projects`);
|
|
526
|
-
|
|
527
|
-
// Load memory-initializer for vectorized storage
|
|
528
|
-
let memInit = null;
|
|
529
|
-
try {
|
|
530
|
-
const cliDistPath = await resolveBundledFile('@claude-flow/cli', 'dist/src/memory/memory-initializer.js');
|
|
531
|
-
if (cliDistPath) {
|
|
532
|
-
memInit = await import(`file://${cliDistPath}`);
|
|
533
|
-
await memInit.initializeMemoryDatabase({ force: false, verbose: false });
|
|
534
|
-
}
|
|
535
|
-
} catch (err) {
|
|
536
|
-
dim('Memory initializer not available: ' + err.message?.slice(0, 60));
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
if (!memInit) {
|
|
540
|
-
dim('Cannot vectorize without memory-initializer. Run: cd v3/@claude-flow/cli && npm run build');
|
|
541
|
-
return;
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
let imported = 0;
|
|
545
|
-
let skipped = 0;
|
|
546
|
-
|
|
547
|
-
for (const memFile of memoryFiles) {
|
|
548
|
-
try {
|
|
549
|
-
const content = readFileSync(memFile.path, 'utf-8');
|
|
550
|
-
|
|
551
|
-
// Parse YAML frontmatter + body
|
|
552
|
-
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
|
|
553
|
-
let name = memFile.file.replace('.md', '');
|
|
554
|
-
let description = '';
|
|
555
|
-
let type = 'auto-memory';
|
|
556
|
-
let body = content;
|
|
557
|
-
|
|
558
|
-
if (frontmatterMatch) {
|
|
559
|
-
const yaml = frontmatterMatch[1];
|
|
560
|
-
body = frontmatterMatch[2].trim();
|
|
561
|
-
const nameMatch = yaml.match(/^name:\s*(.+)$/m);
|
|
562
|
-
const descMatch = yaml.match(/^description:\s*(.+)$/m);
|
|
563
|
-
const typeMatch = yaml.match(/^type:\s*(.+)$/m);
|
|
564
|
-
if (nameMatch) name = nameMatch[1].trim();
|
|
565
|
-
if (descMatch) description = descMatch[1].trim();
|
|
566
|
-
if (typeMatch) type = typeMatch[1].trim();
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
// Split body into sections (## headers) for granular entries
|
|
570
|
-
const sections = body.split(/^(?=## )/m).filter(s => s.trim().length > 20);
|
|
571
|
-
|
|
572
|
-
if (sections.length === 0) {
|
|
573
|
-
// Store whole file as one entry
|
|
574
|
-
if (body.length > 10) {
|
|
575
|
-
await memInit.storeEntry({
|
|
576
|
-
key: `claude-memory:${memFile.project}:${name}`,
|
|
577
|
-
value: body.slice(0, 4096),
|
|
578
|
-
namespace: 'claude-memories',
|
|
579
|
-
generateEmbeddingFlag: true,
|
|
580
|
-
});
|
|
581
|
-
imported++;
|
|
582
|
-
}
|
|
583
|
-
} else {
|
|
584
|
-
// Store each section separately for better search granularity
|
|
585
|
-
for (const section of sections) {
|
|
586
|
-
const titleMatch = section.match(/^##\s+(.+)/);
|
|
587
|
-
const sectionTitle = titleMatch ? titleMatch[1].trim() : name;
|
|
588
|
-
const sectionBody = section.replace(/^##\s+.+\n/, '').trim();
|
|
589
|
-
if (sectionBody.length < 10) continue;
|
|
590
|
-
|
|
591
|
-
await memInit.storeEntry({
|
|
592
|
-
key: `claude-memory:${memFile.project}:${name}:${sectionTitle.slice(0, 50)}`,
|
|
593
|
-
value: sectionBody.slice(0, 4096),
|
|
594
|
-
namespace: 'claude-memories',
|
|
595
|
-
generateEmbeddingFlag: true,
|
|
596
|
-
});
|
|
597
|
-
imported++;
|
|
598
|
-
}
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
dim(` ✓ ${memFile.project}/${memFile.file} (${sections.length || 1} entries)`);
|
|
602
|
-
} catch (err) {
|
|
603
|
-
dim(` ✗ ${memFile.project}/${memFile.file}: ${err.message?.slice(0, 60)}`);
|
|
604
|
-
skipped++;
|
|
605
|
-
}
|
|
606
|
-
}
|
|
607
|
-
|
|
608
|
-
success(`Imported ${imported} entries from ${memoryFiles.length} files (${skipped} skipped)`);
|
|
609
|
-
success('All Claude Code memories now searchable via AgentDB vector search');
|
|
610
|
-
}
|
|
611
|
-
|
|
612
398
|
// ============================================================================
|
|
613
399
|
// Main
|
|
614
400
|
// ============================================================================
|
|
@@ -630,16 +416,15 @@ process.on('unhandledRejection', (reason) => {
|
|
|
630
416
|
try {
|
|
631
417
|
switch (command) {
|
|
632
418
|
case 'import': await doImport(); break;
|
|
633
|
-
case 'import-all': await doImportAll(); break;
|
|
634
419
|
case 'sync': await doSync(); break;
|
|
635
420
|
case 'status': await doStatus(); break;
|
|
636
421
|
default:
|
|
637
422
|
console.log('Usage: auto-memory-hook.mjs <import|sync|status>');
|
|
638
|
-
|
|
423
|
+
break;
|
|
639
424
|
}
|
|
640
425
|
} catch (err) {
|
|
641
426
|
// Hooks must never crash Claude Code - fail silently
|
|
642
|
-
dim(`Error (non-critical): ${err.message}`);
|
|
427
|
+
try { dim(`Error (non-critical): ${err.message}`); } catch (_) {}
|
|
643
428
|
}
|
|
644
|
-
//
|
|
429
|
+
// Force clean exit — process.exitCode alone isn't enough if async errors override it
|
|
645
430
|
process.exit(0);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"manifest": {
|
|
3
|
+
"version": "3.23.0",
|
|
4
|
+
"files": {
|
|
5
|
+
"auto-memory-hook.mjs": "68be7e9a9eba7bf9c4e8a230db7bf61a243b965639f8504842799d6c6ca28762",
|
|
6
|
+
"hook-handler.cjs": "bc4d2d26823d49b3ab1dded2946b66369f1f67bd76b4c30dca9f3b6df3cca8f0",
|
|
7
|
+
"intelligence.cjs": "760cb82ed2000031abc1ac1fa90a014e7d91d93966e3aa4741b07ab7aff8d066"
|
|
8
|
+
}
|
|
9
|
+
},
|
|
10
|
+
"signature": "of5l9RP68iPcmcC5dckDv+KIOiENJKifWxYKwQTwAiXiyRNNZuMwQ8y8Bd8+wGviTRxIzBfSuxL1nuJ/rX3xDQ==",
|
|
11
|
+
"algorithm": "ed25519"
|
|
12
|
+
}
|