claude-flow-novice 2.18.2 → 2.18.3

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.
Files changed (106) hide show
  1. package/README.md +106 -712
  2. package/claude-assets/agents/AGENT_LIFECYCLE.md +2 -0
  3. package/claude-assets/agents/SHARED_PROTOCOL.md +64 -0
  4. package/claude-assets/agents/cfn-dev-team/analysts/analyst.md +2 -0
  5. package/claude-assets/agents/cfn-dev-team/analysts/root-cause-analyst.md +2 -0
  6. package/claude-assets/agents/cfn-dev-team/architecture/api-designer-persona.md +2 -0
  7. package/claude-assets/agents/cfn-dev-team/architecture/base-template-generator.md +2 -0
  8. package/claude-assets/agents/cfn-dev-team/architecture/goal-planner.md +2 -0
  9. package/claude-assets/agents/cfn-dev-team/architecture/planner.md +2 -0
  10. package/claude-assets/agents/cfn-dev-team/architecture/system-architect.md +2 -0
  11. package/claude-assets/agents/cfn-dev-team/coordinators/cfn-frontend-coordinator.md +2 -0
  12. package/claude-assets/agents/cfn-dev-team/coordinators/consensus-builder.md +2 -0
  13. package/claude-assets/agents/cfn-dev-team/coordinators/handoff-coordinator.md +2 -0
  14. package/claude-assets/agents/cfn-dev-team/coordinators/multi-sprint-coordinator.md +2 -0
  15. package/claude-assets/agents/cfn-dev-team/dev-ops/devops-engineer.md +2 -0
  16. package/claude-assets/agents/cfn-dev-team/dev-ops/docker-specialist.md +2 -0
  17. package/claude-assets/agents/cfn-dev-team/dev-ops/github-commit-agent.md +2 -0
  18. package/claude-assets/agents/cfn-dev-team/dev-ops/kubernetes-specialist.md +2 -0
  19. package/claude-assets/agents/cfn-dev-team/developers/api-gateway-specialist.md +2 -0
  20. package/claude-assets/agents/cfn-dev-team/developers/backend-developer.md +2 -0
  21. package/claude-assets/agents/cfn-dev-team/developers/data/data-engineer.md +2 -0
  22. package/claude-assets/agents/cfn-dev-team/developers/database/database-architect.md +2 -0
  23. package/claude-assets/agents/cfn-dev-team/developers/database/supabase-specialist.md +2 -0
  24. package/claude-assets/agents/cfn-dev-team/developers/frontend/mobile-dev.md +2 -0
  25. package/claude-assets/agents/cfn-dev-team/developers/frontend/react-frontend-engineer.md +2 -0
  26. package/claude-assets/agents/cfn-dev-team/developers/frontend/typescript-specialist.md +2 -0
  27. package/claude-assets/agents/cfn-dev-team/developers/frontend/ui-designer.md +2 -0
  28. package/claude-assets/agents/cfn-dev-team/developers/graphql-specialist.md +2 -0
  29. package/claude-assets/agents/cfn-dev-team/developers/rust-developer.md +2 -0
  30. package/claude-assets/agents/cfn-dev-team/documentation/agent-type-guidelines.md +2 -0
  31. package/claude-assets/agents/cfn-dev-team/documentation/api-documentation.md +2 -0
  32. package/claude-assets/agents/cfn-dev-team/documentation/pseudocode.md +2 -0
  33. package/claude-assets/agents/cfn-dev-team/documentation/specification-agent.md +2 -0
  34. package/claude-assets/agents/cfn-dev-team/product-owners/accessibility-advocate-persona.md +2 -0
  35. package/claude-assets/agents/cfn-dev-team/product-owners/cto-agent.md +2 -0
  36. package/claude-assets/agents/cfn-dev-team/product-owners/power-user-persona.md +2 -0
  37. package/claude-assets/agents/cfn-dev-team/product-owners/product-owner.md +2 -0
  38. package/claude-assets/agents/cfn-dev-team/reviewers/code-reviewer.md +2 -0
  39. package/claude-assets/agents/cfn-dev-team/reviewers/quality/code-quality-validator.md +2 -0
  40. package/claude-assets/agents/cfn-dev-team/reviewers/quality/cyclomatic-complexity-reducer.md +2 -0
  41. package/claude-assets/agents/cfn-dev-team/reviewers/quality/perf-analyzer.md +2 -0
  42. package/claude-assets/agents/cfn-dev-team/reviewers/quality/performance-benchmarker.md +2 -0
  43. package/claude-assets/agents/cfn-dev-team/reviewers/quality/quality-metrics.md +2 -0
  44. package/claude-assets/agents/cfn-dev-team/reviewers/quality/security-specialist.md +2 -0
  45. package/claude-assets/agents/cfn-dev-team/testers/api-testing-specialist.md +2 -0
  46. package/claude-assets/agents/cfn-dev-team/testers/chaos-engineering-specialist.md +2 -0
  47. package/claude-assets/agents/cfn-dev-team/testers/contract-tester.md +2 -0
  48. package/claude-assets/agents/cfn-dev-team/testers/e2e/playwright-tester.md +2 -0
  49. package/claude-assets/agents/cfn-dev-team/testers/integration-tester.md +2 -0
  50. package/claude-assets/agents/cfn-dev-team/testers/interaction-tester.md +2 -0
  51. package/claude-assets/agents/cfn-dev-team/testers/load-testing-specialist.md +2 -0
  52. package/claude-assets/agents/cfn-dev-team/testers/mutation-testing-specialist.md +2 -0
  53. package/claude-assets/agents/cfn-dev-team/testers/playwright-tester.md +2 -0
  54. package/claude-assets/agents/cfn-dev-team/testers/tester.md +2 -0
  55. package/claude-assets/agents/cfn-dev-team/testers/unit/tdd-london-unit-swarm.md +2 -0
  56. package/claude-assets/agents/cfn-dev-team/testers/validation/validation-production-validator.md +2 -0
  57. package/claude-assets/agents/cfn-dev-team/testing/test-validation-agent.md +2 -0
  58. package/claude-assets/agents/cfn-dev-team/utility/agent-builder.md +39 -16
  59. package/claude-assets/agents/cfn-dev-team/utility/context-curator.md +2 -0
  60. package/claude-assets/agents/cfn-dev-team/utility/epic-creator.md +2 -0
  61. package/claude-assets/agents/cfn-dev-team/utility/memory-leak-specialist.md +2 -0
  62. package/claude-assets/agents/cfn-dev-team/utility/researcher.md +2 -0
  63. package/claude-assets/agents/cfn-dev-team/utility/z-ai-specialist.md +2 -0
  64. package/claude-assets/agents/custom/cfn-docker-expert.md +2 -0
  65. package/claude-assets/agents/custom/cfn-loops-cli-expert.md +2 -0
  66. package/claude-assets/agents/custom/cfn-redis-operations.md +2 -0
  67. package/claude-assets/agents/custom/cfn-system-expert.md +2 -0
  68. package/claude-assets/agents/custom/claude-code-expert.md +2 -0
  69. package/claude-assets/agents/custom/mdap-trigger-specialist.md +2 -0
  70. package/claude-assets/agents/custom/trigger-dev-expert.md +2 -0
  71. package/claude-assets/agents/docker-coordinators/cfn-docker-v3-coordinator.md +2 -0
  72. package/claude-assets/agents/docker-ts-fixer.md +2 -0
  73. package/claude-assets/agents/project-only-agents/npm-package-specialist.md +2 -0
  74. package/claude-assets/skills/cfn-cerebras-mcp/SKILL.md +58 -0
  75. package/claude-assets/skills/cfn-ruvector-codebase-index/.cfn-manifest.json +37 -0
  76. package/claude-assets/skills/cfn-ruvector-codebase-index/check-db.js +8 -0
  77. package/claude-assets/skills/cfn-ruvector-codebase-index/config.json +1 -1
  78. package/claude-assets/skills/cfn-ruvector-codebase-index/data/codebase_index.db +0 -0
  79. package/claude-assets/skills/cfn-ruvector-codebase-index/debug-search.js +19 -0
  80. package/claude-assets/skills/cfn-ruvector-codebase-index/get-embedding-text.js +26 -0
  81. package/claude-assets/skills/cfn-ruvector-codebase-index/index.sh +22 -11
  82. package/claude-assets/skills/cfn-ruvector-codebase-index/search.js +55 -0
  83. package/claude-assets/skills/cfn-ruvector-codebase-index/search.sh +32 -36
  84. package/claude-assets/skills/cfn-ruvector-codebase-index/standalone-indexer.js +129 -0
  85. package/dist/agents/agent-loader.js +165 -146
  86. package/dist/agents/agent-loader.js.map +1 -1
  87. package/dist/index.js +1 -0
  88. package/dist/index.js.map +1 -1
  89. package/dist/ruvector/cli.js +62 -0
  90. package/dist/ruvector/cli.js.map +1 -0
  91. package/dist/ruvector/core/file-processor.js +72 -0
  92. package/dist/ruvector/core/file-processor.js.map +1 -0
  93. package/dist/ruvector/core/index.js +133 -0
  94. package/dist/ruvector/core/index.js.map +1 -0
  95. package/dist/ruvector/embeddings/index.js +24 -0
  96. package/dist/ruvector/embeddings/index.js.map +1 -0
  97. package/dist/ruvector/embeddings/openai.js +67 -0
  98. package/dist/ruvector/embeddings/openai.js.map +1 -0
  99. package/dist/ruvector/embeddings/provider.js +12 -0
  100. package/dist/ruvector/embeddings/provider.js.map +1 -0
  101. package/dist/ruvector/index.js +9 -0
  102. package/dist/ruvector/index.js.map +1 -0
  103. package/package.json +13 -5
  104. package/readme/README.md +25 -15
  105. package/scripts/update-agent-protocols.sh +116 -0
  106. package/LICENSE +0 -21
@@ -0,0 +1,62 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * CFN RuVector CLI - Semantic codebase search
4
+ */ import { Command } from 'commander';
5
+ import { RuVectorIndex } from './core/index.js';
6
+ const program = new Command();
7
+ program.name('cfn-ruvector').description('Semantic codebase search using vector embeddings').version('1.0.0');
8
+ program.command('index').description('Index the codebase').argument('[directory]', 'Directory to index', '.').option('-v, --verbose', 'Verbose output').action(async (directory, options)=>{
9
+ try {
10
+ const index = new RuVectorIndex({
11
+ verbose: options.verbose
12
+ });
13
+ console.log(`Indexing ${directory}...`);
14
+ const stats = await index.indexDirectory(directory);
15
+ console.log(`\nDone: ${stats.indexedFiles}/${stats.totalFiles} indexed, ${stats.failedFiles} failed`);
16
+ } catch (error) {
17
+ console.error('Error:', error.message);
18
+ process.exit(1);
19
+ }
20
+ });
21
+ program.command('search').description('Search the codebase').argument('<query>', 'Search query').option('-n, --limit <n>', 'Number of results', '10').action(async (query, options)=>{
22
+ try {
23
+ const index = new RuVectorIndex();
24
+ const limit = parseInt(options.limit ?? '10', 10);
25
+ const results = await index.search(query, {
26
+ limit
27
+ });
28
+ if (results.length === 0) {
29
+ console.log('No results found.');
30
+ return;
31
+ }
32
+ console.log(`\nResults for: "${query}"\n`);
33
+ for (const r of results){
34
+ console.log(`[${(r.score * 100).toFixed(1)}%] ${r.path}`);
35
+ }
36
+ } catch (error) {
37
+ console.error('Error:', error.message);
38
+ process.exit(1);
39
+ }
40
+ });
41
+ program.command('status').description('Show index stats').action(async ()=>{
42
+ try {
43
+ const index = new RuVectorIndex();
44
+ const stats = await index.getStats();
45
+ console.log(`Indexed files: ${stats.indexedFiles}`);
46
+ } catch (error) {
47
+ console.error('Error:', error.message);
48
+ process.exit(1);
49
+ }
50
+ });
51
+ program.command('clear').description('Clear the index').option('-f, --force', 'Force clear').action(async (options)=>{
52
+ if (!options.force) {
53
+ console.log('Use --force to confirm.');
54
+ process.exit(1);
55
+ }
56
+ const index = new RuVectorIndex();
57
+ await index.clear();
58
+ console.log('Index cleared.');
59
+ });
60
+ program.parse();
61
+
62
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/ruvector/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * CFN RuVector CLI - Semantic codebase search\n */\n\nimport { Command } from 'commander';\nimport { RuVectorIndex } from './core/index.js';\n\nconst program = new Command();\n\nprogram\n .name('cfn-ruvector')\n .description('Semantic codebase search using vector embeddings')\n .version('1.0.0');\n\nprogram\n .command('index')\n .description('Index the codebase')\n .argument('[directory]', 'Directory to index', '.')\n .option('-v, --verbose', 'Verbose output')\n .action(async (directory: string, options: { verbose?: boolean }) => {\n try {\n const index = new RuVectorIndex({ verbose: options.verbose });\n console.log(`Indexing ${directory}...`);\n const stats = await index.indexDirectory(directory);\n console.log(`\\nDone: ${stats.indexedFiles}/${stats.totalFiles} indexed, ${stats.failedFiles} failed`);\n } catch (error) {\n console.error('Error:', (error as Error).message);\n process.exit(1);\n }\n });\n\nprogram\n .command('search')\n .description('Search the codebase')\n .argument('<query>', 'Search query')\n .option('-n, --limit <n>', 'Number of results', '10')\n .action(async (query: string, options: { limit?: string }) => {\n try {\n const index = new RuVectorIndex();\n const limit = parseInt(options.limit ?? '10', 10);\n const results = await index.search(query, { limit });\n \n if (results.length === 0) {\n console.log('No results found.');\n return;\n }\n \n console.log(`\\nResults for: \"${query}\"\\n`);\n for (const r of results) {\n console.log(`[${(r.score * 100).toFixed(1)}%] ${r.path}`);\n }\n } catch (error) {\n console.error('Error:', (error as Error).message);\n process.exit(1);\n }\n });\n\nprogram\n .command('status')\n .description('Show index stats')\n .action(async () => {\n try {\n const index = new RuVectorIndex();\n const stats = await index.getStats();\n console.log(`Indexed files: ${stats.indexedFiles}`);\n } catch (error) {\n console.error('Error:', (error as Error).message);\n process.exit(1);\n }\n });\n\nprogram\n .command('clear')\n .description('Clear the index')\n .option('-f, --force', 'Force clear')\n .action(async (options: { force?: boolean }) => {\n if (!options.force) {\n console.log('Use --force to confirm.');\n process.exit(1);\n }\n const index = new RuVectorIndex();\n await index.clear();\n console.log('Index cleared.');\n });\n\nprogram.parse();"],"names":["Command","RuVectorIndex","program","name","description","version","command","argument","option","action","directory","options","index","verbose","console","log","stats","indexDirectory","indexedFiles","totalFiles","failedFiles","error","message","process","exit","query","limit","parseInt","results","search","length","r","score","toFixed","path","getStats","force","clear","parse"],"mappings":";AACA;;CAEC,GAED,SAASA,OAAO,QAAQ,YAAY;AACpC,SAASC,aAAa,QAAQ,kBAAkB;AAEhD,MAAMC,UAAU,IAAIF;AAEpBE,QACGC,IAAI,CAAC,gBACLC,WAAW,CAAC,oDACZC,OAAO,CAAC;AAEXH,QACGI,OAAO,CAAC,SACRF,WAAW,CAAC,sBACZG,QAAQ,CAAC,eAAe,sBAAsB,KAC9CC,MAAM,CAAC,iBAAiB,kBACxBC,MAAM,CAAC,OAAOC,WAAmBC;IAChC,IAAI;QACF,MAAMC,QAAQ,IAAIX,cAAc;YAAEY,SAASF,QAAQE,OAAO;QAAC;QAC3DC,QAAQC,GAAG,CAAC,CAAC,SAAS,EAAEL,UAAU,GAAG,CAAC;QACtC,MAAMM,QAAQ,MAAMJ,MAAMK,cAAc,CAACP;QACzCI,QAAQC,GAAG,CAAC,CAAC,QAAQ,EAAEC,MAAME,YAAY,CAAC,CAAC,EAAEF,MAAMG,UAAU,CAAC,UAAU,EAAEH,MAAMI,WAAW,CAAC,OAAO,CAAC;IACtG,EAAE,OAAOC,OAAO;QACdP,QAAQO,KAAK,CAAC,UAAU,AAACA,MAAgBC,OAAO;QAChDC,QAAQC,IAAI,CAAC;IACf;AACF;AAEFtB,QACGI,OAAO,CAAC,UACRF,WAAW,CAAC,uBACZG,QAAQ,CAAC,WAAW,gBACpBC,MAAM,CAAC,mBAAmB,qBAAqB,MAC/CC,MAAM,CAAC,OAAOgB,OAAed;IAC5B,IAAI;QACF,MAAMC,QAAQ,IAAIX;QAClB,MAAMyB,QAAQC,SAAShB,QAAQe,KAAK,IAAI,MAAM;QAC9C,MAAME,UAAU,MAAMhB,MAAMiB,MAAM,CAACJ,OAAO;YAAEC;QAAM;QAElD,IAAIE,QAAQE,MAAM,KAAK,GAAG;YACxBhB,QAAQC,GAAG,CAAC;YACZ;QACF;QAEAD,QAAQC,GAAG,CAAC,CAAC,gBAAgB,EAAEU,MAAM,GAAG,CAAC;QACzC,KAAK,MAAMM,KAAKH,QAAS;YACvBd,QAAQC,GAAG,CAAC,CAAC,CAAC,EAAE,AAACgB,CAAAA,EAAEC,KAAK,GAAG,GAAE,EAAGC,OAAO,CAAC,GAAG,IAAI,EAAEF,EAAEG,IAAI,EAAE;QAC3D;IACF,EAAE,OAAOb,OAAO;QACdP,QAAQO,KAAK,CAAC,UAAU,AAACA,MAAgBC,OAAO;QAChDC,QAAQC,IAAI,CAAC;IACf;AACF;AAEFtB,QACGI,OAAO,CAAC,UACRF,WAAW,CAAC,oBACZK,MAAM,CAAC;IACN,IAAI;QACF,MAAMG,QAAQ,IAAIX;QAClB,MAAMe,QAAQ,MAAMJ,MAAMuB,QAAQ;QAClCrB,QAAQC,GAAG,CAAC,CAAC,eAAe,EAAEC,MAAME,YAAY,EAAE;IACpD,EAAE,OAAOG,OAAO;QACdP,QAAQO,KAAK,CAAC,UAAU,AAACA,MAAgBC,OAAO;QAChDC,QAAQC,IAAI,CAAC;IACf;AACF;AAEFtB,QACGI,OAAO,CAAC,SACRF,WAAW,CAAC,mBACZI,MAAM,CAAC,eAAe,eACtBC,MAAM,CAAC,OAAOE;IACb,IAAI,CAACA,QAAQyB,KAAK,EAAE;QAClBtB,QAAQC,GAAG,CAAC;QACZQ,QAAQC,IAAI,CAAC;IACf;IACA,MAAMZ,QAAQ,IAAIX;IAClB,MAAMW,MAAMyB,KAAK;IACjBvB,QAAQC,GAAG,CAAC;AACd;AAEFb,QAAQoC,KAAK"}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * File Processor - Extracts indexable text from source files
3
+ */ import * as fs from 'fs/promises';
4
+ import * as path from 'path';
5
+ const LANGUAGE_MAP = {
6
+ '.ts': 'typescript',
7
+ '.tsx': 'typescript',
8
+ '.js': 'javascript',
9
+ '.jsx': 'javascript',
10
+ '.mjs': 'javascript',
11
+ '.py': 'python',
12
+ '.rb': 'ruby',
13
+ '.go': 'go',
14
+ '.rs': 'rust',
15
+ '.java': 'java',
16
+ '.kt': 'kotlin',
17
+ '.swift': 'swift',
18
+ '.c': 'c',
19
+ '.cpp': 'cpp',
20
+ '.h': 'c',
21
+ '.hpp': 'cpp',
22
+ '.cs': 'csharp',
23
+ '.php': 'php',
24
+ '.md': 'markdown',
25
+ '.mdx': 'markdown',
26
+ '.json': 'json',
27
+ '.yaml': 'yaml',
28
+ '.yml': 'yaml',
29
+ '.html': 'html',
30
+ '.css': 'css',
31
+ '.scss': 'scss',
32
+ '.sql': 'sql',
33
+ '.sh': 'shell',
34
+ '.bash': 'shell'
35
+ };
36
+ export class SourceFileProcessor {
37
+ maxFileSize;
38
+ constructor(maxFileSize = 100 * 1024){
39
+ this.maxFileSize = maxFileSize;
40
+ }
41
+ canProcess(filePath) {
42
+ const ext = path.extname(filePath).toLowerCase();
43
+ return ext in LANGUAGE_MAP;
44
+ }
45
+ async process(filePath) {
46
+ try {
47
+ const stats = await fs.stat(filePath);
48
+ if (stats.size > this.maxFileSize || !stats.isFile()) return null;
49
+ const content = await fs.readFile(filePath, 'utf-8');
50
+ const ext = path.extname(filePath).toLowerCase();
51
+ const language = LANGUAGE_MAP[ext] ?? 'unknown';
52
+ let processed = content.replace(/\n{3,}/g, '\n\n');
53
+ const maxChars = 8000;
54
+ if (processed.length > maxChars) {
55
+ processed = processed.slice(0, maxChars) + '\n[truncated]';
56
+ }
57
+ return {
58
+ path: filePath,
59
+ content: processed.trim(),
60
+ language,
61
+ size: stats.size
62
+ };
63
+ } catch {
64
+ return null;
65
+ }
66
+ }
67
+ }
68
+ export function createFileProcessor(maxFileSize) {
69
+ return new SourceFileProcessor(maxFileSize);
70
+ }
71
+
72
+ //# sourceMappingURL=file-processor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/ruvector/core/file-processor.ts"],"sourcesContent":["/**\n * File Processor - Extracts indexable text from source files\n */\n\nimport * as fs from 'fs/promises';\nimport * as path from 'path';\n\nexport interface ProcessedFile {\n path: string;\n content: string;\n language: string;\n size: number;\n}\n\nexport interface FileProcessor {\n process(filePath: string): Promise<ProcessedFile | null>;\n canProcess(filePath: string): boolean;\n}\n\nconst LANGUAGE_MAP: Record<string, string> = {\n '.ts': 'typescript', '.tsx': 'typescript',\n '.js': 'javascript', '.jsx': 'javascript', '.mjs': 'javascript',\n '.py': 'python', '.rb': 'ruby', '.go': 'go', '.rs': 'rust',\n '.java': 'java', '.kt': 'kotlin', '.swift': 'swift',\n '.c': 'c', '.cpp': 'cpp', '.h': 'c', '.hpp': 'cpp',\n '.cs': 'csharp', '.php': 'php',\n '.md': 'markdown', '.mdx': 'markdown',\n '.json': 'json', '.yaml': 'yaml', '.yml': 'yaml',\n '.html': 'html', '.css': 'css', '.scss': 'scss',\n '.sql': 'sql', '.sh': 'shell', '.bash': 'shell',\n};\n\nexport class SourceFileProcessor implements FileProcessor {\n private maxFileSize: number;\n \n constructor(maxFileSize: number = 100 * 1024) {\n this.maxFileSize = maxFileSize;\n }\n \n canProcess(filePath: string): boolean {\n const ext = path.extname(filePath).toLowerCase();\n return ext in LANGUAGE_MAP;\n }\n \n async process(filePath: string): Promise<ProcessedFile | null> {\n try {\n const stats = await fs.stat(filePath);\n if (stats.size > this.maxFileSize || !stats.isFile()) return null;\n \n const content = await fs.readFile(filePath, 'utf-8');\n const ext = path.extname(filePath).toLowerCase();\n const language = LANGUAGE_MAP[ext] ?? 'unknown';\n \n let processed = content.replace(/\\n{3,}/g, '\\n\\n');\n const maxChars = 8000;\n if (processed.length > maxChars) {\n processed = processed.slice(0, maxChars) + '\\n[truncated]';\n }\n \n return { path: filePath, content: processed.trim(), language, size: stats.size };\n } catch {\n return null;\n }\n }\n}\n\nexport function createFileProcessor(maxFileSize?: number): FileProcessor {\n return new SourceFileProcessor(maxFileSize);\n}"],"names":["fs","path","LANGUAGE_MAP","SourceFileProcessor","maxFileSize","canProcess","filePath","ext","extname","toLowerCase","process","stats","stat","size","isFile","content","readFile","language","processed","replace","maxChars","length","slice","trim","createFileProcessor"],"mappings":"AAAA;;CAEC,GAED,YAAYA,QAAQ,cAAc;AAClC,YAAYC,UAAU,OAAO;AAc7B,MAAMC,eAAuC;IAC3C,OAAO;IAAc,QAAQ;IAC7B,OAAO;IAAc,QAAQ;IAAc,QAAQ;IACnD,OAAO;IAAU,OAAO;IAAQ,OAAO;IAAM,OAAO;IACpD,SAAS;IAAQ,OAAO;IAAU,UAAU;IAC5C,MAAM;IAAK,QAAQ;IAAO,MAAM;IAAK,QAAQ;IAC7C,OAAO;IAAU,QAAQ;IACzB,OAAO;IAAY,QAAQ;IAC3B,SAAS;IAAQ,SAAS;IAAQ,QAAQ;IAC1C,SAAS;IAAQ,QAAQ;IAAO,SAAS;IACzC,QAAQ;IAAO,OAAO;IAAS,SAAS;AAC1C;AAEA,OAAO,MAAMC;IACHC,YAAoB;IAE5B,YAAYA,cAAsB,MAAM,IAAI,CAAE;QAC5C,IAAI,CAACA,WAAW,GAAGA;IACrB;IAEAC,WAAWC,QAAgB,EAAW;QACpC,MAAMC,MAAMN,KAAKO,OAAO,CAACF,UAAUG,WAAW;QAC9C,OAAOF,OAAOL;IAChB;IAEA,MAAMQ,QAAQJ,QAAgB,EAAiC;QAC7D,IAAI;YACF,MAAMK,QAAQ,MAAMX,GAAGY,IAAI,CAACN;YAC5B,IAAIK,MAAME,IAAI,GAAG,IAAI,CAACT,WAAW,IAAI,CAACO,MAAMG,MAAM,IAAI,OAAO;YAE7D,MAAMC,UAAU,MAAMf,GAAGgB,QAAQ,CAACV,UAAU;YAC5C,MAAMC,MAAMN,KAAKO,OAAO,CAACF,UAAUG,WAAW;YAC9C,MAAMQ,WAAWf,YAAY,CAACK,IAAI,IAAI;YAEtC,IAAIW,YAAYH,QAAQI,OAAO,CAAC,WAAW;YAC3C,MAAMC,WAAW;YACjB,IAAIF,UAAUG,MAAM,GAAGD,UAAU;gBAC/BF,YAAYA,UAAUI,KAAK,CAAC,GAAGF,YAAY;YAC7C;YAEA,OAAO;gBAAEnB,MAAMK;gBAAUS,SAASG,UAAUK,IAAI;gBAAIN;gBAAUJ,MAAMF,MAAME,IAAI;YAAC;QACjF,EAAE,OAAM;YACN,OAAO;QACT;IACF;AACF;AAEA,OAAO,SAASW,oBAAoBpB,WAAoB;IACtD,OAAO,IAAID,oBAAoBC;AACjC"}
@@ -0,0 +1,133 @@
1
+ /**
2
+ * RuVectorIndex - Core API for semantic codebase search
3
+ */ import { glob } from 'glob';
4
+ import * as path from 'path';
5
+ import * as fs from 'fs/promises';
6
+ import { createEmbeddingProvider } from '../embeddings/index.js';
7
+ import { createFileProcessor } from './file-processor.js';
8
+ export class RuVectorIndex {
9
+ embeddingProvider;
10
+ fileProcessor;
11
+ db = null;
12
+ workingDir;
13
+ storagePath;
14
+ include;
15
+ exclude;
16
+ batchSize;
17
+ verbose;
18
+ constructor(options = {}, workingDir = process.cwd()){
19
+ this.workingDir = workingDir;
20
+ this.storagePath = options.storagePath ?? './data/codebase.db';
21
+ this.include = options.indexing?.include ?? [
22
+ '**/*.ts',
23
+ '**/*.js',
24
+ '**/*.md'
25
+ ];
26
+ this.exclude = options.indexing?.exclude ?? [
27
+ 'node_modules/**',
28
+ 'dist/**',
29
+ '.git/**'
30
+ ];
31
+ this.batchSize = options.indexing?.batchSize ?? 50;
32
+ this.verbose = options.verbose ?? false;
33
+ this.embeddingProvider = createEmbeddingProvider({
34
+ provider: options.embedding?.provider ?? 'openai',
35
+ model: options.embedding?.model,
36
+ apiKey: options.embedding?.apiKey,
37
+ baseUrl: options.embedding?.baseUrl
38
+ });
39
+ this.fileProcessor = createFileProcessor(options.indexing?.maxFileSize);
40
+ }
41
+ async getDb() {
42
+ if (this.db) return this.db;
43
+ const { VectorDB } = await import('@ruvector/core');
44
+ const storagePath = path.resolve(this.workingDir, this.storagePath);
45
+ await fs.mkdir(path.dirname(storagePath), {
46
+ recursive: true
47
+ });
48
+ this.db = new VectorDB({
49
+ dimensions: 1536,
50
+ storagePath
51
+ });
52
+ return this.db;
53
+ }
54
+ log(msg) {
55
+ if (this.verbose) console.log(`[ruvector] ${msg}`);
56
+ }
57
+ async indexDirectory(directory = '.') {
58
+ const absoluteDir = path.resolve(this.workingDir, directory);
59
+ this.log(`Indexing: ${absoluteDir}`);
60
+ const patterns = this.include.map((p)=>path.join(absoluteDir, p));
61
+ const files = await glob(patterns, {
62
+ ignore: this.exclude,
63
+ nodir: true,
64
+ absolute: true
65
+ });
66
+ this.log(`Found ${files.length} files`);
67
+ const stats = {
68
+ totalFiles: files.length,
69
+ indexedFiles: 0,
70
+ failedFiles: 0,
71
+ lastIndexedAt: new Date()
72
+ };
73
+ const db = await this.getDb();
74
+ for(let i = 0; i < files.length; i += this.batchSize){
75
+ const batch = files.slice(i, i + this.batchSize);
76
+ const processed = [];
77
+ for (const file of batch){
78
+ const result = await this.fileProcessor.process(file);
79
+ if (result) processed.push(result);
80
+ else stats.failedFiles++;
81
+ }
82
+ if (processed.length === 0) continue;
83
+ try {
84
+ const texts = processed.map((p)=>p.content);
85
+ const embeddings = await this.embeddingProvider.embedBatch(texts);
86
+ const items = processed.map((p, idx)=>({
87
+ id: path.relative(this.workingDir, p.path),
88
+ vector: new Float32Array(embeddings[idx].embedding)
89
+ }));
90
+ await db.upsert(items);
91
+ stats.indexedFiles += processed.length;
92
+ this.log(`Indexed ${stats.indexedFiles}/${stats.totalFiles}`);
93
+ } catch (error) {
94
+ this.log(`Batch failed: ${error.message}`);
95
+ stats.failedFiles += processed.length;
96
+ }
97
+ }
98
+ return stats;
99
+ }
100
+ async search(query, options = {}) {
101
+ const limit = options.limit ?? 10;
102
+ const { embedding } = await this.embeddingProvider.embed(query);
103
+ const db = await this.getDb();
104
+ const results = await db.search({
105
+ vector: new Float32Array(embedding),
106
+ k: limit
107
+ });
108
+ return results.map((r)=>({
109
+ path: r.id,
110
+ score: r.score
111
+ }));
112
+ }
113
+ async getStats() {
114
+ const db = await this.getDb();
115
+ const count = await db.count();
116
+ return {
117
+ totalFiles: count,
118
+ indexedFiles: count,
119
+ failedFiles: 0,
120
+ lastIndexedAt: null
121
+ };
122
+ }
123
+ async clear() {
124
+ const storagePath = path.resolve(this.workingDir, this.storagePath);
125
+ try {
126
+ await fs.unlink(storagePath);
127
+ this.db = null;
128
+ } catch {}
129
+ }
130
+ }
131
+ export { createFileProcessor } from './file-processor.js';
132
+
133
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/ruvector/core/index.ts"],"sourcesContent":["/**\n * RuVectorIndex - Core API for semantic codebase search\n */\n\nimport { glob } from 'glob';\nimport * as path from 'path';\nimport * as fs from 'fs/promises';\n\nimport { createEmbeddingProvider, type EmbeddingProvider } from '../embeddings/index.js';\nimport { createFileProcessor, type FileProcessor, type ProcessedFile } from './file-processor.js';\n\nexport interface SearchResult {\n path: string;\n score: number;\n}\n\nexport interface IndexStats {\n totalFiles: number;\n indexedFiles: number;\n failedFiles: number;\n lastIndexedAt: Date | null;\n}\n\nexport interface RuVectorIndexOptions {\n storagePath?: string;\n embedding?: {\n provider?: 'openai' | 'ollama' | 'transformers';\n model?: string;\n apiKey?: string;\n baseUrl?: string;\n };\n indexing?: {\n include?: string[];\n exclude?: string[];\n maxFileSize?: number;\n batchSize?: number;\n };\n verbose?: boolean;\n}\n\ninterface VectorDB {\n upsert(items: Array<{ id: string; vector: Float32Array }>): Promise<void>;\n search(params: { vector: Float32Array; k: number }): Promise<Array<{ id: string; score: number }>>;\n count(): Promise<number>;\n}\n\nexport class RuVectorIndex {\n private embeddingProvider: EmbeddingProvider;\n private fileProcessor: FileProcessor;\n private db: VectorDB | null = null;\n private workingDir: string;\n private storagePath: string;\n private include: string[];\n private exclude: string[];\n private batchSize: number;\n private verbose: boolean;\n \n constructor(options: RuVectorIndexOptions = {}, workingDir: string = process.cwd()) {\n this.workingDir = workingDir;\n this.storagePath = options.storagePath ?? './data/codebase.db';\n this.include = options.indexing?.include ?? ['**/*.ts', '**/*.js', '**/*.md'];\n this.exclude = options.indexing?.exclude ?? ['node_modules/**', 'dist/**', '.git/**'];\n this.batchSize = options.indexing?.batchSize ?? 50;\n this.verbose = options.verbose ?? false;\n \n this.embeddingProvider = createEmbeddingProvider({\n provider: options.embedding?.provider ?? 'openai',\n model: options.embedding?.model,\n apiKey: options.embedding?.apiKey,\n baseUrl: options.embedding?.baseUrl,\n });\n \n this.fileProcessor = createFileProcessor(options.indexing?.maxFileSize);\n }\n \n private async getDb(): Promise<VectorDB> {\n if (this.db) return this.db;\n \n const { VectorDB } = await import('@ruvector/core');\n const storagePath = path.resolve(this.workingDir, this.storagePath);\n await fs.mkdir(path.dirname(storagePath), { recursive: true });\n \n this.db = new VectorDB({ dimensions: 1536, storagePath });\n return this.db;\n }\n \n private log(msg: string): void {\n if (this.verbose) console.log(`[ruvector] ${msg}`);\n }\n \n async indexDirectory(directory: string = '.'): Promise<IndexStats> {\n const absoluteDir = path.resolve(this.workingDir, directory);\n this.log(`Indexing: ${absoluteDir}`);\n \n const patterns = this.include.map(p => path.join(absoluteDir, p));\n const files = await glob(patterns, { ignore: this.exclude, nodir: true, absolute: true });\n \n this.log(`Found ${files.length} files`);\n \n const stats: IndexStats = { totalFiles: files.length, indexedFiles: 0, failedFiles: 0, lastIndexedAt: new Date() };\n const db = await this.getDb();\n \n for (let i = 0; i < files.length; i += this.batchSize) {\n const batch = files.slice(i, i + this.batchSize);\n const processed: ProcessedFile[] = [];\n \n for (const file of batch) {\n const result = await this.fileProcessor.process(file);\n if (result) processed.push(result);\n else stats.failedFiles++;\n }\n \n if (processed.length === 0) continue;\n \n try {\n const texts = processed.map(p => p.content);\n const embeddings = await this.embeddingProvider.embedBatch(texts);\n \n const items = processed.map((p, idx) => ({\n id: path.relative(this.workingDir, p.path),\n vector: new Float32Array(embeddings[idx].embedding),\n }));\n \n await db.upsert(items);\n stats.indexedFiles += processed.length;\n this.log(`Indexed ${stats.indexedFiles}/${stats.totalFiles}`);\n } catch (error) {\n this.log(`Batch failed: ${(error as Error).message}`);\n stats.failedFiles += processed.length;\n }\n }\n \n return stats;\n }\n \n async search(query: string, options: { limit?: number } = {}): Promise<SearchResult[]> {\n const limit = options.limit ?? 10;\n const { embedding } = await this.embeddingProvider.embed(query);\n const db = await this.getDb();\n \n const results = await db.search({ vector: new Float32Array(embedding), k: limit });\n return results.map(r => ({ path: r.id, score: r.score }));\n }\n \n async getStats(): Promise<IndexStats> {\n const db = await this.getDb();\n const count = await db.count();\n return { totalFiles: count, indexedFiles: count, failedFiles: 0, lastIndexedAt: null };\n }\n \n async clear(): Promise<void> {\n const storagePath = path.resolve(this.workingDir, this.storagePath);\n try { await fs.unlink(storagePath); this.db = null; } catch {}\n }\n}\n\nexport { createFileProcessor, type ProcessedFile, type FileProcessor } from './file-processor.js';"],"names":["glob","path","fs","createEmbeddingProvider","createFileProcessor","RuVectorIndex","embeddingProvider","fileProcessor","db","workingDir","storagePath","include","exclude","batchSize","verbose","options","process","cwd","indexing","provider","embedding","model","apiKey","baseUrl","maxFileSize","getDb","VectorDB","resolve","mkdir","dirname","recursive","dimensions","log","msg","console","indexDirectory","directory","absoluteDir","patterns","map","p","join","files","ignore","nodir","absolute","length","stats","totalFiles","indexedFiles","failedFiles","lastIndexedAt","Date","i","batch","slice","processed","file","result","push","texts","content","embeddings","embedBatch","items","idx","id","relative","vector","Float32Array","upsert","error","message","search","query","limit","embed","results","k","r","score","getStats","count","clear","unlink"],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Embedding Providers Module
3
+ */ export * from './provider.js';
4
+ export * from './openai.js';
5
+ import { EmbeddingError } from './provider.js';
6
+ import { createOpenAIProvider } from './openai.js';
7
+ export function createEmbeddingProvider(config) {
8
+ switch(config.provider){
9
+ case 'openai':
10
+ return createOpenAIProvider({
11
+ apiKey: config.apiKey,
12
+ baseUrl: config.baseUrl,
13
+ model: config.model,
14
+ dimensions: config.dimensions
15
+ });
16
+ case 'ollama':
17
+ case 'transformers':
18
+ throw new EmbeddingError(`${config.provider} provider not yet implemented`, config.provider);
19
+ default:
20
+ throw new EmbeddingError(`Unknown provider: ${config.provider}`, 'unknown');
21
+ }
22
+ }
23
+
24
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/ruvector/embeddings/index.ts"],"sourcesContent":["/**\n * Embedding Providers Module\n */\n\nexport * from './provider.js';\nexport * from './openai.js';\n\nimport type { EmbeddingProvider, EmbeddingProviderConfig } from './provider.js';\nimport { EmbeddingError } from './provider.js';\nimport { createOpenAIProvider } from './openai.js';\n\nexport function createEmbeddingProvider(config: EmbeddingProviderConfig): EmbeddingProvider {\n switch (config.provider) {\n case 'openai':\n return createOpenAIProvider({\n apiKey: config.apiKey,\n baseUrl: config.baseUrl,\n model: config.model,\n dimensions: config.dimensions,\n });\n case 'ollama':\n case 'transformers':\n throw new EmbeddingError(`${config.provider} provider not yet implemented`, config.provider);\n default:\n throw new EmbeddingError(`Unknown provider: ${(config as any).provider}`, 'unknown');\n }\n}"],"names":["EmbeddingError","createOpenAIProvider","createEmbeddingProvider","config","provider","apiKey","baseUrl","model","dimensions"],"mappings":"AAAA;;CAEC,GAED,cAAc,gBAAgB;AAC9B,cAAc,cAAc;AAG5B,SAASA,cAAc,QAAQ,gBAAgB;AAC/C,SAASC,oBAAoB,QAAQ,cAAc;AAEnD,OAAO,SAASC,wBAAwBC,MAA+B;IACrE,OAAQA,OAAOC,QAAQ;QACrB,KAAK;YACH,OAAOH,qBAAqB;gBAC1BI,QAAQF,OAAOE,MAAM;gBACrBC,SAASH,OAAOG,OAAO;gBACvBC,OAAOJ,OAAOI,KAAK;gBACnBC,YAAYL,OAAOK,UAAU;YAC/B;QACF,KAAK;QACL,KAAK;YACH,MAAM,IAAIR,eAAe,GAAGG,OAAOC,QAAQ,CAAC,6BAA6B,CAAC,EAAED,OAAOC,QAAQ;QAC7F;YACE,MAAM,IAAIJ,eAAe,CAAC,kBAAkB,EAAE,AAACG,OAAeC,QAAQ,EAAE,EAAE;IAC9E;AACF"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * OpenAI Embedding Provider
3
+ */ import { EmbeddingError } from './provider.js';
4
+ export class OpenAIEmbeddingProvider {
5
+ name = 'openai';
6
+ dimensions;
7
+ apiKey;
8
+ model;
9
+ baseUrl;
10
+ constructor(config){
11
+ this.apiKey = config.apiKey;
12
+ this.model = config.model ?? 'text-embedding-3-small';
13
+ this.baseUrl = config.baseUrl ?? 'https://api.openai.com/v1';
14
+ this.dimensions = config.dimensions ?? 1536;
15
+ }
16
+ async embed(text) {
17
+ const results = await this.embedBatch([
18
+ text
19
+ ]);
20
+ return results[0];
21
+ }
22
+ async embedBatch(texts) {
23
+ if (texts.length === 0) return [];
24
+ try {
25
+ const response = await fetch(`${this.baseUrl}/embeddings`, {
26
+ method: 'POST',
27
+ headers: {
28
+ 'Content-Type': 'application/json',
29
+ 'Authorization': `Bearer ${this.apiKey}`
30
+ },
31
+ body: JSON.stringify({
32
+ model: this.model,
33
+ input: texts,
34
+ dimensions: this.dimensions
35
+ })
36
+ });
37
+ if (!response.ok) {
38
+ const error = await response.text();
39
+ throw new EmbeddingError(`OpenAI API error: ${response.status} ${error}`, this.name);
40
+ }
41
+ const data = await response.json();
42
+ const sorted = data.data.sort((a, b)=>a.index - b.index);
43
+ return sorted.map((item)=>({
44
+ embedding: item.embedding,
45
+ model: data.model,
46
+ tokenCount: Math.floor(data.usage.total_tokens / texts.length)
47
+ }));
48
+ } catch (error) {
49
+ if (error instanceof EmbeddingError) throw error;
50
+ throw new EmbeddingError(`Failed to generate embeddings: ${error.message}`, this.name, error);
51
+ }
52
+ }
53
+ }
54
+ export function createOpenAIProvider(config) {
55
+ const apiKey = config?.apiKey ?? process.env.OPENAI_API_KEY ?? process.env.ZAI_API_KEY;
56
+ if (!apiKey) {
57
+ throw new EmbeddingError('OpenAI API key required. Set OPENAI_API_KEY or ZAI_API_KEY.', 'openai');
58
+ }
59
+ const baseUrl = config?.baseUrl ?? (process.env.ZAI_API_KEY ? 'https://api.zai.com/v1' : undefined);
60
+ return new OpenAIEmbeddingProvider({
61
+ apiKey,
62
+ baseUrl,
63
+ ...config
64
+ });
65
+ }
66
+
67
+ //# sourceMappingURL=openai.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/ruvector/embeddings/openai.ts"],"sourcesContent":["/**\n * OpenAI Embedding Provider\n */\n\nimport type { EmbeddingProvider, EmbeddingResult } from './provider.js';\nimport { EmbeddingError } from './provider.js';\n\nexport interface OpenAIEmbeddingConfig {\n apiKey: string;\n model?: string;\n baseUrl?: string;\n dimensions?: number;\n}\n\nexport class OpenAIEmbeddingProvider implements EmbeddingProvider {\n readonly name = 'openai';\n readonly dimensions: number;\n \n private readonly apiKey: string;\n private readonly model: string;\n private readonly baseUrl: string;\n \n constructor(config: OpenAIEmbeddingConfig) {\n this.apiKey = config.apiKey;\n this.model = config.model ?? 'text-embedding-3-small';\n this.baseUrl = config.baseUrl ?? 'https://api.openai.com/v1';\n this.dimensions = config.dimensions ?? 1536;\n }\n \n async embed(text: string): Promise<EmbeddingResult> {\n const results = await this.embedBatch([text]);\n return results[0];\n }\n \n async embedBatch(texts: string[]): Promise<EmbeddingResult[]> {\n if (texts.length === 0) return [];\n \n try {\n const response = await fetch(`${this.baseUrl}/embeddings`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.apiKey}`,\n },\n body: JSON.stringify({\n model: this.model,\n input: texts,\n dimensions: this.dimensions,\n }),\n });\n \n if (!response.ok) {\n const error = await response.text();\n throw new EmbeddingError(`OpenAI API error: ${response.status} ${error}`, this.name);\n }\n \n const data = await response.json() as {\n data: Array<{ embedding: number[]; index: number }>;\n model: string;\n usage: { total_tokens: number };\n };\n \n const sorted = data.data.sort((a, b) => a.index - b.index);\n \n return sorted.map((item) => ({\n embedding: item.embedding,\n model: data.model,\n tokenCount: Math.floor(data.usage.total_tokens / texts.length),\n }));\n } catch (error) {\n if (error instanceof EmbeddingError) throw error;\n throw new EmbeddingError(\n `Failed to generate embeddings: ${(error as Error).message}`,\n this.name,\n error as Error\n );\n }\n }\n}\n\nexport function createOpenAIProvider(config?: Partial<OpenAIEmbeddingConfig>): OpenAIEmbeddingProvider {\n const apiKey = config?.apiKey ?? process.env.OPENAI_API_KEY ?? process.env.ZAI_API_KEY;\n \n if (!apiKey) {\n throw new EmbeddingError(\n 'OpenAI API key required. Set OPENAI_API_KEY or ZAI_API_KEY.',\n 'openai'\n );\n }\n \n const baseUrl = config?.baseUrl ?? (process.env.ZAI_API_KEY ? 'https://api.zai.com/v1' : undefined);\n \n return new OpenAIEmbeddingProvider({ apiKey, baseUrl, ...config });\n}"],"names":["EmbeddingError","OpenAIEmbeddingProvider","name","dimensions","apiKey","model","baseUrl","config","embed","text","results","embedBatch","texts","length","response","fetch","method","headers","body","JSON","stringify","input","ok","error","status","data","json","sorted","sort","a","b","index","map","item","embedding","tokenCount","Math","floor","usage","total_tokens","message","createOpenAIProvider","process","env","OPENAI_API_KEY","ZAI_API_KEY","undefined"],"mappings":"AAAA;;CAEC,GAGD,SAASA,cAAc,QAAQ,gBAAgB;AAS/C,OAAO,MAAMC;IACFC,OAAO,SAAS;IAChBC,WAAmB;IAEXC,OAAe;IACfC,MAAc;IACdC,QAAgB;IAEjC,YAAYC,MAA6B,CAAE;QACzC,IAAI,CAACH,MAAM,GAAGG,OAAOH,MAAM;QAC3B,IAAI,CAACC,KAAK,GAAGE,OAAOF,KAAK,IAAI;QAC7B,IAAI,CAACC,OAAO,GAAGC,OAAOD,OAAO,IAAI;QACjC,IAAI,CAACH,UAAU,GAAGI,OAAOJ,UAAU,IAAI;IACzC;IAEA,MAAMK,MAAMC,IAAY,EAA4B;QAClD,MAAMC,UAAU,MAAM,IAAI,CAACC,UAAU,CAAC;YAACF;SAAK;QAC5C,OAAOC,OAAO,CAAC,EAAE;IACnB;IAEA,MAAMC,WAAWC,KAAe,EAA8B;QAC5D,IAAIA,MAAMC,MAAM,KAAK,GAAG,OAAO,EAAE;QAEjC,IAAI;YACF,MAAMC,WAAW,MAAMC,MAAM,GAAG,IAAI,CAACT,OAAO,CAAC,WAAW,CAAC,EAAE;gBACzDU,QAAQ;gBACRC,SAAS;oBACP,gBAAgB;oBAChB,iBAAiB,CAAC,OAAO,EAAE,IAAI,CAACb,MAAM,EAAE;gBAC1C;gBACAc,MAAMC,KAAKC,SAAS,CAAC;oBACnBf,OAAO,IAAI,CAACA,KAAK;oBACjBgB,OAAOT;oBACPT,YAAY,IAAI,CAACA,UAAU;gBAC7B;YACF;YAEA,IAAI,CAACW,SAASQ,EAAE,EAAE;gBAChB,MAAMC,QAAQ,MAAMT,SAASL,IAAI;gBACjC,MAAM,IAAIT,eAAe,CAAC,kBAAkB,EAAEc,SAASU,MAAM,CAAC,CAAC,EAAED,OAAO,EAAE,IAAI,CAACrB,IAAI;YACrF;YAEA,MAAMuB,OAAO,MAAMX,SAASY,IAAI;YAMhC,MAAMC,SAASF,KAAKA,IAAI,CAACG,IAAI,CAAC,CAACC,GAAGC,IAAMD,EAAEE,KAAK,GAAGD,EAAEC,KAAK;YAEzD,OAAOJ,OAAOK,GAAG,CAAC,CAACC,OAAU,CAAA;oBAC3BC,WAAWD,KAAKC,SAAS;oBACzB7B,OAAOoB,KAAKpB,KAAK;oBACjB8B,YAAYC,KAAKC,KAAK,CAACZ,KAAKa,KAAK,CAACC,YAAY,GAAG3B,MAAMC,MAAM;gBAC/D,CAAA;QACF,EAAE,OAAOU,OAAO;YACd,IAAIA,iBAAiBvB,gBAAgB,MAAMuB;YAC3C,MAAM,IAAIvB,eACR,CAAC,+BAA+B,EAAE,AAACuB,MAAgBiB,OAAO,EAAE,EAC5D,IAAI,CAACtC,IAAI,EACTqB;QAEJ;IACF;AACF;AAEA,OAAO,SAASkB,qBAAqBlC,MAAuC;IAC1E,MAAMH,SAASG,QAAQH,UAAUsC,QAAQC,GAAG,CAACC,cAAc,IAAIF,QAAQC,GAAG,CAACE,WAAW;IAEtF,IAAI,CAACzC,QAAQ;QACX,MAAM,IAAIJ,eACR,+DACA;IAEJ;IAEA,MAAMM,UAAUC,QAAQD,WAAYoC,CAAAA,QAAQC,GAAG,CAACE,WAAW,GAAG,2BAA2BC,SAAQ;IAEjG,OAAO,IAAI7C,wBAAwB;QAAEG;QAAQE;QAAS,GAAGC,MAAM;IAAC;AAClE"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Embedding Provider Interface for RuVector
3
+ */ export class EmbeddingError extends Error {
4
+ provider;
5
+ cause;
6
+ constructor(message, provider, cause){
7
+ super(message), this.provider = provider, this.cause = cause;
8
+ this.name = 'EmbeddingError';
9
+ }
10
+ }
11
+
12
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/ruvector/embeddings/provider.ts"],"sourcesContent":["/**\n * Embedding Provider Interface for RuVector\n */\n\nexport interface EmbeddingResult {\n embedding: number[];\n model: string;\n tokenCount?: number;\n}\n\nexport interface EmbeddingProvider {\n readonly name: string;\n readonly dimensions: number;\n embed(text: string): Promise<EmbeddingResult>;\n embedBatch(texts: string[]): Promise<EmbeddingResult[]>;\n}\n\nexport interface EmbeddingProviderConfig {\n provider: 'openai' | 'ollama' | 'transformers';\n model?: string;\n apiKey?: string;\n baseUrl?: string;\n dimensions?: number;\n}\n\nexport class EmbeddingError extends Error {\n constructor(\n message: string,\n public readonly provider: string,\n public readonly cause?: Error\n ) {\n super(message);\n this.name = 'EmbeddingError';\n }\n}"],"names":["EmbeddingError","Error","message","provider","cause","name"],"mappings":"AAAA;;CAEC,GAuBD,OAAO,MAAMA,uBAAuBC;;;IAClC,YACEC,OAAe,EACf,AAAgBC,QAAgB,EAChC,AAAgBC,KAAa,CAC7B;QACA,KAAK,CAACF,eAHUC,WAAAA,eACAC,QAAAA;QAGhB,IAAI,CAACC,IAAI,GAAG;IACd;AACF"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * RuVector - Semantic codebase search for CFN
3
+ */ // Core
4
+ export { RuVectorIndex } from './core/index.js';
5
+ export { createFileProcessor } from './core/file-processor.js';
6
+ // Embeddings
7
+ export { EmbeddingError, createEmbeddingProvider, OpenAIEmbeddingProvider, createOpenAIProvider } from './embeddings/index.js';
8
+
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/ruvector/index.ts"],"sourcesContent":["/**\n * RuVector - Semantic codebase search for CFN\n */\n\n// Core\nexport { RuVectorIndex } from './core/index.js';\nexport type { SearchResult, IndexStats, RuVectorIndexOptions } from './core/index.js';\nexport { createFileProcessor } from './core/file-processor.js';\nexport type { ProcessedFile, FileProcessor } from './core/file-processor.js';\n\n// Embeddings\nexport { EmbeddingError, createEmbeddingProvider, OpenAIEmbeddingProvider, createOpenAIProvider } from './embeddings/index.js';\nexport type { EmbeddingProvider, EmbeddingResult, EmbeddingProviderConfig } from './embeddings/index.js';"],"names":["RuVectorIndex","createFileProcessor","EmbeddingError","createEmbeddingProvider","OpenAIEmbeddingProvider","createOpenAIProvider"],"mappings":"AAAA;;CAEC,GAED,OAAO;AACP,SAASA,aAAa,QAAQ,kBAAkB;AAEhD,SAASC,mBAAmB,QAAQ,2BAA2B;AAG/D,aAAa;AACb,SAASC,cAAc,EAAEC,uBAAuB,EAAEC,uBAAuB,EAAEC,oBAAoB,QAAQ,wBAAwB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-flow-novice",
3
- "version": "2.18.2",
3
+ "version": "2.18.3",
4
4
  "description": "AI agent orchestration framework with namespace-isolated skills, agents, and CFN Loop validation. Safe installation with ~0.01% collision risk.",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -13,7 +13,8 @@
13
13
  "cfn-portal": "dist/cli/cfn-portal.js",
14
14
  "cfn-context": "dist/cli/cfn-context.js",
15
15
  "cfn-metrics": "dist/cli/cfn-metrics.js",
16
- "cfn-redis": "dist/cli/cfn-redis.js"
16
+ "cfn-redis": "dist/cli/cfn-redis.js",
17
+ "cfn-ruvector": "dist/ruvector/cli.js"
17
18
  },
18
19
  "files": [
19
20
  "dist/",
@@ -89,7 +90,10 @@
89
90
  "docker",
90
91
  "containers",
91
92
  "memory-leaks",
92
- "concurrent-execution"
93
+ "concurrent-execution",
94
+ "semantic-search",
95
+ "ruvector",
96
+ "vector-embeddings"
93
97
  ],
94
98
  "author": "Claude Flow Novice Team",
95
99
  "license": "MIT",
@@ -105,7 +109,7 @@
105
109
  "dev": "tsx src/cli/index.ts",
106
110
  "build": "npm run clean && npm run build:swc && npm run build:orchestrator",
107
111
  "build:swc": "swc src -d dist --config-file .swcrc --ignore '**/*.test.ts' --ignore '**/*.test.tsx' --ignore '**/*.spec.ts'",
108
- "build:orchestrator": "(cd .claude/skills/cfn-loop-orchestration && npm run build || true) || echo 'Orchestrator build skipped (optional)'",
112
+ "build:orchestrator": "cd .claude/skills/cfn-loop-orchestration && npm run build 2>/dev/null || echo 'Orchestrator build skipped (optional)'",
109
113
  "build:all": "npm run build && npm run build:spawner && npm run build:selector && npm run build:coordination",
110
114
  "build:spawner": "cd src/coordination && tsc spawn-agent.ts --outDir ../../dist/coordination --module commonjs --target es2020 --skipLibCheck 2>/dev/null || echo 'Spawner build skipped'",
111
115
  "build:selector": "cd .claude/skills/cfn-agent-selection-with-fallback && npm run build 2>/dev/null || echo 'Selector build skipped'",
@@ -183,7 +187,11 @@
183
187
  "socket.io": "^4.8.1",
184
188
  "sqlite": "^5.1.1",
185
189
  "sqlite3": "^5.1.7",
186
- "uuid": "^10.0.0"
190
+ "uuid": "^10.0.0",
191
+ "@ruvector/core": "^0.1.0",
192
+ "simple-git": "^3.22.0",
193
+ "cosmiconfig": "^9.0.0",
194
+ "zod": "^3.22.0"
187
195
  },
188
196
  "engines": {
189
197
  "node": ">=18.0.0"
package/readme/README.md CHANGED
@@ -1,16 +1,16 @@
1
- # Claude Flow Novice v2.16.0 Documentation
1
+ # Claude Flow Novice v2.18.1 Documentation
2
2
 
3
- **Version:** 2.16.0 (Integration Standardization)
4
- **Last Updated:** 2025-11-17
3
+ **Version:** 2.18.1 (RuVector Integration)
4
+ **Last Updated:** 2025-12-05
5
5
 
6
6
  **Package Metrics**:
7
- - 2.4 MB unpacked
8
- - 303 files
9
- - Namespace-isolated installation
7
+ - Namespace-isolated installation (~0.01% collision risk)
8
+ - Semantic codebase search via RuVector
9
+ - Multi-provider routing (Z.ai, Kimi, OpenRouter, Anthropic)
10
10
 
11
11
  ## Overview
12
12
 
13
- Claude Flow Novice is a production-ready AI agent orchestration framework built on a skills-first architecture with Redis-based coordination, zero-token waiting mechanisms, and multi-loop consensus validation (CFN Loop).
13
+ AI agent orchestration with semantic codebase search, Redis coordination, and multi-loop consensus validation (CFN Loop).
14
14
 
15
15
  ## CFN Loop Execution Modes
16
16
 
@@ -85,7 +85,7 @@ npx claude-flow-novice swarm "Task Description" \
85
85
  ### Core Concepts
86
86
  - **[Skills System](log-skills.md)** - Modular, reusable agent capabilities
87
87
  - **[CFN Loop](cfn-loop-modes.md)** - Three-loop consensus validation framework
88
- - **[CFN Loop Task Mode](claude-assets/commands/CFN_LOOP_TASK_MODE.md)** - Task execution guide with agent specialization
88
+ - **[RuVector Search](../docs/RUVECTOR_ARCHITECTURE.md)** - Semantic codebase indexing
89
89
  - **[Redis Coordination](logs-cli-redis.md)** - Zero-token agent coordination
90
90
 
91
91
  ### User Guides
@@ -111,14 +111,24 @@ npx claude-flow-novice swarm "Task Description" \
111
111
  - **[Deprecated MCP Logs](deprecated-logs-mcp.md)** - Historical MCP implementation
112
112
  - **[v1 Documentation](../legacy/readme-v1/)** - Previous documentation version
113
113
 
114
- ## Key Features (v2.16.0)
114
+ ## Key Features (v2.18.1)
115
115
 
116
- ### Integration Standardization (NEW - 90% Complete)
117
- - **Skill Lifecycle Automation**: Deploy, version, promote skills with single command
118
- - **Cross-Database Transactions**: Coordinated PostgreSQL + SQLite + Redis operations
119
- - **File System Standardization**: Unified backups, logging, state persistence
120
- - **Edge Case Auto-Patching**: Feedback loop generates patches from test failures
121
- - **Data Format Harmonization**: Consistent JSON schemas across all skill outputs
116
+ ### RuVector Codebase Search (NEW)
117
+ - **Semantic Search**: Natural language queries against codebase
118
+ - **OpenAI Embeddings**: text-embedding-3-small (1536 dimensions)
119
+ - **Manifest System**: `.cfn-manifest.json` tracks CFN vs custom files
120
+ - **Safe Distribution**: Custom files preserved during CFN updates
121
+
122
+ ```bash
123
+ # Index codebase
124
+ ./.claude/skills/cfn-ruvector-codebase-index/index.sh --full
125
+
126
+ # Search
127
+ ./.claude/skills/cfn-ruvector-codebase-index/search.sh "authentication" --top 5
128
+
129
+ # Incremental reindex
130
+ /cfn-ruvector:codebase-reindex
131
+ ```
122
132
 
123
133
  ### Skills-First Architecture
124
134
  - **Modular Skills**: Independently maintainable, testable capabilities