claude-flow 3.6.0 → 3.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-flow",
3
- "version": "3.6.0",
3
+ "version": "3.6.2",
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",
@@ -505,7 +505,7 @@ export const agentdbConsolidate = {
505
505
  // ===== agentdb_batch — Batch operations (insert, update, delete) =====
506
506
  export const agentdbBatch = {
507
507
  name: 'agentdb_batch',
508
- description: 'Batch operations on memory entries (insert, update, delete)',
508
+ description: 'Batch operations on AgentDB episodes (insert, update, delete). Note: entries are stored in the AgentDB episodes table, not the memory_search namespace. Use memory_store for entries that should be searchable via memory_search.',
509
509
  inputSchema: {
510
510
  type: 'object',
511
511
  properties: {
@@ -20,9 +20,16 @@ function getPackageVersion() {
20
20
  try {
21
21
  const __filename = fileURLToPath(import.meta.url);
22
22
  const __dirname = dirname(__filename);
23
- const pkgPath = join(__dirname, '..', '..', 'package.json');
24
- const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
25
- return pkg.version || '3.0.0';
23
+ for (const depth of ['../..', '../../..']) {
24
+ const pkgPath = join(__dirname, depth, 'package.json');
25
+ if (existsSync(pkgPath)) {
26
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
27
+ if (pkg.name?.includes('claude-flow') || pkg.name === 'ruflo') {
28
+ return pkg.version || '3.0.0';
29
+ }
30
+ }
31
+ }
32
+ return '3.0.0';
26
33
  }
27
34
  catch {
28
35
  return '3.0.0';
@@ -5,7 +5,7 @@
5
5
  * @module @claude-flow/cli/mcp-tools/transfer-tools
6
6
  * @version 3.0.0
7
7
  */
8
- import { validateIdentifier, validateText } from './validate-input.js';
8
+ import { validateIdentifier, validatePackageName, validateText } from './validate-input.js';
9
9
  /**
10
10
  * Helper to create MCP tool result
11
11
  */
@@ -363,7 +363,7 @@ export const transferTools = [
363
363
  },
364
364
  handler: async (input) => {
365
365
  {
366
- const v = validateIdentifier(input.name, 'name');
366
+ const v = validatePackageName(input.name, 'name');
367
367
  if (!v.valid)
368
368
  return createResult({ error: v.error }, true);
369
369
  }
@@ -21,6 +21,10 @@ export declare function validateIdentifier(value: unknown, label: string): Valid
21
21
  * Allows ~, ^, and / which are standard git revision selectors.
22
22
  */
23
23
  export declare function validateGitRef(value: unknown, label: string): ValidationResult;
24
+ /**
25
+ * Validate an npm package name (allows @scope/name format).
26
+ */
27
+ export declare function validatePackageName(value: unknown, label: string): ValidationResult;
24
28
  /**
25
29
  * Validate a file path (prevents traversal and shell injection).
26
30
  */
@@ -11,6 +11,7 @@ const SHELL_META = /[;&|`$(){}[\]<>!#\\]/;
11
11
  const PATH_TRAVERSAL = /\.\.[/\\]/;
12
12
  const IDENTIFIER_RE = /^[a-zA-Z0-9_][a-zA-Z0-9_\-.:]{0,127}$/;
13
13
  const GIT_REF_RE = /^[a-zA-Z0-9_][a-zA-Z0-9_\-.:~^/]{0,255}$/;
14
+ const NPM_PACKAGE_RE = /^(@[a-zA-Z0-9_\-]+\/)?[a-zA-Z0-9_\-][a-zA-Z0-9_\-.]{0,213}$/;
14
15
  /**
15
16
  * Validate an identifier (agent ID, agent type, namespace, key, etc.)
16
17
  * Rejects shell metacharacters and path traversal.
@@ -52,6 +53,24 @@ export function validateGitRef(value, label) {
52
53
  }
53
54
  return { valid: true, sanitized: value };
54
55
  }
56
+ /**
57
+ * Validate an npm package name (allows @scope/name format).
58
+ */
59
+ export function validatePackageName(value, label) {
60
+ if (typeof value !== 'string' || value.length === 0) {
61
+ return { valid: false, sanitized: '', error: `${label} must be a non-empty string` };
62
+ }
63
+ if (value.length > 214) {
64
+ return { valid: false, sanitized: '', error: `${label} exceeds 214 characters` };
65
+ }
66
+ if (SHELL_META.test(value)) {
67
+ return { valid: false, sanitized: '', error: `${label} contains disallowed characters` };
68
+ }
69
+ if (!NPM_PACKAGE_RE.test(value)) {
70
+ return { valid: false, sanitized: '', error: `${label} contains invalid characters (expected npm package name, e.g. @scope/name)` };
71
+ }
72
+ return { valid: true, sanitized: value };
73
+ }
55
74
  /**
56
75
  * Validate a file path (prevents traversal and shell injection).
57
76
  */
@@ -1432,12 +1432,22 @@ export async function bridgeBatchOperation(params) {
1432
1432
  let result;
1433
1433
  switch (params.operation) {
1434
1434
  case 'insert': {
1435
- // insertEpisodes expects [{content, metadata?, embedding?}]
1435
+ if (typeof batch.insertEpisodes !== 'function') {
1436
+ return { success: false, error: 'BatchOperations.insertEpisodes not available — embedder may not be initialized. Use memory_store instead.' };
1437
+ }
1436
1438
  const episodes = params.entries.map((e) => ({
1437
1439
  content: e.value || e.content || JSON.stringify(e),
1438
1440
  metadata: e.metadata || { key: e.key },
1439
1441
  }));
1440
- result = await batch.insertEpisodes(episodes);
1442
+ try {
1443
+ result = await batch.insertEpisodes(episodes);
1444
+ }
1445
+ catch (insertErr) {
1446
+ if (insertErr?.message?.includes('null') || insertErr?.message?.includes('embedBatch')) {
1447
+ return { success: false, error: 'Embedder not initialized for batch insert. Use memory_store for individual entries or run embeddings_init first.' };
1448
+ }
1449
+ throw insertErr;
1450
+ }
1441
1451
  break;
1442
1452
  }
1443
1453
  case 'delete': {
@@ -22,6 +22,8 @@
22
22
  */
23
23
  import { readFileSync } from 'node:fs';
24
24
  import { createRequire } from 'node:module';
25
+ // WASM binary requires at least 768-dim input for MicroLoRA adapt()
26
+ const MICROLORA_WASM_MIN_DIM = 768;
25
27
  // ── WASM Module Detection & Init ─────────────────────────────
26
28
  let _wasmReady = false;
27
29
  /**
@@ -107,7 +109,12 @@ export async function createHnswRouter(config) {
107
109
  return ok;
108
110
  },
109
111
  route(query, k = 3) {
110
- return router.route(query, k);
112
+ const raw = router.route(query, k);
113
+ return Array.from(raw).map((r) => ({
114
+ name: r.name ?? r.pattern_name ?? '',
115
+ score: r.score ?? r.distance ?? 0,
116
+ metadata: r.metadata ? (typeof r.metadata === 'string' ? JSON.parse(r.metadata) : r.metadata) : undefined,
117
+ }));
111
118
  },
112
119
  clear() {
113
120
  router.clear();
@@ -183,17 +190,14 @@ export async function createMicroLora(config) {
183
190
  return lora.apply(input);
184
191
  },
185
192
  adapt(quality, learningRate = 0.01, success = true) {
186
- // v2.0.2: adapt(input, feedback) — two args
187
193
  const feedback = new mod.AdaptFeedbackWasm();
188
194
  feedback.quality = quality;
189
195
  feedback.learningRate = learningRate;
190
- // Note: feedback.success not on prototype in v2.0.2, set via property
191
196
  try {
192
197
  feedback.success = success;
193
198
  }
194
199
  catch { /* v2.0.2 quirk */ }
195
- // Create a dummy input vector matching the configured inputDim
196
- const input = new Float32Array(config.inputDim);
200
+ const input = new Float32Array(Math.max(config.inputDim, MICROLORA_WASM_MIN_DIM));
197
201
  lora.adapt(input, feedback);
198
202
  },
199
203
  applyUpdates(gradients) {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@claude-flow/cli",
3
- "version": "3.6.0",
3
+ "version": "3.6.2",
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",