claude-flow 3.5.64 → 3.5.65

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.
@@ -508,5 +508,231 @@ export const memoryTools = [
508
508
  };
509
509
  },
510
510
  },
511
+ // ===== Claude Code Memory Bridge Tools =====
512
+ {
513
+ name: 'memory_import_claude',
514
+ description: 'Import Claude Code auto-memory files into AgentDB with ONNX vector embeddings. Reads ~/.claude/projects/*/memory/*.md files, parses YAML frontmatter, splits into sections, and stores with 384-dim embeddings for semantic search. Use allProjects=true to import from ALL Claude projects.',
515
+ category: 'memory',
516
+ inputSchema: {
517
+ type: 'object',
518
+ properties: {
519
+ allProjects: { type: 'boolean', description: 'Import from all Claude projects (default: current project only)' },
520
+ namespace: { type: 'string', description: 'Target namespace (default: "claude-memories")' },
521
+ },
522
+ },
523
+ handler: async (input) => {
524
+ await ensureInitialized();
525
+ const { storeEntry } = await getMemoryFunctions();
526
+ const { homedir } = await import('os');
527
+ const ns = input.namespace || 'claude-memories';
528
+ const allProjects = input.allProjects;
529
+ const claudeProjectsDir = join(homedir(), '.claude', 'projects');
530
+ // Find memory files
531
+ const memoryFiles = [];
532
+ if (allProjects) {
533
+ // Scan all projects
534
+ if (existsSync(claudeProjectsDir)) {
535
+ try {
536
+ const projects = readFileSync; // just need fs methods already imported
537
+ const { readdirSync: readDir } = await import('fs');
538
+ for (const project of readDir(claudeProjectsDir, { withFileTypes: true })) {
539
+ if (!project.isDirectory())
540
+ continue;
541
+ const memDir = join(claudeProjectsDir, project.name, 'memory');
542
+ if (!existsSync(memDir))
543
+ continue;
544
+ for (const file of readDir(memDir).filter((f) => f.endsWith('.md'))) {
545
+ memoryFiles.push({ path: join(memDir, file), project: project.name, file });
546
+ }
547
+ }
548
+ }
549
+ catch { /* scan error */ }
550
+ }
551
+ }
552
+ else {
553
+ // Current project only — find by CWD hash
554
+ const cwd = process.cwd();
555
+ const projectHash = cwd.replace(/\//g, '-');
556
+ const memDir = join(claudeProjectsDir, projectHash, 'memory');
557
+ if (existsSync(memDir)) {
558
+ try {
559
+ const { readdirSync: readDir } = await import('fs');
560
+ for (const file of readDir(memDir).filter((f) => f.endsWith('.md'))) {
561
+ memoryFiles.push({ path: join(memDir, file), project: projectHash, file });
562
+ }
563
+ }
564
+ catch { /* scan error */ }
565
+ }
566
+ }
567
+ if (memoryFiles.length === 0) {
568
+ return { success: true, imported: 0, message: 'No Claude memory files found' };
569
+ }
570
+ let imported = 0;
571
+ let skipped = 0;
572
+ const projects = new Set();
573
+ for (const memFile of memoryFiles) {
574
+ projects.add(memFile.project);
575
+ try {
576
+ const content = readFileSync(memFile.path, 'utf-8');
577
+ const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
578
+ let name = memFile.file.replace('.md', '');
579
+ let body = content;
580
+ if (frontmatterMatch) {
581
+ const yaml = frontmatterMatch[1];
582
+ body = frontmatterMatch[2].trim();
583
+ const nameMatch = yaml.match(/^name:\s*(.+)$/m);
584
+ if (nameMatch)
585
+ name = nameMatch[1].trim();
586
+ }
587
+ // Split into sections for granular search
588
+ const sections = body.split(/^(?=## )/m).filter(s => s.trim().length > 20);
589
+ if (sections.length === 0 && body.length > 10) {
590
+ await storeEntry({ key: `claude:${memFile.project}:${name}`, value: body.slice(0, 4096), namespace: ns, generateEmbeddingFlag: true });
591
+ imported++;
592
+ }
593
+ else {
594
+ for (const section of sections) {
595
+ const titleMatch = section.match(/^##\s+(.+)/);
596
+ const sectionTitle = titleMatch ? titleMatch[1].trim() : name;
597
+ const sectionBody = section.replace(/^##\s+.+\n/, '').trim();
598
+ if (sectionBody.length < 10)
599
+ continue;
600
+ await storeEntry({ key: `claude:${memFile.project}:${name}:${sectionTitle.slice(0, 50)}`, value: sectionBody.slice(0, 4096), namespace: ns, generateEmbeddingFlag: true });
601
+ imported++;
602
+ }
603
+ }
604
+ }
605
+ catch {
606
+ skipped++;
607
+ }
608
+ }
609
+ return {
610
+ success: true,
611
+ imported,
612
+ skipped,
613
+ files: memoryFiles.length,
614
+ projects: projects.size,
615
+ namespace: ns,
616
+ embedding: 'ONNX all-MiniLM-L6-v2 (384-dim)',
617
+ };
618
+ },
619
+ },
620
+ {
621
+ name: 'memory_bridge_status',
622
+ description: 'Show Claude Code memory bridge status — AgentDB vectors, SONA learning, intelligence patterns, and connection health.',
623
+ category: 'memory',
624
+ inputSchema: { type: 'object', properties: {} },
625
+ handler: async () => {
626
+ await ensureInitialized();
627
+ const { homedir } = await import('os');
628
+ // Count Claude memory files
629
+ const claudeProjectsDir = join(homedir(), '.claude', 'projects');
630
+ let claudeFiles = 0;
631
+ let claudeProjects = 0;
632
+ if (existsSync(claudeProjectsDir)) {
633
+ try {
634
+ const { readdirSync: readDir } = await import('fs');
635
+ for (const project of readDir(claudeProjectsDir, { withFileTypes: true })) {
636
+ if (!project.isDirectory())
637
+ continue;
638
+ const memDir = join(claudeProjectsDir, project.name, 'memory');
639
+ if (!existsSync(memDir))
640
+ continue;
641
+ const files = readDir(memDir).filter((f) => f.endsWith('.md'));
642
+ if (files.length > 0) {
643
+ claudeProjects++;
644
+ claudeFiles += files.length;
645
+ }
646
+ }
647
+ }
648
+ catch { /* ignore */ }
649
+ }
650
+ // AgentDB status
651
+ let agentdbEntries = 0;
652
+ let claudeMemoryEntries = 0;
653
+ try {
654
+ const { listEntries } = await getMemoryFunctions();
655
+ const allEntries = await listEntries({});
656
+ agentdbEntries = allEntries?.entries?.length ?? 0;
657
+ const claudeEntries = await listEntries({ namespace: 'claude-memories' });
658
+ claudeMemoryEntries = claudeEntries?.entries?.length ?? 0;
659
+ }
660
+ catch { /* ignore */ }
661
+ // Intelligence status
662
+ let intelligence = { sonaEnabled: false, patternsLearned: 0, trajectoriesRecorded: 0 };
663
+ try {
664
+ const int = await import('../memory/intelligence.js');
665
+ const stats = int.getIntelligenceStats?.();
666
+ if (stats)
667
+ intelligence = { sonaEnabled: stats.sonaEnabled, patternsLearned: stats.patternsLearned, trajectoriesRecorded: stats.trajectoriesRecorded };
668
+ }
669
+ catch { /* not initialized */ }
670
+ return {
671
+ claudeCode: { memoryFiles: claudeFiles, projects: claudeProjects },
672
+ agentdb: { totalEntries: agentdbEntries, claudeMemoryEntries, backend: 'sql.js + ONNX' },
673
+ intelligence,
674
+ bridge: { status: claudeMemoryEntries > 0 ? 'connected' : 'not-synced', embedding: 'all-MiniLM-L6-v2 (384-dim)' },
675
+ };
676
+ },
677
+ },
678
+ {
679
+ name: 'memory_search_unified',
680
+ description: 'Search across both Claude Code memories and AgentDB entries using semantic vector similarity. Returns merged, deduplicated results from all namespaces.',
681
+ category: 'memory',
682
+ inputSchema: {
683
+ type: 'object',
684
+ properties: {
685
+ query: { type: 'string', description: 'Search query (natural language)' },
686
+ limit: { type: 'number', description: 'Max results (default: 10)' },
687
+ namespace: { type: 'string', description: 'Filter to namespace (omit for all)' },
688
+ },
689
+ required: ['query'],
690
+ },
691
+ handler: async (input) => {
692
+ await ensureInitialized();
693
+ const { searchEntries } = await getMemoryFunctions();
694
+ validateMemoryInput(undefined, undefined, input.query);
695
+ const query = input.query;
696
+ const limit = input.limit || 10;
697
+ const ns = input.namespace;
698
+ // Search all namespaces unless filtered
699
+ const namespaces = ns ? [ns] : ['default', 'claude-memories', 'auto-memory', 'patterns', 'tasks', 'feedback'];
700
+ const allResults = [];
701
+ for (const searchNs of namespaces) {
702
+ try {
703
+ const r = await searchEntries({ query, namespace: searchNs, limit: limit * 2 });
704
+ if (r?.results) {
705
+ for (const entry of r.results) {
706
+ allResults.push({
707
+ key: entry.key || entry.id || '',
708
+ content: (entry.content || entry.value || '').toString().slice(0, 200),
709
+ score: entry.score || 0,
710
+ namespace: searchNs,
711
+ source: searchNs === 'claude-memories' ? 'claude-code' : searchNs === 'auto-memory' ? 'auto-memory' : 'agentdb',
712
+ });
713
+ }
714
+ }
715
+ }
716
+ catch { /* namespace may not exist */ }
717
+ }
718
+ // Sort by score, deduplicate by key, take top N
719
+ allResults.sort((a, b) => b.score - a.score);
720
+ const seen = new Set();
721
+ const deduplicated = allResults.filter(r => {
722
+ if (seen.has(r.key))
723
+ return false;
724
+ seen.add(r.key);
725
+ return true;
726
+ }).slice(0, limit);
727
+ return {
728
+ success: true,
729
+ query,
730
+ results: deduplicated,
731
+ total: deduplicated.length,
732
+ searchedNamespaces: namespaces,
733
+ searchTime: Date.now(),
734
+ };
735
+ },
736
+ },
511
737
  ];
512
738
  //# sourceMappingURL=memory-tools.js.map
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@claude-flow/cli",
3
- "version": "3.5.64",
3
+ "version": "3.5.65",
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",