claude-flow 3.7.0-alpha.6 → 3.7.0-alpha.8

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.7.0-alpha.6",
3
+ "version": "3.7.0-alpha.8",
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",
@@ -26,5 +26,8 @@ export declare const agentdbConsolidate: MCPTool;
26
26
  export declare const agentdbBatch: MCPTool;
27
27
  export declare const agentdbContextSynthesize: MCPTool;
28
28
  export declare const agentdbSemanticRoute: MCPTool;
29
+ export declare const agentdbHierarchicalDelete: MCPTool;
30
+ export declare const agentdbCausalEdgeDelete: MCPTool;
31
+ export declare const agentdbCausalNodeDelete: MCPTool;
29
32
  export declare const agentdbTools: MCPTool[];
30
33
  //# sourceMappingURL=agentdb-tools.d.ts.map
@@ -661,6 +661,111 @@ export const agentdbSemanticRoute = {
661
661
  }
662
662
  },
663
663
  };
664
+ // ===== #1784: Delete tools — symmetry for hierarchical-store + causal-edge =====
665
+ export const agentdbHierarchicalDelete = {
666
+ name: 'agentdb_hierarchical-delete',
667
+ description: 'Delete a hierarchical-memory entry by key. Returns controller="native-unsupported" when the entry is in a backend without a public delete API.',
668
+ inputSchema: {
669
+ type: 'object',
670
+ properties: {
671
+ key: { type: 'string', description: 'Memory entry key to delete' },
672
+ tier: {
673
+ type: 'string',
674
+ description: 'Optional tier filter (working, episodic, semantic)',
675
+ enum: ['working', 'episodic', 'semantic'],
676
+ },
677
+ },
678
+ required: ['key'],
679
+ },
680
+ handler: async (params) => {
681
+ try {
682
+ const vKey = validateIdentifier(params.key, 'key');
683
+ if (!vKey.valid)
684
+ return { success: false, deleted: false, error: vKey.error };
685
+ if (params.tier) {
686
+ const vTier = validateIdentifier(params.tier, 'tier');
687
+ if (!vTier.valid)
688
+ return { success: false, deleted: false, error: vTier.error };
689
+ }
690
+ const key = validateString(params.key, 'key', 1000);
691
+ if (!key)
692
+ return { success: false, deleted: false, error: 'key is required (non-empty string, max 1KB)' };
693
+ const tier = validateString(params.tier, 'tier', 20);
694
+ if (tier && !['working', 'episodic', 'semantic'].includes(tier)) {
695
+ return { success: false, deleted: false, error: `Invalid tier: ${tier}. Must be working, episodic, or semantic` };
696
+ }
697
+ const bridge = await getBridge();
698
+ const result = await bridge.bridgeDeleteHierarchical({ key, tier: tier ?? undefined });
699
+ return result ?? { success: false, deleted: false, error: 'AgentDB bridge not available' };
700
+ }
701
+ catch (error) {
702
+ return { success: false, deleted: false, error: sanitizeError(error) };
703
+ }
704
+ },
705
+ };
706
+ export const agentdbCausalEdgeDelete = {
707
+ name: 'agentdb_causal-edge-delete',
708
+ description: 'Delete a causal edge between two memory entries. Returns controller="native-unsupported" when the edge lives in graph-node native storage (no public delete API).',
709
+ inputSchema: {
710
+ type: 'object',
711
+ properties: {
712
+ sourceId: { type: 'string', description: 'Source entry ID' },
713
+ targetId: { type: 'string', description: 'Target entry ID' },
714
+ relation: { type: 'string', description: 'Optional relationship type filter' },
715
+ },
716
+ required: ['sourceId', 'targetId'],
717
+ },
718
+ handler: async (params) => {
719
+ try {
720
+ const vSourceId = validateIdentifier(params.sourceId, 'sourceId');
721
+ if (!vSourceId.valid)
722
+ return { success: false, deleted: false, error: vSourceId.error };
723
+ const vTargetId = validateIdentifier(params.targetId, 'targetId');
724
+ if (!vTargetId.valid)
725
+ return { success: false, deleted: false, error: vTargetId.error };
726
+ const sourceId = validateString(params.sourceId, 'sourceId', 500);
727
+ const targetId = validateString(params.targetId, 'targetId', 500);
728
+ if (!sourceId)
729
+ return { success: false, deleted: false, error: 'sourceId is required (non-empty string)' };
730
+ if (!targetId)
731
+ return { success: false, deleted: false, error: 'targetId is required (non-empty string)' };
732
+ const relation = validateString(params.relation, 'relation', 200) ?? undefined;
733
+ const bridge = await getBridge();
734
+ const result = await bridge.bridgeDeleteCausalEdge({ sourceId, targetId, relation });
735
+ return result ?? { success: false, deleted: false, error: 'AgentDB bridge not available' };
736
+ }
737
+ catch (error) {
738
+ return { success: false, deleted: false, error: sanitizeError(error) };
739
+ }
740
+ },
741
+ };
742
+ export const agentdbCausalNodeDelete = {
743
+ name: 'agentdb_causal-node-delete',
744
+ description: 'Cascade-delete a causal node and all its incident edges from the SQL fallback. Native graph-node entries are unaffected (no delete API in the binding).',
745
+ inputSchema: {
746
+ type: 'object',
747
+ properties: {
748
+ nodeId: { type: 'string', description: 'Node ID to delete (cascades to all incident edges)' },
749
+ },
750
+ required: ['nodeId'],
751
+ },
752
+ handler: async (params) => {
753
+ try {
754
+ const vNodeId = validateIdentifier(params.nodeId, 'nodeId');
755
+ if (!vNodeId.valid)
756
+ return { success: false, deletedNode: false, deletedEdges: 0, error: vNodeId.error };
757
+ const nodeId = validateString(params.nodeId, 'nodeId', 500);
758
+ if (!nodeId)
759
+ return { success: false, deletedNode: false, deletedEdges: 0, error: 'nodeId is required (non-empty string)' };
760
+ const bridge = await getBridge();
761
+ const result = await bridge.bridgeDeleteCausalNode({ nodeId });
762
+ return result ?? { success: false, deletedNode: false, deletedEdges: 0, error: 'AgentDB bridge not available' };
763
+ }
764
+ catch (error) {
765
+ return { success: false, deletedNode: false, deletedEdges: 0, error: sanitizeError(error) };
766
+ }
767
+ },
768
+ };
664
769
  // ===== Export all tools =====
665
770
  export const agentdbTools = [
666
771
  agentdbHealth,
@@ -669,11 +774,14 @@ export const agentdbTools = [
669
774
  agentdbPatternSearch,
670
775
  agentdbFeedback,
671
776
  agentdbCausalEdge,
777
+ agentdbCausalEdgeDelete,
778
+ agentdbCausalNodeDelete,
672
779
  agentdbRoute,
673
780
  agentdbSessionStart,
674
781
  agentdbSessionEnd,
675
782
  agentdbHierarchicalStore,
676
783
  agentdbHierarchicalRecall,
784
+ agentdbHierarchicalDelete,
677
785
  agentdbConsolidate,
678
786
  agentdbBatch,
679
787
  agentdbContextSynthesize,
@@ -66,11 +66,12 @@ async function getEWCConsolidator() {
66
66
  return ewcConsolidator;
67
67
  }
68
68
  // MoE Router - lazy loaded
69
+ // #1773 item 4 — moe-router migrated to @claude-flow/neural
69
70
  let moeRouter = null;
70
71
  async function getMoERouter() {
71
72
  if (!moeRouter) {
72
73
  try {
73
- const { getMoERouter: getMoE } = await import('../ruvector/moe-router.js');
74
+ const { getMoERouter: getMoE } = await import('@claude-flow/neural');
74
75
  moeRouter = await getMoE();
75
76
  }
76
77
  catch {
@@ -336,11 +337,12 @@ function getRouterBackendInfo() {
336
337
  }
337
338
  }
338
339
  // Flash Attention - lazy loaded
340
+ // #1773 item 4 — flash-attention migrated to @claude-flow/neural
339
341
  let flashAttention = null;
340
342
  async function getFlashAttention() {
341
343
  if (!flashAttention) {
342
344
  try {
343
- const { getFlashAttention: getFlash } = await import('../ruvector/flash-attention.js');
345
+ const { getFlashAttention: getFlash } = await import('@claude-flow/neural');
344
346
  flashAttention = await getFlash();
345
347
  }
346
348
  catch {
@@ -668,7 +668,8 @@ export const neuralTools = [
668
668
  // The two surfaces now agree on a single source of truth.
669
669
  flashAttention: await (async () => {
670
670
  try {
671
- const { getFlashAttention } = await import('../ruvector/flash-attention.js');
671
+ // #1773 item 4 flash-attention now lives in @claude-flow/neural
672
+ const { getFlashAttention } = await import('@claude-flow/neural');
672
673
  return getFlashAttention() !== null;
673
674
  }
674
675
  catch {
@@ -278,6 +278,75 @@ export declare function bridgeRecordCausalEdge(options: {
278
278
  success: boolean;
279
279
  controller: string;
280
280
  } | null>;
281
+ /**
282
+ * Delete a hierarchical-memory entry by key (#1784).
283
+ *
284
+ * Reality check: agentdb's HierarchicalMemory class doesn't expose a public
285
+ * delete API today, so the real-backend path falls back to direct SQL on
286
+ * the underlying SQLite tables (status flip to 'deleted' + AttestationLog
287
+ * audit). The bridge-fallback path that bridgeHierarchicalStore uses when
288
+ * HierarchicalMemory isn't loaded writes plain memory_entries rows that
289
+ * `bridgeDeleteEntry` already handles.
290
+ *
291
+ * Returns { controller: 'native-unsupported' } when the real HM is loaded
292
+ * and the SQL fallback can't reach its private tables — surfacing the
293
+ * limitation honestly instead of silently returning success.
294
+ */
295
+ export declare function bridgeDeleteHierarchical(options: {
296
+ key: string;
297
+ tier?: string;
298
+ dbPath?: string;
299
+ }): Promise<{
300
+ success: boolean;
301
+ deleted: boolean;
302
+ key: string;
303
+ tier?: string;
304
+ controller: string;
305
+ guarded?: boolean;
306
+ error?: string;
307
+ } | null>;
308
+ /**
309
+ * Delete a causal edge between two memory entries (#1784).
310
+ *
311
+ * The bridge stores fallback edges in namespace='causal-edges' with key
312
+ * '{sourceId}→{targetId}'. Those CAN be soft-deleted. The native graph-node
313
+ * backend has no delete API (createNode/createEdge/createHyperedge only),
314
+ * so an edge that landed in graph-node native storage stays there. We
315
+ * surface that explicitly via controller: 'native-unsupported'.
316
+ */
317
+ export declare function bridgeDeleteCausalEdge(options: {
318
+ sourceId: string;
319
+ targetId: string;
320
+ relation?: string;
321
+ dbPath?: string;
322
+ }): Promise<{
323
+ success: boolean;
324
+ deleted: boolean;
325
+ sourceId: string;
326
+ targetId: string;
327
+ controller: string;
328
+ guarded?: boolean;
329
+ error?: string;
330
+ } | null>;
331
+ /**
332
+ * Cascade-delete a causal node and all its incident edges (#1784).
333
+ *
334
+ * Same constraint as bridgeDeleteCausalEdge — native graph-node lacks a
335
+ * delete API. SQL fallback path soft-deletes the node (if stored as a
336
+ * memory_entries row) and every edge whose key contains the nodeId.
337
+ */
338
+ export declare function bridgeDeleteCausalNode(options: {
339
+ nodeId: string;
340
+ dbPath?: string;
341
+ }): Promise<{
342
+ success: boolean;
343
+ deletedNode: boolean;
344
+ deletedEdges: number;
345
+ nodeId: string;
346
+ controller: string;
347
+ guarded?: boolean;
348
+ error?: string;
349
+ } | null>;
281
350
  /**
282
351
  * Start a session with ReflexionMemory episodic replay.
283
352
  * Loads relevant past session patterns for the new session.
@@ -1354,6 +1354,259 @@ export async function bridgeRecordCausalEdge(options) {
1354
1354
  return null;
1355
1355
  }
1356
1356
  }
1357
+ // ===== #1784: Delete tools for hierarchical + causal-graph =====
1358
+ /**
1359
+ * Delete a hierarchical-memory entry by key (#1784).
1360
+ *
1361
+ * Reality check: agentdb's HierarchicalMemory class doesn't expose a public
1362
+ * delete API today, so the real-backend path falls back to direct SQL on
1363
+ * the underlying SQLite tables (status flip to 'deleted' + AttestationLog
1364
+ * audit). The bridge-fallback path that bridgeHierarchicalStore uses when
1365
+ * HierarchicalMemory isn't loaded writes plain memory_entries rows that
1366
+ * `bridgeDeleteEntry` already handles.
1367
+ *
1368
+ * Returns { controller: 'native-unsupported' } when the real HM is loaded
1369
+ * and the SQL fallback can't reach its private tables — surfacing the
1370
+ * limitation honestly instead of silently returning success.
1371
+ */
1372
+ export async function bridgeDeleteHierarchical(options) {
1373
+ const registry = await getRegistry(options.dbPath);
1374
+ if (!registry)
1375
+ return null;
1376
+ try {
1377
+ const { key, tier } = options;
1378
+ // MutationGuard validation
1379
+ const guardResult = await guardValidate(registry, 'delete', { key, namespace: 'hierarchical' });
1380
+ if (!guardResult.allowed) {
1381
+ return { success: false, deleted: false, key, tier, controller: 'guard', error: `MutationGuard rejected: ${guardResult.reason}` };
1382
+ }
1383
+ const hm = registry.get('hierarchicalMemory');
1384
+ // 1. agentdb@3.0.0-alpha.13+: ReflexionMemory.deleteEpisode propagates through
1385
+ // graph adapter / generic graph backend / vector backend AND purges SQL
1386
+ // episodes + episode_embeddings rows. Single call, durably consistent.
1387
+ // See agentic-flow#150/#151 (closes ruvnet/RuVector#427 the cli-visible way).
1388
+ const reflexion = registry.get('reflexionMemory');
1389
+ if (reflexion && typeof reflexion.deleteEpisode === 'function') {
1390
+ try {
1391
+ const removed = await reflexion.deleteEpisode(key);
1392
+ if (removed) {
1393
+ await logAttestation(registry, 'delete', key, { namespace: 'hierarchical', tier });
1394
+ return { success: true, deleted: true, key, tier, controller: 'reflexionMemory', guarded: true };
1395
+ }
1396
+ }
1397
+ catch { /* fall through */ }
1398
+ }
1399
+ // 2. Try HierarchicalMemory's own delete API if it ever ships one.
1400
+ if (hm && typeof hm.delete === 'function') {
1401
+ try {
1402
+ await hm.delete(key);
1403
+ await logAttestation(registry, 'delete', key, { namespace: 'hierarchical', tier });
1404
+ return { success: true, deleted: true, key, tier, controller: 'hierarchicalMemory', guarded: true };
1405
+ }
1406
+ catch (err) {
1407
+ // Fall through to SQL fallback
1408
+ }
1409
+ }
1410
+ // 3. Stub HierarchicalMemory may expose `remove` or `forget`
1411
+ if (hm && typeof hm.remove === 'function') {
1412
+ try {
1413
+ await hm.remove(key);
1414
+ await logAttestation(registry, 'delete', key, { namespace: 'hierarchical', tier });
1415
+ return { success: true, deleted: true, key, tier, controller: 'hierarchicalMemory-stub', guarded: true };
1416
+ }
1417
+ catch { /* fall through */ }
1418
+ }
1419
+ // 3. Bridge-fallback: HM stored to memory_entries with namespace prefix
1420
+ // (used when the real controller isn't loaded). Soft-delete via SQL.
1421
+ const ctx = getDb(registry);
1422
+ if (ctx) {
1423
+ try {
1424
+ const result = ctx.db.prepare(`
1425
+ UPDATE memory_entries
1426
+ SET status = 'deleted', updated_at = ?
1427
+ WHERE key = ? AND namespace LIKE 'hierarchical%' AND status = 'active'
1428
+ `).run(Date.now(), key);
1429
+ const changes = result?.changes ?? 0;
1430
+ if (changes > 0) {
1431
+ await logAttestation(registry, 'delete', key, { namespace: 'hierarchical', tier });
1432
+ return { success: true, deleted: true, key, tier, controller: 'bridge-fallback', guarded: true };
1433
+ }
1434
+ // Nothing to delete in SQL fallback — and no real-HM delete API.
1435
+ // Surface the situation honestly.
1436
+ return {
1437
+ success: false, deleted: false, key, tier,
1438
+ controller: hm ? 'native-unsupported' : 'not-found',
1439
+ error: hm
1440
+ ? 'HierarchicalMemory has no public delete API; entry remains in native storage'
1441
+ : 'No hierarchical entry found with this key',
1442
+ };
1443
+ }
1444
+ catch (err) {
1445
+ return { success: false, deleted: false, key, tier, controller: 'sql-error', error: err.message };
1446
+ }
1447
+ }
1448
+ return null;
1449
+ }
1450
+ catch {
1451
+ return null;
1452
+ }
1453
+ }
1454
+ /**
1455
+ * Delete a causal edge between two memory entries (#1784).
1456
+ *
1457
+ * The bridge stores fallback edges in namespace='causal-edges' with key
1458
+ * '{sourceId}→{targetId}'. Those CAN be soft-deleted. The native graph-node
1459
+ * backend has no delete API (createNode/createEdge/createHyperedge only),
1460
+ * so an edge that landed in graph-node native storage stays there. We
1461
+ * surface that explicitly via controller: 'native-unsupported'.
1462
+ */
1463
+ export async function bridgeDeleteCausalEdge(options) {
1464
+ const registry = await getRegistry(options.dbPath);
1465
+ if (!registry)
1466
+ return null;
1467
+ try {
1468
+ const { sourceId, targetId, relation } = options;
1469
+ const edgeKey = `${sourceId}→${targetId}`;
1470
+ const guardResult = await guardValidate(registry, 'delete', { key: edgeKey, namespace: 'causal-edges' });
1471
+ if (!guardResult.allowed) {
1472
+ return { success: false, deleted: false, sourceId, targetId, controller: 'guard', error: `MutationGuard rejected: ${guardResult.reason}` };
1473
+ }
1474
+ const causalGraph = registry.get('causalGraph');
1475
+ // 1. agentdb@3.0.0-alpha.13+: GraphDatabaseAdapter.deleteEdgesByEndpoints
1476
+ // handles the (sourceId, targetId, relation?) tuple case directly via
1477
+ // Cypher MATCH … DETACH DELETE. Cypher-injection-safe (label validated
1478
+ // against /^[A-Za-z_][A-Za-z0-9_]*$/ upstream).
1479
+ if (causalGraph && typeof causalGraph.deleteEdgesByEndpoints === 'function') {
1480
+ try {
1481
+ const r = await causalGraph.deleteEdgesByEndpoints(sourceId, targetId, relation);
1482
+ const deletedCount = typeof r === 'object' && r ? (r.deleted ?? 0) : (r ? 1 : 0);
1483
+ if (deletedCount > 0) {
1484
+ await logAttestation(registry, 'delete', edgeKey, { namespace: 'causal-edges', relation, count: deletedCount });
1485
+ return { success: true, deleted: true, sourceId, targetId, controller: 'causalGraph-cypher', guarded: true };
1486
+ }
1487
+ }
1488
+ catch { /* fall through */ }
1489
+ }
1490
+ // 2. Pre-alpha.13 / different controller: try removeEdge() if exposed.
1491
+ if (causalGraph && typeof causalGraph.removeEdge === 'function') {
1492
+ try {
1493
+ await causalGraph.removeEdge(sourceId, targetId, relation);
1494
+ await logAttestation(registry, 'delete', edgeKey, { namespace: 'causal-edges', relation });
1495
+ return { success: true, deleted: true, sourceId, targetId, controller: 'causalGraph', guarded: true };
1496
+ }
1497
+ catch { /* fall through */ }
1498
+ }
1499
+ // 2. Bridge-fallback: soft-delete the memory_entries row.
1500
+ const ctx = getDb(registry);
1501
+ if (ctx) {
1502
+ try {
1503
+ const result = ctx.db.prepare(`
1504
+ UPDATE memory_entries
1505
+ SET status = 'deleted', updated_at = ?
1506
+ WHERE key = ? AND namespace = 'causal-edges' AND status = 'active'
1507
+ `).run(Date.now(), edgeKey);
1508
+ const changes = result?.changes ?? 0;
1509
+ if (changes > 0) {
1510
+ await logAttestation(registry, 'delete', edgeKey, { namespace: 'causal-edges', relation });
1511
+ return { success: true, deleted: true, sourceId, targetId, controller: 'bridge-fallback', guarded: true };
1512
+ }
1513
+ return {
1514
+ success: false, deleted: false, sourceId, targetId,
1515
+ controller: 'native-unsupported',
1516
+ error: 'graph-node native backend has no delete API; edge cannot be removed from native storage. SQL fallback found no matching row.',
1517
+ };
1518
+ }
1519
+ catch (err) {
1520
+ return { success: false, deleted: false, sourceId, targetId, controller: 'sql-error', error: err.message };
1521
+ }
1522
+ }
1523
+ return null;
1524
+ }
1525
+ catch {
1526
+ return null;
1527
+ }
1528
+ }
1529
+ /**
1530
+ * Cascade-delete a causal node and all its incident edges (#1784).
1531
+ *
1532
+ * Same constraint as bridgeDeleteCausalEdge — native graph-node lacks a
1533
+ * delete API. SQL fallback path soft-deletes the node (if stored as a
1534
+ * memory_entries row) and every edge whose key contains the nodeId.
1535
+ */
1536
+ export async function bridgeDeleteCausalNode(options) {
1537
+ const registry = await getRegistry(options.dbPath);
1538
+ if (!registry)
1539
+ return null;
1540
+ try {
1541
+ const { nodeId } = options;
1542
+ const guardResult = await guardValidate(registry, 'delete', { key: nodeId, namespace: 'causal-nodes' });
1543
+ if (!guardResult.allowed) {
1544
+ return { success: false, deletedNode: false, deletedEdges: 0, nodeId, controller: 'guard', error: `MutationGuard rejected: ${guardResult.reason}` };
1545
+ }
1546
+ // 1. agentdb@3.0.0-alpha.13+: GraphDatabaseAdapter.deleteNode(id, {cascade})
1547
+ // counts incident edges before delete so we get accurate audit numbers
1548
+ // regardless of binding stats. Cypher MATCH (n {id}) DETACH DELETE n.
1549
+ const causalGraph = registry.get('causalGraph');
1550
+ if (causalGraph && typeof causalGraph.deleteNode === 'function') {
1551
+ try {
1552
+ const r = await causalGraph.deleteNode(nodeId, { cascade: true });
1553
+ if (r && typeof r === 'object') {
1554
+ const deletedNodeNative = !!r.deletedNode;
1555
+ const deletedEdgesNative = typeof r.deletedEdges === 'number' ? r.deletedEdges : 0;
1556
+ await logAttestation(registry, 'delete', nodeId, { namespace: 'causal-nodes', deletedEdges: deletedEdgesNative });
1557
+ return {
1558
+ success: true,
1559
+ deletedNode: deletedNodeNative,
1560
+ deletedEdges: deletedEdgesNative,
1561
+ nodeId,
1562
+ controller: 'causalGraph-cypher',
1563
+ guarded: true,
1564
+ };
1565
+ }
1566
+ }
1567
+ catch { /* fall through to SQL */ }
1568
+ }
1569
+ // 2. SQL fallback: soft-delete the node row + every causal-edges row whose
1570
+ // key contains nodeId on either side. Used when agentdb pre-alpha.13 OR
1571
+ // when the entry was stored via the bridge's SQL fallback path.
1572
+ const ctx = getDb(registry);
1573
+ if (!ctx)
1574
+ return null;
1575
+ let deletedEdges = 0;
1576
+ let deletedNode = false;
1577
+ try {
1578
+ const edgeResult = ctx.db.prepare(`
1579
+ UPDATE memory_entries
1580
+ SET status = 'deleted', updated_at = ?
1581
+ WHERE namespace = 'causal-edges'
1582
+ AND status = 'active'
1583
+ AND (key LIKE ? OR key LIKE ?)
1584
+ `).run(Date.now(), `${nodeId}→%`, `%→${nodeId}`);
1585
+ deletedEdges = edgeResult?.changes ?? 0;
1586
+ const nodeResult = ctx.db.prepare(`
1587
+ UPDATE memory_entries
1588
+ SET status = 'deleted', updated_at = ?
1589
+ WHERE key = ? AND status = 'active'
1590
+ `).run(Date.now(), nodeId);
1591
+ deletedNode = (nodeResult?.changes ?? 0) > 0;
1592
+ await logAttestation(registry, 'delete', nodeId, { namespace: 'causal-nodes', deletedEdges });
1593
+ }
1594
+ catch (err) {
1595
+ return { success: false, deletedNode: false, deletedEdges: 0, nodeId, controller: 'sql-error', error: err.message };
1596
+ }
1597
+ return {
1598
+ success: true,
1599
+ deletedNode,
1600
+ deletedEdges,
1601
+ nodeId,
1602
+ controller: 'bridge-fallback',
1603
+ guarded: true,
1604
+ };
1605
+ }
1606
+ catch {
1607
+ return null;
1608
+ }
1609
+ }
1357
1610
  // ===== Phase 5: ReflexionMemory session lifecycle =====
1358
1611
  /**
1359
1612
  * Start a session with ReflexionMemory episodic replay.
@@ -13,13 +13,11 @@
13
13
  * @module @claude-flow/cli/ruvector
14
14
  */
15
15
  export { QLearningRouter, createQLearningRouter, type QLearningRouterConfig, type RouteDecision } from './q-learning-router.js';
16
- export { MoERouter, getMoERouter, resetMoERouter, createMoERouter, EXPERT_NAMES, NUM_EXPERTS, INPUT_DIM, HIDDEN_DIM, type ExpertType, type MoERouterConfig, type RoutingResult, type LoadBalanceStats, } from './moe-router.js';
17
16
  export { ASTAnalyzer, createASTAnalyzer, type ASTAnalysis, type ASTNode, type ASTAnalyzerConfig } from './ast-analyzer.js';
18
17
  export { DiffClassifier, createDiffClassifier, analyzeDiff, analyzeDiffSync, assessFileRisk, assessOverallRisk, classifyDiff, suggestReviewers, getGitDiffNumstat, getGitDiffNumstatAsync, clearDiffCache, clearAllDiffCaches, type DiffClassification, type DiffHunk, type DiffChange, type FileDiff, type DiffAnalysis, type DiffClassifierConfig, type DiffFile, type RiskLevel, type FileRisk, type OverallRisk, type DiffAnalysisResult, } from './diff-classifier.js';
19
18
  export { CoverageRouter, createCoverageRouter, coverageRoute, coverageSuggest, coverageGaps, clearCoverageCache, getCoverageCacheStats, type CoverageRouterConfig, type FileCoverage, type CoverageReport, type CoverageRouteResult, type CoverageSuggestResult, type CoverageGapsResult, type CoverageRouteOptions, type CoverageSuggestOptions, type CoverageGapsOptions, } from './coverage-router.js';
20
19
  export { coverageRouterTools, hooksCoverageRoute, hooksCoverageSuggest, hooksCoverageGaps } from './coverage-tools.js';
21
20
  export { buildDependencyGraph, analyzeGraph, analyzeMinCutBoundaries, analyzeModuleCommunities, detectCircularDependencies, exportToDot, loadRuVector, fallbackMinCut, fallbackLouvain, clearGraphCaches, getGraphCacheStats, type GraphNode, type GraphEdge, type DependencyGraph, type MinCutBoundary, type ModuleCommunity, type CircularDependency, type GraphAnalysisResult, } from './graph-analyzer.js';
22
- export { FlashAttention, getFlashAttention, resetFlashAttention, computeAttention, benchmarkFlashAttention, getFlashAttentionSpeedup, type FlashAttentionConfig, type AttentionResult, type BenchmarkResult, } from './flash-attention.js';
23
21
  export { LoRAAdapter, getLoRAAdapter, resetLoRAAdapter, createLoRAAdapter, adaptEmbedding, trainLoRA, getLoRAStats, DEFAULT_RANK, DEFAULT_ALPHA, INPUT_DIM as LORA_INPUT_DIM, OUTPUT_DIM as LORA_OUTPUT_DIM, type LoRAConfig, type LoRAWeights, type AdaptationResult, type LoRAStats, } from './lora-adapter.js';
24
22
  export { ModelRouter, getModelRouter, resetModelRouter, createModelRouter, routeToModel, routeToModelFull, analyzeTaskComplexity, getModelRouterStats, recordModelOutcome, MODEL_CAPABILITIES, COMPLEXITY_INDICATORS, type ClaudeModel, type ModelRouterConfig, type ModelRoutingResult, type ComplexityAnalysis, } from './model-router.js';
25
23
  export { SemanticRouter, createSemanticRouter, type Intent, type RouteResult, type RouterConfig, } from './semantic-router.js';
@@ -13,7 +13,10 @@
13
13
  * @module @claude-flow/cli/ruvector
14
14
  */
15
15
  export { QLearningRouter, createQLearningRouter } from './q-learning-router.js';
16
- export { MoERouter, getMoERouter, resetMoERouter, createMoERouter, EXPERT_NAMES, NUM_EXPERTS, INPUT_DIM, HIDDEN_DIM, } from './moe-router.js';
16
+ // #1773 item 4 moe-router migrated to @claude-flow/neural. Direct
17
+ // consumers (hooks-tools.ts) import from '@claude-flow/neural' explicitly;
18
+ // re-exporting through this barrel would force vitest to resolve the
19
+ // neural pkg's transitive @ruvector/sona dep eagerly. Keep imports direct.
17
20
  export { ASTAnalyzer, createASTAnalyzer } from './ast-analyzer.js';
18
21
  export { DiffClassifier, createDiffClassifier,
19
22
  // MCP tool exports
@@ -29,7 +32,10 @@ export { coverageRouterTools, hooksCoverageRoute, hooksCoverageSuggest, hooksCov
29
32
  export { buildDependencyGraph, analyzeGraph, analyzeMinCutBoundaries, analyzeModuleCommunities, detectCircularDependencies, exportToDot, loadRuVector, fallbackMinCut, fallbackLouvain,
30
33
  // Cache utilities (NEW)
31
34
  clearGraphCaches, getGraphCacheStats, } from './graph-analyzer.js';
32
- export { FlashAttention, getFlashAttention, resetFlashAttention, computeAttention, benchmarkFlashAttention, getFlashAttentionSpeedup, } from './flash-attention.js';
35
+ // #1773 item 4 flash-attention migrated to @claude-flow/neural. Direct
36
+ // consumers (hooks-tools.ts, neural-tools.ts) import from '@claude-flow/neural'
37
+ // explicitly; re-exporting through this barrel pulls the package's
38
+ // transitive @ruvector/sona dep into vitest's eager resolution.
33
39
  export { LoRAAdapter, getLoRAAdapter, resetLoRAAdapter, createLoRAAdapter, adaptEmbedding, trainLoRA, getLoRAStats, DEFAULT_RANK, DEFAULT_ALPHA, INPUT_DIM as LORA_INPUT_DIM, OUTPUT_DIM as LORA_OUTPUT_DIM, } from './lora-adapter.js';
34
40
  export { ModelRouter, getModelRouter, resetModelRouter, createModelRouter, routeToModel, routeToModelFull, analyzeTaskComplexity, getModelRouterStats, recordModelOutcome, MODEL_CAPABILITIES, COMPLEXITY_INDICATORS, } from './model-router.js';
35
41
  export { SemanticRouter, createSemanticRouter, } from './semantic-router.js';
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@claude-flow/cli",
3
- "version": "3.7.0-alpha.6",
3
+ "version": "3.7.0-alpha.8",
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",
@@ -97,7 +97,7 @@
97
97
  "dependencies": {
98
98
  "@claude-flow/cli-core": "^3.7.0-alpha.5",
99
99
  "@claude-flow/mcp": "^3.0.0-alpha.8",
100
- "@claude-flow/neural": "^3.0.0-alpha.7",
100
+ "@claude-flow/neural": "^3.0.0-alpha.8",
101
101
  "@claude-flow/shared": "^3.0.0-alpha.7",
102
102
  "@noble/ed25519": "^2.1.0",
103
103
  "@ruvector/rabitq-wasm": "^0.1.0",
@@ -119,7 +119,7 @@
119
119
  "@ruvector/ruvllm-wasm": "^2.0.2",
120
120
  "@ruvector/rvagent-wasm": "^0.1.0",
121
121
  "@ruvector/sona": "^0.1.5",
122
- "agentdb": "^3.0.0-alpha.11",
122
+ "agentdb": "^3.0.0-alpha.13",
123
123
  "agentic-flow": "^3.0.0-alpha.1"
124
124
  },
125
125
  "publishConfig": {