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.
- package/.claude/helpers/auto-memory-hook.mjs +20 -7
- package/.claude/helpers/hook-handler.cjs +40 -11
- package/.claude/helpers/statusline.cjs +3 -3
- package/.claude/settings.json +1 -1
- package/README.md +156 -26
- package/package.json +1 -2
- package/v3/@claude-flow/cli/README.md +156 -26
- package/v3/@claude-flow/cli/dist/src/appliance/gguf-engine.d.ts +91 -0
- package/v3/@claude-flow/cli/dist/src/appliance/gguf-engine.js +425 -0
- package/v3/@claude-flow/cli/dist/src/appliance/ruvllm-bridge.d.ts +102 -0
- package/v3/@claude-flow/cli/dist/src/appliance/ruvllm-bridge.js +292 -0
- package/v3/@claude-flow/cli/dist/src/appliance/rvfa-builder.d.ts +44 -0
- package/v3/@claude-flow/cli/dist/src/appliance/rvfa-builder.js +329 -0
- package/v3/@claude-flow/cli/dist/src/appliance/rvfa-distribution.d.ts +97 -0
- package/v3/@claude-flow/cli/dist/src/appliance/rvfa-distribution.js +370 -0
- package/v3/@claude-flow/cli/dist/src/appliance/rvfa-format.d.ts +111 -0
- package/v3/@claude-flow/cli/dist/src/appliance/rvfa-format.js +393 -0
- package/v3/@claude-flow/cli/dist/src/appliance/rvfa-runner.d.ts +69 -0
- package/v3/@claude-flow/cli/dist/src/appliance/rvfa-runner.js +237 -0
- package/v3/@claude-flow/cli/dist/src/appliance/rvfa-signing.d.ts +123 -0
- package/v3/@claude-flow/cli/dist/src/appliance/rvfa-signing.js +347 -0
- package/v3/@claude-flow/cli/dist/src/commands/appliance-advanced.d.ts +9 -0
- package/v3/@claude-flow/cli/dist/src/commands/appliance-advanced.js +215 -0
- package/v3/@claude-flow/cli/dist/src/commands/appliance.d.ts +8 -0
- package/v3/@claude-flow/cli/dist/src/commands/appliance.js +406 -0
- package/v3/@claude-flow/cli/dist/src/commands/benchmark.js +2 -2
- package/v3/@claude-flow/cli/dist/src/commands/claims.js +1 -1
- package/v3/@claude-flow/cli/dist/src/commands/config.js +1 -1
- package/v3/@claude-flow/cli/dist/src/commands/deployment.js +1 -1
- package/v3/@claude-flow/cli/dist/src/commands/doctor.js +7 -2
- package/v3/@claude-flow/cli/dist/src/commands/embeddings.js +1 -1
- package/v3/@claude-flow/cli/dist/src/commands/hooks.js +1 -1
- package/v3/@claude-flow/cli/dist/src/commands/index.d.ts +2 -0
- package/v3/@claude-flow/cli/dist/src/commands/index.js +6 -0
- package/v3/@claude-flow/cli/dist/src/commands/init.js +11 -11
- package/v3/@claude-flow/cli/dist/src/commands/mcp.js +18 -3
- package/v3/@claude-flow/cli/dist/src/commands/memory.js +24 -0
- package/v3/@claude-flow/cli/dist/src/commands/neural.js +1 -1
- package/v3/@claude-flow/cli/dist/src/commands/performance.js +1 -1
- package/v3/@claude-flow/cli/dist/src/commands/plugins.js +1 -1
- package/v3/@claude-flow/cli/dist/src/commands/providers.js +1 -1
- package/v3/@claude-flow/cli/dist/src/commands/security.js +1 -1
- package/v3/@claude-flow/cli/dist/src/commands/start.js +11 -11
- package/v3/@claude-flow/cli/dist/src/commands/status.js +12 -5
- package/v3/@claude-flow/cli/dist/src/commands/transfer-store.js +1 -1
- package/v3/@claude-flow/cli/dist/src/index.js +2 -2
- package/v3/@claude-flow/cli/dist/src/init/claudemd-generator.js +1 -1
- package/v3/@claude-flow/cli/dist/src/init/executor.js +9 -8
- package/v3/@claude-flow/cli/dist/src/init/helpers-generator.js +28 -5
- package/v3/@claude-flow/cli/dist/src/init/settings-generator.js +66 -16
- package/v3/@claude-flow/cli/dist/src/init/statusline-generator.d.ts +1 -1
- package/v3/@claude-flow/cli/dist/src/init/statusline-generator.js +4 -4
- package/v3/@claude-flow/cli/dist/src/mcp-server.js +16 -0
- package/v3/@claude-flow/cli/dist/src/mcp-tools/coordination-tools.js +1 -1
- package/v3/@claude-flow/cli/dist/src/mcp-tools/daa-tools.js +5 -5
- package/v3/@claude-flow/cli/dist/src/mcp-tools/github-tools.js +2 -2
- package/v3/@claude-flow/cli/dist/src/mcp-tools/hooks-tools.js +21 -1
- package/v3/@claude-flow/cli/dist/src/mcp-tools/performance-tools.js +1 -1
- package/v3/@claude-flow/cli/dist/src/mcp-tools/system-tools.js +109 -6
- package/v3/@claude-flow/cli/dist/src/mcp-tools/task-tools.js +36 -0
- package/v3/@claude-flow/cli/dist/src/mcp-tools/workflow-tools.js +91 -0
- package/v3/@claude-flow/cli/dist/src/memory/memory-bridge.js +1 -0
- package/v3/@claude-flow/cli/dist/src/memory/memory-initializer.d.ts +6 -0
- package/v3/@claude-flow/cli/dist/src/memory/memory-initializer.js +54 -2
- package/v3/@claude-flow/cli/dist/src/output.js +1 -0
- package/v3/@claude-flow/cli/dist/src/runtime/headless.js +3 -3
- package/v3/@claude-flow/cli/dist/src/services/claim-service.js +1 -1
- package/v3/@claude-flow/cli/dist/src/services/container-worker-pool.js +2 -0
- package/v3/@claude-flow/cli/dist/src/services/worker-queue.js +2 -0
- 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:
|
|
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:
|
|
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',
|
|
@@ -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
|
}
|
|
@@ -63,7 +63,7 @@ function parseArgs() {
|
|
|
63
63
|
*/
|
|
64
64
|
function showHelp() {
|
|
65
65
|
console.log(`
|
|
66
|
-
Headless Runtime for
|
|
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('===
|
|
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('===
|
|
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
|
|
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.
|
|
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",
|