@claude-flow/cli 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.
Files changed (59) hide show
  1. package/.claude/evolve-proof/generation-0.json +211 -0
  2. package/.claude/evolve-proof/real-generation-0.json +406 -0
  3. package/.claude/evolve-proof/real-generation-1.json +406 -0
  4. package/.claude/helpers/.helpers-version +1 -0
  5. package/.claude/helpers/helpers.manifest.json +2 -2
  6. package/.claude/helpers/hook-handler.cjs +0 -0
  7. package/.claude/helpers/intelligence.cjs +10 -0
  8. package/.claude/proven-config.manifest.json +37 -0
  9. package/.claude/proven-config.signed.json +41 -0
  10. package/.claude/proven-config.signed.rvf +0 -0
  11. package/dist/src/commands/memory-backup.d.ts +11 -0
  12. package/dist/src/commands/memory-backup.js +46 -0
  13. package/dist/src/commands/memory.js +2 -1
  14. package/dist/src/config/harness-feedback-applier.d.ts +50 -0
  15. package/dist/src/config/harness-feedback-applier.js +122 -0
  16. package/dist/src/config/proven-config-refresh.d.ts +39 -0
  17. package/dist/src/config/proven-config-refresh.js +154 -0
  18. package/dist/src/config/proven-config-rvfa.d.ts +23 -0
  19. package/dist/src/config/proven-config-rvfa.js +73 -0
  20. package/dist/src/config/proven-config.d.ts +86 -0
  21. package/dist/src/config/proven-config.js +176 -0
  22. package/dist/src/index.js +35 -0
  23. package/dist/src/mcp-tools/neural-tools.d.ts +10 -0
  24. package/dist/src/mcp-tools/neural-tools.js +107 -18
  25. package/dist/src/services/daemon-autostart.d.ts +17 -0
  26. package/dist/src/services/daemon-autostart.js +79 -0
  27. package/dist/src/services/evolve-proof.d.ts +247 -0
  28. package/dist/src/services/evolve-proof.js +341 -0
  29. package/dist/src/services/harness-benchmark.d.ts +68 -0
  30. package/dist/src/services/harness-benchmark.js +94 -0
  31. package/dist/src/services/harness-canary.d.ts +60 -0
  32. package/dist/src/services/harness-canary.js +69 -0
  33. package/dist/src/services/harness-corpus-harvester.d.ts +51 -0
  34. package/dist/src/services/harness-corpus-harvester.js +74 -0
  35. package/dist/src/services/harness-flywheel-generations.d.ts +111 -0
  36. package/dist/src/services/harness-flywheel-generations.js +354 -0
  37. package/dist/src/services/harness-flywheel-runtime.d.ts +25 -0
  38. package/dist/src/services/harness-flywheel-runtime.js +101 -0
  39. package/dist/src/services/harness-flywheel.d.ts +48 -0
  40. package/dist/src/services/harness-flywheel.js +207 -0
  41. package/dist/src/services/harness-hosts.d.ts +40 -0
  42. package/dist/src/services/harness-hosts.js +88 -0
  43. package/dist/src/services/harness-improvement-ledger.d.ts +63 -0
  44. package/dist/src/services/harness-improvement-ledger.js +101 -0
  45. package/dist/src/services/harness-loop.d.ts +53 -0
  46. package/dist/src/services/harness-loop.js +85 -0
  47. package/dist/src/services/harness-qualification.d.ts +66 -0
  48. package/dist/src/services/harness-qualification.js +143 -0
  49. package/dist/src/services/harness-replay.d.ts +37 -0
  50. package/dist/src/services/harness-replay.js +92 -0
  51. package/dist/src/services/harness-verify.d.ts +33 -0
  52. package/dist/src/services/harness-verify.js +26 -0
  53. package/dist/src/services/harness-worker.d.ts +23 -0
  54. package/dist/src/services/harness-worker.js +66 -0
  55. package/dist/src/services/memory-backup.d.ts +24 -0
  56. package/dist/src/services/memory-backup.js +94 -0
  57. package/dist/src/services/worker-daemon.d.ts +16 -1
  58. package/dist/src/services/worker-daemon.js +84 -0
  59. package/package.json +1 -1
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Vector-memory DB backup.
3
+ *
4
+ * Snapshots `.swarm/memory.db` (the sqlite store holding memory_entries +
5
+ * embeddings + the distilled reasoning_patterns) to a timestamped file using
6
+ * better-sqlite3's ONLINE backup API — a consistent, WAL-safe copy that does not
7
+ * block or corrupt a concurrently-written DB (unlike a naive file copy of a
8
+ * WAL-mode DB). Rotates to keep the last N snapshots and, optionally, uploads
9
+ * offsite to Google Cloud Storage.
10
+ *
11
+ * Used by `memory backup` (manual) and the daemon's nightly `backup` worker.
12
+ * Best-effort + non-destructive: it only reads the source DB and writes new
13
+ * files; it never mutates or deletes the live memory DB.
14
+ */
15
+ import * as fs from 'fs';
16
+ import * as path from 'path';
17
+ export function defaultMemoryDbPath(cwd = process.cwd()) {
18
+ return path.join(cwd, '.swarm', 'memory.db');
19
+ }
20
+ /** ISO timestamp safe for filenames (no ':' or '.'). */
21
+ function fileStamp(ms) {
22
+ return new Date(ms).toISOString().replace(/[:.]/g, '-');
23
+ }
24
+ export async function backupMemoryDb(opts = {}) {
25
+ const dbPath = opts.dbPath ?? defaultMemoryDbPath();
26
+ if (!dbPath || !fs.existsSync(dbPath))
27
+ return { backedUp: false, skipped: 'no-db' };
28
+ let Database;
29
+ try {
30
+ const mod = 'better-sqlite3';
31
+ Database = (await import(mod)).default;
32
+ }
33
+ catch {
34
+ return { backedUp: false, skipped: 'better-sqlite3 unavailable' };
35
+ }
36
+ const destDir = opts.destDir ?? path.join(path.dirname(dbPath), 'backups');
37
+ try {
38
+ fs.mkdirSync(destDir, { recursive: true });
39
+ }
40
+ catch { /* */ }
41
+ const destPath = path.join(destDir, `memory-${fileStamp(opts.timestamp ?? Date.now())}.db`);
42
+ // WAL-safe online backup: read-only source, consistent snapshot to destPath.
43
+ let db;
44
+ try {
45
+ db = new Database(dbPath, { readonly: true });
46
+ await db.backup(destPath);
47
+ db.close();
48
+ }
49
+ catch (e) {
50
+ try {
51
+ db?.close();
52
+ }
53
+ catch { /* */ }
54
+ return { backedUp: false, skipped: `backup failed: ${e?.message ?? e}` };
55
+ }
56
+ let sizeBytes = 0;
57
+ try {
58
+ sizeBytes = fs.statSync(destPath).size;
59
+ }
60
+ catch { /* */ }
61
+ // Rotation — ISO-stamped names sort chronologically, so keep the tail.
62
+ const keep = typeof opts.keep === 'number' && opts.keep > 0 ? opts.keep : 7;
63
+ const rotatedAway = [];
64
+ try {
65
+ const snaps = fs.readdirSync(destDir).filter(f => /^memory-.*\.db$/.test(f)).sort();
66
+ while (snaps.length > keep) {
67
+ const old = snaps.shift();
68
+ try {
69
+ fs.rmSync(path.join(destDir, old), { force: true });
70
+ rotatedAway.push(old);
71
+ }
72
+ catch { /* */ }
73
+ }
74
+ }
75
+ catch { /* */ }
76
+ // Optional offsite to GCS (best-effort; local backup already succeeded).
77
+ let gcsUri;
78
+ if (opts.gcs) {
79
+ try {
80
+ const { execFileSync } = await import('child_process');
81
+ const dest = opts.gcs.replace(/\/+$/, '') + '/' + path.basename(destPath);
82
+ execFileSync('gcloud', ['storage', 'cp', destPath, dest], { stdio: ['ignore', 'ignore', 'inherit'] });
83
+ gcsUri = dest;
84
+ }
85
+ catch { /* offsite failed — local snapshot stands */ }
86
+ }
87
+ if (opts.verbose) {
88
+ console.log(`memory DB backed up → ${destPath} (${Math.round(sizeBytes / 1024)} KB)` +
89
+ (rotatedAway.length ? `, rotated ${rotatedAway.length} old` : '') +
90
+ (gcsUri ? `, offsite ${gcsUri}` : ''));
91
+ }
92
+ return { backedUp: true, path: destPath, sizeBytes, rotatedAway, gcsUri };
93
+ }
94
+ //# sourceMappingURL=memory-backup.js.map
@@ -12,7 +12,7 @@
12
12
  */
13
13
  import { EventEmitter } from 'events';
14
14
  import { HeadlessWorkerExecutor } from './headless-worker-executor.js';
15
- export type WorkerType = 'ultralearn' | 'optimize' | 'consolidate' | 'predict' | 'audit' | 'map' | 'preload' | 'deepdive' | 'document' | 'refactor' | 'benchmark' | 'testgaps';
15
+ export type WorkerType = 'ultralearn' | 'optimize' | 'consolidate' | 'predict' | 'audit' | 'map' | 'preload' | 'deepdive' | 'document' | 'refactor' | 'benchmark' | 'testgaps' | 'backup' | 'harness';
16
16
  interface WorkerConfig {
17
17
  type: WorkerType;
18
18
  intervalMs: number;
@@ -319,6 +319,21 @@ export declare class WorkerDaemon extends EventEmitter {
319
319
  * call defensively — a background worker must never crash the daemon.
320
320
  */
321
321
  private runConsolidateWorker;
322
+ /**
323
+ * Nightly memory-DB backup worker (24h interval). Takes a WAL-safe, consistent
324
+ * snapshot of .swarm/memory.db with rotation (keep last N). Never throws — a
325
+ * worker must not crash the daemon; a skip/error is written to the metrics
326
+ * file. Opt-out by omitting `backup` from `-w`; offsite GCS is opt-in via
327
+ * RUFLO_BACKUP_GCS (a gs:// prefix), retention via RUFLO_BACKUP_KEEP.
328
+ */
329
+ private runBackupWorker;
330
+ /**
331
+ * Self-optimizing harness loop worker (ADR-176 phase 8). Strictly bounded:
332
+ * OPT-IN (RUFLO_HARNESS_LOOP), $0-default (no optimizer/verifier wired => no
333
+ * promotion), trajectory-capped, single-flight via the daemon, never throws.
334
+ * On acceptance the (unsigned) champion is staged for the separate sign step.
335
+ */
336
+ private runHarnessWorker;
322
337
  /**
323
338
  * Local testgaps worker (fallback when headless unavailable)
324
339
  */
@@ -21,6 +21,7 @@ import { HeadlessWorkerExecutor, isHeadlessWorker, } from './headless-worker-exe
21
21
  // incremental (rowid cursor), non-destructive, transactional, and
22
22
  // quick_check-gated, so it's safe to call unconditionally on every tick.
23
23
  import { runDistillation, defaultMemoryDbPath } from './memory-distillation.js';
24
+ import { backupMemoryDb } from './memory-backup.js';
24
25
  // Default worker configurations with improved intervals (P0 fix: map 5min -> 15min)
25
26
  const DEFAULT_WORKERS = [
26
27
  { type: 'map', intervalMs: 15 * 60 * 1000, offsetMs: 0, priority: 'normal', description: 'Codebase mapping', enabled: true },
@@ -28,6 +29,8 @@ const DEFAULT_WORKERS = [
28
29
  { type: 'optimize', intervalMs: 15 * 60 * 1000, offsetMs: 4 * 60 * 1000, priority: 'high', description: 'Performance optimization', enabled: true },
29
30
  { type: 'consolidate', intervalMs: 30 * 60 * 1000, offsetMs: 6 * 60 * 1000, priority: 'low', description: 'Memory distillation (ADR-174)', enabled: true },
30
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 },
33
+ { type: 'harness', intervalMs: 6 * 60 * 60 * 1000, offsetMs: 12 * 60 * 1000, priority: 'low', description: 'Self-optimizing harness loop (opt-in RUFLO_HARNESS_LOOP, $0-default)', enabled: true },
31
34
  { type: 'predict', intervalMs: 10 * 60 * 1000, offsetMs: 0, priority: 'low', description: 'Predictive preloading', enabled: false },
32
35
  { type: 'document', intervalMs: 60 * 60 * 1000, offsetMs: 0, priority: 'low', description: 'Auto-documentation', enabled: false },
33
36
  ];
@@ -1158,6 +1161,10 @@ export class WorkerDaemon extends EventEmitter {
1158
1161
  return this.runOptimizeWorkerLocal();
1159
1162
  case 'consolidate':
1160
1163
  return this.runConsolidateWorker();
1164
+ case 'backup':
1165
+ return this.runBackupWorker();
1166
+ case 'harness':
1167
+ return this.runHarnessWorker();
1161
1168
  case 'testgaps':
1162
1169
  return this.runTestGapsWorkerLocal();
1163
1170
  case 'predict':
@@ -1395,6 +1402,83 @@ export class WorkerDaemon extends EventEmitter {
1395
1402
  writeFileSync(consolidateFile, JSON.stringify(result, null, 2));
1396
1403
  return result;
1397
1404
  }
1405
+ /**
1406
+ * Nightly memory-DB backup worker (24h interval). Takes a WAL-safe, consistent
1407
+ * snapshot of .swarm/memory.db with rotation (keep last N). Never throws — a
1408
+ * worker must not crash the daemon; a skip/error is written to the metrics
1409
+ * file. Opt-out by omitting `backup` from `-w`; offsite GCS is opt-in via
1410
+ * RUFLO_BACKUP_GCS (a gs:// prefix), retention via RUFLO_BACKUP_KEEP.
1411
+ */
1412
+ async runBackupWorker() {
1413
+ const metricsDir = join(this.projectRoot, '.claude-flow', 'metrics');
1414
+ if (!existsSync(metricsDir))
1415
+ mkdirSync(metricsDir, { recursive: true });
1416
+ const backupFile = join(metricsDir, 'backup.json');
1417
+ let result;
1418
+ try {
1419
+ const keepEnv = Number(process.env.RUFLO_BACKUP_KEEP);
1420
+ const r = await backupMemoryDb({
1421
+ dbPath: defaultMemoryDbPath(this.projectRoot),
1422
+ keep: Number.isFinite(keepEnv) && keepEnv > 0 ? keepEnv : 7,
1423
+ gcs: process.env.RUFLO_BACKUP_GCS || undefined,
1424
+ });
1425
+ result = {
1426
+ timestamp: new Date().toISOString(),
1427
+ backedUp: r.backedUp,
1428
+ path: r.path,
1429
+ sizeBytes: r.sizeBytes ?? 0,
1430
+ rotatedAway: r.rotatedAway?.length ?? 0,
1431
+ gcsUri: r.gcsUri,
1432
+ skipped: r.skipped,
1433
+ };
1434
+ }
1435
+ catch (error) {
1436
+ const message = error instanceof Error ? error.message : String(error);
1437
+ this.log('warn', `Backup worker failed: ${message}`);
1438
+ result = { timestamp: new Date().toISOString(), backedUp: false, error: message };
1439
+ }
1440
+ writeFileSync(backupFile, JSON.stringify(result, null, 2));
1441
+ return result;
1442
+ }
1443
+ /**
1444
+ * Self-optimizing harness loop worker (ADR-176 phase 8). Strictly bounded:
1445
+ * OPT-IN (RUFLO_HARNESS_LOOP), $0-default (no optimizer/verifier wired => no
1446
+ * promotion), trajectory-capped, single-flight via the daemon, never throws.
1447
+ * On acceptance the (unsigned) champion is staged for the separate sign step.
1448
+ */
1449
+ async runHarnessWorker() {
1450
+ const metricsDir = join(this.projectRoot, '.claude-flow', 'metrics');
1451
+ if (!existsSync(metricsDir))
1452
+ mkdirSync(metricsDir, { recursive: true });
1453
+ const harnessFile = join(metricsDir, 'harness-loop.json');
1454
+ let result;
1455
+ try {
1456
+ // ADR-176 flywheel (A-P3b autonomy loop): run ONE COMPOUNDING generation
1457
+ // on the install's REAL data — read the persisted champion as baseline,
1458
+ // gate a constrained candidate on the frozen self-supervised held-out with
1459
+ // the human-anchor guard + separate canary, and on a verified promotion
1460
+ // advance the champion so the NEXT tick compounds. Shadow-first (serve lags
1461
+ // one tick). Opt-in ($0 no-op without RUFLO_HARNESS_LOOP).
1462
+ const { runFlywheelGenerationWorker } = await import('./harness-flywheel-runtime.js');
1463
+ const gen = await runFlywheelGenerationWorker(this.projectRoot, { sample: 120 });
1464
+ let status = null;
1465
+ try {
1466
+ const { flywheelStatus } = await import('./harness-flywheel-generations.js');
1467
+ status = flywheelStatus(this.projectRoot);
1468
+ }
1469
+ catch { /* no lineage yet */ }
1470
+ if (gen.promoted)
1471
+ this.log('info', `Flywheel gen ${gen.generation}: PROMOTED (+${(gen.delta ?? 0).toFixed(4)} held-out, significant=${gen.significant}) — champion advanced`);
1472
+ result = { timestamp: new Date().toISOString(), flywheel: gen, lineage: status };
1473
+ }
1474
+ catch (error) {
1475
+ const message = error instanceof Error ? error.message : String(error);
1476
+ this.log('warn', `Harness worker failed: ${message}`);
1477
+ result = { timestamp: new Date().toISOString(), ran: false, error: message };
1478
+ }
1479
+ writeFileSync(harnessFile, JSON.stringify(result, null, 2));
1480
+ return result;
1481
+ }
1398
1482
  /**
1399
1483
  * Local testgaps worker (fallback when headless unavailable)
1400
1484
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@claude-flow/cli",
3
- "version": "3.22.0",
3
+ "version": "3.24.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",