claude-flow 3.10.38 → 3.10.40

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/README.md CHANGED
@@ -35,7 +35,7 @@ Orchestrate 100+ specialized AI agents across machines, teams, and trust boundar
35
35
 
36
36
  ### What Ruflo Does
37
37
 
38
- One `npx ruvflo init` gives Claude Code a nervous system: agents self-organize into swarms, learn from every task, remember across sessions, and — with federation — securely talk to agents on other machines without leaking data. You keep writing code. Ruflo handles the coordination.
38
+ One `npx ruflo init` gives Claude Code a nervous system: agents self-organize into swarms, learn from every task, remember across sessions, and — with federation — securely talk to agents on other machines without leaking data. You keep writing code. Ruflo handles the coordination.
39
39
 
40
40
  ```
41
41
  Self-Learning / Self-Optimizing Agent Architecture
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-flow",
3
- "version": "3.10.38",
3
+ "version": "3.10.40",
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",
@@ -35,7 +35,7 @@ Orchestrate 100+ specialized AI agents across machines, teams, and trust boundar
35
35
 
36
36
  ### What Ruflo Does
37
37
 
38
- One `npx ruvflo init` gives Claude Code a nervous system: agents self-organize into swarms, learn from every task, remember across sessions, and — with federation — securely talk to agents on other machines without leaking data. You keep writing code. Ruflo handles the coordination.
38
+ One `npx ruflo init` gives Claude Code a nervous system: agents self-organize into swarms, learn from every task, remember across sessions, and — with federation — securely talk to agents on other machines without leaking data. You keep writing code. Ruflo handles the coordination.
39
39
 
40
40
  ```
41
41
  Self-Learning / Self-Optimizing Agent Architecture
@@ -27,7 +27,7 @@ export function generateSettings(options) {
27
27
  'Bash(npx @claude-flow*)',
28
28
  'Bash(npx claude-flow*)',
29
29
  'Bash(node .claude/*)',
30
- 'mcp__claude-flow__:*',
30
+ 'mcp__claude-flow__*',
31
31
  ],
32
32
  deny: [
33
33
  'Read(./.env)',
@@ -107,8 +107,9 @@ function getStatuslineData() {
107
107
  const jsonStart = raw.indexOf('{');
108
108
  if (jsonStart === -1) throw new Error('no JSON in CLI output');
109
109
  const data = JSON.parse(raw.slice(jsonStart));
110
- // Overlay real ADR count from both local directories (fast, no network).
111
- data.adrs = getLocalADRCount();
110
+ // Overlay every block the CLI JSON omits (adrs/agentdb/tests/hooks/integration)
111
+ // with real local reads, so those segments reflect actual state instead of 0.
112
+ applyLocalOverlays(data);
112
113
  writeCache(data);
113
114
  return data;
114
115
  } catch { /* CLI unavailable or timed out */ }
@@ -141,13 +142,40 @@ function getLocalADRCount() {
141
142
  return { count: total, implemented: total, compliance: 0 };
142
143
  }
143
144
 
144
- // Minimal local fallback when the CLI is not installed or times out.
145
- // Returns a structure that matches the CLI JSON schema so the renderer works.
146
- function buildLocalFallback() {
147
- const memMB = Math.floor(process.memoryUsage().heapUsed / 1024 / 1024);
148
- const adrs = getLocalADRCount();
145
+ // ─── Local overlays for segments the CLI JSON omits ──────────────
146
+ // 'hooks statusline --json' only returns user/v3Progress/security/swarm/system.
147
+ // agentdb/tests/hooks/integration are never populated, so without these overlays
148
+ // they render as a permanent 0. Each reader is cheap and degrades to zeros.
149
+
150
+ // Real AgentDB stats from the local memory DB. Vectors live in .swarm/memory.db
151
+ // (sql.js + HNSW); ruvector.db is an opaque redb store counted only toward size.
152
+ // One read-only sqlite3 query (mode=ro never takes a write lock the daemon owns).
153
+ function getLocalAgentDB() {
154
+ const result = { vectorCount: 0, dbSizeKB: 0, hasHnsw: false };
155
+ try {
156
+ let bytes = 0;
157
+ for (const f of ['.swarm/memory.db', 'ruvector.db']) {
158
+ try { bytes += fs.statSync(path.join(CWD, f)).size; } catch { /* missing */ }
159
+ }
160
+ result.dbSizeKB = Math.round(bytes / 1024);
161
+
162
+ const memDb = path.join(CWD, '.swarm', 'memory.db');
163
+ if (fs.existsSync(memDb)) {
164
+ const Q = String.fromCharCode(34);
165
+ const sql = Q + 'SELECT (SELECT COUNT(*) FROM memory_entries WHERE embedding IS NOT NULL)||' + "'|'" + '||(SELECT COUNT(*) FROM vector_indexes);' + Q;
166
+ const out = safeExec("sqlite3 'file:" + memDb + "?mode=ro' " + sql, 1500);
167
+ if (out && out.indexOf('|') !== -1) {
168
+ const parts = out.split('|');
169
+ result.vectorCount = parseInt(parts[0], 10) || 0;
170
+ result.hasHnsw = (parseInt(parts[1], 10) || 0) > 0;
171
+ }
172
+ }
173
+ } catch { /* ignore */ }
174
+ return result;
175
+ }
149
176
 
150
- // Test file count (pure directory walk, no file reads)
177
+ // Count test files via a bounded directory walk (no file reads).
178
+ function getLocalTests() {
151
179
  let testFiles = 0;
152
180
  function countTests(dir, depth) {
153
181
  if ((depth || 0) > 4) return;
@@ -163,19 +191,82 @@ function buildLocalFallback() {
163
191
  } catch { /* ignore */ }
164
192
  }
165
193
  for (const d of ['tests', 'test', '__tests__', 'src', 'v3']) countTests(path.join(CWD, d));
194
+ return { testFiles, testCases: testFiles * 4 };
195
+ }
166
196
 
167
- return {
197
+ // Count configured hooks from project .claude/settings.json. Claude Code hooks
198
+ // have no enabled/disabled flag, so every configured hook counts as enabled.
199
+ function getLocalHooks() {
200
+ const result = { enabled: 0, total: 0 };
201
+ try {
202
+ const settings = readJSON(path.join(CWD, '.claude', 'settings.json'));
203
+ const hooks = settings && settings.hooks;
204
+ if (hooks && typeof hooks === 'object') {
205
+ let n = 0;
206
+ for (const ev of Object.keys(hooks)) {
207
+ const groups = hooks[ev];
208
+ if (Array.isArray(groups)) {
209
+ for (const g of groups) {
210
+ if (g && Array.isArray(g.hooks)) n += g.hooks.length;
211
+ }
212
+ }
213
+ }
214
+ result.total = n;
215
+ result.enabled = n;
216
+ }
217
+ } catch { /* ignore */ }
218
+ return result;
219
+ }
220
+
221
+ // Best-effort integration block: DB presence + locally-configured stdio MCP
222
+ // servers (project .mcp.json + global ~/.claude.json). Remote connectors are
223
+ // account-managed and not present in local config, so they are not counted.
224
+ function getLocalIntegration() {
225
+ const integration = { mcpServers: { enabled: 0, total: 0 }, hasDatabase: false };
226
+ try {
227
+ for (const f of ['.swarm/memory.db', 'ruvector.db']) {
228
+ if (fs.existsSync(path.join(CWD, f))) { integration.hasDatabase = true; break; }
229
+ }
230
+ const names = new Set();
231
+ const projMcp = readJSON(path.join(CWD, '.mcp.json'));
232
+ if (projMcp && projMcp.mcpServers) for (const k of Object.keys(projMcp.mcpServers)) names.add(k);
233
+ const claudeJson = readJSON(path.join(os.homedir(), '.claude.json'));
234
+ if (claudeJson) {
235
+ if (claudeJson.mcpServers) for (const k of Object.keys(claudeJson.mcpServers)) names.add(k);
236
+ const proj = claudeJson.projects && claudeJson.projects[CWD];
237
+ if (proj && proj.mcpServers && !Array.isArray(proj.mcpServers)) {
238
+ for (const k of Object.keys(proj.mcpServers)) names.add(k);
239
+ }
240
+ }
241
+ integration.mcpServers.total = names.size;
242
+ integration.mcpServers.enabled = names.size;
243
+ } catch { /* ignore */ }
244
+ return integration;
245
+ }
246
+
247
+ // Overlay every locally-derived block onto the CLI data (mutates in place).
248
+ function applyLocalOverlays(data) {
249
+ data.adrs = getLocalADRCount();
250
+ data.agentdb = getLocalAgentDB();
251
+ data.tests = getLocalTests();
252
+ data.hooks = getLocalHooks();
253
+ data.integration = getLocalIntegration();
254
+ return data;
255
+ }
256
+
257
+ // Minimal local fallback when the CLI is not installed or times out.
258
+ // Returns a structure that matches the CLI JSON schema so the renderer works.
259
+ function buildLocalFallback() {
260
+ const memMB = Math.floor(process.memoryUsage().heapUsed / 1024 / 1024);
261
+
262
+ return applyLocalOverlays({
168
263
  user: { name: 'user', gitBranch: '', modelName: 'Claude Code' },
169
264
  v3Progress: { domainsCompleted: 0, totalDomains: 5, dddProgress: 0, patternsLearned: 0, sessionsCompleted: 0 },
170
265
  security: { status: 'NONE', cvesFixed: 0, totalCves: 0 },
171
266
  swarm: { activeAgents: 0, maxAgents: CONFIG.maxAgents, coordinationActive: false },
172
267
  system: { memoryMB: memMB, contextPct: 0, intelligencePct: 0, subAgents: 0 },
173
- adrs,
174
- hooks: { enabled: 0, total: 0 },
175
- agentdb: { vectorCount: 0, dbSizeKB: 0, hasHnsw: false },
176
- tests: { testFiles, testCases: testFiles * 4 },
177
268
  lastUpdated: new Date().toISOString(),
178
- };
269
+ });
179
270
  }
180
271
 
181
272
  // ANSI colors
@@ -375,7 +466,14 @@ function getPkgVersion() {
375
466
  // (bin/node_modules) layouts.
376
467
  try {
377
468
  const binDir = path.dirname(process.execPath);
378
- for (const gm of [path.join(binDir, '..', 'lib', 'node_modules'), path.join(binDir, 'node_modules')]) {
469
+ const globalModuleDirs = [path.join(binDir, '..', 'lib', 'node_modules'), path.join(binDir, 'node_modules')];
470
+ // #2221 follow-up: a custom npm prefix (e.g. ~/.npm-global) is decoupled from
471
+ // the node binary location, so the binDir-derived probes above all miss. Also
472
+ // probe the npm prefix from the environment and the common ~/.npm-global default.
473
+ for (const prefix of [process.env.npm_config_prefix, process.env.PREFIX, path.join(home, '.npm-global')]) {
474
+ if (prefix) globalModuleDirs.push(path.join(prefix, 'lib', 'node_modules'));
475
+ }
476
+ for (const gm of globalModuleDirs) {
379
477
  pkgPaths.push(
380
478
  path.join(gm, 'ruflo', 'package.json'),
381
479
  path.join(gm, '@claude-flow', 'cli', 'package.json'),
@@ -3931,7 +3931,10 @@ export const hooksModelRoute = {
3931
3931
  alternatives: result.alternatives,
3932
3932
  inferenceTimeUs: result.inferenceTimeUs,
3933
3933
  costMultiplier: result.costMultiplier,
3934
- implementation: 'tiny-dancer-neural',
3934
+ // Historical name kept for telemetry / dashboard schema stability.
3935
+ // The shipped router is the heuristic + Thompson-bandit described in
3936
+ // ruvector/model-router.ts — not a neural network. See #2329.
3937
+ implementation: 'heuristic-thompson-bandit',
3935
3938
  };
3936
3939
  },
3937
3940
  };
@@ -71,7 +71,7 @@ export interface EnhancedModelRouterConfig {
71
71
  */
72
72
  export declare class EnhancedModelRouter {
73
73
  private config;
74
- private tinyDancerRouter;
74
+ private baseRouter;
75
75
  constructor(config?: Partial<EnhancedModelRouterConfig>);
76
76
  /**
77
77
  * Detect code editing intent from task description
@@ -177,7 +177,12 @@ const LANGUAGE_MAP = {
177
177
  */
178
178
  export class EnhancedModelRouter {
179
179
  config;
180
- tinyDancerRouter;
180
+ // The base text-routing path delegated to here is the local
181
+ // heuristic + Thompson-bandit ModelRouter — NOT the @ruvector/tiny-dancer
182
+ // neural router that an earlier design (ADR-026) described (#2329). The
183
+ // public `getStats()` return still exposes the field as `tinyDancerStats`
184
+ // for telemetry-schema stability.
185
+ baseRouter;
181
186
  constructor(config) {
182
187
  this.config = {
183
188
  agentBoosterEnabled: true,
@@ -199,7 +204,7 @@ export class EnhancedModelRouter {
199
204
  preferQuality: false,
200
205
  ...config,
201
206
  };
202
- this.tinyDancerRouter = getModelRouter();
207
+ this.baseRouter = getModelRouter();
203
208
  }
204
209
  /**
205
210
  * Detect code editing intent from task description
@@ -355,13 +360,13 @@ export class EnhancedModelRouter {
355
360
  // AST analysis not available, continue with text-based routing
356
361
  }
357
362
  }
358
- // Step 4: Text-based complexity + tiny-dancer routing
359
- const tinyDancerResult = await this.tinyDancerRouter.route(task);
360
- // Step 5: Combine AST complexity with tiny-dancer result
361
- // Also boost if single tier3 keyword found
363
+ // Step 4: Text-based complexity via the local heuristic + bandit router.
364
+ const baseResult = await this.baseRouter.route(task);
365
+ // Step 5: Combine AST complexity with the text-routing result.
366
+ // Also boost if a single tier3 keyword is found.
362
367
  let finalComplexity = astComplexity !== undefined
363
- ? (astComplexity + tinyDancerResult.complexity) / 2
364
- : tinyDancerResult.complexity;
368
+ ? (astComplexity + baseResult.complexity) / 2
369
+ : baseResult.complexity;
365
370
  // Boost complexity if tier3 keywords found (even just one)
366
371
  if (tier3Check.matches) {
367
372
  finalComplexity = Math.min(1.0, finalComplexity + 0.25);
@@ -373,7 +378,7 @@ export class EnhancedModelRouter {
373
378
  tier: 2,
374
379
  handler: 'haiku',
375
380
  model: 'haiku',
376
- confidence: tinyDancerResult.confidence,
381
+ confidence: baseResult.confidence,
377
382
  complexity: finalComplexity,
378
383
  reasoning: `Low complexity (${(finalComplexity * 100).toFixed(0)}%) - using haiku`,
379
384
  canSkipLLM: false,
@@ -386,7 +391,7 @@ export class EnhancedModelRouter {
386
391
  tier: 2,
387
392
  handler: 'sonnet',
388
393
  model: 'sonnet',
389
- confidence: tinyDancerResult.confidence,
394
+ confidence: baseResult.confidence,
390
395
  complexity: finalComplexity,
391
396
  reasoning: `Medium complexity (${(finalComplexity * 100).toFixed(0)}%) - using sonnet`,
392
397
  canSkipLLM: false,
@@ -398,7 +403,7 @@ export class EnhancedModelRouter {
398
403
  tier: 3,
399
404
  handler: 'opus',
400
405
  model: 'opus',
401
- confidence: tinyDancerResult.confidence,
406
+ confidence: baseResult.confidence,
402
407
  complexity: finalComplexity,
403
408
  reasoning: `High complexity (${(finalComplexity * 100).toFixed(0)}%) - using opus`,
404
409
  canSkipLLM: false,
@@ -494,7 +499,10 @@ export class EnhancedModelRouter {
494
499
  getStats() {
495
500
  return {
496
501
  config: { ...this.config },
497
- tinyDancerStats: this.tinyDancerRouter.getStats(),
502
+ // Field name kept as `tinyDancerStats` for telemetry-schema
503
+ // stability; the underlying router is the local heuristic + bandit
504
+ // ModelRouter, not @ruvector/tiny-dancer. See #2329.
505
+ tinyDancerStats: this.baseRouter.getStats(),
498
506
  };
499
507
  }
500
508
  }
@@ -1,20 +1,33 @@
1
1
  /**
2
- * Intelligent Model Router using Tiny Dancer
2
+ * Intelligent Model Router lexical complexity heuristic + Thompson bandit
3
3
  *
4
- * Dynamically routes requests to optimal Claude model (haiku/sonnet/opus)
5
- * based on task complexity, confidence scores, and historical performance.
4
+ * Dynamically routes requests to the optimal Claude model (haiku/sonnet/opus)
5
+ * based on task complexity, uncertainty, and online-learned routing outcomes.
6
6
  *
7
- * Features:
8
- * - FastGRNN-based routing decisions (<100μs)
9
- * - Uncertainty quantification for model escalation
10
- * - Circuit breaker for failover
11
- * - Online learning from routing outcomes
12
- * - Complexity scoring via embeddings
7
+ * Mechanism (shipped):
8
+ * - Complexity score = blend of lexical, semantic-depth, task-scope, and
9
+ * uncertainty heuristics (see `computeLexicalComplexity` and friends).
10
+ * Pure JS arithmetic no model load, no tensor math.
11
+ * - Model selection = Thompson-sampling Beta-Bernoulli bandit with
12
+ * complexity-bucketed Beta(α,β) priors, persisted to
13
+ * `.swarm/model-router-state.json` and updated by `recordOutcome` after
14
+ * each routing decision.
15
+ * - Uncertainty quantification + a circuit breaker drive escalation when
16
+ * the bandit's confidence is low or downstream failures are observed.
13
17
  *
14
18
  * Routing Strategy:
15
- * - Haiku: High confidence, low complexity (fast, cheap)
16
- * - Sonnet: Medium confidence, moderate complexity (balanced)
17
- * - Opus: Low confidence, high complexity (most capable)
19
+ * - Haiku: high confidence, low complexity (fast, cheap)
20
+ * - Sonnet: medium confidence, moderate complexity (balanced)
21
+ * - Opus: low confidence, high complexity (most capable)
22
+ *
23
+ * Note (#2329): An earlier design (ADR-026 + this file's previous header)
24
+ * described a Tiny-Dancer / FastGRNN neural router with embedding-based
25
+ * complexity scoring. That path was never wired in — `@ruvector/tiny-dancer`
26
+ * is not imported here and the `embedding`-consuming branch in
27
+ * `computeSemanticDepth` is only reachable via the externally-callable
28
+ * `routeToModelFull(task, embedding)` wrapper (no internal callers). The
29
+ * shipped router is the heuristic + bandit described above; the neural
30
+ * path remains a future direction tracked in #2329.
18
31
  *
19
32
  * @module model-router
20
33
  */
@@ -1,20 +1,33 @@
1
1
  /**
2
- * Intelligent Model Router using Tiny Dancer
2
+ * Intelligent Model Router lexical complexity heuristic + Thompson bandit
3
3
  *
4
- * Dynamically routes requests to optimal Claude model (haiku/sonnet/opus)
5
- * based on task complexity, confidence scores, and historical performance.
4
+ * Dynamically routes requests to the optimal Claude model (haiku/sonnet/opus)
5
+ * based on task complexity, uncertainty, and online-learned routing outcomes.
6
6
  *
7
- * Features:
8
- * - FastGRNN-based routing decisions (<100μs)
9
- * - Uncertainty quantification for model escalation
10
- * - Circuit breaker for failover
11
- * - Online learning from routing outcomes
12
- * - Complexity scoring via embeddings
7
+ * Mechanism (shipped):
8
+ * - Complexity score = blend of lexical, semantic-depth, task-scope, and
9
+ * uncertainty heuristics (see `computeLexicalComplexity` and friends).
10
+ * Pure JS arithmetic no model load, no tensor math.
11
+ * - Model selection = Thompson-sampling Beta-Bernoulli bandit with
12
+ * complexity-bucketed Beta(α,β) priors, persisted to
13
+ * `.swarm/model-router-state.json` and updated by `recordOutcome` after
14
+ * each routing decision.
15
+ * - Uncertainty quantification + a circuit breaker drive escalation when
16
+ * the bandit's confidence is low or downstream failures are observed.
13
17
  *
14
18
  * Routing Strategy:
15
- * - Haiku: High confidence, low complexity (fast, cheap)
16
- * - Sonnet: Medium confidence, moderate complexity (balanced)
17
- * - Opus: Low confidence, high complexity (most capable)
19
+ * - Haiku: high confidence, low complexity (fast, cheap)
20
+ * - Sonnet: medium confidence, moderate complexity (balanced)
21
+ * - Opus: low confidence, high complexity (most capable)
22
+ *
23
+ * Note (#2329): An earlier design (ADR-026 + this file's previous header)
24
+ * described a Tiny-Dancer / FastGRNN neural router with embedding-based
25
+ * complexity scoring. That path was never wired in — `@ruvector/tiny-dancer`
26
+ * is not imported here and the `embedding`-consuming branch in
27
+ * `computeSemanticDepth` is only reachable via the externally-callable
28
+ * `routeToModelFull(task, embedding)` wrapper (no internal callers). The
29
+ * shipped router is the heuristic + bandit described above; the neural
30
+ * path remains a future direction tracked in #2329.
18
31
  *
19
32
  * @module model-router
20
33
  */
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@claude-flow/cli",
3
- "version": "3.10.38",
3
+ "version": "3.10.40",
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",
@@ -109,7 +109,7 @@
109
109
  "@claude-flow/codex": "^3.0.0-alpha.8",
110
110
  "@claude-flow/embeddings": "^3.0.0-alpha.18",
111
111
  "@claude-flow/guidance": "^3.0.0-alpha.1",
112
- "@claude-flow/memory": "^3.0.0-alpha.17",
112
+ "@claude-flow/memory": "^3.0.0-alpha.20",
113
113
  "@claude-flow/plugin-gastown-bridge": "^0.1.3",
114
114
  "@claude-flow/security": "^3.0.0-alpha.10",
115
115
  "@ruvector/attention": "^0.1.32",
@@ -1 +0,0 @@
1
- {"sessionId":"fd9b0530-a395-4da0-9b21-a26731cef01f","pid":91923,"procStart":"Mon May 11 02:12:51 2026","acquiredAt":1778466450635}