claude-flow 3.21.1 → 3.23.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/daemon.js +23 -2
- 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-distill.d.ts +27 -0
- package/v3/@claude-flow/cli/dist/src/commands/memory-distill.js +374 -0
- package/v3/@claude-flow/cli/dist/src/commands/memory.js +5 -2
- package/v3/@claude-flow/cli/dist/src/index.d.ts +1 -1
- package/v3/@claude-flow/cli/dist/src/index.js +22 -1
- package/v3/@claude-flow/cli/dist/src/init/executor.js +20 -0
- package/v3/@claude-flow/cli/dist/src/init/helper-refresh.d.ts +19 -0
- package/v3/@claude-flow/cli/dist/src/init/helper-refresh.js +175 -0
- package/v3/@claude-flow/cli/dist/src/init/helper-signing.d.ts +30 -0
- package/v3/@claude-flow/cli/dist/src/init/helper-signing.js +60 -0
- package/v3/@claude-flow/cli/dist/src/init/helpers-generator.d.ts +16 -0
- package/v3/@claude-flow/cli/dist/src/init/helpers-generator.js +63 -6
- package/v3/@claude-flow/cli/dist/src/init/statusline-generator.js +18 -7
- package/v3/@claude-flow/cli/dist/src/mcp-client.js +13 -0
- package/v3/@claude-flow/cli/dist/src/mcp-tools/agenticow-speculate-tools.js +9 -2
- package/v3/@claude-flow/cli/dist/src/mcp-tools/browser-intent-tools.d.ts +162 -0
- package/v3/@claude-flow/cli/dist/src/mcp-tools/browser-intent-tools.js +548 -0
- package/v3/@claude-flow/cli/dist/src/mcp-tools/browser-tools.d.ts +9 -1
- package/v3/@claude-flow/cli/dist/src/mcp-tools/browser-tools.js +4 -1
- package/v3/@claude-flow/cli/dist/src/memory/memory-bridge.js +67 -47
- package/v3/@claude-flow/cli/dist/src/memory/memory-initializer.d.ts +71 -0
- package/v3/@claude-flow/cli/dist/src/memory/memory-initializer.js +330 -2
- package/v3/@claude-flow/cli/dist/src/services/distill-tuning.d.ts +111 -0
- package/v3/@claude-flow/cli/dist/src/services/distill-tuning.js +510 -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/memory-distillation.d.ts +41 -0
- package/v3/@claude-flow/cli/dist/src/services/memory-distillation.js +277 -0
- package/v3/@claude-flow/cli/dist/src/services/worker-daemon.d.ts +31 -2
- package/v3/@claude-flow/cli/dist/src/services/worker-daemon.js +159 -6
- package/v3/@claude-flow/cli/package.json +5 -2
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
* - map: Codebase mapping (5 min interval)
|
|
7
7
|
* - audit: Security analysis (10 min interval)
|
|
8
8
|
* - optimize: Performance optimization (15 min interval)
|
|
9
|
-
* - consolidate: Memory
|
|
9
|
+
* - consolidate: Memory distillation — memory_entries -> episodes/reasoning_patterns/
|
|
10
|
+
* causal_edges (30 min interval, ADR-174; RUFLO_DAEMON_NO_DISTILL=1 / --no-distill to skip)
|
|
10
11
|
* - testgaps: Test coverage analysis (20 min interval)
|
|
11
12
|
*/
|
|
12
13
|
import { EventEmitter } from 'events';
|
|
@@ -14,19 +15,48 @@ import { existsSync, mkdirSync, writeFileSync, readFileSync, appendFileSync, unl
|
|
|
14
15
|
import { cpus } from 'os';
|
|
15
16
|
import { join } from 'path';
|
|
16
17
|
import { HeadlessWorkerExecutor, isHeadlessWorker, } from './headless-worker-executor.js';
|
|
18
|
+
// ADR-174 M3: the consolidate worker below drives the real DISTILL/CONSOLIDATE
|
|
19
|
+
// pass instead of writing a hardcoded { patternsConsolidated: 0 } stub. The
|
|
20
|
+
// service itself is owned/frozen elsewhere (memory-distillation.ts) — it is
|
|
21
|
+
// incremental (rowid cursor), non-destructive, transactional, and
|
|
22
|
+
// quick_check-gated, so it's safe to call unconditionally on every tick.
|
|
23
|
+
import { runDistillation, defaultMemoryDbPath } from './memory-distillation.js';
|
|
24
|
+
import { backupMemoryDb } from './memory-backup.js';
|
|
17
25
|
// Default worker configurations with improved intervals (P0 fix: map 5min -> 15min)
|
|
18
26
|
const DEFAULT_WORKERS = [
|
|
19
27
|
{ type: 'map', intervalMs: 15 * 60 * 1000, offsetMs: 0, priority: 'normal', description: 'Codebase mapping', enabled: true },
|
|
20
28
|
{ type: 'audit', intervalMs: 10 * 60 * 1000, offsetMs: 2 * 60 * 1000, priority: 'critical', description: 'Security analysis', enabled: true },
|
|
21
29
|
{ type: 'optimize', intervalMs: 15 * 60 * 1000, offsetMs: 4 * 60 * 1000, priority: 'high', description: 'Performance optimization', enabled: true },
|
|
22
|
-
{ type: 'consolidate', intervalMs: 30 * 60 * 1000, offsetMs: 6 * 60 * 1000, priority: 'low', description: 'Memory
|
|
30
|
+
{ type: 'consolidate', intervalMs: 30 * 60 * 1000, offsetMs: 6 * 60 * 1000, priority: 'low', description: 'Memory distillation (ADR-174)', enabled: true },
|
|
23
31
|
{ type: 'testgaps', intervalMs: 20 * 60 * 1000, offsetMs: 8 * 60 * 1000, priority: 'normal', description: 'Test coverage analysis', enabled: true },
|
|
32
|
+
{ type: 'backup', intervalMs: 24 * 60 * 60 * 1000, offsetMs: 10 * 60 * 1000, priority: 'low', description: 'Nightly memory DB backup (WAL-safe, rotated)', enabled: true },
|
|
24
33
|
{ type: 'predict', intervalMs: 10 * 60 * 1000, offsetMs: 0, priority: 'low', description: 'Predictive preloading', enabled: false },
|
|
25
34
|
{ type: 'document', intervalMs: 60 * 60 * 1000, offsetMs: 0, priority: 'low', description: 'Auto-documentation', enabled: false },
|
|
26
35
|
];
|
|
27
36
|
// Worker timeout — must exceed the longest per-worker headless timeout (15 min for audit/refactor).
|
|
28
37
|
// Previously 5 min, which caused orphan processes when daemon timeout fired before executor timeout (#1117).
|
|
29
38
|
const DEFAULT_WORKER_TIMEOUT_MS = 16 * 60 * 1000;
|
|
39
|
+
// ADR-174 M3: hard cap on rows the `consolidate` worker distills in a single
|
|
40
|
+
// tick. The distillation service is cursor-driven (per-namespace rowid) and
|
|
41
|
+
// batches in transactions of `batchSize`, so a capped `maxEntries` guarantees
|
|
42
|
+
// this worker returns well within DEFAULT_WORKER_TIMEOUT_MS even against a
|
|
43
|
+
// large backlog — the cursor just picks up where it left off next tick
|
|
44
|
+
// (every 30 min per DEFAULT_WORKERS), draining an arbitrarily large backlog
|
|
45
|
+
// over several ticks instead of blocking on one.
|
|
46
|
+
const CONSOLIDATE_MAX_ENTRIES_PER_TICK = 1000;
|
|
47
|
+
const CONSOLIDATE_BATCH_SIZE = 200;
|
|
48
|
+
// ADR-174 M5: platform-default distillation config, chosen by the M4 self-
|
|
49
|
+
// optimization grid-search (scripts/tune-distill.mjs) on the real ~7.9k-entry
|
|
50
|
+
// corpus. Winner: batchSize=200, dedupDistance=0.2 (held-out MRR@10 0.753 vs
|
|
51
|
+
// 0.749 baseline — measured on-par, not a large uplift; the payoff is the
|
|
52
|
+
// populated substrate + trainable model). Override per-run via `memory distill`.
|
|
53
|
+
const CONSOLIDATE_DEDUP_DISTANCE = 0.2;
|
|
54
|
+
// ADR-174 M3 opt-out: set to skip the real distillation pass entirely (e.g.
|
|
55
|
+
// constrained CI hosts, or a user who wants the daemon's other workers but
|
|
56
|
+
// not this one without touching persisted worker-enabled state). Mirrors the
|
|
57
|
+
// `--no-distill` flag on `daemon start` (see commands/daemon.ts), which sets
|
|
58
|
+
// this env var on the forked/foreground daemon process.
|
|
59
|
+
const NO_DISTILL_ENV = 'RUFLO_DAEMON_NO_DISTILL';
|
|
30
60
|
// #2356 — Self-terminating lifecycle defaults. A background daemon with no
|
|
31
61
|
// upper bound on its lifetime runs until the box reboots; in the field this
|
|
32
62
|
// leaked tens of thousands of headless `claude --print` sweeps over many days
|
|
@@ -1130,6 +1160,8 @@ export class WorkerDaemon extends EventEmitter {
|
|
|
1130
1160
|
return this.runOptimizeWorkerLocal();
|
|
1131
1161
|
case 'consolidate':
|
|
1132
1162
|
return this.runConsolidateWorker();
|
|
1163
|
+
case 'backup':
|
|
1164
|
+
return this.runBackupWorker();
|
|
1133
1165
|
case 'testgaps':
|
|
1134
1166
|
return this.runTestGapsWorkerLocal();
|
|
1135
1167
|
case 'predict':
|
|
@@ -1268,22 +1300,143 @@ export class WorkerDaemon extends EventEmitter {
|
|
|
1268
1300
|
writeFileSync(optimizeFile, JSON.stringify(perf, null, 2));
|
|
1269
1301
|
return perf;
|
|
1270
1302
|
}
|
|
1303
|
+
/**
|
|
1304
|
+
* ADR-174 M3: memory consolidation — runs the real DISTILL/CONSOLIDATE pass
|
|
1305
|
+
* (memory-distillation.ts) against `.swarm/memory.db`, turning raw
|
|
1306
|
+
* `memory_entries` into `episodes` / `reasoning_patterns` /
|
|
1307
|
+
* `pattern_embeddings` / `causal_edges`. Previously this wrote a hardcoded
|
|
1308
|
+
* `{ patternsConsolidated: 0 }` stub and touched no database — the root
|
|
1309
|
+
* cause of the intelligence tables staying empty.
|
|
1310
|
+
*
|
|
1311
|
+
* Kept as `runConsolidateWorker` / worker type `'consolidate'` for
|
|
1312
|
+
* back-compat with existing `-w consolidate` scripts and docs.
|
|
1313
|
+
*
|
|
1314
|
+
* Safety:
|
|
1315
|
+
* - Bounded via CONSOLIDATE_MAX_ENTRIES_PER_TICK so a large backlog can
|
|
1316
|
+
* never approach DEFAULT_WORKER_TIMEOUT_MS — the incremental cursor in
|
|
1317
|
+
* runDistillation() drains a bounded slice per tick and picks up where
|
|
1318
|
+
* it left off on the next scheduled run.
|
|
1319
|
+
* - runDistillation() never throws (it catches internally and returns
|
|
1320
|
+
* `{ skipped }` / `{ corrupt: true }`), but this worker still wraps the
|
|
1321
|
+
* call defensively — a background worker must never crash the daemon.
|
|
1322
|
+
*/
|
|
1271
1323
|
async runConsolidateWorker() {
|
|
1272
|
-
// Memory consolidation - clean up old patterns
|
|
1273
1324
|
const consolidateFile = join(this.projectRoot, '.claude-flow', 'metrics', 'consolidation.json');
|
|
1274
1325
|
const metricsDir = join(this.projectRoot, '.claude-flow', 'metrics');
|
|
1275
1326
|
if (!existsSync(metricsDir)) {
|
|
1276
1327
|
mkdirSync(metricsDir, { recursive: true });
|
|
1277
1328
|
}
|
|
1329
|
+
// Opt-out: RUFLO_DAEMON_NO_DISTILL=1 (or `daemon start --no-distill`)
|
|
1330
|
+
// skips the real distillation pass entirely without touching persisted
|
|
1331
|
+
// worker-enabled state (see also: `daemon enable -w consolidate --disable`,
|
|
1332
|
+
// which disables the worker's schedule altogether).
|
|
1333
|
+
if (process.env[NO_DISTILL_ENV] === '1') {
|
|
1334
|
+
const disabledResult = {
|
|
1335
|
+
timestamp: new Date().toISOString(),
|
|
1336
|
+
distillationEnabled: false,
|
|
1337
|
+
note: `Distillation disabled via ${NO_DISTILL_ENV}=1 / --no-distill`,
|
|
1338
|
+
patternsConsolidated: 0,
|
|
1339
|
+
memoryCleaned: 0,
|
|
1340
|
+
duplicatesRemoved: 0,
|
|
1341
|
+
};
|
|
1342
|
+
writeFileSync(consolidateFile, JSON.stringify(disabledResult, null, 2));
|
|
1343
|
+
return disabledResult;
|
|
1344
|
+
}
|
|
1345
|
+
let report;
|
|
1346
|
+
try {
|
|
1347
|
+
report = await runDistillation({
|
|
1348
|
+
dbPath: defaultMemoryDbPath(this.projectRoot),
|
|
1349
|
+
maxEntries: CONSOLIDATE_MAX_ENTRIES_PER_TICK,
|
|
1350
|
+
batchSize: CONSOLIDATE_BATCH_SIZE,
|
|
1351
|
+
dedupDistance: CONSOLIDATE_DEDUP_DISTANCE,
|
|
1352
|
+
});
|
|
1353
|
+
}
|
|
1354
|
+
catch (error) {
|
|
1355
|
+
// Defensive only — runDistillation() is internally try/catch'd and
|
|
1356
|
+
// should never reach here. A worker must never crash the daemon.
|
|
1357
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1358
|
+
this.log('warn', `Consolidate worker: distillation threw unexpectedly: ${message}`);
|
|
1359
|
+
const errorResult = {
|
|
1360
|
+
timestamp: new Date().toISOString(),
|
|
1361
|
+
distillationEnabled: true,
|
|
1362
|
+
error: message,
|
|
1363
|
+
patternsConsolidated: 0,
|
|
1364
|
+
memoryCleaned: 0,
|
|
1365
|
+
duplicatesRemoved: 0,
|
|
1366
|
+
};
|
|
1367
|
+
writeFileSync(consolidateFile, JSON.stringify(errorResult, null, 2));
|
|
1368
|
+
return errorResult;
|
|
1369
|
+
}
|
|
1370
|
+
if (report.corrupt) {
|
|
1371
|
+
this.log('warn', `Consolidate worker: memory DB reports corruption — ${report.skipped ?? 'skipped'}`);
|
|
1372
|
+
}
|
|
1373
|
+
else if (report.skipped) {
|
|
1374
|
+
this.log('info', `Consolidate worker: distillation skipped (${report.skipped})`);
|
|
1375
|
+
}
|
|
1278
1376
|
const result = {
|
|
1279
1377
|
timestamp: new Date().toISOString(),
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1378
|
+
distillationEnabled: true,
|
|
1379
|
+
// Mapping onto the pre-existing metrics shape (ADR-174 M3):
|
|
1380
|
+
patternsConsolidated: report.patterns,
|
|
1381
|
+
// rows drained from the incremental cursor this tick — distillation is
|
|
1382
|
+
// non-destructive (never mutates/deletes memory_entries), so "cleaned"
|
|
1383
|
+
// here means "processed into the intelligence tables", not removed.
|
|
1384
|
+
memoryCleaned: report.processed,
|
|
1385
|
+
// clustering collapses near-duplicate entries into a single pattern
|
|
1386
|
+
// rather than deleting them; this is the count that got merged away
|
|
1387
|
+
// instead of becoming their own distinct pattern.
|
|
1388
|
+
duplicatesRemoved: Math.max(0, report.processed - report.patterns),
|
|
1389
|
+
episodes: report.episodes,
|
|
1390
|
+
patternEmbeddings: report.patternEmbeddings,
|
|
1391
|
+
causalEdges: report.causalEdges,
|
|
1392
|
+
promoted: report.promoted,
|
|
1393
|
+
byProvenance: report.byProvenance,
|
|
1394
|
+
namespaces: report.namespaces,
|
|
1395
|
+
dryRun: report.dryRun,
|
|
1396
|
+
corrupt: report.corrupt ?? false,
|
|
1397
|
+
skipped: report.skipped,
|
|
1283
1398
|
};
|
|
1284
1399
|
writeFileSync(consolidateFile, JSON.stringify(result, null, 2));
|
|
1285
1400
|
return result;
|
|
1286
1401
|
}
|
|
1402
|
+
/**
|
|
1403
|
+
* Nightly memory-DB backup worker (24h interval). Takes a WAL-safe, consistent
|
|
1404
|
+
* snapshot of .swarm/memory.db with rotation (keep last N). Never throws — a
|
|
1405
|
+
* worker must not crash the daemon; a skip/error is written to the metrics
|
|
1406
|
+
* file. Opt-out by omitting `backup` from `-w`; offsite GCS is opt-in via
|
|
1407
|
+
* RUFLO_BACKUP_GCS (a gs:// prefix), retention via RUFLO_BACKUP_KEEP.
|
|
1408
|
+
*/
|
|
1409
|
+
async runBackupWorker() {
|
|
1410
|
+
const metricsDir = join(this.projectRoot, '.claude-flow', 'metrics');
|
|
1411
|
+
if (!existsSync(metricsDir))
|
|
1412
|
+
mkdirSync(metricsDir, { recursive: true });
|
|
1413
|
+
const backupFile = join(metricsDir, 'backup.json');
|
|
1414
|
+
let result;
|
|
1415
|
+
try {
|
|
1416
|
+
const keepEnv = Number(process.env.RUFLO_BACKUP_KEEP);
|
|
1417
|
+
const r = await backupMemoryDb({
|
|
1418
|
+
dbPath: defaultMemoryDbPath(this.projectRoot),
|
|
1419
|
+
keep: Number.isFinite(keepEnv) && keepEnv > 0 ? keepEnv : 7,
|
|
1420
|
+
gcs: process.env.RUFLO_BACKUP_GCS || undefined,
|
|
1421
|
+
});
|
|
1422
|
+
result = {
|
|
1423
|
+
timestamp: new Date().toISOString(),
|
|
1424
|
+
backedUp: r.backedUp,
|
|
1425
|
+
path: r.path,
|
|
1426
|
+
sizeBytes: r.sizeBytes ?? 0,
|
|
1427
|
+
rotatedAway: r.rotatedAway?.length ?? 0,
|
|
1428
|
+
gcsUri: r.gcsUri,
|
|
1429
|
+
skipped: r.skipped,
|
|
1430
|
+
};
|
|
1431
|
+
}
|
|
1432
|
+
catch (error) {
|
|
1433
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1434
|
+
this.log('warn', `Backup worker failed: ${message}`);
|
|
1435
|
+
result = { timestamp: new Date().toISOString(), backedUp: false, error: message };
|
|
1436
|
+
}
|
|
1437
|
+
writeFileSync(backupFile, JSON.stringify(result, null, 2));
|
|
1438
|
+
return result;
|
|
1439
|
+
}
|
|
1287
1440
|
/**
|
|
1288
1441
|
* Local testgaps worker (fallback when headless unavailable)
|
|
1289
1442
|
*/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@claude-flow/cli",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.23.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Ruflo CLI - Enterprise AI agent orchestration with 60+ specialized agents, swarm coordination, MCP server, self-learning hooks, and vector memory for Claude Code",
|
|
6
6
|
"main": "dist/src/index.js",
|
|
@@ -75,8 +75,10 @@
|
|
|
75
75
|
},
|
|
76
76
|
"files": [
|
|
77
77
|
"dist",
|
|
78
|
+
"!dist/**/*.map",
|
|
79
|
+
"!dist/**/*.tsbuildinfo",
|
|
78
80
|
"bin",
|
|
79
|
-
"scripts",
|
|
81
|
+
"scripts/postinstall.cjs",
|
|
80
82
|
".claude",
|
|
81
83
|
"plugins",
|
|
82
84
|
"README.md"
|
|
@@ -132,6 +134,7 @@
|
|
|
132
134
|
"agentic-flow": "^3.0.0-alpha.1",
|
|
133
135
|
"agenticow": "~0.2.4",
|
|
134
136
|
"metaharness": "~0.2.8",
|
|
137
|
+
"page-agent": "~1.11.0",
|
|
135
138
|
"ruvector": "^0.2.27"
|
|
136
139
|
},
|
|
137
140
|
"publishConfig": {
|