claude-flow 3.5.82 → 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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-flow",
3
- "version": "3.5.82",
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');
@@ -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 {
@@ -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
  };
@@ -3351,6 +3354,12 @@ export const hooksWorkerDispatch = {
3351
3354
  background,
3352
3355
  note: background ? 'Worker scheduled. Use hooks_worker-status to check progress. Start the daemon (daemon start) for real background execution.' : undefined,
3353
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
+ },
3354
3363
  };
3355
3364
  },
3356
3365
  };
@@ -3408,6 +3417,9 @@ export const hooksWorkerStatus = {
3408
3417
  completed: workers.filter(w => w.status === 'completed').length,
3409
3418
  failed: workers.filter(w => w.status === 'failed').length,
3410
3419
  },
3420
+ nativeIntegration: {
3421
+ monitorSuggestion: '[MONITOR_AVAILABLE] For live worker updates: Monitor("npx @claude-flow/cli hooks worker list --stream")',
3422
+ },
3411
3423
  };
3412
3424
  },
3413
3425
  };
@@ -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
  },
@@ -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 {
@@ -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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@claude-flow/cli",
3
- "version": "3.5.82",
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",