@claude-flow/cli 3.42.5 → 3.44.0
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/helpers.manifest.json +4 -3
- package/.claude/helpers/router.js +1 -1
- package/catalog-manifest.json +2 -2
- package/dist/src/commands/doctor.js +22 -1
- package/dist/src/commands/hooks.js +9 -3
- package/dist/src/init/executor.js +2 -1
- package/dist/src/init/helper-refresh.js +5 -0
- package/dist/src/init/helpers-generator.js +11 -10
- package/dist/src/mcp-tools/capability-brain.js +4 -2
- package/dist/src/mcp-tools/hooks-tools.d.ts +36 -0
- package/dist/src/mcp-tools/hooks-tools.js +291 -189
- package/dist/src/mcp-tools/memory-tools.js +42 -0
- package/dist/src/memory/graph-edge-writer.d.ts +10 -0
- package/dist/src/memory/graph-edge-writer.js +77 -1
- package/dist/src/memory/memory-bridge.d.ts +6 -0
- package/dist/src/memory/memory-bridge.js +76 -28
- package/dist/src/memory/memory-initializer.d.ts +3 -0
- package/dist/src/memory/memory-initializer.js +53 -11
- package/dist/src/ruvector/router-embedder.d.ts +58 -0
- package/dist/src/ruvector/router-embedder.js +141 -0
- package/dist/src/ruvector/typesafe-router.d.ts +119 -0
- package/dist/src/ruvector/typesafe-router.js +245 -0
- package/dist/src/services/policy-runtime.js +40 -11
- package/node_modules/@claude-flow/codex/dist/cli.js +0 -0
- package/node_modules/@claude-flow/plugin-agent-federation/dist/bin.js +0 -0
- package/node_modules/@claude-flow/security/dist/input-validator.d.ts +6 -6
- package/package.json +5 -1
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"manifest": {
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.44.0",
|
|
4
4
|
"files": {
|
|
5
5
|
"auto-memory-hook.mjs": "85fe05c757421c52137c0bc8545a0896bab6b4714538c2a11d1d0835bfcc8c1c",
|
|
6
6
|
"hook-handler.cjs": "209d9fafe10e17d1be0866727f6f9cf9ac66f9a0793f1c793a4f58319e8e4583",
|
|
7
7
|
"intelligence.cjs": "30e42ed7ec4ca5a94ac54fdb1330d2d47ac5f3fdeeef207753574723a9e77b5c",
|
|
8
|
-
"statusline.cjs": "4a48353b4f1566fa4379b00fd0321b6676a22b6cc91fbbd8380ac5183d619468"
|
|
8
|
+
"statusline.cjs": "4a48353b4f1566fa4379b00fd0321b6676a22b6cc91fbbd8380ac5183d619468",
|
|
9
|
+
"router.js": "b6998397e7883191b62229ccdc66fb87f1ccca1d5b2039ecb8c1e686d1ad81f8"
|
|
9
10
|
}
|
|
10
11
|
},
|
|
11
|
-
"signature": "
|
|
12
|
+
"signature": "vl9y84CRx7XaIXMi3iD1q3UVqeUvGsvpwjXkhMuA42myuVhCbgtnSNM9W8M3Pv9Odqy5qucwwDsz7MB7mUqDBg==",
|
|
12
13
|
"algorithm": "ed25519"
|
|
13
14
|
}
|
|
@@ -30,7 +30,7 @@ const AGENT_CAPABILITIES = {
|
|
|
30
30
|
const TASK_PATTERNS = [
|
|
31
31
|
// Code patterns
|
|
32
32
|
{ tokens: ['implement', 'create', 'build', 'add', 'write code', 'refactor', 'debug'], agent: 'coder' },
|
|
33
|
-
{ tokens: ['test', 'tests', 'spec', 'coverage', 'unit test', 'integration test'], agent: 'tester' },
|
|
33
|
+
{ tokens: ['test', 'tests', 'testing', 'spec', 'specs', 'coverage', 'unit test', 'integration test'], agent: 'tester' },
|
|
34
34
|
{ tokens: ['review', 'audit', 'check', 'validate', 'security'], agent: 'reviewer' },
|
|
35
35
|
{ tokens: ['research', 'find', 'search', 'documentation', 'explore'], agent: 'researcher' },
|
|
36
36
|
{ tokens: ['design', 'architect', 'architecture', 'structure', 'plan'], agent: 'architect' },
|
package/catalog-manifest.json
CHANGED
|
@@ -2059,6 +2059,26 @@ async function checkMetaharness() {
|
|
|
2059
2059
|
};
|
|
2060
2060
|
}
|
|
2061
2061
|
}
|
|
2062
|
+
// Opt-in @ruvector/typesafe task router (optional peer). `--component typesafe` only.
|
|
2063
|
+
async function checkTypesafeRouter() {
|
|
2064
|
+
const name = '@ruvector/typesafe router';
|
|
2065
|
+
const { readTypesafeConfig } = await import('../ruvector/typesafe-router.js');
|
|
2066
|
+
const cfg = readTypesafeConfig();
|
|
2067
|
+
const gate = cfg.enabled ? `enabled (${cfg.embedder === 'hash' ? 'hash embedder, uncalibrated' : 'onnx embedder'})` : 'disabled (set CLAUDE_FLOW_ROUTER_TYPESAFE=1)';
|
|
2068
|
+
try {
|
|
2069
|
+
const { createRequire } = await import('module');
|
|
2070
|
+
const pj = createRequire(import.meta.url)('@ruvector/typesafe/package.json');
|
|
2071
|
+
return { name, status: 'pass', message: `v${pj.version ?? '?'} installed; ${gate}` };
|
|
2072
|
+
}
|
|
2073
|
+
catch {
|
|
2074
|
+
return {
|
|
2075
|
+
name,
|
|
2076
|
+
status: cfg.enabled ? 'warn' : 'pass',
|
|
2077
|
+
message: `Not installed; ${gate} — hooks_route uses the built-in router`,
|
|
2078
|
+
...(cfg.enabled ? { fix: 'npm install @ruvector/typesafe # optional peer' } : {}),
|
|
2079
|
+
};
|
|
2080
|
+
}
|
|
2081
|
+
}
|
|
2062
2082
|
async function checkClaudeCode() {
|
|
2063
2083
|
try {
|
|
2064
2084
|
const version = await runCommand('claude --version');
|
|
@@ -2252,7 +2272,7 @@ export const doctorCommand = {
|
|
|
2252
2272
|
{
|
|
2253
2273
|
name: 'component',
|
|
2254
2274
|
short: 'c',
|
|
2255
|
-
description: 'Check specific component (version, node, npm, config, daemon, memory, api, git, mcp, mcp-overhead, claude, disk, typescript, agentic-flow, encryption, federation, funnel, proxy, auth, metaharness)',
|
|
2275
|
+
description: 'Check specific component (version, node, npm, config, daemon, memory, api, git, mcp, mcp-overhead, claude, disk, typescript, agentic-flow, encryption, federation, funnel, proxy, auth, typesafe, metaharness)',
|
|
2256
2276
|
type: 'string'
|
|
2257
2277
|
},
|
|
2258
2278
|
{
|
|
@@ -2435,6 +2455,7 @@ export const doctorCommand = {
|
|
|
2435
2455
|
// a user would actually debug them (is it installed? running? exposed?).
|
|
2436
2456
|
'proxy': [checkProxySponsoredConsent, checkProxyBinary, checkProxyProcess, checkProxyBindAddress],
|
|
2437
2457
|
'auth': checkAuth, // ADR-306
|
|
2458
|
+
'typesafe': checkTypesafeRouter, // opt-in @ruvector/typesafe task router
|
|
2438
2459
|
};
|
|
2439
2460
|
let checksToRun = allChecks;
|
|
2440
2461
|
if (component && componentMap[component]) {
|
|
@@ -1811,6 +1811,12 @@ const postTaskCommand = {
|
|
|
1811
1811
|
}
|
|
1812
1812
|
output.writeln();
|
|
1813
1813
|
output.printSuccess(`Task outcome recorded: ${success ? 'SUCCESS' : 'FAILED'}`);
|
|
1814
|
+
// #3353: only show observed learning results; say so when degraded.
|
|
1815
|
+
const lu = result.learningUpdates;
|
|
1816
|
+
if (lu.available === false) {
|
|
1817
|
+
output.writeln();
|
|
1818
|
+
output.printWarning(`Learning degraded: ${lu.reason ?? 'feedback not recorded'} — no pattern updates were observed`);
|
|
1819
|
+
}
|
|
1814
1820
|
output.writeln();
|
|
1815
1821
|
output.writeln(output.bold('Learning Updates'));
|
|
1816
1822
|
output.printTable({
|
|
@@ -1819,10 +1825,10 @@ const postTaskCommand = {
|
|
|
1819
1825
|
{ key: 'value', header: 'Value', width: 20, align: 'right' }
|
|
1820
1826
|
],
|
|
1821
1827
|
data: [
|
|
1822
|
-
{ metric: 'Patterns Updated', value:
|
|
1823
|
-
{ metric: 'New Patterns', value:
|
|
1828
|
+
{ metric: 'Patterns Updated', value: lu.patternsUpdated },
|
|
1829
|
+
{ metric: 'New Patterns', value: lu.newPatterns ?? 'unknown' },
|
|
1830
|
+
{ metric: 'Trajectory Recorded', value: result.trajectory ? (result.trajectory.recorded ? 'yes' : 'no') : 'unknown' },
|
|
1824
1831
|
{ metric: 'Duration', value: `${(result.duration / 1000).toFixed(1)}s` },
|
|
1825
|
-
{ metric: 'Trajectory ID', value: result.learningUpdates.trajectoryId }
|
|
1826
1832
|
]
|
|
1827
1833
|
});
|
|
1828
1834
|
return { success: true, data: result };
|
|
@@ -499,7 +499,7 @@ export async function executeUpgrade(targetDir, upgradeSettings = false) {
|
|
|
499
499
|
const sourceHelpersForUpgrade = findSourceHelpersDir();
|
|
500
500
|
if (sourceHelpersForUpgrade) {
|
|
501
501
|
// Keep in sync with helper-refresh.ts:CRITICAL_HELPERS.
|
|
502
|
-
const criticalHelpers = ['auto-memory-hook.mjs', 'hook-handler.cjs', 'intelligence.cjs', 'statusline.cjs'];
|
|
502
|
+
const criticalHelpers = ['auto-memory-hook.mjs', 'hook-handler.cjs', 'intelligence.cjs', 'statusline.cjs', 'router.js'];
|
|
503
503
|
for (const helperName of criticalHelpers) {
|
|
504
504
|
const targetPath = path.join(targetDir, '.claude', 'helpers', helperName);
|
|
505
505
|
const sourcePath = path.join(sourceHelpersForUpgrade, helperName);
|
|
@@ -524,6 +524,7 @@ export async function executeUpgrade(targetDir, upgradeSettings = false) {
|
|
|
524
524
|
'hook-handler.cjs': generateHookHandler(),
|
|
525
525
|
'intelligence.cjs': generateIntelligenceStub(),
|
|
526
526
|
'auto-memory-hook.mjs': generateAutoMemoryHook(),
|
|
527
|
+
'router.js': generateAgentRouter(), // ADR-389
|
|
527
528
|
};
|
|
528
529
|
for (const [helperName, content] of Object.entries(generatedCritical)) {
|
|
529
530
|
const targetPath = path.join(targetDir, '.claude', 'helpers', helperName);
|
|
@@ -71,6 +71,10 @@ export const CRITICAL_HELPERS = [
|
|
|
71
71
|
// statusline.cjs is here so the funnel disclosure row (ADR-301) reaches
|
|
72
72
|
// existing installs on the next `ruflo` command, not only fresh `ruflo init`.
|
|
73
73
|
'statusline.cjs',
|
|
74
|
+
// router.js is loaded by hook-handler.cjs to label each prompt with an agent.
|
|
75
|
+
// Without it here, installs kept the pre-#2257 substring router forever
|
|
76
|
+
// ("latest" -> tester). ADR-389 / #3401.
|
|
77
|
+
'router.js',
|
|
74
78
|
];
|
|
75
79
|
function errorCode(error) {
|
|
76
80
|
return typeof error === 'object' && error !== null && 'code' in error
|
|
@@ -309,6 +313,7 @@ async function writeCriticalHelpers(helpersDir, version, opts = {}) {
|
|
|
309
313
|
'hook-handler.cjs': gen.generateHookHandler(),
|
|
310
314
|
'intelligence.cjs': gen.generateIntelligenceStub(),
|
|
311
315
|
'auto-memory-hook.mjs': gen.generateAutoMemoryHook(),
|
|
316
|
+
'router.js': gen.generateAgentRouter(), // ADR-389
|
|
312
317
|
// Fallback needs the same generator inputs `ruflo init` uses. We match the
|
|
313
318
|
// hardcoded default (maxAgents 15) because the fallback fires when the
|
|
314
319
|
// installed package is unresolvable — no way to read the user's project
|
|
@@ -283,7 +283,7 @@ const AGENT_CAPABILITIES = {
|
|
|
283
283
|
// the whitespace acts as a natural boundary.
|
|
284
284
|
const TASK_PATTERNS = [
|
|
285
285
|
{ tokens: ['implement', 'create', 'build', 'add', 'write code', 'refactor', 'debug'], agent: 'coder' },
|
|
286
|
-
{ tokens: ['test', 'tests', 'spec', 'coverage', 'unit test', 'integration test'], agent: 'tester' },
|
|
286
|
+
{ tokens: ['test', 'tests', 'testing', 'spec', 'specs', 'coverage', 'unit test', 'integration test'], agent: 'tester' },
|
|
287
287
|
{ tokens: ['review', 'audit', 'check', 'validate', 'security'], agent: 'reviewer' },
|
|
288
288
|
{ tokens: ['research', 'find', 'search', 'documentation', 'explore'], agent: 'researcher' },
|
|
289
289
|
{ tokens: ['design', 'architect', 'architecture', 'structure', 'plan'], agent: 'architect' },
|
|
@@ -329,15 +329,16 @@ function routeTask(task) {
|
|
|
329
329
|
};
|
|
330
330
|
}
|
|
331
331
|
|
|
332
|
-
// CLI
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
if (task) {
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
} else {
|
|
339
|
-
|
|
340
|
-
|
|
332
|
+
// CLI — only when executed directly, not when require()d by hook-handler.cjs
|
|
333
|
+
if (require.main === module) {
|
|
334
|
+
const task = process.argv.slice(2).join(' ');
|
|
335
|
+
if (task) {
|
|
336
|
+
const result = routeTask(task);
|
|
337
|
+
console.log(JSON.stringify(result, null, 2));
|
|
338
|
+
} else {
|
|
339
|
+
console.log('Usage: router.js <task description>');
|
|
340
|
+
console.log('\\nAvailable agents:', Object.keys(AGENT_CAPABILITIES).join(', '));
|
|
341
|
+
}
|
|
341
342
|
}
|
|
342
343
|
|
|
343
344
|
module.exports = { routeTask, AGENT_CAPABILITIES, TASK_PATTERNS, buildPattern };
|
|
@@ -125,7 +125,7 @@ export const CAPABILITY_DOMAINS = [
|
|
|
125
125
|
{
|
|
126
126
|
id: 'guidance',
|
|
127
127
|
name: 'Capability Guidance',
|
|
128
|
-
prefixes: ['guidance_'],
|
|
128
|
+
prefixes: ['guidance_', 'seraphina_'],
|
|
129
129
|
description: 'Live capability inventory, task routing, workflow guidance, and system discovery.',
|
|
130
130
|
taskSignals: ['guidance', 'discover', 'capability', 'what can ruflo do'],
|
|
131
131
|
commands: ['guidance compile', 'guidance retrieve', 'guidance gates', 'guidance optimize'],
|
|
@@ -430,7 +430,7 @@ export const CAPABILITY_DOMAINS = [
|
|
|
430
430
|
id: 'business-collaboration',
|
|
431
431
|
name: 'AgentBBS & Business Pods',
|
|
432
432
|
// Metadata classification only; execution remains behind the existing loadAgentbbs guard.
|
|
433
|
-
prefixes: ['agentbbs_', 'business_pod_', 'federation_bbs_'],
|
|
433
|
+
prefixes: ['agentbbs_', 'business_pod_', 'federation_bbs_', 'x_federation_'],
|
|
434
434
|
description: 'Federated business rooms, domain-affinity routing, and business-pod validation.',
|
|
435
435
|
taskSignals: ['business pod', 'bbs', 'room', 'domain affinity'],
|
|
436
436
|
commands: [],
|
|
@@ -551,6 +551,8 @@ const TOOL_OWNERSHIP = [
|
|
|
551
551
|
{ prefixes: ['testgen_'], packageOwner: '@claude-flow/cli', pluginOwner: 'ruflo-testgen' },
|
|
552
552
|
{ prefixes: ['managed_agent_', 'wasm_agent_', 'wasm_gallery_'], packageOwner: '@claude-flow/cli', pluginOwner: 'ruflo-agent' },
|
|
553
553
|
{ prefixes: ['guidance_'], packageOwner: '@claude-flow/guidance', pluginOwner: 'ruflo-core' },
|
|
554
|
+
{ prefixes: ['seraphina_'], packageOwner: '@claude-flow/cli', pluginOwner: 'ruflo-core' },
|
|
555
|
+
{ prefixes: ['x_federation_'], packageOwner: '@claude-flow/cli', pluginOwner: 'ruflo-x-gateway' },
|
|
554
556
|
];
|
|
555
557
|
function ownershipForTool(toolName, definition) {
|
|
556
558
|
const explicit = TOOL_OWNERSHIP.find((entry) => entry.prefixes.some((prefix) => toolName.startsWith(prefix)));
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* Provides intelligent hooks functionality via MCP protocol
|
|
4
4
|
*/
|
|
5
5
|
import { type MCPTool } from './types.js';
|
|
6
|
+
import { type RouterEmbedderKind } from '../ruvector/router-embedder.js';
|
|
6
7
|
/**
|
|
7
8
|
* Strip extended-thinking blocks from text before it enters a learning
|
|
8
9
|
* trajectory (hermes-agent think_scrubber pattern). Claude models with extended
|
|
@@ -13,11 +14,46 @@ import { type MCPTool } from './types.js';
|
|
|
13
14
|
* the tag names untouched.
|
|
14
15
|
*/
|
|
15
16
|
export declare function scrubReasoningBlocks(text: string): string;
|
|
17
|
+
/** Test hook: drop the cached semantic index so the next route rebuilds it. */
|
|
18
|
+
export declare function resetSemanticRouterForTests(): void;
|
|
19
|
+
/** Exported for tests. */
|
|
20
|
+
export declare function suggestAgentsForTask(task: string): {
|
|
21
|
+
agents: string[];
|
|
22
|
+
confidence: number;
|
|
23
|
+
};
|
|
16
24
|
export declare const hooksPreEdit: MCPTool;
|
|
17
25
|
export declare const hooksPostEdit: MCPTool;
|
|
18
26
|
export declare const hooksPreCommand: MCPTool;
|
|
19
27
|
export declare const hooksPostCommand: MCPTool;
|
|
20
28
|
export declare const hooksRoute: MCPTool;
|
|
29
|
+
/** Result of {@link routeTaskForBench}. */
|
|
30
|
+
export interface BenchRouteResult {
|
|
31
|
+
primaryAgent: string;
|
|
32
|
+
confidence: number;
|
|
33
|
+
/** Matched pattern name, or 'keyword-fallback'. */
|
|
34
|
+
pattern: string;
|
|
35
|
+
/** Embedder actually used ('hash' if MiniLM was requested but unavailable). */
|
|
36
|
+
embedder: RouterEmbedderKind;
|
|
37
|
+
embedderReason?: string;
|
|
38
|
+
/** routing.method of the underlying route ('semantic-native' | 'semantic-pure-js' | 'keyword'). */
|
|
39
|
+
method: string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* INTERNAL / BENCH-ONLY (ADR-391). Not a public API; may change without notice.
|
|
43
|
+
*
|
|
44
|
+
* Routes `task` through the same local path `hooks_route` uses (semantic index +
|
|
45
|
+
* keyword fallback) with an explicit embedder, without the MCP layer. It skips
|
|
46
|
+
* the two steps that are neither ADR-391 candidate A nor B: the AgentDB
|
|
47
|
+
* pre-route (`bridgeRouteTask`, which answers first when its confidence > 0.5)
|
|
48
|
+
* and the opt-in typesafe wrapper (CLAUDE_FLOW_ROUTER_TYPESAFE). With those
|
|
49
|
+
* inactive, `primaryAgent` equals `hooks_route`'s `primaryAgent.type`.
|
|
50
|
+
*
|
|
51
|
+
* Switching `embedder` between calls rebuilds the index; benchmark in blocks.
|
|
52
|
+
*/
|
|
53
|
+
export declare function routeTaskForBench(task: string, opts: {
|
|
54
|
+
embedder: RouterEmbedderKind;
|
|
55
|
+
context?: string;
|
|
56
|
+
}): Promise<BenchRouteResult>;
|
|
21
57
|
export declare const hooksMetrics: MCPTool;
|
|
22
58
|
export declare const hooksList: MCPTool;
|
|
23
59
|
export declare const hooksPreTask: MCPTool;
|