claude-flow 3.5.2 → 3.5.4

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 (70) hide show
  1. package/.claude/helpers/auto-memory-hook.mjs +20 -7
  2. package/.claude/helpers/hook-handler.cjs +40 -11
  3. package/.claude/helpers/statusline.cjs +3 -3
  4. package/.claude/settings.json +1 -1
  5. package/README.md +156 -26
  6. package/package.json +1 -2
  7. package/v3/@claude-flow/cli/README.md +156 -26
  8. package/v3/@claude-flow/cli/dist/src/appliance/gguf-engine.d.ts +91 -0
  9. package/v3/@claude-flow/cli/dist/src/appliance/gguf-engine.js +425 -0
  10. package/v3/@claude-flow/cli/dist/src/appliance/ruvllm-bridge.d.ts +102 -0
  11. package/v3/@claude-flow/cli/dist/src/appliance/ruvllm-bridge.js +292 -0
  12. package/v3/@claude-flow/cli/dist/src/appliance/rvfa-builder.d.ts +44 -0
  13. package/v3/@claude-flow/cli/dist/src/appliance/rvfa-builder.js +329 -0
  14. package/v3/@claude-flow/cli/dist/src/appliance/rvfa-distribution.d.ts +97 -0
  15. package/v3/@claude-flow/cli/dist/src/appliance/rvfa-distribution.js +370 -0
  16. package/v3/@claude-flow/cli/dist/src/appliance/rvfa-format.d.ts +111 -0
  17. package/v3/@claude-flow/cli/dist/src/appliance/rvfa-format.js +393 -0
  18. package/v3/@claude-flow/cli/dist/src/appliance/rvfa-runner.d.ts +69 -0
  19. package/v3/@claude-flow/cli/dist/src/appliance/rvfa-runner.js +237 -0
  20. package/v3/@claude-flow/cli/dist/src/appliance/rvfa-signing.d.ts +123 -0
  21. package/v3/@claude-flow/cli/dist/src/appliance/rvfa-signing.js +347 -0
  22. package/v3/@claude-flow/cli/dist/src/commands/appliance-advanced.d.ts +9 -0
  23. package/v3/@claude-flow/cli/dist/src/commands/appliance-advanced.js +215 -0
  24. package/v3/@claude-flow/cli/dist/src/commands/appliance.d.ts +8 -0
  25. package/v3/@claude-flow/cli/dist/src/commands/appliance.js +406 -0
  26. package/v3/@claude-flow/cli/dist/src/commands/benchmark.js +2 -2
  27. package/v3/@claude-flow/cli/dist/src/commands/claims.js +1 -1
  28. package/v3/@claude-flow/cli/dist/src/commands/config.js +1 -1
  29. package/v3/@claude-flow/cli/dist/src/commands/deployment.js +1 -1
  30. package/v3/@claude-flow/cli/dist/src/commands/doctor.js +7 -2
  31. package/v3/@claude-flow/cli/dist/src/commands/embeddings.js +1 -1
  32. package/v3/@claude-flow/cli/dist/src/commands/hooks.js +1 -1
  33. package/v3/@claude-flow/cli/dist/src/commands/index.d.ts +2 -0
  34. package/v3/@claude-flow/cli/dist/src/commands/index.js +6 -0
  35. package/v3/@claude-flow/cli/dist/src/commands/init.js +11 -11
  36. package/v3/@claude-flow/cli/dist/src/commands/mcp.js +18 -3
  37. package/v3/@claude-flow/cli/dist/src/commands/memory.js +24 -0
  38. package/v3/@claude-flow/cli/dist/src/commands/neural.js +1 -1
  39. package/v3/@claude-flow/cli/dist/src/commands/performance.js +1 -1
  40. package/v3/@claude-flow/cli/dist/src/commands/plugins.js +1 -1
  41. package/v3/@claude-flow/cli/dist/src/commands/providers.js +1 -1
  42. package/v3/@claude-flow/cli/dist/src/commands/security.js +1 -1
  43. package/v3/@claude-flow/cli/dist/src/commands/start.js +11 -11
  44. package/v3/@claude-flow/cli/dist/src/commands/status.js +12 -5
  45. package/v3/@claude-flow/cli/dist/src/commands/transfer-store.js +1 -1
  46. package/v3/@claude-flow/cli/dist/src/index.js +2 -2
  47. package/v3/@claude-flow/cli/dist/src/init/claudemd-generator.js +1 -1
  48. package/v3/@claude-flow/cli/dist/src/init/executor.js +9 -8
  49. package/v3/@claude-flow/cli/dist/src/init/helpers-generator.js +28 -5
  50. package/v3/@claude-flow/cli/dist/src/init/settings-generator.js +66 -16
  51. package/v3/@claude-flow/cli/dist/src/init/statusline-generator.d.ts +1 -1
  52. package/v3/@claude-flow/cli/dist/src/init/statusline-generator.js +4 -4
  53. package/v3/@claude-flow/cli/dist/src/mcp-server.js +16 -0
  54. package/v3/@claude-flow/cli/dist/src/mcp-tools/coordination-tools.js +1 -1
  55. package/v3/@claude-flow/cli/dist/src/mcp-tools/daa-tools.js +5 -5
  56. package/v3/@claude-flow/cli/dist/src/mcp-tools/github-tools.js +2 -2
  57. package/v3/@claude-flow/cli/dist/src/mcp-tools/hooks-tools.js +21 -1
  58. package/v3/@claude-flow/cli/dist/src/mcp-tools/performance-tools.js +1 -1
  59. package/v3/@claude-flow/cli/dist/src/mcp-tools/system-tools.js +109 -6
  60. package/v3/@claude-flow/cli/dist/src/mcp-tools/task-tools.js +36 -0
  61. package/v3/@claude-flow/cli/dist/src/mcp-tools/workflow-tools.js +91 -0
  62. package/v3/@claude-flow/cli/dist/src/memory/memory-bridge.js +1 -0
  63. package/v3/@claude-flow/cli/dist/src/memory/memory-initializer.d.ts +6 -0
  64. package/v3/@claude-flow/cli/dist/src/memory/memory-initializer.js +54 -2
  65. package/v3/@claude-flow/cli/dist/src/output.js +1 -0
  66. package/v3/@claude-flow/cli/dist/src/runtime/headless.js +3 -3
  67. package/v3/@claude-flow/cli/dist/src/services/claim-service.js +1 -1
  68. package/v3/@claude-flow/cli/dist/src/services/container-worker-pool.js +2 -0
  69. package/v3/@claude-flow/cli/dist/src/services/worker-queue.js +2 -0
  70. package/v3/@claude-flow/cli/package.json +1 -1
@@ -56,7 +56,7 @@ export const daaTools = [
56
56
  cognitivePattern: { type: 'string', enum: ['convergent', 'divergent', 'lateral', 'systems', 'critical', 'adaptive'], description: 'Cognitive pattern' },
57
57
  learningRate: { type: 'number', description: 'Learning rate (0-1)' },
58
58
  enableMemory: { type: 'boolean', description: 'Enable persistent memory' },
59
- capabilities: { type: 'array', description: 'Agent capabilities' },
59
+ capabilities: { type: 'array', items: { type: 'string' }, description: 'Agent capabilities' },
60
60
  },
61
61
  required: ['id'],
62
62
  },
@@ -106,7 +106,7 @@ export const daaTools = [
106
106
  agentId: { type: 'string', description: 'Agent ID' },
107
107
  feedback: { type: 'string', description: 'Feedback message' },
108
108
  performanceScore: { type: 'number', description: 'Performance score (0-1)' },
109
- suggestions: { type: 'array', description: 'Improvement suggestions' },
109
+ suggestions: { type: 'array', items: { type: 'string' }, description: 'Improvement suggestions' },
110
110
  },
111
111
  required: ['agentId'],
112
112
  },
@@ -149,7 +149,7 @@ export const daaTools = [
149
149
  properties: {
150
150
  id: { type: 'string', description: 'Workflow ID' },
151
151
  name: { type: 'string', description: 'Workflow name' },
152
- steps: { type: 'array', description: 'Workflow steps' },
152
+ steps: { type: 'array', items: { type: 'object' }, description: 'Workflow steps' },
153
153
  strategy: { type: 'string', enum: ['parallel', 'sequential', 'adaptive'], description: 'Execution strategy' },
154
154
  dependencies: { type: 'object', description: 'Step dependencies' },
155
155
  },
@@ -189,7 +189,7 @@ export const daaTools = [
189
189
  type: 'object',
190
190
  properties: {
191
191
  workflowId: { type: 'string', description: 'Workflow ID' },
192
- agentIds: { type: 'array', description: 'Agent IDs to use' },
192
+ agentIds: { type: 'array', items: { type: 'string' }, description: 'Agent IDs to use' },
193
193
  parallelExecution: { type: 'boolean', description: 'Enable parallel execution' },
194
194
  },
195
195
  required: ['workflowId'],
@@ -229,7 +229,7 @@ export const daaTools = [
229
229
  type: 'object',
230
230
  properties: {
231
231
  sourceAgentId: { type: 'string', description: 'Source agent ID' },
232
- targetAgentIds: { type: 'array', description: 'Target agent IDs' },
232
+ targetAgentIds: { type: 'array', items: { type: 'string' }, description: 'Target agent IDs' },
233
233
  knowledgeDomain: { type: 'string', description: 'Knowledge domain' },
234
234
  knowledgeContent: { type: 'object', description: 'Knowledge to share' },
235
235
  },
@@ -200,8 +200,8 @@ export const githubTools = [
200
200
  issueNumber: { type: 'number', description: 'Issue number' },
201
201
  title: { type: 'string', description: 'Issue title' },
202
202
  body: { type: 'string', description: 'Issue body' },
203
- labels: { type: 'array', description: 'Issue labels' },
204
- assignees: { type: 'array', description: 'Assignees' },
203
+ labels: { type: 'array', items: { type: 'string' }, description: 'Issue labels' },
204
+ assignees: { type: 'array', items: { type: 'string' }, description: 'Assignees' },
205
205
  },
206
206
  },
207
207
  handler: async (input) => {
@@ -512,12 +512,32 @@ export const hooksPostEdit = {
512
512
  handler: async (params) => {
513
513
  const filePath = params.filePath;
514
514
  const success = params.success !== false;
515
+ const agent = params.agent;
516
+ // Wire recordFeedback through bridge (issue #1209)
517
+ let feedbackResult = null;
518
+ try {
519
+ const bridge = await import('../memory/memory-bridge.js');
520
+ feedbackResult = await bridge.bridgeRecordFeedback({
521
+ taskId: `edit-${filePath}-${Date.now()}`,
522
+ success,
523
+ quality: success ? 0.85 : 0.3,
524
+ agent,
525
+ });
526
+ }
527
+ catch {
528
+ // Bridge not available — continue with basic response
529
+ }
515
530
  return {
516
531
  recorded: true,
517
532
  filePath,
518
533
  success,
519
534
  timestamp: new Date().toISOString(),
520
535
  learningUpdate: success ? 'pattern_reinforced' : 'pattern_adjusted',
536
+ feedback: feedbackResult ? {
537
+ recorded: feedbackResult.success,
538
+ controller: feedbackResult.controller,
539
+ updates: feedbackResult.updated,
540
+ } : { recorded: false, controller: 'unavailable', updates: 0 },
521
541
  };
522
542
  },
523
543
  };
@@ -2124,7 +2144,7 @@ export const hooksIntelligenceLearn = {
2124
2144
  inputSchema: {
2125
2145
  type: 'object',
2126
2146
  properties: {
2127
- trajectoryIds: { type: 'array', description: 'Specific trajectories to learn from' },
2147
+ trajectoryIds: { type: 'array', items: { type: 'string' }, description: 'Specific trajectories to learn from' },
2128
2148
  consolidate: { type: 'boolean', description: 'Run EWC++ consolidation' },
2129
2149
  },
2130
2150
  },
@@ -57,7 +57,7 @@ export const performanceTools = [
57
57
  properties: {
58
58
  timeRange: { type: 'string', description: 'Time range (1h, 24h, 7d)' },
59
59
  format: { type: 'string', enum: ['json', 'summary', 'detailed'], description: 'Report format' },
60
- components: { type: 'array', description: 'Components to include' },
60
+ components: { type: 'array', items: { type: 'string' }, description: 'Components to include' },
61
61
  },
62
62
  },
63
63
  handler: async (input) => {
@@ -9,8 +9,23 @@
9
9
  * - os module for system information
10
10
  */
11
11
  import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
12
- import { join } from 'node:path';
12
+ import { join, dirname } from 'node:path';
13
+ import { fileURLToPath } from 'node:url';
13
14
  import * as os from 'node:os';
15
+ // Read version dynamically from package.json
16
+ function getPackageVersion() {
17
+ try {
18
+ const __filename = fileURLToPath(import.meta.url);
19
+ const __dirname = dirname(__filename);
20
+ const pkgPath = join(__dirname, '..', '..', 'package.json');
21
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
22
+ return pkg.version || '3.0.0';
23
+ }
24
+ catch {
25
+ return '3.0.0';
26
+ }
27
+ }
28
+ const PKG_VERSION = getPackageVersion();
14
29
  // Storage paths
15
30
  const STORAGE_DIR = '.claude-flow';
16
31
  const SYSTEM_DIR = 'system';
@@ -63,7 +78,7 @@ export const systemTools = [
63
78
  type: 'object',
64
79
  properties: {
65
80
  verbose: { type: 'boolean', description: 'Include detailed information' },
66
- components: { type: 'array', description: 'Specific components to check' },
81
+ components: { type: 'array', items: { type: 'string' }, description: 'Specific components to check' },
67
82
  },
68
83
  },
69
84
  handler: async (input) => {
@@ -73,7 +88,7 @@ export const systemTools = [
73
88
  status: metrics.health >= 0.8 ? 'healthy' : metrics.health >= 0.5 ? 'degraded' : 'unhealthy',
74
89
  uptime,
75
90
  uptimeFormatted: `${Math.floor(uptime / 3600000)}h ${Math.floor((uptime % 3600000) / 60000)}m`,
76
- version: '3.0.0-alpha',
91
+ version: PKG_VERSION,
77
92
  components: {
78
93
  swarm: { status: 'running', health: metrics.health },
79
94
  memory: { status: 'running', health: 0.95 },
@@ -171,7 +186,7 @@ export const systemTools = [
171
186
  type: 'object',
172
187
  properties: {
173
188
  deep: { type: 'boolean', description: 'Perform deep health check' },
174
- components: { type: 'array', description: 'Components to check' },
189
+ components: { type: 'array', items: { type: 'string' }, description: 'Components to check' },
175
190
  fix: { type: 'boolean', description: 'Attempt to fix issues' },
176
191
  },
177
192
  },
@@ -244,12 +259,12 @@ export const systemTools = [
244
259
  inputSchema: {
245
260
  type: 'object',
246
261
  properties: {
247
- include: { type: 'array', description: 'Information to include' },
262
+ include: { type: 'array', items: { type: 'string' }, description: 'Information to include' },
248
263
  },
249
264
  },
250
265
  handler: async () => {
251
266
  return {
252
- version: '3.0.0-alpha',
267
+ version: PKG_VERSION,
253
268
  nodeVersion: process.version,
254
269
  platform: process.platform,
255
270
  arch: process.arch,
@@ -310,5 +325,93 @@ export const systemTools = [
310
325
  };
311
326
  },
312
327
  },
328
+ {
329
+ name: 'mcp_status',
330
+ description: 'Get MCP server status, including stdio mode detection',
331
+ category: 'system',
332
+ inputSchema: {
333
+ type: 'object',
334
+ properties: {},
335
+ },
336
+ handler: async () => {
337
+ // Detect if we are running inside an MCP stdio session.
338
+ // When Claude Code launches us via `claude mcp add`, stdin is piped (not a TTY)
339
+ // and the process IS the MCP server, so it is running.
340
+ const isStdio = !process.stdin.isTTY;
341
+ const transport = process.env.CLAUDE_FLOW_MCP_TRANSPORT || (isStdio ? 'stdio' : 'http');
342
+ const port = parseInt(process.env.CLAUDE_FLOW_MCP_PORT || '3000', 10);
343
+ if (transport === 'stdio' || isStdio) {
344
+ // In stdio mode the MCP server is this process itself
345
+ return {
346
+ running: true,
347
+ pid: process.pid,
348
+ transport: 'stdio',
349
+ port: null,
350
+ host: null,
351
+ };
352
+ }
353
+ // For HTTP/WebSocket, try to check if the server is listening
354
+ const host = process.env.CLAUDE_FLOW_MCP_HOST || 'localhost';
355
+ try {
356
+ const { createConnection } = await import('node:net');
357
+ const connected = await new Promise((resolve) => {
358
+ const socket = createConnection({ host, port }, () => {
359
+ socket.destroy();
360
+ resolve(true);
361
+ });
362
+ socket.on('error', () => resolve(false));
363
+ socket.setTimeout(2000, () => {
364
+ socket.destroy();
365
+ resolve(false);
366
+ });
367
+ });
368
+ return {
369
+ running: connected,
370
+ transport,
371
+ port,
372
+ host,
373
+ };
374
+ }
375
+ catch {
376
+ return {
377
+ running: false,
378
+ transport,
379
+ port,
380
+ host,
381
+ };
382
+ }
383
+ },
384
+ },
385
+ {
386
+ name: 'task_summary',
387
+ description: 'Get a summary of all tasks by status',
388
+ category: 'task',
389
+ inputSchema: {
390
+ type: 'object',
391
+ properties: {},
392
+ },
393
+ handler: async () => {
394
+ // Read from the task store file
395
+ const storePath = join(process.cwd(), '.claude-flow', 'tasks', 'store.json');
396
+ let tasks = [];
397
+ try {
398
+ if (existsSync(storePath)) {
399
+ const data = readFileSync(storePath, 'utf-8');
400
+ const store = JSON.parse(data);
401
+ tasks = Object.values(store.tasks || {});
402
+ }
403
+ }
404
+ catch {
405
+ // empty store
406
+ }
407
+ return {
408
+ total: tasks.length,
409
+ pending: tasks.filter(t => t.status === 'pending').length,
410
+ running: tasks.filter(t => t.status === 'in_progress').length,
411
+ completed: tasks.filter(t => t.status === 'completed').length,
412
+ failed: tasks.filter(t => t.status === 'failed').length,
413
+ };
414
+ },
415
+ },
313
416
  ];
314
417
  //# sourceMappingURL=system-tools.js.map
@@ -263,6 +263,42 @@ export const taskTools = [
263
263
  };
264
264
  },
265
265
  },
266
+ {
267
+ name: 'task_assign',
268
+ description: 'Assign a task to one or more agents',
269
+ category: 'task',
270
+ inputSchema: {
271
+ type: 'object',
272
+ properties: {
273
+ taskId: { type: 'string', description: 'Task ID to assign' },
274
+ agentIds: { type: 'array', items: { type: 'string' }, description: 'Agent IDs to assign' },
275
+ unassign: { type: 'boolean', description: 'Unassign all agents from task' },
276
+ },
277
+ required: ['taskId'],
278
+ },
279
+ handler: async (input) => {
280
+ const store = loadTaskStore();
281
+ const taskId = input.taskId;
282
+ const task = store.tasks[taskId];
283
+ if (!task) {
284
+ return { taskId, error: 'Task not found' };
285
+ }
286
+ const previouslyAssigned = [...task.assignedTo];
287
+ if (input.unassign) {
288
+ task.assignedTo = [];
289
+ }
290
+ else {
291
+ const agentIds = input.agentIds || [];
292
+ task.assignedTo = agentIds;
293
+ }
294
+ saveTaskStore(store);
295
+ return {
296
+ taskId: task.taskId,
297
+ assignedTo: task.assignedTo,
298
+ previouslyAssigned,
299
+ };
300
+ },
301
+ },
266
302
  {
267
303
  name: 'task_cancel',
268
304
  description: 'Cancel a task',
@@ -39,6 +39,97 @@ function saveWorkflowStore(store) {
39
39
  writeFileSync(getWorkflowPath(), JSON.stringify(store, null, 2), 'utf-8');
40
40
  }
41
41
  export const workflowTools = [
42
+ {
43
+ name: 'workflow_run',
44
+ description: 'Run a workflow from a template or file',
45
+ category: 'workflow',
46
+ inputSchema: {
47
+ type: 'object',
48
+ properties: {
49
+ template: { type: 'string', description: 'Template name to run' },
50
+ file: { type: 'string', description: 'Workflow file path' },
51
+ task: { type: 'string', description: 'Task description' },
52
+ options: {
53
+ type: 'object',
54
+ description: 'Workflow options',
55
+ properties: {
56
+ parallel: { type: 'boolean', description: 'Run stages in parallel' },
57
+ maxAgents: { type: 'number', description: 'Maximum agents to use' },
58
+ timeout: { type: 'number', description: 'Timeout in seconds' },
59
+ dryRun: { type: 'boolean', description: 'Validate without executing' },
60
+ },
61
+ },
62
+ },
63
+ },
64
+ handler: async (input) => {
65
+ const store = loadWorkflowStore();
66
+ const template = input.template;
67
+ const task = input.task;
68
+ const options = input.options || {};
69
+ const dryRun = options.dryRun;
70
+ // Build workflow from template or inline
71
+ const workflowId = `workflow-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
72
+ const stages = [];
73
+ // Generate stages based on template
74
+ const templateName = template || 'custom';
75
+ const stageNames = (() => {
76
+ switch (templateName) {
77
+ case 'feature':
78
+ return ['Research', 'Design', 'Implement', 'Test', 'Review'];
79
+ case 'bugfix':
80
+ return ['Investigate', 'Fix', 'Test', 'Review'];
81
+ case 'refactor':
82
+ return ['Analyze', 'Refactor', 'Test', 'Review'];
83
+ case 'security':
84
+ return ['Scan', 'Analyze', 'Report'];
85
+ default:
86
+ return ['Execute'];
87
+ }
88
+ })();
89
+ for (const name of stageNames) {
90
+ stages.push({
91
+ name,
92
+ status: dryRun ? 'validated' : 'pending',
93
+ agents: [],
94
+ });
95
+ }
96
+ if (!dryRun) {
97
+ // Create and save the workflow
98
+ const steps = stageNames.map((name, i) => ({
99
+ stepId: `step-${i + 1}`,
100
+ name,
101
+ type: 'task',
102
+ config: { task: task || name },
103
+ status: 'pending',
104
+ }));
105
+ const workflow = {
106
+ workflowId,
107
+ name: task || `${templateName} workflow`,
108
+ description: task,
109
+ steps,
110
+ status: 'running',
111
+ currentStep: 0,
112
+ variables: { template: templateName, ...options },
113
+ createdAt: new Date().toISOString(),
114
+ startedAt: new Date().toISOString(),
115
+ };
116
+ store.workflows[workflowId] = workflow;
117
+ saveWorkflowStore(store);
118
+ }
119
+ return {
120
+ workflowId,
121
+ template: templateName,
122
+ status: dryRun ? 'validated' : 'running',
123
+ stages,
124
+ metrics: {
125
+ totalStages: stages.length,
126
+ completedStages: 0,
127
+ agentsSpawned: 0,
128
+ estimatedDuration: `${stages.length * 30}s`,
129
+ },
130
+ };
131
+ },
132
+ },
42
133
  {
43
134
  name: 'workflow_create',
44
135
  description: 'Create a new workflow',
@@ -83,6 +83,7 @@ async function getRegistry(dbPath) {
83
83
  tieredCache: true,
84
84
  hierarchicalMemory: true,
85
85
  memoryConsolidation: true,
86
+ memoryGraph: true, // issue #1214: enable MemoryGraph for graph-aware ranking
86
87
  },
87
88
  });
88
89
  }
@@ -150,6 +150,12 @@ export interface MemoryInitResult {
150
150
  hnswIndexing: boolean;
151
151
  migrationTracking: boolean;
152
152
  };
153
+ /** ADR-053: Controllers activated via ControllerRegistry */
154
+ controllers?: {
155
+ activated: string[];
156
+ failed: string[];
157
+ initTimeMs: number;
158
+ };
153
159
  error?: string;
154
160
  }
155
161
  /**
@@ -914,6 +914,51 @@ export async function checkAndMigrateLegacy(options) {
914
914
  }
915
915
  return { needsMigration: false };
916
916
  }
917
+ /**
918
+ * ADR-053: Activate ControllerRegistry so AgentDB v3 controllers
919
+ * (ReasoningBank, SkillLibrary, ExplainableRecall, etc.) are instantiated.
920
+ *
921
+ * Uses the memory-bridge's getControllerRegistry() which lazily creates
922
+ * a singleton ControllerRegistry and initializes it with the given dbPath.
923
+ * After this call, all enabled controllers are ready for immediate use.
924
+ *
925
+ * Failures are isolated: if @claude-flow/memory or agentdb is not installed,
926
+ * this returns an empty result without throwing.
927
+ */
928
+ async function activateControllerRegistry(dbPath, verbose) {
929
+ const startTime = performance.now();
930
+ const activated = [];
931
+ const failed = [];
932
+ try {
933
+ const bridge = await getBridge();
934
+ if (!bridge) {
935
+ return { activated, failed, initTimeMs: performance.now() - startTime };
936
+ }
937
+ const registry = await bridge.getControllerRegistry(dbPath);
938
+ if (!registry) {
939
+ return { activated, failed, initTimeMs: performance.now() - startTime };
940
+ }
941
+ // Collect controller status from the registry
942
+ if (typeof registry.listControllers === 'function') {
943
+ const controllers = registry.listControllers();
944
+ for (const ctrl of controllers) {
945
+ if (ctrl.enabled) {
946
+ activated.push(ctrl.name);
947
+ }
948
+ else {
949
+ failed.push(ctrl.name);
950
+ }
951
+ }
952
+ }
953
+ if (verbose && activated.length > 0) {
954
+ console.log(`ControllerRegistry: ${activated.length} controllers activated`);
955
+ }
956
+ }
957
+ catch {
958
+ // ControllerRegistry activation is best-effort
959
+ }
960
+ return { activated, failed, initTimeMs: performance.now() - startTime };
961
+ }
917
962
  /**
918
963
  * Initialize the memory database properly using sql.js
919
964
  */
@@ -987,6 +1032,9 @@ export async function initializeMemoryDatabase(options) {
987
1032
  // Also create schema file for reference
988
1033
  const schemaPath = path.join(dbDir, 'schema.sql');
989
1034
  fs.writeFileSync(schemaPath, MEMORY_SCHEMA_V3 + '\n' + getInitialMetadata(backend));
1035
+ // ADR-053: Activate ControllerRegistry so controllers (ReasoningBank,
1036
+ // SkillLibrary, ExplainableRecall, etc.) are instantiated during init
1037
+ const controllerResult = await activateControllerRegistry(dbPath, verbose);
990
1038
  return {
991
1039
  success: true,
992
1040
  backend,
@@ -1024,7 +1072,8 @@ export async function initializeMemoryDatabase(options) {
1024
1072
  temporalDecay: true,
1025
1073
  hnswIndexing: true,
1026
1074
  migrationTracking: true
1027
- }
1075
+ },
1076
+ controllers: controllerResult,
1028
1077
  };
1029
1078
  }
1030
1079
  else {
@@ -1044,6 +1093,8 @@ export async function initializeMemoryDatabase(options) {
1044
1093
  sqliteHeader[26] = 0x20; // min embedded payload
1045
1094
  sqliteHeader[27] = 0x20; // leaf payload
1046
1095
  fs.writeFileSync(dbPath, sqliteHeader);
1096
+ // ADR-053: Activate ControllerRegistry even on fallback path
1097
+ const controllerResult = await activateControllerRegistry(dbPath, verbose);
1047
1098
  return {
1048
1099
  success: true,
1049
1100
  backend,
@@ -1067,7 +1118,8 @@ export async function initializeMemoryDatabase(options) {
1067
1118
  temporalDecay: true,
1068
1119
  hnswIndexing: true,
1069
1120
  migrationTracking: true
1070
- }
1121
+ },
1122
+ controllers: controllerResult,
1071
1123
  };
1072
1124
  }
1073
1125
  }
@@ -481,6 +481,7 @@ export class Spinner {
481
481
  this.render();
482
482
  this.frameIndex = (this.frameIndex + 1) % this.frames.length;
483
483
  }, 100);
484
+ this.interval.unref();
484
485
  this.render();
485
486
  }
486
487
  stop(message) {
@@ -63,7 +63,7 @@ function parseArgs() {
63
63
  */
64
64
  function showHelp() {
65
65
  console.log(`
66
- Headless Runtime for Claude Flow V3
66
+ Headless Runtime for RuFlo V3
67
67
 
68
68
  Usage:
69
69
  headless --worker <type> Run a specific worker
@@ -150,7 +150,7 @@ async function runDaemon() {
150
150
  * Run benchmarks
151
151
  */
152
152
  async function runBenchmarks() {
153
- console.log('=== Claude Flow V3 Performance Benchmarks ===\n');
153
+ console.log('=== RuFlo V3 Performance Benchmarks ===\n');
154
154
  // Initialize intelligence
155
155
  await initializeIntelligence();
156
156
  // SONA Benchmark
@@ -216,7 +216,7 @@ async function runBenchmarks() {
216
216
  * Show system status
217
217
  */
218
218
  async function showStatus() {
219
- console.log('=== Claude Flow V3 System Status ===\n');
219
+ console.log('=== RuFlo V3 System Status ===\n');
220
220
  // Check daemon
221
221
  const daemon = getDaemon();
222
222
  console.log('Daemon:');
@@ -675,7 +675,7 @@ export class GitHubSync {
675
675
  const claimantStr = claimant.type === 'human'
676
676
  ? `@${claimant.name.replace(/[^a-zA-Z0-9_-]/g, '')}`
677
677
  : `Agent: ${(claimant.agentType || 'unknown').replace(/[^a-zA-Z0-9_-]/g, '')}`;
678
- const comment = `🤖 **Issue claimed** by ${claimantStr}\n\n_Coordinated by Claude Flow V3_`;
678
+ const comment = `🤖 **Issue claimed** by ${claimantStr}\n\n_Coordinated by RuFlo V3_`;
679
679
  try {
680
680
  execFileSync('gh', [
681
681
  'issue', 'comment', String(issueNumber),
@@ -481,6 +481,7 @@ export class ContainerWorkerPool extends EventEmitter {
481
481
  this.healthCheckTimer = setInterval(async () => {
482
482
  await this.runHealthChecks();
483
483
  }, this.config.healthCheckIntervalMs);
484
+ this.healthCheckTimer.unref();
484
485
  }
485
486
  /**
486
487
  * Run health checks on all containers
@@ -522,6 +523,7 @@ export class ContainerWorkerPool extends EventEmitter {
522
523
  this.idleCheckTimer = setInterval(async () => {
523
524
  await this.runIdleChecks();
524
525
  }, 60000); // Check every minute
526
+ this.idleCheckTimer.unref();
525
527
  }
526
528
  /**
527
529
  * Terminate idle containers above minimum
@@ -57,6 +57,7 @@ class InMemoryStore {
57
57
  if (this.cleanupTimer)
58
58
  return;
59
59
  this.cleanupTimer = setInterval(() => this.cleanupExpired(), 60000);
60
+ this.cleanupTimer.unref();
60
61
  }
61
62
  /**
62
63
  * Stop cleanup timer
@@ -495,6 +496,7 @@ export class WorkerQueue extends EventEmitter {
495
496
  this.store.setWorker(this.workerId, registration);
496
497
  }
497
498
  }, this.config.heartbeatIntervalMs);
499
+ this.heartbeatTimer.unref();
498
500
  }
499
501
  /**
500
502
  * Stop heartbeat timer
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@claude-flow/cli",
3
- "version": "3.5.2",
3
+ "version": "3.5.4",
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",