@claude-flow/cli 3.1.0-alpha.4 → 3.1.0-alpha.40

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 (44) hide show
  1. package/.claude/helpers/auto-memory-hook.mjs +350 -0
  2. package/.claude/helpers/hook-handler.cjs +232 -0
  3. package/.claude/helpers/intelligence.cjs +916 -0
  4. package/.claude/helpers/session.js +8 -0
  5. package/.claude/helpers/statusline.cjs +96 -28
  6. package/.claude/settings.json +86 -141
  7. package/README.md +830 -353
  8. package/bin/cli.js +6 -2
  9. package/dist/src/commands/hooks.d.ts.map +1 -1
  10. package/dist/src/commands/hooks.js +224 -32
  11. package/dist/src/commands/hooks.js.map +1 -1
  12. package/dist/src/commands/init.d.ts.map +1 -1
  13. package/dist/src/commands/init.js +191 -4
  14. package/dist/src/commands/init.js.map +1 -1
  15. package/dist/src/commands/memory.d.ts.map +1 -1
  16. package/dist/src/commands/memory.js +12 -2
  17. package/dist/src/commands/memory.js.map +1 -1
  18. package/dist/src/init/executor.d.ts +8 -2
  19. package/dist/src/init/executor.d.ts.map +1 -1
  20. package/dist/src/init/executor.js +310 -41
  21. package/dist/src/init/executor.js.map +1 -1
  22. package/dist/src/init/helpers-generator.d.ts +18 -0
  23. package/dist/src/init/helpers-generator.d.ts.map +1 -1
  24. package/dist/src/init/helpers-generator.js +498 -0
  25. package/dist/src/init/helpers-generator.js.map +1 -1
  26. package/dist/src/init/settings-generator.d.ts.map +1 -1
  27. package/dist/src/init/settings-generator.js +134 -91
  28. package/dist/src/init/settings-generator.js.map +1 -1
  29. package/dist/src/init/statusline-generator.d.ts.map +1 -1
  30. package/dist/src/init/statusline-generator.js +104 -34
  31. package/dist/src/init/statusline-generator.js.map +1 -1
  32. package/dist/src/init/types.d.ts +12 -0
  33. package/dist/src/init/types.d.ts.map +1 -1
  34. package/dist/src/init/types.js +12 -0
  35. package/dist/src/init/types.js.map +1 -1
  36. package/dist/src/mcp-tools/memory-tools.d.ts.map +1 -1
  37. package/dist/src/mcp-tools/memory-tools.js +4 -1
  38. package/dist/src/mcp-tools/memory-tools.js.map +1 -1
  39. package/dist/src/memory/memory-initializer.d.ts +1 -0
  40. package/dist/src/memory/memory-initializer.d.ts.map +1 -1
  41. package/dist/src/memory/memory-initializer.js +14 -9
  42. package/dist/src/memory/memory-initializer.js.map +1 -1
  43. package/dist/tsconfig.tsbuildinfo +1 -1
  44. package/package.json +4 -2
@@ -5,15 +5,16 @@
5
5
  import * as fs from 'fs';
6
6
  import * as path from 'path';
7
7
  import { fileURLToPath } from 'url';
8
+ import { createRequire } from 'module';
8
9
  import { dirname } from 'path';
9
10
  // ESM-compatible __dirname
10
11
  const __filename = fileURLToPath(import.meta.url);
11
12
  const __dirname = dirname(__filename);
12
13
  import { detectPlatform, DEFAULT_INIT_OPTIONS } from './types.js';
13
- import { generateSettingsJson } from './settings-generator.js';
14
+ import { generateSettingsJson, generateSettings } from './settings-generator.js';
14
15
  import { generateMCPJson } from './mcp-generator.js';
15
- import { generateStatuslineScript, generateStatuslineHook } from './statusline-generator.js';
16
- import { generatePreCommitHook, generatePostCommitHook, generateSessionManager, generateAgentRouter, generateMemoryHelper, } from './helpers-generator.js';
16
+ import { generateStatuslineScript } from './statusline-generator.js';
17
+ import { generatePreCommitHook, generatePostCommitHook, generateSessionManager, generateAgentRouter, generateMemoryHelper, generateHookHandler, generateIntelligenceStub, generateAutoMemoryHook, } from './helpers-generator.js';
17
18
  import { generateClaudeMd } from './claudemd-generator.js';
18
19
  /**
19
20
  * Skills to copy based on configuration
@@ -30,6 +31,7 @@ const SKILLS_MAP = {
30
31
  'skill-builder',
31
32
  ],
32
33
  browser: ['browser'], // agent-browser integration
34
+ dualMode: ['dual-mode'], // Claude Code + Codex hybrid execution
33
35
  agentdb: [
34
36
  'agentdb-advanced',
35
37
  'agentdb-learning',
@@ -87,6 +89,7 @@ const AGENTS_MAP = {
87
89
  sparc: ['sparc'],
88
90
  swarm: ['swarm'],
89
91
  browser: ['browser'], // agent-browser integration
92
+ dualMode: ['dual-mode'], // Claude Code + Codex hybrid execution
90
93
  // V3-specific agents
91
94
  v3: ['v3'],
92
95
  optimization: ['optimization'],
@@ -202,17 +205,155 @@ export async function executeInit(options) {
202
205
  }
203
206
  return result;
204
207
  }
208
+ /**
209
+ * Merge new settings into existing settings.json
210
+ * Preserves user customizations while adding new features like Agent Teams
211
+ * Uses platform-specific commands for Mac, Linux, and Windows
212
+ */
213
+ function mergeSettingsForUpgrade(existing) {
214
+ const merged = { ...existing };
215
+ const platform = detectPlatform();
216
+ const isWindows = platform.os === 'windows';
217
+ // Platform-specific command wrappers
218
+ // Windows: Use PowerShell-compatible commands
219
+ // Mac/Linux: Use bash-compatible commands with 2>/dev/null
220
+ const teammateIdleCmd = isWindows
221
+ ? 'npx @claude-flow/cli@latest hooks teammate-idle --auto-assign true 2>$null; exit 0'
222
+ : 'npx @claude-flow/cli@latest hooks teammate-idle --auto-assign true 2>/dev/null || true';
223
+ const taskCompletedCmd = isWindows
224
+ ? 'if ($env:TASK_ID) { npx @claude-flow/cli@latest hooks task-completed --task-id $env:TASK_ID --train-patterns true 2>$null }; exit 0'
225
+ : '[ -n "$TASK_ID" ] && npx @claude-flow/cli@latest hooks task-completed --task-id "$TASK_ID" --train-patterns true 2>/dev/null || true';
226
+ // 1. Merge env vars (preserve existing, add new)
227
+ const existingEnv = existing.env || {};
228
+ merged.env = {
229
+ ...existingEnv,
230
+ CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS: '1',
231
+ CLAUDE_FLOW_V3_ENABLED: existingEnv.CLAUDE_FLOW_V3_ENABLED || 'true',
232
+ CLAUDE_FLOW_HOOKS_ENABLED: existingEnv.CLAUDE_FLOW_HOOKS_ENABLED || 'true',
233
+ };
234
+ // 2. Merge hooks (preserve existing, add new Agent Teams + auto-memory hooks)
235
+ const existingHooks = existing.hooks || {};
236
+ merged.hooks = { ...existingHooks };
237
+ // Platform-specific auto-memory hook commands
238
+ const autoMemoryImportCmd = isWindows
239
+ ? 'node .claude/helpers/auto-memory-hook.mjs import 2>$null; exit 0'
240
+ : 'node .claude/helpers/auto-memory-hook.mjs import 2>/dev/null || true';
241
+ const autoMemorySyncCmd = isWindows
242
+ ? 'node .claude/helpers/auto-memory-hook.mjs sync 2>$null; exit 0'
243
+ : 'node .claude/helpers/auto-memory-hook.mjs sync 2>/dev/null || true';
244
+ // Add auto-memory import to SessionStart (if not already present)
245
+ const sessionStartHooks = existingHooks.SessionStart;
246
+ const hasAutoMemoryImport = sessionStartHooks?.some(group => group.hooks?.some(h => h.command?.includes('auto-memory-hook')));
247
+ if (!hasAutoMemoryImport) {
248
+ const startHooks = merged.hooks;
249
+ if (!startHooks.SessionStart) {
250
+ startHooks.SessionStart = [{ hooks: [] }];
251
+ }
252
+ const startGroup = startHooks.SessionStart[0];
253
+ if (!startGroup.hooks)
254
+ startGroup.hooks = [];
255
+ startGroup.hooks.push({
256
+ type: 'command',
257
+ command: autoMemoryImportCmd,
258
+ timeout: 6000,
259
+ continueOnError: true,
260
+ });
261
+ }
262
+ // Add auto-memory sync to SessionEnd (if not already present)
263
+ const sessionEndHooks = existingHooks.SessionEnd;
264
+ const hasAutoMemorySync = sessionEndHooks?.some(group => group.hooks?.some(h => h.command?.includes('auto-memory-hook')));
265
+ if (!hasAutoMemorySync) {
266
+ const endHooks = merged.hooks;
267
+ if (!endHooks.SessionEnd) {
268
+ endHooks.SessionEnd = [{ hooks: [] }];
269
+ }
270
+ const endGroup = endHooks.SessionEnd[0];
271
+ if (!endGroup.hooks)
272
+ endGroup.hooks = [];
273
+ // Insert at beginning so sync runs before other cleanup
274
+ endGroup.hooks.unshift({
275
+ type: 'command',
276
+ command: autoMemorySyncCmd,
277
+ timeout: 8000,
278
+ continueOnError: true,
279
+ });
280
+ }
281
+ // Add TeammateIdle hook if not present
282
+ if (!existingHooks.TeammateIdle) {
283
+ merged.hooks.TeammateIdle = [
284
+ {
285
+ hooks: [
286
+ {
287
+ type: 'command',
288
+ command: teammateIdleCmd,
289
+ timeout: 5000,
290
+ continueOnError: true,
291
+ },
292
+ ],
293
+ },
294
+ ];
295
+ }
296
+ // Add TaskCompleted hook if not present
297
+ if (!existingHooks.TaskCompleted) {
298
+ merged.hooks.TaskCompleted = [
299
+ {
300
+ hooks: [
301
+ {
302
+ type: 'command',
303
+ command: taskCompletedCmd,
304
+ timeout: 5000,
305
+ continueOnError: true,
306
+ },
307
+ ],
308
+ },
309
+ ];
310
+ }
311
+ // 3. Merge claudeFlow settings (preserve existing, add agentTeams + memory)
312
+ const existingClaudeFlow = existing.claudeFlow || {};
313
+ const existingMemory = existingClaudeFlow.memory || {};
314
+ merged.claudeFlow = {
315
+ ...existingClaudeFlow,
316
+ version: existingClaudeFlow.version || '3.0.0',
317
+ enabled: existingClaudeFlow.enabled !== false,
318
+ agentTeams: {
319
+ enabled: true,
320
+ teammateMode: 'auto',
321
+ taskListEnabled: true,
322
+ mailboxEnabled: true,
323
+ coordination: {
324
+ autoAssignOnIdle: true,
325
+ trainPatternsOnComplete: true,
326
+ notifyLeadOnComplete: true,
327
+ sharedMemoryNamespace: 'agent-teams',
328
+ },
329
+ hooks: {
330
+ teammateIdle: { enabled: true, autoAssign: true, checkTaskList: true },
331
+ taskCompleted: { enabled: true, trainPatterns: true, notifyLead: true },
332
+ },
333
+ },
334
+ memory: {
335
+ ...existingMemory,
336
+ learningBridge: existingMemory.learningBridge ?? { enabled: true },
337
+ memoryGraph: existingMemory.memoryGraph ?? { enabled: true },
338
+ agentScopes: existingMemory.agentScopes ?? { enabled: true },
339
+ },
340
+ };
341
+ return merged;
342
+ }
205
343
  /**
206
344
  * Execute upgrade - updates helpers and creates missing metrics without losing data
207
345
  * This is safe for existing users who want the latest statusline fixes
346
+ * @param targetDir - Target directory
347
+ * @param upgradeSettings - If true, merge new settings into existing settings.json
208
348
  */
209
- export async function executeUpgrade(targetDir) {
349
+ export async function executeUpgrade(targetDir, upgradeSettings = false) {
210
350
  const result = {
211
351
  success: true,
212
352
  updated: [],
213
353
  created: [],
214
354
  preserved: [],
215
355
  errors: [],
356
+ settingsUpdated: [],
216
357
  };
217
358
  try {
218
359
  // Ensure required directories exist
@@ -228,6 +369,50 @@ export async function executeUpgrade(targetDir) {
228
369
  fs.mkdirSync(fullPath, { recursive: true });
229
370
  }
230
371
  }
372
+ // 0. ALWAYS update critical helpers (force overwrite)
373
+ const sourceHelpersForUpgrade = findSourceHelpersDir();
374
+ if (sourceHelpersForUpgrade) {
375
+ const criticalHelpers = ['auto-memory-hook.mjs', 'hook-handler.cjs', 'intelligence.cjs'];
376
+ for (const helperName of criticalHelpers) {
377
+ const targetPath = path.join(targetDir, '.claude', 'helpers', helperName);
378
+ const sourcePath = path.join(sourceHelpersForUpgrade, helperName);
379
+ if (fs.existsSync(sourcePath)) {
380
+ if (fs.existsSync(targetPath)) {
381
+ result.updated.push(`.claude/helpers/${helperName}`);
382
+ }
383
+ else {
384
+ result.created.push(`.claude/helpers/${helperName}`);
385
+ }
386
+ fs.copyFileSync(sourcePath, targetPath);
387
+ try {
388
+ fs.chmodSync(targetPath, '755');
389
+ }
390
+ catch { }
391
+ }
392
+ }
393
+ }
394
+ else {
395
+ // Source not found (npx with broken paths) — use generated fallbacks
396
+ const generatedCritical = {
397
+ 'hook-handler.cjs': generateHookHandler(),
398
+ 'intelligence.cjs': generateIntelligenceStub(),
399
+ 'auto-memory-hook.mjs': generateAutoMemoryHook(),
400
+ };
401
+ for (const [helperName, content] of Object.entries(generatedCritical)) {
402
+ const targetPath = path.join(targetDir, '.claude', 'helpers', helperName);
403
+ if (fs.existsSync(targetPath)) {
404
+ result.updated.push(`.claude/helpers/${helperName}`);
405
+ }
406
+ else {
407
+ result.created.push(`.claude/helpers/${helperName}`);
408
+ }
409
+ fs.writeFileSync(targetPath, content, 'utf-8');
410
+ try {
411
+ fs.chmodSync(targetPath, '755');
412
+ }
413
+ catch { }
414
+ }
415
+ }
231
416
  // 1. ALWAYS update statusline helper (force overwrite)
232
417
  const statuslinePath = path.join(targetDir, '.claude', 'helpers', 'statusline.cjs');
233
418
  // Use default options with statusline config
@@ -318,6 +503,37 @@ export async function executeUpgrade(targetDir) {
318
503
  else {
319
504
  result.preserved.push('.claude-flow/security/audit-status.json');
320
505
  }
506
+ // 3. Merge settings if requested
507
+ if (upgradeSettings) {
508
+ const settingsPath = path.join(targetDir, '.claude', 'settings.json');
509
+ if (fs.existsSync(settingsPath)) {
510
+ try {
511
+ const existingSettings = JSON.parse(fs.readFileSync(settingsPath, 'utf-8'));
512
+ const mergedSettings = mergeSettingsForUpgrade(existingSettings);
513
+ fs.writeFileSync(settingsPath, JSON.stringify(mergedSettings, null, 2), 'utf-8');
514
+ result.updated.push('.claude/settings.json');
515
+ result.settingsUpdated = [
516
+ 'env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS',
517
+ 'hooks.SessionStart (auto-memory import)',
518
+ 'hooks.SessionEnd (auto-memory sync)',
519
+ 'hooks.TeammateIdle',
520
+ 'hooks.TaskCompleted',
521
+ 'claudeFlow.agentTeams',
522
+ 'claudeFlow.memory (learningBridge, memoryGraph, agentScopes)',
523
+ ];
524
+ }
525
+ catch (settingsError) {
526
+ result.errors.push(`Settings merge failed: ${settingsError instanceof Error ? settingsError.message : String(settingsError)}`);
527
+ }
528
+ }
529
+ else {
530
+ // Create new settings.json with defaults
531
+ const defaultSettings = generateSettings(DEFAULT_INIT_OPTIONS);
532
+ fs.writeFileSync(settingsPath, JSON.stringify(defaultSettings, null, 2), 'utf-8');
533
+ result.created.push('.claude/settings.json');
534
+ result.settingsUpdated = ['Created new settings.json with Agent Teams'];
535
+ }
536
+ }
321
537
  }
322
538
  catch (error) {
323
539
  result.success = false;
@@ -328,10 +544,12 @@ export async function executeUpgrade(targetDir) {
328
544
  /**
329
545
  * Execute upgrade with --add-missing flag
330
546
  * Adds any new skills, agents, and commands that don't exist yet
547
+ * @param targetDir - Target directory
548
+ * @param upgradeSettings - If true, merge new settings into existing settings.json
331
549
  */
332
- export async function executeUpgradeWithMissing(targetDir) {
333
- // First do the normal upgrade
334
- const result = await executeUpgrade(targetDir);
550
+ export async function executeUpgradeWithMissing(targetDir, upgradeSettings = false) {
551
+ // First do the normal upgrade (pass through upgradeSettings)
552
+ const result = await executeUpgrade(targetDir, upgradeSettings);
335
553
  if (!result.success) {
336
554
  return result;
337
555
  }
@@ -486,6 +704,8 @@ async function copySkills(targetDir, options, result) {
486
704
  skillsToCopy.push(...SKILLS_MAP.browser);
487
705
  if (skillsConfig.v3)
488
706
  skillsToCopy.push(...SKILLS_MAP.v3);
707
+ if (skillsConfig.dualMode)
708
+ skillsToCopy.push(...SKILLS_MAP.dualMode);
489
709
  }
490
710
  // Find source skills directory
491
711
  const sourceSkillsDir = findSourceDir('skills', options.sourceBaseDir);
@@ -598,6 +818,9 @@ async function copyAgents(targetDir, options, result) {
598
818
  agentsToCopy.push(...(AGENTS_MAP.optimization || []));
599
819
  if (agentsConfig.testing)
600
820
  agentsToCopy.push(...(AGENTS_MAP.testing || []));
821
+ // Dual-mode agents (Claude Code + Codex hybrid)
822
+ if (agentsConfig.dualMode)
823
+ agentsToCopy.push(...(AGENTS_MAP.dualMode || []));
601
824
  }
602
825
  // Find source agents directory
603
826
  const sourceAgentsDir = findSourceDir('agents', options.sourceBaseDir);
@@ -625,42 +848,51 @@ async function copyAgents(targetDir, options, result) {
625
848
  }
626
849
  }
627
850
  /**
628
- * Find source helpers directory
851
+ * Find source helpers directory.
852
+ * Validates that the directory contains hook-handler.cjs to avoid
853
+ * returning the target directory or an incomplete source.
629
854
  */
630
855
  function findSourceHelpersDir(sourceBaseDir) {
631
856
  const possiblePaths = [];
857
+ const SENTINEL_FILE = 'hook-handler.cjs'; // Must exist in valid source
632
858
  // If explicit source base directory is provided, check it first
633
859
  if (sourceBaseDir) {
634
860
  possiblePaths.push(path.join(sourceBaseDir, '.claude', 'helpers'));
635
861
  }
636
- // IMPORTANT: Check the package's own .claude/helpers directory
637
- // This is the primary path when running as an npm package
638
- // __dirname is typically /path/to/node_modules/@claude-flow/cli/dist/src/init
639
- // We need to go up 3 levels to reach the package root (dist/src/init -> dist/src -> dist -> root)
862
+ // Strategy 1: require.resolve to find package root (most reliable for npx)
863
+ try {
864
+ const esmRequire = createRequire(import.meta.url);
865
+ const pkgJsonPath = esmRequire.resolve('@claude-flow/cli/package.json');
866
+ const pkgRoot = path.dirname(pkgJsonPath);
867
+ possiblePaths.push(path.join(pkgRoot, '.claude', 'helpers'));
868
+ }
869
+ catch {
870
+ // Not installed as a package — skip
871
+ }
872
+ // Strategy 2: __dirname-based (dist/src/init -> package root)
640
873
  const packageRoot = path.resolve(__dirname, '..', '..', '..');
641
874
  const packageHelpers = path.join(packageRoot, '.claude', 'helpers');
642
- if (fs.existsSync(packageHelpers)) {
643
- possiblePaths.unshift(packageHelpers); // Add to beginning (highest priority)
644
- }
645
- // From dist/src/init -> go up to project root
875
+ possiblePaths.push(packageHelpers);
876
+ // Strategy 3: Walk up from __dirname looking for package root
646
877
  let currentDir = __dirname;
647
878
  for (let i = 0; i < 10; i++) {
648
879
  const parentDir = path.dirname(currentDir);
880
+ if (parentDir === currentDir)
881
+ break; // hit filesystem root
649
882
  const helpersPath = path.join(parentDir, '.claude', 'helpers');
650
- if (fs.existsSync(helpersPath)) {
651
- possiblePaths.push(helpersPath);
652
- }
883
+ possiblePaths.push(helpersPath);
653
884
  currentDir = parentDir;
654
885
  }
655
- // Also check relative to process.cwd() for development
886
+ // Strategy 4: Check cwd-relative paths (for local dev)
656
887
  const cwdBased = [
657
888
  path.join(process.cwd(), '.claude', 'helpers'),
658
889
  path.join(process.cwd(), '..', '.claude', 'helpers'),
659
890
  path.join(process.cwd(), '..', '..', '.claude', 'helpers'),
660
891
  ];
661
892
  possiblePaths.push(...cwdBased);
893
+ // Return first path that exists AND contains the sentinel file
662
894
  for (const p of possiblePaths) {
663
- if (fs.existsSync(p)) {
895
+ if (fs.existsSync(p) && fs.existsSync(path.join(p, SENTINEL_FILE))) {
664
896
  return p;
665
897
  }
666
898
  }
@@ -707,6 +939,9 @@ async function writeHelpers(targetDir, options, result) {
707
939
  'session.js': generateSessionManager(),
708
940
  'router.js': generateAgentRouter(),
709
941
  'memory.js': generateMemoryHelper(),
942
+ 'hook-handler.cjs': generateHookHandler(),
943
+ 'intelligence.cjs': generateIntelligenceStub(),
944
+ 'auto-memory-hook.mjs': generateAutoMemoryHook(),
710
945
  };
711
946
  for (const [name, content] of Object.entries(helpers)) {
712
947
  const filePath = path.join(helpersDir, name);
@@ -769,7 +1004,6 @@ async function writeStatusline(targetDir, options, result) {
769
1004
  { src: 'statusline.sh', dest: 'statusline.sh', dir: claudeDir },
770
1005
  { src: 'statusline.mjs', dest: 'statusline.mjs', dir: claudeDir },
771
1006
  ];
772
- let copiedAdvanced = false;
773
1007
  if (sourceClaudeDir) {
774
1008
  for (const file of advancedStatuslineFiles) {
775
1009
  const sourcePath = path.join(sourceClaudeDir, file.src);
@@ -782,7 +1016,6 @@ async function writeStatusline(targetDir, options, result) {
782
1016
  fs.chmodSync(destPath, '755');
783
1017
  }
784
1018
  result.created.files.push(`.claude/${file.dest}`);
785
- copiedAdvanced = true;
786
1019
  }
787
1020
  else {
788
1021
  result.skipped.push(`.claude/${file.dest}`);
@@ -790,24 +1023,16 @@ async function writeStatusline(targetDir, options, result) {
790
1023
  }
791
1024
  }
792
1025
  }
793
- // Fall back to generating simple statusline if advanced files not available
794
- if (!copiedAdvanced) {
795
- const statuslineScript = generateStatuslineScript(options);
796
- const statuslineHook = generateStatuslineHook(options);
797
- const files = {
798
- 'statusline.cjs': statuslineScript, // .cjs for ES module project compatibility
799
- 'statusline-hook.sh': statuslineHook,
800
- };
801
- for (const [name, content] of Object.entries(files)) {
802
- const filePath = path.join(helpersDir, name);
803
- if (!fs.existsSync(filePath) || options.force) {
804
- fs.writeFileSync(filePath, content, 'utf-8');
805
- result.created.files.push(`.claude/helpers/${name}`);
806
- }
807
- else {
808
- result.skipped.push(`.claude/helpers/${name}`);
809
- }
810
- }
1026
+ // ALWAYS generate statusline.cjs settings.json references this path
1027
+ // regardless of whether advanced statusline files were also copied.
1028
+ const statuslineScript = generateStatuslineScript(options);
1029
+ const statuslinePath = path.join(helpersDir, 'statusline.cjs');
1030
+ if (!fs.existsSync(statuslinePath) || options.force) {
1031
+ fs.writeFileSync(statuslinePath, statuslineScript, 'utf-8');
1032
+ result.created.files.push('.claude/helpers/statusline.cjs');
1033
+ }
1034
+ else {
1035
+ result.skipped.push('.claude/helpers/statusline.cjs');
811
1036
  }
812
1037
  }
813
1038
  /**
@@ -835,6 +1060,21 @@ memory:
835
1060
  enableHNSW: ${options.runtime.enableHNSW}
836
1061
  persistPath: .claude-flow/data
837
1062
  cacheSize: 100
1063
+ # ADR-049: Self-Learning Memory
1064
+ learningBridge:
1065
+ enabled: ${options.runtime.enableLearningBridge ?? options.runtime.enableNeural}
1066
+ sonaMode: balanced
1067
+ confidenceDecayRate: 0.005
1068
+ accessBoostAmount: 0.03
1069
+ consolidationThreshold: 10
1070
+ memoryGraph:
1071
+ enabled: ${options.runtime.enableMemoryGraph ?? true}
1072
+ pageRankDamping: 0.85
1073
+ maxNodes: 5000
1074
+ similarityThreshold: 0.8
1075
+ agentScopes:
1076
+ enabled: ${options.runtime.enableAgentScopes ?? true}
1077
+ defaultScope: project
838
1078
 
839
1079
  neural:
840
1080
  enabled: ${options.runtime.enableNeural}
@@ -1020,6 +1260,9 @@ Claude Flow V3 is a domain-driven design architecture for multi-agent AI coordin
1020
1260
  | Memory Backend | ${options.runtime.memoryBackend} |
1021
1261
  | HNSW Indexing | ${options.runtime.enableHNSW ? 'Enabled' : 'Disabled'} |
1022
1262
  | Neural Learning | ${options.runtime.enableNeural ? 'Enabled' : 'Disabled'} |
1263
+ | LearningBridge | ${options.runtime.enableLearningBridge ? 'Enabled (SONA + ReasoningBank)' : 'Disabled'} |
1264
+ | Knowledge Graph | ${options.runtime.enableMemoryGraph ? 'Enabled (PageRank + Communities)' : 'Disabled'} |
1265
+ | Agent Scopes | ${options.runtime.enableAgentScopes ? 'Enabled (project/local/user)' : 'Disabled'} |
1023
1266
 
1024
1267
  ---
1025
1268
 
@@ -1220,6 +1463,25 @@ npx @claude-flow/cli@latest doctor --fix
1220
1463
  3. **DISTILL** - LoRA learning extraction
1221
1464
  4. **CONSOLIDATE** - EWC++ preservation
1222
1465
 
1466
+ ### Self-Learning Memory (ADR-049)
1467
+
1468
+ | Component | Status | Description |
1469
+ |-----------|--------|-------------|
1470
+ | **LearningBridge** | ${options.runtime.enableLearningBridge ? '✅ Enabled' : '⏸ Disabled'} | Connects insights to SONA/ReasoningBank neural pipeline |
1471
+ | **MemoryGraph** | ${options.runtime.enableMemoryGraph ? '✅ Enabled' : '⏸ Disabled'} | PageRank knowledge graph + community detection |
1472
+ | **AgentMemoryScope** | ${options.runtime.enableAgentScopes ? '✅ Enabled' : '⏸ Disabled'} | 3-scope agent memory (project/local/user) |
1473
+
1474
+ **LearningBridge** - Insights trigger learning trajectories. Confidence evolves: +0.03 on access, -0.005/hour decay. Consolidation runs the JUDGE/DISTILL/CONSOLIDATE pipeline.
1475
+
1476
+ **MemoryGraph** - Builds a knowledge graph from entry references. PageRank identifies influential insights. Communities group related knowledge. Graph-aware ranking blends vector + structural scores.
1477
+
1478
+ **AgentMemoryScope** - Maps Claude Code 3-scope directories:
1479
+ - \`project\`: \`<gitRoot>/.claude/agent-memory/<agent>/\`
1480
+ - \`local\`: \`<gitRoot>/.claude/agent-memory-local/<agent>/\`
1481
+ - \`user\`: \`~/.claude/agent-memory/<agent>/\`
1482
+
1483
+ High-confidence insights (>0.8) can transfer between agents.
1484
+
1223
1485
  ### Memory Commands
1224
1486
  \`\`\`bash
1225
1487
  # Store pattern
@@ -1286,6 +1548,11 @@ npx @claude-flow/cli@latest hive-mind consensus --propose "task"
1286
1548
  | MCP Response | <100ms | ✅ Achieved |
1287
1549
  | CLI Startup | <500ms | ✅ Achieved |
1288
1550
  | SONA Adaptation | <0.05ms | 🔄 In Progress |
1551
+ | Graph Build (1k) | <200ms | ✅ 2.78ms (71.9x headroom) |
1552
+ | PageRank (1k) | <100ms | ✅ 12.21ms (8.2x headroom) |
1553
+ | Insight Recording | <5ms/each | ✅ 0.12ms (41x headroom) |
1554
+ | Consolidation | <500ms | ✅ 0.26ms (1,955x headroom) |
1555
+ | Knowledge Transfer | <100ms | ✅ 1.25ms (80x headroom) |
1289
1556
 
1290
1557
  ---
1291
1558
 
@@ -1480,6 +1747,8 @@ function countEnabledHooks(options) {
1480
1747
  count++;
1481
1748
  if (hooks.stop)
1482
1749
  count++;
1750
+ if (hooks.preCompact)
1751
+ count++;
1483
1752
  if (hooks.notification)
1484
1753
  count++;
1485
1754
  return count;