claude-flow 3.5.81 → 3.5.83

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 (25) hide show
  1. package/package.json +1 -1
  2. package/v3/@claude-flow/cli/dist/src/commands/daemon.js +59 -5
  3. package/v3/@claude-flow/cli/dist/src/commands/hooks.js +3 -3
  4. package/v3/@claude-flow/cli/dist/src/commands/init.js +5 -5
  5. package/v3/@claude-flow/cli/dist/src/commands/swarm.js +101 -4
  6. package/v3/@claude-flow/cli/dist/src/init/claudemd-generator.js +21 -0
  7. package/v3/@claude-flow/cli/dist/src/mcp-tools/agent-tools.js +11 -0
  8. package/v3/@claude-flow/cli/dist/src/mcp-tools/guidance-tools.js +1 -1
  9. package/v3/@claude-flow/cli/dist/src/mcp-tools/hooks-tools.js +43 -23
  10. package/v3/@claude-flow/cli/dist/src/mcp-tools/neural-tools.js +3 -0
  11. package/v3/@claude-flow/cli/dist/src/mcp-tools/swarm-tools.js +10 -0
  12. package/v3/@claude-flow/cli/dist/src/mcp-tools/system-tools.js +5 -3
  13. package/v3/@claude-flow/cli/dist/src/mcp-tools/task-tools.js +8 -0
  14. package/v3/@claude-flow/cli/dist/src/mcp-tools/types.js +5 -1
  15. package/v3/@claude-flow/cli/dist/src/memory/memory-bridge.js +3 -1
  16. package/v3/@claude-flow/cli/dist/src/services/event-stream.d.ts +25 -0
  17. package/v3/@claude-flow/cli/dist/src/services/event-stream.js +27 -0
  18. package/v3/@claude-flow/cli/dist/src/services/index.d.ts +3 -0
  19. package/v3/@claude-flow/cli/dist/src/services/index.js +6 -0
  20. package/v3/@claude-flow/cli/dist/src/services/loop-worker-runner.d.ts +16 -0
  21. package/v3/@claude-flow/cli/dist/src/services/loop-worker-runner.js +34 -0
  22. package/v3/@claude-flow/cli/dist/src/services/runtime-capabilities.d.ts +22 -0
  23. package/v3/@claude-flow/cli/dist/src/services/runtime-capabilities.js +45 -0
  24. package/v3/@claude-flow/cli/dist/src/services/worker-daemon.js +4 -2
  25. package/v3/@claude-flow/cli/package.json +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-flow",
3
- "version": "3.5.81",
3
+ "version": "3.5.83",
4
4
  "description": "Ruflo - Enterprise AI agent orchestration for Claude Code. Deploy 60+ specialized agents in coordinated swarms with self-learning, fault-tolerant consensus, vector memory, and MCP integration",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -64,6 +64,15 @@ const startCommand = {
64
64
  config.resourceThresholds = thresholds;
65
65
  }
66
66
  }
67
+ // Detect Claude Code runtime — suggest native alternatives
68
+ if (!isDaemonProcess && (process.env.CLAUDE_CODE || !process.stdin.isTTY)) {
69
+ if (!quiet) {
70
+ output.printInfo('[NATIVE_AVAILABLE] Running inside Claude Code. Consider using:');
71
+ output.writeln(' /loop "Run workers" — for in-session periodic execution');
72
+ output.writeln(' CronCreate — for persistent background workers');
73
+ output.writeln(' Proceeding with daemon start as fallback...');
74
+ }
75
+ }
67
76
  // Check if background daemon already running (skip if we ARE the daemon process)
68
77
  if (!isDaemonProcess) {
69
78
  const bgPid = getBackgroundDaemonPid(projectRoot);
@@ -628,6 +637,49 @@ const enableCommand = {
628
637
  }
629
638
  },
630
639
  };
640
+ // Schedule subcommand - suggest native Claude Code alternatives for persistent scheduling
641
+ const scheduleCommand = {
642
+ name: 'schedule',
643
+ description: 'Schedule a worker for periodic execution (suggests native Claude Code primitives)',
644
+ options: [
645
+ { name: 'worker', short: 'w', type: 'string', description: 'Worker type to schedule', required: true },
646
+ { name: 'interval', short: 'i', type: 'string', description: 'Interval in minutes (e.g. 15)', required: true },
647
+ ],
648
+ examples: [
649
+ { command: 'claude-flow daemon schedule -w audit -i 30', description: 'Schedule audit worker every 30 minutes' },
650
+ { command: 'claude-flow daemon schedule -w map -i 5', description: 'Schedule map worker every 5 minutes' },
651
+ ],
652
+ action: async (ctx) => {
653
+ const worker = ctx.flags.worker;
654
+ const intervalStr = ctx.flags.interval;
655
+ if (!worker) {
656
+ output.printError('Worker type is required. Use --worker or -w flag.');
657
+ return { success: false, exitCode: 1 };
658
+ }
659
+ if (!intervalStr) {
660
+ output.printError('Interval is required. Use --interval or -i flag.');
661
+ return { success: false, exitCode: 1 };
662
+ }
663
+ const minutes = parseInt(intervalStr, 10);
664
+ if (isNaN(minutes) || minutes < 1 || minutes > 1440) {
665
+ output.printError('Interval must be a number between 1 and 1440 (minutes).');
666
+ return { success: false, exitCode: 1 };
667
+ }
668
+ // Convert minutes to cron expression
669
+ const cronExpr = minutes < 60
670
+ ? `*/${minutes} * * * *`
671
+ : `0 */${Math.floor(minutes / 60)} * * *`;
672
+ output.writeln();
673
+ output.printBox([
674
+ `[CRON_SUGGESTION] To schedule this worker persistently:`,
675
+ `CronCreate("${worker}-worker", "${cronExpr}", "Run npx @claude-flow/cli hooks worker dispatch --trigger ${worker}")`,
676
+ ``,
677
+ `For in-session periodic execution, use:`,
678
+ `/loop "Run ${worker} worker" (auto-paced with cache-aware delays)`,
679
+ ].join('\n'), 'Schedule Worker');
680
+ return { success: true };
681
+ },
682
+ };
631
683
  // Helper functions for time formatting
632
684
  function formatTimeAgo(date) {
633
685
  const seconds = Math.floor((Date.now() - date.getTime()) / 1000);
@@ -661,6 +713,7 @@ export const daemonCommand = {
661
713
  statusCommand,
662
714
  triggerCommand,
663
715
  enableCommand,
716
+ scheduleCommand,
664
717
  ],
665
718
  options: [],
666
719
  examples: [
@@ -699,11 +752,12 @@ export const daemonCommand = {
699
752
  output.writeln();
700
753
  output.writeln(output.bold('Subcommands'));
701
754
  output.printList([
702
- `${output.highlight('start')} - Start the daemon`,
703
- `${output.highlight('stop')} - Stop the daemon`,
704
- `${output.highlight('status')} - Show daemon status`,
705
- `${output.highlight('trigger')} - Manually run a worker`,
706
- `${output.highlight('enable')} - Enable/disable a worker`,
755
+ `${output.highlight('start')} - Start the daemon`,
756
+ `${output.highlight('stop')} - Stop the daemon`,
757
+ `${output.highlight('status')} - Show daemon status`,
758
+ `${output.highlight('trigger')} - Manually run a worker`,
759
+ `${output.highlight('enable')} - Enable/disable a worker`,
760
+ `${output.highlight('schedule')} - Schedule periodic worker execution`,
707
761
  ]);
708
762
  output.writeln();
709
763
  output.writeln('Run "claude-flow daemon <subcommand> --help" for details');
@@ -3365,14 +3365,14 @@ const statuslineCommand = {
3365
3365
  const isWindows = process.platform === 'win32';
3366
3366
  try {
3367
3367
  const psCmd = isWindows
3368
- ? 'tasklist /FI "IMAGENAME eq node.exe" 2>NUL | findstr /I /C:"node" >NUL && echo 1 || echo 0'
3368
+ ? 'tasklist /FI "IMAGENAME eq node.exe" /NH 2>NUL | find /c /v "" 2>NUL || echo 0'
3369
3369
  : 'ps aux 2>/dev/null | grep -c agentic-flow || echo "0"';
3370
- const ps = execSync(psCmd, { encoding: 'utf-8' });
3370
+ const ps = execSync(psCmd, { encoding: 'utf-8', timeout: 3000 });
3371
3371
  activeAgents = Math.max(0, parseInt(ps.trim()) - 1);
3372
3372
  coordinationActive = activeAgents > 0;
3373
3373
  }
3374
3374
  catch {
3375
- // Ignore
3375
+ // ps/tasklist unavailable or timed out — report zero
3376
3376
  }
3377
3377
  return { activeAgents, maxAgents, coordinationActive };
3378
3378
  }
@@ -344,13 +344,13 @@ const initAction = async (ctx) => {
344
344
  }
345
345
  }
346
346
  if (!startDaemon && !startAll) {
347
- // Next steps (only if not auto-starting)
347
+ const bin = (process.argv[1] || '').includes('ruflo') ? 'ruflo' : 'claude-flow';
348
348
  output.writeln(output.bold('Next steps:'));
349
349
  output.printList([
350
- `Run ${output.highlight('claude-flow daemon start')} to start background workers`,
351
- `Run ${output.highlight('claude-flow memory init')} to initialize memory database`,
352
- `Run ${output.highlight('claude-flow swarm init')} to initialize a swarm`,
353
- `Or use ${output.highlight('claude-flow init --start-all')} to do all of the above`,
350
+ `Run ${output.highlight(`${bin} daemon start`)} to start background workers`,
351
+ `Run ${output.highlight(`${bin} memory init`)} to initialize memory database`,
352
+ `Run ${output.highlight(`${bin} swarm init`)} to initialize a swarm`,
353
+ `Or use ${output.highlight(`${bin} init --start-all`)} to do all of the above`,
354
354
  options.components.settings ? `Review ${output.highlight('.claude/settings.json')} for hook configurations` : '',
355
355
  ].filter(Boolean));
356
356
  }
@@ -5,6 +5,7 @@
5
5
  import { output } from '../output.js';
6
6
  import { select, confirm } from '../prompt.js';
7
7
  import { callMCPTool, MCPClientError } from '../mcp-client.js';
8
+ import { createRunId, emitEvent } from '../services/event-stream.js';
8
9
  import * as fs from 'fs';
9
10
  import * as path from 'path';
10
11
  // Get dynamic swarm status from memory/session files
@@ -524,14 +525,72 @@ const startCommand = {
524
525
  return { success: true, data: executionState };
525
526
  }
526
527
  };
528
+ // Shared polling loop used by `status --stream` and `watch`
529
+ function startStatusPoll(swarmId, runId, includeHealth) {
530
+ let prev = '';
531
+ const tick = () => {
532
+ const s = getSwarmStatus(swarmId);
533
+ const key = JSON.stringify(s);
534
+ if (key !== prev) {
535
+ prev = key;
536
+ emitEvent({
537
+ runId,
538
+ event: 'swarm_status',
539
+ agents: s.agents.total,
540
+ active: s.agents.active,
541
+ completed: s.tasks.completed,
542
+ pending: s.tasks.pending,
543
+ inProgress: s.tasks.inProgress,
544
+ progress: s.progress,
545
+ status: s.status,
546
+ });
547
+ }
548
+ if (includeHealth) {
549
+ emitEvent({
550
+ runId,
551
+ event: 'swarm_health',
552
+ memoryOk: s.hasActiveSwarm,
553
+ agentsTotal: s.agents.total,
554
+ agentsActive: s.agents.active,
555
+ successRate: s.metrics.successRate,
556
+ avgResponseTime: s.metrics.avgResponseTime,
557
+ elapsedTime: s.metrics.elapsedTime,
558
+ });
559
+ }
560
+ };
561
+ // Emit once immediately, then every 2 s
562
+ tick();
563
+ const timer = setInterval(tick, 2000);
564
+ const stop = () => { clearInterval(timer); };
565
+ return { stop };
566
+ }
527
567
  // Swarm status
528
568
  const statusCommand = {
529
569
  name: 'status',
530
- description: 'Show swarm status',
570
+ description: 'Show swarm status. Use --stream for live NDJSON output (pairs with Claude Code Monitor tool)',
571
+ options: [
572
+ {
573
+ name: 'stream',
574
+ description: 'Continuously emit NDJSON status events to stdout (use with Claude Code Monitor tool for live updates)',
575
+ type: 'boolean',
576
+ default: false
577
+ }
578
+ ],
531
579
  action: async (ctx) => {
532
580
  const swarmId = ctx.args[0];
533
581
  // Get dynamic status from actual swarm state files
534
582
  const status = getSwarmStatus(swarmId);
583
+ // --stream: enter NDJSON polling mode instead of one-shot output
584
+ if (ctx.flags.stream) {
585
+ const runId = createRunId();
586
+ const { stop } = startStatusPoll(swarmId, runId, false);
587
+ await new Promise((resolve) => {
588
+ const onSig = () => { stop(); resolve(); };
589
+ process.once('SIGINT', onSig);
590
+ process.once('SIGTERM', onSig);
591
+ });
592
+ return { success: true };
593
+ }
535
594
  if (ctx.flags.format === 'json') {
536
595
  output.printJson(status);
537
596
  return { success: true, data: status };
@@ -797,11 +856,48 @@ const coordinateCommand = {
797
856
  return { success: true, data: { agents: v3Agents, count: agentCount } };
798
857
  }
799
858
  };
859
+ // Watch swarm (NDJSON event stream)
860
+ const watchCommand = {
861
+ name: 'watch',
862
+ description: 'Stream live swarm status as NDJSON events to stdout',
863
+ options: [
864
+ {
865
+ name: 'health',
866
+ description: 'Include periodic health-metric events',
867
+ type: 'boolean',
868
+ default: false
869
+ }
870
+ ],
871
+ examples: [
872
+ { command: 'claude-flow swarm watch', description: 'Stream NDJSON status events' },
873
+ { command: 'claude-flow swarm watch --health', description: 'Include health metrics' }
874
+ ],
875
+ action: async (ctx) => {
876
+ const swarmId = ctx.args[0];
877
+ const includeHealth = ctx.flags.health;
878
+ const runId = createRunId();
879
+ emitEvent({
880
+ runId,
881
+ event: 'watch_start',
882
+ swarmId: swarmId ?? null,
883
+ health: includeHealth,
884
+ });
885
+ const { stop } = startStatusPoll(swarmId, runId, includeHealth);
886
+ // Block until SIGINT / SIGTERM, then clean up
887
+ await new Promise((resolve) => {
888
+ const onSig = () => { stop(); resolve(); };
889
+ process.once('SIGINT', onSig);
890
+ process.once('SIGTERM', onSig);
891
+ });
892
+ emitEvent({ runId, event: 'watch_stop' });
893
+ return { success: true };
894
+ }
895
+ };
800
896
  // Main swarm command
801
897
  export const swarmCommand = {
802
898
  name: 'swarm',
803
899
  description: 'Swarm coordination commands',
804
- subcommands: [initCommand, startCommand, statusCommand, stopCommand, scaleCommand, coordinateCommand],
900
+ subcommands: [initCommand, startCommand, statusCommand, stopCommand, scaleCommand, coordinateCommand, watchCommand],
805
901
  options: [],
806
902
  examples: [
807
903
  { command: 'claude-flow swarm init --v3-mode', description: 'Initialize V3 swarm' },
@@ -818,10 +914,11 @@ export const swarmCommand = {
818
914
  output.printList([
819
915
  `${output.highlight('init')} - Initialize a new swarm`,
820
916
  `${output.highlight('start')} - Start swarm execution`,
821
- `${output.highlight('status')} - Show swarm status`,
917
+ `${output.highlight('status')} - Show swarm status (--stream for live NDJSON)`,
822
918
  `${output.highlight('stop')} - Stop swarm execution`,
823
919
  `${output.highlight('scale')} - Scale swarm agent count`,
824
- `${output.highlight('coordinate')} - V3 15-agent coordination`
920
+ `${output.highlight('coordinate')} - V3 15-agent coordination`,
921
+ `${output.highlight('watch')} - Stream live NDJSON status events`
825
922
  ]);
826
923
  return { success: true };
827
924
  }
@@ -394,6 +394,22 @@ ToolSearch("hive consensus") → hive-mind_consensus, hive-mind_status
394
394
  ToolSearch("+aidefence") → aidefence_scan, aidefence_is_safe, aidefence_has_pii
395
395
  \`\`\``;
396
396
  }
397
+ function nativeCapabilities() {
398
+ return `## Native Claude Code Capabilities (PREFER OVER MCP) — ADR-091
399
+
400
+ When running inside Claude Code, ALWAYS prefer native tools over MCP equivalents:
401
+
402
+ | Need | Use This | Not This |
403
+ |------|----------|----------|
404
+ | Periodic tasks | \`/loop\` with ScheduleWakeup (delay <270s for cache) | \`daemon start\` |
405
+ | Live monitoring | \`Monitor("npx @claude-flow/cli swarm watch --stream")\` | Polling \`swarm status\` |
406
+ | Background workers | \`CronCreate("audit", "*/15 * * * *", "...")\` | \`daemon start --background\` |
407
+ | Agent isolation | \`Task({ ..., isolation: "worktree" })\` | Shared worktree |
408
+ | Multi-agent comms | \`TeamCreate\` + \`SendMessage\` | Memory namespace coordination |
409
+ | Cross-session | \`PushNotification\` + \`RemoteTrigger\` | No equivalent |
410
+
411
+ MCP tool responses include hints: \`[LOOP_SUGGESTION]\`, \`[MONITOR_AVAILABLE]\`, \`[CRON_SUGGESTION]\`, \`[TEAM_SUGGESTION]\`, \`[WORKTREE_SUGGESTION]\` — follow them. In CI/headless, Ruflo falls back to daemon mode automatically.`;
412
+ }
397
413
  function setupAndBoundary() {
398
414
  return `## Quick Setup
399
415
 
@@ -422,6 +438,7 @@ npx @claude-flow/cli@latest doctor --fix
422
438
  const TEMPLATE_SECTIONS = {
423
439
  minimal: [
424
440
  behavioralRules,
441
+ (_opts) => nativeCapabilities(),
425
442
  fileOrganization,
426
443
  projectArchitecture,
427
444
  (_opts) => buildAndTest(),
@@ -434,6 +451,7 @@ const TEMPLATE_SECTIONS = {
434
451
  ],
435
452
  standard: [
436
453
  behavioralRules,
454
+ (_opts) => nativeCapabilities(),
437
455
  fileOrganization,
438
456
  projectArchitecture,
439
457
  (_opts) => buildAndTest(),
@@ -450,6 +468,7 @@ const TEMPLATE_SECTIONS = {
450
468
  ],
451
469
  full: [
452
470
  behavioralRules,
471
+ (_opts) => nativeCapabilities(),
453
472
  fileOrganization,
454
473
  projectArchitecture,
455
474
  (_opts) => buildAndTest(),
@@ -471,6 +490,7 @@ const TEMPLATE_SECTIONS = {
471
490
  ],
472
491
  security: [
473
492
  behavioralRules,
493
+ (_opts) => nativeCapabilities(),
474
494
  fileOrganization,
475
495
  projectArchitecture,
476
496
  (_opts) => buildAndTest(),
@@ -486,6 +506,7 @@ const TEMPLATE_SECTIONS = {
486
506
  ],
487
507
  performance: [
488
508
  behavioralRules,
509
+ (_opts) => nativeCapabilities(),
489
510
  fileOrganization,
490
511
  projectArchitecture,
491
512
  (_opts) => buildAndTest(),
@@ -211,6 +211,13 @@ export const agentTools = [
211
211
  else if (routingResult.tier) {
212
212
  response.tier = routingResult.tier;
213
213
  }
214
+ // ADR-091 Phase 1: Native Claude Code capability suggestions
215
+ response.nativeIntegration = {
216
+ taskSuggestion: '[AGENT_NATIVE] For better isolation, spawn this agent via Claude Code Task tool: Task({ prompt: "...", subagent_type: "' + (input.agentType || 'coder') + '", isolation: "worktree" })',
217
+ isolationNote: agentType === 'coder' || agentType === 'reviewer'
218
+ ? '[WORKTREE_SUGGESTION] This agent type modifies files. Use isolation: "worktree" to prevent conflicts.'
219
+ : undefined,
220
+ };
214
221
  return response;
215
222
  },
216
223
  },
@@ -277,6 +284,10 @@ export const agentTools = [
277
284
  createdAt: agent.createdAt,
278
285
  domain: agent.domain,
279
286
  lastResult: agent.lastResult || null,
287
+ // ADR-091 Phase 1: Native Claude Code capability suggestions
288
+ nativeIntegration: {
289
+ monitorSuggestion: '[MONITOR_AVAILABLE] For live agent updates: Monitor("npx @claude-flow/cli agent logs --stream")',
290
+ },
280
291
  };
281
292
  }
282
293
  return {
@@ -65,7 +65,7 @@ const CAPABILITY_CATALOG = {
65
65
  'memory-knowledge': {
66
66
  name: 'Memory & Knowledge',
67
67
  description: 'Persistent memory with HNSW vector search, AgentDB storage, and embeddings.',
68
- tools: ['memory_store', 'memory_retrieve', 'memory_search', 'memory_list', 'memory_delete', 'memory_init', 'memory_export', 'memory_import', 'memory_stats', 'memory_compact', 'memory_namespace'],
68
+ tools: ['memory_store', 'memory_retrieve', 'memory_search', 'memory_list', 'memory_delete', 'memory_init', 'memory_export', 'memory_import_claude', 'memory_stats', 'memory_compact', 'memory_namespace'],
69
69
  commands: ['memory store', 'memory retrieve', 'memory search', 'memory list', 'memory delete', 'memory init'],
70
70
  agents: ['swarm-memory-manager', 'v3-memory-specialist'],
71
71
  skills: ['v3-memory-unification', 'agentdb-advanced', 'agentdb-vector-search', 'agentdb-memory-patterns', 'agentdb-learning'],
@@ -1743,6 +1743,9 @@ export const hooksSessionStart = {
1743
1743
  tasksRestored: sessionMemory?.restoredPatterns || 0,
1744
1744
  memoryRestored: sessionMemory?.restoredPatterns || 0,
1745
1745
  } : null,
1746
+ nativeCapabilities: {
1747
+ note: 'Claude Code native capabilities detected. Prefer /loop over daemon start, Monitor over polling, CronCreate over background processes.',
1748
+ },
1746
1749
  };
1747
1750
  },
1748
1751
  };
@@ -2196,6 +2199,21 @@ export const hooksTrajectoryStart = {
2196
2199
  startedAt,
2197
2200
  };
2198
2201
  activeTrajectories.set(trajectoryId, trajectory);
2202
+ // Persist pending trajectory to disk so it survives MCP restarts
2203
+ const storeFn = await getRealStoreFunction();
2204
+ if (storeFn) {
2205
+ try {
2206
+ await storeFn({
2207
+ key: `trajectory-pending-${trajectoryId}`,
2208
+ value: JSON.stringify(trajectory),
2209
+ namespace: 'trajectories',
2210
+ tags: [agent, 'pending', 'sona-trajectory'],
2211
+ });
2212
+ }
2213
+ catch {
2214
+ // Best-effort persistence — trajectory still lives in-memory
2215
+ }
2216
+ }
2199
2217
  return {
2200
2218
  trajectoryId,
2201
2219
  task,
@@ -2607,8 +2625,19 @@ export const hooksIntelligenceStats = {
2607
2625
  const moe = await getMoERouter();
2608
2626
  const flash = await getFlashAttention();
2609
2627
  const lora = await getLoRAAdapter();
2610
- // Fallback to memory store for legacy data
2611
- const memoryStats = getIntelligenceStatsFromMemory();
2628
+ // Fallback to memory store for legacy data (may not exist yet)
2629
+ let memoryStats;
2630
+ try {
2631
+ memoryStats = getIntelligenceStatsFromMemory();
2632
+ }
2633
+ catch {
2634
+ memoryStats = {
2635
+ trajectories: { total: 0, successful: 0 },
2636
+ patterns: { learned: 0, categories: {} },
2637
+ memory: { indexSize: 0, totalAccessCount: 0, memorySizeBytes: 0 },
2638
+ routing: { decisions: 0, avgConfidence: 0 },
2639
+ };
2640
+ }
2612
2641
  // SONA stats from real implementation
2613
2642
  let sonaStats = {
2614
2643
  trajectoriesTotal: memoryStats.trajectories.total,
@@ -3304,26 +3333,7 @@ export const hooksWorkerDispatch = {
3304
3333
  startedAt: new Date(),
3305
3334
  };
3306
3335
  activeWorkers.set(workerId, worker);
3307
- // Update worker progress in background
3308
- if (background) {
3309
- setTimeout(() => {
3310
- const w = activeWorkers.get(workerId);
3311
- if (w) {
3312
- w.progress = 50;
3313
- w.phase = 'processing';
3314
- }
3315
- }, 500);
3316
- setTimeout(() => {
3317
- const w = activeWorkers.get(workerId);
3318
- if (w) {
3319
- w.progress = 100;
3320
- w.phase = 'completed';
3321
- w.status = 'completed';
3322
- w.completedAt = new Date();
3323
- }
3324
- }, 1500);
3325
- }
3326
- else {
3336
+ if (!background) {
3327
3337
  worker.progress = 100;
3328
3338
  worker.phase = 'completed';
3329
3339
  worker.status = 'completed';
@@ -3340,9 +3350,16 @@ export const hooksWorkerDispatch = {
3340
3350
  estimatedDuration: config.estimatedDuration,
3341
3351
  capabilities: config.capabilities,
3342
3352
  },
3343
- status: background ? 'dispatched' : 'completed',
3353
+ status: background ? 'scheduled' : 'completed',
3344
3354
  background,
3355
+ note: background ? 'Worker scheduled. Use hooks_worker-status to check progress. Start the daemon (daemon start) for real background execution.' : undefined,
3345
3356
  timestamp: new Date().toISOString(),
3357
+ nativeIntegration: {
3358
+ loopSuggestion: `[LOOP_SUGGESTION] This worker would benefit from /loop for periodic execution.\nRecommended: /loop "${trigger} worker"\nInterval: 270s (stays within cache window)`,
3359
+ suggestedDelay: 270,
3360
+ loopPrompt: `Run ${trigger} worker and check results`,
3361
+ cronSuggestion: `[CRON_SUGGESTION] For persistent background execution: CronCreate("${trigger}-worker", "*/15 * * * *", "Run ${trigger} worker")`,
3362
+ },
3346
3363
  };
3347
3364
  },
3348
3365
  };
@@ -3400,6 +3417,9 @@ export const hooksWorkerStatus = {
3400
3417
  completed: workers.filter(w => w.status === 'completed').length,
3401
3418
  failed: workers.filter(w => w.status === 'failed').length,
3402
3419
  },
3420
+ nativeIntegration: {
3421
+ monitorSuggestion: '[MONITOR_AVAILABLE] For live worker updates: Monitor("npx @claude-flow/cli hooks worker list --stream")',
3422
+ },
3403
3423
  };
3404
3424
  },
3405
3425
  };
@@ -251,6 +251,9 @@ export const neuralTools = [
251
251
  totalPatterns: Object.keys(store.patterns).length,
252
252
  epochs,
253
253
  trainedAt: model.trainedAt,
254
+ ...(embeddingServiceName === 'hash-fallback' || embeddingServiceName === 'none' ? {
255
+ platformNote: 'ONNX embeddings not available — using hash-based fallback. Install @claude-flow/embeddings and run "embeddings init --download" for semantic search.',
256
+ } : {}),
254
257
  };
255
258
  },
256
259
  },
@@ -109,6 +109,10 @@ export const swarmTools = [
109
109
  initializedAt: now,
110
110
  config: swarmState.config,
111
111
  persisted: true,
112
+ nativeIntegration: {
113
+ teamSuggestion: '[TEAM_SUGGESTION] Create a Claude Code team for this swarm: TeamCreate({ team_name: "' + (input.name || 'swarm') + '", description: "Ruflo swarm coordination" })',
114
+ worktreeNote: '[WORKTREE_SUGGESTION] Spawn file-modifying agents with isolation: "worktree" to prevent conflicts',
115
+ },
112
116
  };
113
117
  },
114
118
  },
@@ -168,6 +172,9 @@ export const swarmTools = [
168
172
  createdAt: latest.createdAt,
169
173
  updatedAt: latest.updatedAt,
170
174
  totalSwarms: swarmIds.length,
175
+ nativeIntegration: {
176
+ monitorSuggestion: '[MONITOR_AVAILABLE] For live swarm updates: Monitor("npx @claude-flow/cli swarm watch --stream")',
177
+ },
171
178
  };
172
179
  },
173
180
  },
@@ -312,6 +319,9 @@ export const swarmTools = [
312
319
  agentCount: target.agents.length,
313
320
  checks,
314
321
  checkedAt: new Date().toISOString(),
322
+ nativeIntegration: {
323
+ monitorSuggestion: '[MONITOR_AVAILABLE] For continuous health monitoring: Monitor("npx @claude-flow/cli swarm watch --stream --health")',
324
+ },
315
325
  };
316
326
  },
317
327
  },
@@ -284,11 +284,13 @@ export const systemTools = [
284
284
  const metrics = loadMetrics();
285
285
  const checks = [];
286
286
  const projectCwd = getProjectCwd();
287
- // Memory DB check — verify the store file exists
287
+ // Memory DB check — verify any supported store file exists
288
288
  {
289
289
  const t0 = performance.now();
290
- const memoryDbPath = join(projectCwd, '.claude-flow', 'memory', 'store.json');
291
- const memoryExists = existsSync(memoryDbPath);
290
+ const legacyPath = join(projectCwd, '.claude-flow', 'memory', 'store.json');
291
+ const agentDbPath = join(projectCwd, '.claude-flow', 'memory', 'agentdb.sqlite');
292
+ const rvfPath = join(projectCwd, '.claude-flow', 'memory', 'store.rvf');
293
+ const memoryExists = existsSync(legacyPath) || existsSync(agentDbPath) || existsSync(rvfPath);
292
294
  const elapsed = performance.now() - t0;
293
295
  checks.push({
294
296
  name: 'memory',
@@ -90,6 +90,10 @@ export const taskTools = [
90
90
  createdAt: task.createdAt,
91
91
  assignedTo: task.assignedTo,
92
92
  tags: task.tags,
93
+ // ADR-091 Phase 1: Native Claude Code capability suggestions
94
+ nativeIntegration: {
95
+ nativeTaskNote: '[TASK_NATIVE] Claude Code has a native task system. Consider TaskCreate({ subject: "...", description: "..." }) for shared visibility across agents.',
96
+ },
93
97
  };
94
98
  },
95
99
  },
@@ -246,6 +250,10 @@ export const taskTools = [
246
250
  status: task.status,
247
251
  completedAt: task.completedAt,
248
252
  result: task.result,
253
+ // ADR-091 Phase 1: Native Claude Code capability suggestions
254
+ nativeIntegration: {
255
+ notifySuggestion: '[NOTIFY_SUGGESTION] For tasks spanning sessions, use PushNotification to alert when complete.',
256
+ },
249
257
  };
250
258
  }
251
259
  return {
@@ -9,6 +9,10 @@
9
9
  * where process.cwd() may resolve to '/') over the real process.cwd().
10
10
  */
11
11
  export function getProjectCwd() {
12
- return process.env.CLAUDE_FLOW_CWD || process.cwd();
12
+ const envCwd = process.env.CLAUDE_FLOW_CWD;
13
+ if (envCwd && envCwd !== '/' && envCwd !== process.env.HOME) {
14
+ return envCwd;
15
+ }
16
+ return process.cwd();
13
17
  }
14
18
  //# sourceMappingURL=types.js.map
@@ -78,13 +78,15 @@ async function getRegistry(dbPath) {
78
78
  dbPath: dbPath || getDbPath(),
79
79
  embeddingModel: 'Xenova/all-MiniLM-L6-v2',
80
80
  dimension: 384,
81
+ vectorBackend: 'auto',
81
82
  controllers: {
82
83
  reasoningBank: true,
83
84
  learningBridge: false,
84
85
  tieredCache: true,
85
86
  hierarchicalMemory: true,
86
87
  memoryConsolidation: true,
87
- memoryGraph: true, // issue #1214: enable MemoryGraph for graph-aware ranking
88
+ memoryGraph: true,
89
+ vectorBackend: true,
88
90
  },
89
91
  });
90
92
  }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * NDJSON Event Stream for CLI --stream mode
3
+ *
4
+ * Emits newline-delimited JSON events to stdout for consumption
5
+ * by Claude Code's Monitor tool. Each event includes schema versioning.
6
+ *
7
+ * @see ADR-091: NDJSON event streaming infrastructure
8
+ */
9
+ export interface StreamEvent {
10
+ schema: 'ruflo.event.v1';
11
+ event: string;
12
+ runId: string;
13
+ agentId?: string;
14
+ ts: string;
15
+ [key: string]: unknown;
16
+ }
17
+ /** Generate a short unique run ID (e.g. run_m1abc_3f2a1b) */
18
+ export declare function createRunId(): string;
19
+ /** Write one NDJSON line to stdout with schema and timestamp auto-populated */
20
+ export declare function emitEvent(event: Omit<StreamEvent, 'schema' | 'ts'>): void;
21
+ /** Convenience wrapper that binds a runId to an emitter */
22
+ export declare function createEventEmitter(runId: string): {
23
+ emit(event: string, data?: Record<string, unknown>): void;
24
+ };
25
+ //# sourceMappingURL=event-stream.d.ts.map
@@ -0,0 +1,27 @@
1
+ /**
2
+ * NDJSON Event Stream for CLI --stream mode
3
+ *
4
+ * Emits newline-delimited JSON events to stdout for consumption
5
+ * by Claude Code's Monitor tool. Each event includes schema versioning.
6
+ *
7
+ * @see ADR-091: NDJSON event streaming infrastructure
8
+ */
9
+ import { randomBytes } from 'crypto';
10
+ /** Generate a short unique run ID (e.g. run_m1abc_3f2a1b) */
11
+ export function createRunId() {
12
+ return `run_${Date.now().toString(36)}_${randomBytes(3).toString('hex')}`;
13
+ }
14
+ /** Write one NDJSON line to stdout with schema and timestamp auto-populated */
15
+ export function emitEvent(event) {
16
+ const full = Object.assign({ schema: 'ruflo.event.v1', ts: new Date().toISOString() }, event);
17
+ process.stdout.write(JSON.stringify(full) + '\n');
18
+ }
19
+ /** Convenience wrapper that binds a runId to an emitter */
20
+ export function createEventEmitter(runId) {
21
+ return {
22
+ emit(event, data) {
23
+ emitEvent({ runId, event, ...data });
24
+ },
25
+ };
26
+ }
27
+ //# sourceMappingURL=event-stream.js.map
@@ -6,6 +6,9 @@ export { WorkerDaemon, getDaemon, startDaemon, stopDaemon, type WorkerType, } fr
6
6
  export { HeadlessWorkerExecutor, HEADLESS_WORKER_TYPES, HEADLESS_WORKER_CONFIGS, LOCAL_WORKER_TYPES, LOCAL_WORKER_CONFIGS, ALL_WORKER_CONFIGS, isHeadlessWorker, isLocalWorker, getModelId, getWorkerConfig, type HeadlessWorkerType, type LocalWorkerType, type HeadlessWorkerConfig, type HeadlessExecutionResult, type HeadlessExecutorConfig, type HeadlessOptions, type PoolStatus, type SandboxMode, type ModelType, type OutputFormat, type ExecutionMode, type WorkerPriority, type WorkerConfig, } from './headless-worker-executor.js';
7
7
  export { ContainerWorkerPool, type ContainerInfo, type ContainerPoolConfig, type ContainerExecutionOptions, type ContainerPoolStatus, type ContainerState, } from './container-worker-pool.js';
8
8
  export { WorkerQueue, type QueueTask, type WorkerQueueConfig, type QueueStats, type WorkerRegistration, type TaskStatus, } from './worker-queue.js';
9
+ export { createRunId, emitEvent, createEventEmitter, type StreamEvent, } from './event-stream.js';
10
+ export { detectCapabilities, getRuntimeTier, getCacheWarmDelay, type RuntimeCapabilities, type RuntimeTier, } from './runtime-capabilities.js';
11
+ export { runLoopWorker, type LoopWorkerResult, } from './loop-worker-runner.js';
9
12
  export type { default as WorkerDaemonType, DaemonConfig } from './worker-daemon.js';
10
13
  export type { default as HeadlessWorkerExecutorType } from './headless-worker-executor.js';
11
14
  export type { default as ContainerWorkerPoolType } from './container-worker-pool.js';
@@ -8,4 +8,10 @@ export { HeadlessWorkerExecutor, HEADLESS_WORKER_TYPES, HEADLESS_WORKER_CONFIGS,
8
8
  export { ContainerWorkerPool, } from './container-worker-pool.js';
9
9
  // Worker Queue (Phase 4)
10
10
  export { WorkerQueue, } from './worker-queue.js';
11
+ // Event Stream (ADR-091)
12
+ export { createRunId, emitEvent, createEventEmitter, } from './event-stream.js';
13
+ // Runtime Capabilities (ADR-091)
14
+ export { detectCapabilities, getRuntimeTier, getCacheWarmDelay, } from './runtime-capabilities.js';
15
+ // Loop Worker Runner (ADR-091 Phase 2)
16
+ export { runLoopWorker, } from './loop-worker-runner.js';
11
17
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,16 @@
1
+ /**
2
+ * ADR-091 Phase 2 -- Stateless Loop Worker Runner
3
+ *
4
+ * Designed for /loop execution: runs a single worker iteration and returns
5
+ * metadata that the caller can use with ScheduleWakeup.
6
+ */
7
+ export interface LoopWorkerResult {
8
+ workerType: string;
9
+ success: boolean;
10
+ suggestedDelay: number;
11
+ reason: string;
12
+ loopPrompt: string;
13
+ metrics?: Record<string, unknown>;
14
+ }
15
+ export declare function runLoopWorker(workerType: string): Promise<LoopWorkerResult>;
16
+ //# sourceMappingURL=loop-worker-runner.d.ts.map
@@ -0,0 +1,34 @@
1
+ /**
2
+ * ADR-091 Phase 2 -- Stateless Loop Worker Runner
3
+ *
4
+ * Designed for /loop execution: runs a single worker iteration and returns
5
+ * metadata that the caller can use with ScheduleWakeup.
6
+ */
7
+ import { execSync } from 'child_process';
8
+ import { getCacheWarmDelay } from './runtime-capabilities.js';
9
+ export async function runLoopWorker(workerType) {
10
+ const startMs = Date.now();
11
+ let success = false;
12
+ let reason = '';
13
+ try {
14
+ const safeWorkerType = workerType.replace(/[^a-zA-Z0-9_-]/g, '');
15
+ const stdout = execSync(`npx @claude-flow/cli hooks worker dispatch --trigger ${safeWorkerType}`, { encoding: 'utf-8', timeout: 120_000, stdio: ['ignore', 'pipe', 'pipe'] });
16
+ success = true;
17
+ reason = stdout.trim().slice(0, 200) || `${workerType} completed`;
18
+ }
19
+ catch (err) {
20
+ const msg = err instanceof Error ? err.message : String(err);
21
+ reason = `${workerType} failed: ${msg.slice(0, 200)}`;
22
+ }
23
+ const durationMs = Date.now() - startMs;
24
+ const suggestedDelay = getCacheWarmDelay();
25
+ return {
26
+ workerType,
27
+ success,
28
+ suggestedDelay,
29
+ reason,
30
+ loopPrompt: `Run ${workerType} worker and report results`,
31
+ metrics: { durationMs, timestamp: new Date().toISOString() },
32
+ };
33
+ }
34
+ //# sourceMappingURL=loop-worker-runner.js.map
@@ -0,0 +1,22 @@
1
+ /**
2
+ * ADR-091 Phase 1 -- Runtime Capabilities Detection
3
+ *
4
+ * Detects the host environment and exposes which execution primitives are
5
+ * available so that higher-level services can choose the right path:
6
+ * 1. claude-code-native -- full Claude Code tooling (loop, monitor, cron, teams)
7
+ * 2. mcp-fallback -- MCP transport active but native tools missing
8
+ * 3. ci-daemon -- headless / CI, use detached daemon
9
+ */
10
+ export interface RuntimeCapabilities {
11
+ loop: boolean;
12
+ monitor: boolean;
13
+ cron: boolean;
14
+ teams: boolean;
15
+ worktreeIsolation: boolean;
16
+ pushNotification: boolean;
17
+ }
18
+ export type RuntimeTier = 'claude-code-native' | 'mcp-fallback' | 'ci-daemon';
19
+ export declare function detectCapabilities(): RuntimeCapabilities;
20
+ export declare function getRuntimeTier(): RuntimeTier;
21
+ export declare function getCacheWarmDelay(providerCacheTtlSeconds?: number): number;
22
+ //# sourceMappingURL=runtime-capabilities.d.ts.map
@@ -0,0 +1,45 @@
1
+ /**
2
+ * ADR-091 Phase 1 -- Runtime Capabilities Detection
3
+ *
4
+ * Detects the host environment and exposes which execution primitives are
5
+ * available so that higher-level services can choose the right path:
6
+ * 1. claude-code-native -- full Claude Code tooling (loop, monitor, cron, teams)
7
+ * 2. mcp-fallback -- MCP transport active but native tools missing
8
+ * 3. ci-daemon -- headless / CI, use detached daemon
9
+ */
10
+ function isClaudeCodeNative() {
11
+ return !!(process.env.CLAUDE_CODE ||
12
+ process.env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS);
13
+ }
14
+ function isMcpTransportActive() {
15
+ return (!process.stdin.isTTY &&
16
+ process.env.CLAUDE_FLOW_MCP_TRANSPORT === 'stdio');
17
+ }
18
+ function isCiOrHeadless() {
19
+ return !!(process.env.CI || process.env.CLAUDE_FLOW_HEADLESS);
20
+ }
21
+ export function detectCapabilities() {
22
+ const native = isClaudeCodeNative();
23
+ const teamsEnabled = !!process.env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS;
24
+ return {
25
+ loop: native,
26
+ monitor: native,
27
+ cron: native,
28
+ teams: native && teamsEnabled,
29
+ worktreeIsolation: native,
30
+ pushNotification: native,
31
+ };
32
+ }
33
+ export function getRuntimeTier() {
34
+ if (isClaudeCodeNative())
35
+ return 'claude-code-native';
36
+ if (isMcpTransportActive())
37
+ return 'mcp-fallback';
38
+ if (isCiOrHeadless())
39
+ return 'ci-daemon';
40
+ return 'mcp-fallback';
41
+ }
42
+ export function getCacheWarmDelay(providerCacheTtlSeconds) {
43
+ return Math.min(270, (providerCacheTtlSeconds ?? 300) * 0.9);
44
+ }
45
+ //# sourceMappingURL=runtime-capabilities.js.map
@@ -10,7 +10,7 @@
10
10
  * - testgaps: Test coverage analysis (20 min interval)
11
11
  */
12
12
  import { EventEmitter } from 'events';
13
- import { existsSync, mkdirSync, writeFileSync, readFileSync, appendFileSync, unlinkSync } from 'fs';
13
+ import { existsSync, mkdirSync, writeFileSync, readFileSync, appendFileSync, unlinkSync, renameSync } from 'fs';
14
14
  import { cpus } from 'os';
15
15
  import { join } from 'path';
16
16
  import { HeadlessWorkerExecutor, isHeadlessWorker, } from './headless-worker-executor.js';
@@ -903,7 +903,9 @@ export class WorkerDaemon extends EventEmitter {
903
903
  savedAt: new Date().toISOString(),
904
904
  };
905
905
  try {
906
- writeFileSync(this.config.stateFile, JSON.stringify(state, null, 2));
906
+ const tmpFile = this.config.stateFile + '.tmp';
907
+ writeFileSync(tmpFile, JSON.stringify(state, null, 2));
908
+ renameSync(tmpFile, this.config.stateFile);
907
909
  }
908
910
  catch (error) {
909
911
  this.log('error', `Failed to save state: ${error}`);
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@claude-flow/cli",
3
- "version": "3.5.81",
3
+ "version": "3.5.83",
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",