claude-flow-novice 2.18.40 → 2.19.1

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 (197) hide show
  1. package/.claude/agents/AGENT_LIFECYCLE.md +1 -1
  2. package/.claude/agents/SHARED_PROTOCOL.md +33 -5
  3. package/.claude/agents/cfn-dev-team/analysts/analyst.md +4 -4
  4. package/.claude/agents/cfn-dev-team/analysts/root-cause-analyst.md +4 -4
  5. package/.claude/agents/cfn-dev-team/architecture/api-designer-persona.md +4 -4
  6. package/.claude/agents/cfn-dev-team/architecture/base-template-generator.md +4 -4
  7. package/.claude/agents/cfn-dev-team/architecture/goal-planner.md +4 -4
  8. package/.claude/agents/cfn-dev-team/architecture/system-architect.md +4 -4
  9. package/.claude/agents/cfn-dev-team/coordinators/cfn-frontend-coordinator.md +4 -4
  10. package/.claude/agents/cfn-dev-team/coordinators/handoff-coordinator.md +4 -4
  11. package/.claude/agents/cfn-dev-team/dev-ops/devops-engineer.md +4 -4
  12. package/.claude/agents/cfn-dev-team/dev-ops/docker-specialist.md +4 -4
  13. package/.claude/agents/cfn-dev-team/dev-ops/fly-io-specialist.md +418 -0
  14. package/.claude/agents/cfn-dev-team/dev-ops/github-commit-agent.md +4 -4
  15. package/.claude/agents/cfn-dev-team/developers/api-gateway-specialist.md +4 -4
  16. package/.claude/agents/cfn-dev-team/developers/backend-developer.md +4 -4
  17. package/.claude/agents/cfn-dev-team/developers/data/data-engineer.md +4 -4
  18. package/.claude/agents/cfn-dev-team/developers/database/database-architect.md +4 -4
  19. package/.claude/agents/cfn-dev-team/developers/database/mem0-specialist.md +579 -0
  20. package/.claude/agents/cfn-dev-team/developers/database/memgraph-specialist.md +722 -0
  21. package/.claude/agents/cfn-dev-team/developers/database/supabase-specialist.md +4 -4
  22. package/.claude/agents/cfn-dev-team/developers/frontend/mobile-dev.md +4 -4
  23. package/.claude/agents/cfn-dev-team/developers/frontend/react-frontend-engineer.md +4 -4
  24. package/.claude/agents/cfn-dev-team/developers/frontend/typescript-specialist.md +4 -4
  25. package/.claude/agents/cfn-dev-team/developers/frontend/ui-designer.md +4 -4
  26. package/.claude/agents/cfn-dev-team/developers/graphql-specialist.md +4 -4
  27. package/.claude/agents/cfn-dev-team/developers/rust-developer.md +4 -4
  28. package/.claude/agents/cfn-dev-team/documentation/agent-type-guidelines.md +4 -4
  29. package/.claude/agents/cfn-dev-team/documentation/api-documentation.md +4 -4
  30. package/.claude/agents/cfn-dev-team/documentation/pseudocode.md +5 -5
  31. package/.claude/agents/cfn-dev-team/documentation/specification-agent.md +5 -5
  32. package/.claude/agents/cfn-dev-team/product-owners/accessibility-advocate-persona.md +4 -4
  33. package/.claude/agents/cfn-dev-team/product-owners/cto-agent.md +4 -4
  34. package/.claude/agents/cfn-dev-team/product-owners/power-user-persona.md +4 -4
  35. package/.claude/agents/cfn-dev-team/product-owners/product-owner.md +4 -4
  36. package/.claude/agents/cfn-dev-team/reviewers/code-reviewer.md +4 -4
  37. package/.claude/agents/cfn-dev-team/reviewers/quality/code-quality-validator.md +4 -4
  38. package/.claude/agents/cfn-dev-team/reviewers/quality/cyclomatic-complexity-reducer.md +4 -4
  39. package/.claude/agents/cfn-dev-team/reviewers/quality/perf-analyzer.md +4 -4
  40. package/.claude/agents/cfn-dev-team/reviewers/quality/performance-benchmarker.md +4 -4
  41. package/.claude/agents/cfn-dev-team/reviewers/quality/quality-metrics.md +4 -4
  42. package/.claude/agents/cfn-dev-team/testers/api-testing-specialist.md +4 -4
  43. package/.claude/agents/cfn-dev-team/testers/chaos-engineering-specialist.md +4 -4
  44. package/.claude/agents/cfn-dev-team/testers/contract-tester.md +4 -4
  45. package/.claude/agents/cfn-dev-team/testers/e2e/playwright-tester.md +4 -4
  46. package/.claude/agents/cfn-dev-team/testers/integration-tester.md +4 -4
  47. package/.claude/agents/cfn-dev-team/testers/interaction-tester.md +4 -4
  48. package/.claude/agents/cfn-dev-team/testers/load-testing-specialist.md +4 -4
  49. package/.claude/agents/cfn-dev-team/testers/mutation-testing-specialist.md +4 -4
  50. package/.claude/agents/cfn-dev-team/testers/playwright-tester.md +4 -4
  51. package/.claude/agents/cfn-dev-team/{testing → testers}/test-validation-agent.md +4 -4
  52. package/.claude/agents/cfn-dev-team/testers/tester.md +39 -4
  53. package/.claude/agents/cfn-dev-team/testers/unit/tdd-london-unit-swarm.md +4 -4
  54. package/.claude/agents/cfn-dev-team/testers/validation/validation-production-validator.md +4 -4
  55. package/.claude/agents/cfn-dev-team/utility/agent-builder.md +7 -7
  56. package/.claude/agents/cfn-dev-team/utility/memory-leak-specialist.md +4 -4
  57. package/.claude/agents/cfn-dev-team/utility/researcher.md +4 -4
  58. package/.claude/agents/cfn-dev-team/utility/z-ai-specialist.md +4 -4
  59. package/.claude/agents/custom/claude-code-expert.md +1 -1
  60. package/.claude/agents/project-only-agents/npm-package-specialist.md +1 -1
  61. package/.claude/{agents/cfn-dev-team/utility → cfn-extras/agents}/context-curator.md +4 -4
  62. package/.claude/{agents/custom → cfn-extras/agents/custom-agents}/cfn-docker-expert.md +4 -4
  63. package/.claude/{agents/custom → cfn-extras/agents/custom-agents}/cfn-redis-operations.md +1 -1
  64. package/.claude/{agents/custom → cfn-extras/agents/custom-agents}/cfn-system-expert.md +4 -4
  65. package/.claude/{agents/custom → cfn-extras/agents/custom-agents}/trigger-dev-expert.md +4 -4
  66. package/.claude/{agents/cfn-dev-team/coordinators → cfn-extras/agents/deprecated-coordinators}/consensus-builder.md +4 -4
  67. package/.claude/{agents/cfn-dev-team/coordinators → cfn-extras/agents/deprecated-coordinators}/multi-sprint-coordinator.md +4 -4
  68. package/.claude/{agents → cfn-extras/agents/docker-team}/docker-coordinators/cfn-docker-v3-coordinator.md +1 -1
  69. package/.claude/{agents/cfn-dev-team/dev-ops → cfn-extras/agents}/kubernetes-specialist.md +4 -4
  70. package/.claude/{agents/cfn-dev-team/architecture → cfn-extras/agents}/planner.md +4 -4
  71. package/.claude/cfn-extras/skills/cfn-cerebras-coordinator/QUICKSTART.md +1 -1
  72. package/.claude/cfn-extras/skills/cfn-cerebras-coordinator/README.md +19 -19
  73. package/.claude/cfn-extras/skills/cfn-cerebras-coordinator/SKILL.md +7 -7
  74. package/.claude/cfn-extras/skills/cfn-cerebras-coordinator/TDD_COORDINATOR_OVERVIEW.md +3 -3
  75. package/.claude/cfn-extras/skills/cfn-cerebras-coordinator/TEST_RESULTS.md +3 -3
  76. package/.claude/cfn-extras/skills/cfn-cerebras-coordinator/coordinate-generation.sh +19 -19
  77. package/.claude/cfn-extras/skills/cfn-cerebras-coordinator/example-fix-scenario.md +4 -4
  78. package/.claude/cfn-extras/skills/cfn-cerebras-coordinator/example-usage.sh +1 -1
  79. package/.claude/cfn-extras/skills/cfn-cerebras-coordinator/feedback-logger.sh +5 -5
  80. package/.claude/cfn-extras/skills/cfn-cerebras-coordinator/fix-existing-code-v2.sh +2 -2
  81. package/.claude/cfn-extras/skills/cfn-cerebras-coordinator/fix-existing-code.sh +10 -10
  82. package/.claude/cfn-extras/skills/cfn-cerebras-coordinator/pattern-examples.md +3 -3
  83. package/.claude/cfn-extras/skills/cfn-cerebras-coordinator/query-patterns.sh +9 -9
  84. package/.claude/cfn-extras/skills/cfn-cerebras-coordinator/tdd-coordinator.sh +8 -8
  85. package/.claude/cfn-extras/skills/cfn-cerebras-coordinator/test-tdd-coordinator.sh +1 -1
  86. package/.claude/commands/README.md +1 -1
  87. package/.claude/commands/{cfn-ruvector → cfn-codesearch}/cfn-codebase-reindex.md +6 -6
  88. package/.claude/commands/{cfn-ruvector → cfn-codesearch}/cfn-codebase-search.md +8 -8
  89. package/.claude/commands/{cfn-ruvector → cfn-codesearch}/cfn-detect-stale-docs.md +3 -3
  90. package/.claude/commands/cfn-codesearch-search.md +36 -0
  91. package/.claude/commands/cfn-fix-errors.md +1 -1
  92. package/.claude/commands/cfn-loop-task.md +66 -2
  93. package/.claude/commands/cfn-update-search-index.md +2 -2
  94. package/.claude/hooks/cfn-SessionStart-cfn-build-codesearch.sh +24 -0
  95. package/.claude/hooks/cfn-bash-search-hook.sh +6 -6
  96. package/.claude/hooks/cfn-smart-search-hook.sh +15 -15
  97. package/.claude/hooks/cfn-subagent-stop.sh +9 -9
  98. package/.claude/hooks/post-commit-codebase-index +14 -14
  99. package/.claude/skills/{bulk-add-ruvector-instructions.sh → bulk-add-codesearch-instructions.sh} +14 -14
  100. package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/AGENT_INTEGRATION_PATTERNS.md +20 -20
  101. package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/AGENT_LIFECYCLE_INTEGRATION.md +12 -12
  102. package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/Cargo.toml +9 -4
  103. package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/EXTRACTION_EXAMPLES.md +6 -6
  104. package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/IMMEDIATE_ACTION_REQUIRED.md +9 -9
  105. package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/README.md +7 -7
  106. package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/SCHEMA_V2_IMPLEMENTATION.md +1 -1
  107. package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/SECURITY_FINDINGS_SUMMARY.txt +1 -1
  108. package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/SECURITY_IMPLEMENTATION.md +3 -3
  109. package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/SECURITY_TESTING_COMPLETION.md +5 -5
  110. package/.claude/skills/cfn-codesearch/SKILL.md +143 -0
  111. package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/analyze-agent-failures.sh +11 -11
  112. package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/cfn-integration.sh +29 -29
  113. package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/docs/EXECUTIVE_SUMMARY.txt +1 -1
  114. package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/docs/PHASE_4_QUERY_API.md +24 -24
  115. package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/docs/RUST_AST_EXTRACTOR_IMPLEMENTATION.md +7 -7
  116. package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/docs/TRANSACTION_MANAGEMENT.md +1 -1
  117. package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/docs/VALIDATION_FINDINGS.txt +1 -1
  118. package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/epic-ast-indexer.json +8 -8
  119. package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/index-code.sh +11 -11
  120. package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/index_all.sh +2 -2
  121. package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/ingest-agent-transcript.sh +10 -10
  122. package/.claude/skills/{cfn-local-ruvector-accelerator/init-local-ruvector.sh → cfn-codesearch/init-local-codesearch.sh} +16 -16
  123. package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/project-structure.md +10 -10
  124. package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/query-local.sh +6 -6
  125. package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/cli/cleanup.rs +1 -1
  126. package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/cli/index.rs +238 -9
  127. package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/cli/index_ast.rs +3 -3
  128. package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/cli/init.rs +19 -19
  129. package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/cli/migration.rs +5 -5
  130. package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/cli/query.rs +64 -3
  131. package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/cli/reset.rs +5 -5
  132. package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/embeddings.rs +19 -5
  133. package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/lib.rs +6 -4
  134. package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/main.rs +37 -27
  135. package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/migration_v2.rs +1 -1
  136. package/.claude/skills/cfn-codesearch/src/paths.rs +37 -0
  137. package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/query_v2.rs +3 -4
  138. package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/search_engine.rs +3 -3
  139. package/.claude/skills/cfn-codesearch/src/store_pgvector.rs +301 -0
  140. package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/store_v2.rs +12 -1
  141. package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/test-agent-lifecycle-integration.sh +6 -6
  142. package/.claude/skills/{cfn-local-ruvector-accelerator/test-local-ruvector.sh → cfn-codesearch/test-local-codesearch.sh} +7 -7
  143. package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/test_query_api.sh +2 -2
  144. package/.claude/skills/cfn-epic-creator/SKILL.md +110 -2
  145. package/.claude/skills/cfn-epic-creator/invoke.sh +120 -1
  146. package/.claude/skills/cfn-knowledge-base/lib/playbook/SKILL.md +1 -1
  147. package/.claude/skills/cfn-mdap-context-injection/SKILL.md +2 -2
  148. package/.claude/skills/cfn-mdap-context-injection/inject.sh +23 -23
  149. package/CLAUDE.md +3 -3
  150. package/package.json +11 -11
  151. package/readme/feature-status.md +411 -0
  152. package/.claude/agents/docker-ts-fixer.md +0 -65
  153. package/.claude/commands/cfn-ruvector-search.md +0 -36
  154. package/.claude/hooks/cfn-SessionStart-cfn-build-ruvector.sh +0 -24
  155. package/.claude/skills/cfn-local-ruvector-accelerator/.claude/hooks/SessionStart-cfn-build-ruvector.sh +0 -13
  156. package/.claude/skills/cfn-local-ruvector-accelerator/SKILL.md +0 -143
  157. package/.claude/skills/cfn-local-ruvector-accelerator/src/paths.rs +0 -31
  158. /package/.claude/{agents/custom → cfn-extras/agents/custom-agents}/cfn-loops-cli-expert.md +0 -0
  159. /package/.claude/{agents/csuite → cfn-extras/agents/custom-agents}/cto-agent.md +0 -0
  160. /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/Cargo.toml.backup +0 -0
  161. /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/embeddings_manager.py.backup +0 -0
  162. /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/index/index.bin +0 -0
  163. /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/index/metadata.json +0 -0
  164. /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/index-code.sh.backup +0 -0
  165. /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/query-agent-patterns.sh +0 -0
  166. /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/requirements.txt +0 -0
  167. /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/search_engine_v2.py.backup +0 -0
  168. /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/sqlite_store.py.backup +0 -0
  169. /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/cli/export.rs +0 -0
  170. /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/cli/find.rs +0 -0
  171. /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/cli/index_modified.rs +0 -0
  172. /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/cli/mod.rs +0 -0
  173. /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/cli/refs.rs +0 -0
  174. /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/cli/stats.rs +0 -0
  175. /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/extractors/mod.rs +0 -0
  176. /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/extractors/rust.rs +0 -0
  177. /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/extractors/rust_placeholder.rs +0 -0
  178. /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/extractors/text_fallback.rs +0 -0
  179. /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/extractors/typescript.rs +0 -0
  180. /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/extractors/typescript_full.rs +0 -0
  181. /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/main.rs.backup +0 -0
  182. /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/migration.rs +0 -0
  183. /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/migration_backup.rs +0 -0
  184. /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/migration_tx.rs +0 -0
  185. /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/path_validator.rs +0 -0
  186. /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/query_api.rs +0 -0
  187. /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/schema_v2.rs +0 -0
  188. /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/security_tests.rs +0 -0
  189. /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/sqlite_store.rs +0 -0
  190. /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/store_v2_backup.rs +0 -0
  191. /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/store_v2_fixed.rs +0 -0
  192. /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/store_v2_tx.rs +0 -0
  193. /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/test_schema.rs +0 -0
  194. /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/transaction_tests.rs +0 -0
  195. /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/test_ast_indexing.rs +0 -0
  196. /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/test_schema.sql +0 -0
  197. /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/test_schema_v2.sql +0 -0
@@ -1,11 +1,11 @@
1
1
  #!/bin/bash
2
- # query-local.sh - Query local RuVector for patterns using Rust binary
2
+ # query-local.sh - Query local CodeSearch for patterns using Rust binary
3
3
  # This is a wrapper around the Rust binary for convenience
4
4
 
5
5
  set -e
6
6
 
7
7
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
8
- DB_PATH="$HOME/.local/share/ruvector/index_v2.db"
8
+ DB_PATH="$HOME/.local/share/codesearch/index_v2.db"
9
9
 
10
10
  # Parse arguments
11
11
  PATTERN=""
@@ -50,7 +50,7 @@ if [[ "$HELP" == true ]] || [[ -z "$PATTERN" ]]; then
50
50
  cat << EOF
51
51
  Usage: query-local [OPTIONS] PATTERN
52
52
 
53
- Query local RuVector database for code patterns
53
+ Query local CodeSearch database for code patterns
54
54
 
55
55
  Arguments:
56
56
  PATTERN Search pattern (entity name or partial match)
@@ -86,8 +86,8 @@ fi
86
86
 
87
87
  # Check if database exists
88
88
  if [[ ! -f "$DB_PATH" ]]; then
89
- echo "❌ Error: RuVector database not found at $DB_PATH"
90
- echo " Run: local-ruvector index --path /your/project"
89
+ echo "❌ Error: CodeSearch database not found at $DB_PATH"
90
+ echo " Run: local-codesearch index --path /your/project"
91
91
  exit 1
92
92
  fi
93
93
 
@@ -118,7 +118,7 @@ if [[ -z "$RESULTS" ]]; then
118
118
  echo "💡 Tips:"
119
119
  echo " - Try a broader search term"
120
120
  echo " - Check if your project is indexed: sqlite3 $DB_PATH 'SELECT COUNT(*) FROM entities;'"
121
- echo " - Reindex if needed: local-ruvector index --path /your/project"
121
+ echo " - Reindex if needed: local-codesearch index --path /your/project"
122
122
  else
123
123
  echo "$RESULTS"
124
124
  echo ""
@@ -43,7 +43,7 @@ impl CleanupCommand {
43
43
  }
44
44
 
45
45
  let search_engine = SearchEngine::new(&self.project_dir)?;
46
- let store = SqliteStore::new(&self.project_dir.join(".ruvector").join("index.db"))?;
46
+ let store = SqliteStore::new(&self.project_dir.join(".codesearch").join("index.db"))?;
47
47
 
48
48
  // Check if there's anything to clean
49
49
  let stats = store.get_stats()?;
@@ -1,4 +1,4 @@
1
- //! # RuVector Index Command
1
+ //! # CodeSearch Index Command
2
2
  //!
3
3
  //! ## IMPORTANT: Run from PROJECT ROOT
4
4
  //!
@@ -8,7 +8,7 @@
8
8
  //! ## Recommended Usage:
9
9
  //! ```bash
10
10
  //! cd /path/to/project-root
11
- //! local-ruvector index --path . --types rs,ts,js,json,md,sh --force
11
+ //! local-codesearch index --path . --types rs,ts,js,json,md,sh --force
12
12
  //! ```
13
13
  //!
14
14
  //! ## Supported File Types (default):
@@ -23,7 +23,7 @@
23
23
  //! - Cache: .cache, __pycache__, .pytest_cache, .mypy_cache, .ruff_cache, coverage, .nyc_output
24
24
  //! - Virtual envs: .venv, venv, env
25
25
  //! - IaC: .terraform, .serverless, .aws-sam
26
- //! - Project-specific: .artifacts, .ruvector, .archive, archive, .archived, archived
26
+ //! - Project-specific: .artifacts, .codesearch, .archive, archive, .archived, archived
27
27
  //! - Backups/temp: backups, .backups, backup, tmp, .tmp, temp, logs
28
28
  //! - Test artifacts: __snapshots__, __mocks__, playwright-report, test-results
29
29
  //! - Doc builds: _site, .docusaurus, site
@@ -39,7 +39,7 @@
39
39
  //!
40
40
  //! ## Multi-Project Isolation:
41
41
  //! - Each project root is isolated via project_root column in v2 schema
42
- //! - Centralized database at ~/.local/share/ruvector/index_v2.db
42
+ //! - Centralized database at ~/.local/share/codesearch/index_v2.db
43
43
  //! - Queries are scoped to the project root passed during indexing
44
44
 
45
45
  use anyhow::{Result, Context, anyhow};
@@ -63,7 +63,8 @@ use crate::extractors::text_fallback::TextFallbackExtractor;
63
63
  use crate::store_v2::{StoreV2, Entity as StoreEntity, Reference as StoreReference, TypeUsage};
64
64
  use crate::schema_v2::{EntityKind, RefKind, Visibility};
65
65
  use crate::path_validator;
66
- use local_ruvector::paths::{get_ruvector_dir, get_database_path};
66
+ use codesearch::store_pgvector::PgvectorStore;
67
+ use codesearch::paths::{get_codesearch_dir, get_database_path};
67
68
  // V1 index is deprecated - all operations use V2 (index_v2.db)
68
69
 
69
70
  /// Directories to exclude from indexing.
@@ -120,7 +121,7 @@ const EXCLUDED_DIRS: &[&str] = &[
120
121
 
121
122
  // Project-specific
122
123
  ".artifacts", // CFN Loop artifacts
123
- ".ruvector", // RuVector local index (avoid self-indexing)
124
+ ".codesearch", // CodeSearch local index (avoid self-indexing)
124
125
  ".archive", // Archived/deprecated code
125
126
  "archive", // Archive directories
126
127
  ".archived", // Archived code (alternate naming)
@@ -246,11 +247,82 @@ pub struct IndexCommand {
246
247
  search_engine: SearchEngine,
247
248
  store: SqliteStore,
248
249
  store_v2: StoreV2,
250
+ pgvector_store: Option<PgvectorStore>,
251
+ tokio_runtime: Option<tokio::runtime::Runtime>,
249
252
  rust_extractor: RustExtractor,
250
253
  typescript_extractor: TypeScriptExtractor,
251
254
  text_fallback_extractor: TextFallbackExtractor,
252
255
  }
253
256
 
257
+ /// Extract doc comments from a signature string.
258
+ /// Supports Rust-style (///, //!) and JSDoc-style (/** */) comments.
259
+ fn extract_doc_comment(signature: &str) -> Option<String> {
260
+ let lines: Vec<&str> = signature.lines().collect();
261
+ let mut doc_lines: Vec<String> = Vec::new();
262
+ let mut in_jsdoc = false;
263
+
264
+ for line in &lines {
265
+ let trimmed = line.trim();
266
+
267
+ // Handle JSDoc-style comments (/** ... */)
268
+ if trimmed.starts_with("/**") {
269
+ let after_open = trimmed.strip_prefix("/**").unwrap_or("").trim();
270
+ // Check if it's a single-line JSDoc (/** content */)
271
+ if after_open.ends_with("*/") {
272
+ let content = after_open.strip_suffix("*/").unwrap_or(after_open).trim();
273
+ if !content.is_empty() {
274
+ doc_lines.push(content.to_string());
275
+ }
276
+ // Single-line, don't enter jsdoc mode
277
+ continue;
278
+ }
279
+ // Multi-line JSDoc
280
+ in_jsdoc = true;
281
+ if !after_open.is_empty() {
282
+ doc_lines.push(after_open.to_string());
283
+ }
284
+ continue;
285
+ }
286
+
287
+ if in_jsdoc {
288
+ if trimmed.contains("*/") {
289
+ in_jsdoc = false;
290
+ // Extract content before */
291
+ let content = trimmed.strip_suffix("*/").unwrap_or(trimmed)
292
+ .trim_start_matches('*').trim();
293
+ if !content.is_empty() {
294
+ doc_lines.push(content.to_string());
295
+ }
296
+ } else {
297
+ // Middle lines of JSDoc (usually start with *)
298
+ let content = trimmed.trim_start_matches('*').trim();
299
+ if !content.is_empty() {
300
+ doc_lines.push(content.to_string());
301
+ }
302
+ }
303
+ continue;
304
+ }
305
+
306
+ // Handle Rust-style doc comments (/// or //!)
307
+ if trimmed.starts_with("///") {
308
+ let content = trimmed.strip_prefix("///").unwrap_or("").trim();
309
+ doc_lines.push(content.to_string());
310
+ } else if trimmed.starts_with("//!") {
311
+ let content = trimmed.strip_prefix("//!").unwrap_or("").trim();
312
+ doc_lines.push(content.to_string());
313
+ } else if !doc_lines.is_empty() {
314
+ // Stop when we hit a non-doc-comment line after collecting some
315
+ break;
316
+ }
317
+ }
318
+
319
+ if doc_lines.is_empty() {
320
+ None
321
+ } else {
322
+ Some(doc_lines.join("\n"))
323
+ }
324
+ }
325
+
254
326
  impl IndexCommand {
255
327
  pub fn new(
256
328
  project_dir: &Path,
@@ -258,13 +330,33 @@ impl IndexCommand {
258
330
  file_types: Vec<String>,
259
331
  patterns: Option<Vec<String>>,
260
332
  force: bool,
333
+ pg_url: Option<&str>,
261
334
  ) -> Result<Self> {
262
- let index_path = get_ruvector_dir()?;
335
+ let index_path = get_codesearch_dir()?;
263
336
  let embeddings_manager = EmbeddingsManager::new(&index_path)?;
264
337
  let search_engine = SearchEngine::new(&index_path)?;
265
338
  let store = SqliteStore::new(&index_path.join("index.db"))?;
266
339
  let store_v2 = StoreV2::new(&get_database_path()?)?;
267
340
 
341
+ // Initialize pgvector store and runtime if connection URL provided
342
+ let (pgvector_store, tokio_runtime) = if let Some(url) = pg_url {
343
+ info!("Initializing pgvector store with URL: {}", url);
344
+ let rt = tokio::runtime::Runtime::new()?;
345
+ match rt.block_on(PgvectorStore::new(url)) {
346
+ Ok(store) => {
347
+ info!("Successfully connected to pgvector");
348
+ (Some(store), Some(rt))
349
+ }
350
+ Err(e) => {
351
+ warn!("Failed to connect to pgvector: {}. Using SQLite only.", e);
352
+ (None, None)
353
+ }
354
+ }
355
+ } else {
356
+ info!("No pg_url provided, using SQLite only");
357
+ (None, None)
358
+ };
359
+
268
360
  let source_path = if path.as_os_str().is_empty() || path == Path::new(".") {
269
361
  project_dir.to_path_buf()
270
362
  } else {
@@ -282,6 +374,8 @@ impl IndexCommand {
282
374
  search_engine,
283
375
  store,
284
376
  store_v2,
377
+ pgvector_store,
378
+ tokio_runtime,
285
379
  rust_extractor: RustExtractor::new()?,
286
380
  typescript_extractor: TypeScriptExtractor::new()?,
287
381
  text_fallback_extractor: TextFallbackExtractor::new()?,
@@ -476,11 +570,75 @@ impl IndexCommand {
476
570
 
477
571
  let embeddings = self.generate_entity_embeddings(&extraction_result.entities)?;
478
572
 
479
- // Store embeddings in entity_embeddings table
573
+ // Store embeddings in SQLite entity_embeddings table (metadata)
480
574
  for (entity_id, embedding) in entity_ids.iter().zip(embeddings.iter()) {
481
575
  self.store_v2.store_embedding(*entity_id, embedding, "text-embedding-3-small")?;
482
576
  }
483
577
 
578
+ // Store embeddings in pgvector if available
579
+ if let Some(ref pgvector_store) = self.pgvector_store {
580
+ if let Some(ref rt) = self.tokio_runtime {
581
+ let project_root_str = self.project_dir.to_string_lossy().to_string();
582
+
583
+ // Build entities the same way store_entities does
584
+ for (i, entity) in extraction_result.entities.iter().enumerate() {
585
+ let store_entity = codesearch::store_v2::Entity {
586
+ id: entity_ids[i],
587
+ kind: match entity.kind {
588
+ crate::extractors::EntityKind::Function => codesearch::schema_v2::EntityKind::Function,
589
+ crate::extractors::EntityKind::Method => codesearch::schema_v2::EntityKind::Method,
590
+ crate::extractors::EntityKind::Constructor => codesearch::schema_v2::EntityKind::Constructor,
591
+ crate::extractors::EntityKind::Getter => codesearch::schema_v2::EntityKind::Getter,
592
+ crate::extractors::EntityKind::Setter => codesearch::schema_v2::EntityKind::Setter,
593
+ crate::extractors::EntityKind::Class => codesearch::schema_v2::EntityKind::Class,
594
+ crate::extractors::EntityKind::Interface => codesearch::schema_v2::EntityKind::Interface,
595
+ crate::extractors::EntityKind::Struct => codesearch::schema_v2::EntityKind::Struct,
596
+ crate::extractors::EntityKind::Enum => codesearch::schema_v2::EntityKind::Enum,
597
+ crate::extractors::EntityKind::Trait => codesearch::schema_v2::EntityKind::Trait,
598
+ crate::extractors::EntityKind::TypeAlias => codesearch::schema_v2::EntityKind::TypeAlias,
599
+ crate::extractors::EntityKind::Module => codesearch::schema_v2::EntityKind::Module,
600
+ crate::extractors::EntityKind::Namespace => codesearch::schema_v2::EntityKind::Namespace,
601
+ crate::extractors::EntityKind::Variable => codesearch::schema_v2::EntityKind::Variable,
602
+ crate::extractors::EntityKind::Constant => codesearch::schema_v2::EntityKind::Constant,
603
+ crate::extractors::EntityKind::Parameter => codesearch::schema_v2::EntityKind::Parameter,
604
+ crate::extractors::EntityKind::Import => codesearch::schema_v2::EntityKind::Import,
605
+ },
606
+ name: entity.name.clone(),
607
+ signature: Some(entity.signature.clone()),
608
+ visibility: match entity.visibility {
609
+ crate::extractors::Visibility::Public => codesearch::schema_v2::Visibility::Public,
610
+ crate::extractors::Visibility::Private => codesearch::schema_v2::Visibility::Private,
611
+ crate::extractors::Visibility::Protected => codesearch::schema_v2::Visibility::Protected,
612
+ crate::extractors::Visibility::Internal => codesearch::schema_v2::Visibility::Internal,
613
+ crate::extractors::Visibility::FilePrivate => codesearch::schema_v2::Visibility::FilePrivate,
614
+ },
615
+ parent_id: None,
616
+ file_path: file_path.to_string_lossy().to_string(),
617
+ line_number: entity.line as i64,
618
+ column_number: Some(entity.column as i64),
619
+ doc_comment: extract_doc_comment(&entity.signature),
620
+ attributes: None,
621
+ metadata: Some(serde_json::to_string(&entity.metadata)?),
622
+ project_root: project_root_str.clone(),
623
+ created_at: chrono::Utc::now(),
624
+ updated_at: chrono::Utc::now(),
625
+ };
626
+
627
+ // Use the stored runtime (created once in new())
628
+ match rt.block_on(pgvector_store.store_entity_with_embedding(
629
+ &store_entity,
630
+ &embeddings[i],
631
+ &project_root_str,
632
+ )) {
633
+ Ok(_) => debug!("Stored entity in pgvector: {}", store_entity.name),
634
+ Err(e) => warn!("Failed to store entity in pgvector: {:?}", e),
635
+ }
636
+ }
637
+ } else {
638
+ warn!("pgvector_store available but tokio_runtime is None - this is a bug");
639
+ }
640
+ }
641
+
484
642
  {
485
643
  let mut s = stats.write().unwrap();
486
644
  s.files_processed += 1;
@@ -555,7 +713,7 @@ impl IndexCommand {
555
713
  file_path: file_path.to_string_lossy().to_string(),
556
714
  line_number: entity.line as i64,
557
715
  column_number: Some(entity.column as i64),
558
- doc_comment: None,
716
+ doc_comment: extract_doc_comment(&entity.signature),
559
717
  attributes: None,
560
718
  metadata: Some(serde_json::to_string(&entity.metadata)?),
561
719
  project_root: project_root_str.to_string(),
@@ -721,4 +879,75 @@ impl IndexCommand {
721
879
 
722
880
  Ok(format!("{:x}", hasher.finalize()))
723
881
  }
882
+ }
883
+
884
+ #[cfg(test)]
885
+ mod tests {
886
+ use super::*;
887
+
888
+ #[test]
889
+ fn test_extract_rust_doc_comment() {
890
+ let signature = r#"/// Create a new Rust extractor
891
+ pub fn new() -> Self"#;
892
+ let doc = extract_doc_comment(signature);
893
+ assert_eq!(doc, Some("Create a new Rust extractor".to_string()));
894
+ }
895
+
896
+ #[test]
897
+ fn test_extract_rust_multiline_doc_comment() {
898
+ let signature = r#"/// Create a new store
899
+ /// This is the main entry point
900
+ pub fn new() -> Self"#;
901
+ let doc = extract_doc_comment(signature);
902
+ assert_eq!(doc, Some("Create a new store\nThis is the main entry point".to_string()));
903
+ }
904
+
905
+ #[test]
906
+ fn test_extract_rust_inner_doc_comment() {
907
+ let signature = r#"//! Module documentation
908
+ //! This module handles storage
909
+ pub mod store"#;
910
+ let doc = extract_doc_comment(signature);
911
+ assert_eq!(doc, Some("Module documentation\nThis module handles storage".to_string()));
912
+ }
913
+
914
+ #[test]
915
+ fn test_extract_jsdoc_comment() {
916
+ let signature = r#"/**
917
+ * Create a new instance
918
+ * @param name The name
919
+ */
920
+ function create(name: string)"#;
921
+ let doc = extract_doc_comment(signature);
922
+ assert_eq!(doc, Some("Create a new instance\n@param name The name".to_string()));
923
+ }
924
+
925
+ #[test]
926
+ fn test_extract_jsdoc_single_line() {
927
+ let signature = r#"/** Quick summary */
928
+ function test()"#;
929
+ let doc = extract_doc_comment(signature);
930
+ assert_eq!(doc, Some("Quick summary".to_string()));
931
+ }
932
+
933
+ #[test]
934
+ fn test_no_doc_comment() {
935
+ let signature = r#"pub fn new() -> Self"#;
936
+ let doc = extract_doc_comment(signature);
937
+ assert_eq!(doc, None);
938
+ }
939
+
940
+ #[test]
941
+ fn test_empty_signature() {
942
+ let doc = extract_doc_comment("");
943
+ assert_eq!(doc, None);
944
+ }
945
+
946
+ #[test]
947
+ fn test_regular_comment_not_extracted() {
948
+ let signature = r#"// This is a regular comment
949
+ pub fn new() -> Self"#;
950
+ let doc = extract_doc_comment(signature);
951
+ assert_eq!(doc, None);
952
+ }
724
953
  }
@@ -62,8 +62,8 @@ impl AstIndexCommand {
62
62
  patterns: Option<Vec<String>>,
63
63
  force: bool,
64
64
  ) -> Result<Self> {
65
- // Use local .ruvector for embeddings cache, but centralized DB for entities
66
- let index_path = project_dir.join(".ruvector");
65
+ // Use local .codesearch for embeddings cache, but centralized DB for entities
66
+ let index_path = project_dir.join(".codesearch");
67
67
  fs::create_dir_all(&index_path)?;
68
68
 
69
69
  // Embeddings are cached locally per project
@@ -188,7 +188,7 @@ impl AstIndexCommand {
188
188
  return false;
189
189
  }
190
190
 
191
- // Skip .ruvector directory
191
+ // Skip .codesearch directory
192
192
  if e.path().starts_with(&self.index_path) {
193
193
  return false;
194
194
  }
@@ -8,7 +8,7 @@ use crate::embeddings::EmbeddingsManager;
8
8
  use crate::search_engine::SearchEngine;
9
9
  use crate::sqlite_store::SqliteStore;
10
10
  use crate::migration_v2::MigrationV2;
11
- use local_ruvector::paths::{get_ruvector_dir, get_database_path};
11
+ use codesearch::paths::{get_codesearch_dir, get_database_path};
12
12
  // V1 index is deprecated - all operations use V2 (index_v2.db)
13
13
 
14
14
  pub struct InitCommand {
@@ -42,9 +42,9 @@ impl InitCommand {
42
42
  let _ = rusqlite::Connection::open_in_memory()
43
43
  .context("SQLite is not available")?;
44
44
 
45
- let ruvector_dir = get_ruvector_dir()?;
46
- if ruvector_dir.exists() {
47
- info!("RuVector already initialized at: {}", ruvector_dir.display());
45
+ let codesearch_dir = get_codesearch_dir()?;
46
+ if codesearch_dir.exists() {
47
+ info!("CodeSearch already initialized at: {}", codesearch_dir.display());
48
48
  }
49
49
 
50
50
  info!("Environment check passed");
@@ -52,24 +52,24 @@ impl InitCommand {
52
52
  }
53
53
 
54
54
  pub fn execute(&self) -> Result<()> {
55
- let ruvector_dir = get_ruvector_dir()?;
55
+ let codesearch_dir = get_codesearch_dir()?;
56
56
 
57
57
  // Create directory if doesn't exist (idempotent)
58
- if !ruvector_dir.exists() {
59
- info!("Creating centralized RuVector directory: {}", ruvector_dir.display());
60
- fs::create_dir_all(&ruvector_dir)
61
- .context("Failed to create RuVector directory")?;
62
- fs::create_dir_all(ruvector_dir.join("embeddings"))
58
+ if !codesearch_dir.exists() {
59
+ info!("Creating centralized CodeSearch directory: {}", codesearch_dir.display());
60
+ fs::create_dir_all(&codesearch_dir)
61
+ .context("Failed to create CodeSearch directory")?;
62
+ fs::create_dir_all(codesearch_dir.join("embeddings"))
63
63
  .context("Failed to create embeddings directory")?;
64
64
  // V1 index directory no longer created - using centralized V2 database
65
- fs::create_dir_all(ruvector_dir.join("cache"))
65
+ fs::create_dir_all(codesearch_dir.join("cache"))
66
66
  .context("Failed to create cache directory")?;
67
67
  } else {
68
- info!("Using existing centralized RuVector directory: {}", ruvector_dir.display());
68
+ info!("Using existing centralized CodeSearch directory: {}", codesearch_dir.display());
69
69
  }
70
70
 
71
71
  // Create configuration file if missing
72
- if !ruvector_dir.join("config.json").exists() {
72
+ if !codesearch_dir.join("config.json").exists() {
73
73
  self.create_config()?;
74
74
  }
75
75
 
@@ -83,7 +83,7 @@ impl InitCommand {
83
83
  }
84
84
 
85
85
  // Initialize embeddings manager
86
- if !ruvector_dir.join("embeddings").exists() {
86
+ if !codesearch_dir.join("embeddings").exists() {
87
87
  self.initialize_embeddings()?;
88
88
  }
89
89
 
@@ -95,8 +95,8 @@ impl InitCommand {
95
95
  }
96
96
 
97
97
  fn create_config(&self) -> Result<()> {
98
- let ruvector_dir = get_ruvector_dir()?;
99
- let config_path = ruvector_dir.join("config.json");
98
+ let codesearch_dir = get_codesearch_dir()?;
99
+ let config_path = codesearch_dir.join("config.json");
100
100
 
101
101
  let config = json!({
102
102
  "version": "1.0.0",
@@ -129,7 +129,7 @@ impl InitCommand {
129
129
 
130
130
  // Initialize Schema V2 using CREATE TABLE IF NOT EXISTS (always safe)
131
131
  let mut conn = rusqlite::Connection::open(&db_path)?;
132
- local_ruvector::schema_v2::SchemaV2::initialize(&conn)?;
132
+ codesearch::schema_v2::SchemaV2::initialize(&conn)?;
133
133
 
134
134
  // Run v2 migration to add multi-project isolation
135
135
  info!("Running database migrations...");
@@ -163,14 +163,14 @@ impl InitCommand {
163
163
  let conn = rusqlite::Connection::open(&db_path)?;
164
164
 
165
165
  // Re-run schema initialization (uses IF NOT EXISTS)
166
- local_ruvector::schema_v2::SchemaV2::initialize(&conn)?;
166
+ codesearch::schema_v2::SchemaV2::initialize(&conn)?;
167
167
 
168
168
  debug!("Schema tables recreated (non-destructive)");
169
169
  Ok(())
170
170
  }
171
171
 
172
172
  fn initialize_embeddings(&self) -> Result<()> {
173
- let embeddings_dir = get_ruvector_dir()?;
173
+ let embeddings_dir = get_codesearch_dir()?;
174
174
  let _ = EmbeddingsManager::new(&embeddings_dir)?;
175
175
 
176
176
  debug!("Embeddings manager initialized");
@@ -7,7 +7,7 @@ use crate::migration_tx::MigrationWithTx;
7
7
 
8
8
  #[derive(Debug, Clone)]
9
9
  pub enum SourceType {
10
- RuVectorPython,
10
+ CodeSearchPython,
11
11
  CodeBERT,
12
12
  Whoosh,
13
13
  Elastic,
@@ -37,7 +37,7 @@ impl MigrationCommand {
37
37
 
38
38
  pub fn execute(&self) -> Result<()> {
39
39
  match self.source_type {
40
- SourceType::RuVectorPython => self.migrate_from_python(),
40
+ SourceType::CodeSearchPython => self.migrate_from_python(),
41
41
  SourceType::CodeBERT => self.migrate_from_codebert(),
42
42
  SourceType::Whoosh => self.migrate_from_whoosh(),
43
43
  SourceType::Elastic => self.migrate_from_elastic(),
@@ -46,7 +46,7 @@ impl MigrationCommand {
46
46
 
47
47
  /// Execute migration with transaction support
48
48
  pub fn execute_with_tx(&self) -> Result<()> {
49
- let db_path = self.project_dir.join(".ruvector/index_v2.db");
49
+ let db_path = self.project_dir.join(".codesearch/index_v2.db");
50
50
 
51
51
  // Ensure database directory exists
52
52
  std::fs::create_dir_all(db_path.parent().unwrap())
@@ -59,7 +59,7 @@ impl MigrationCommand {
59
59
 
60
60
  // Use the transaction-aware migration
61
61
  match self.source_type {
62
- SourceType::RuVectorPython => {
62
+ SourceType::CodeSearchPython => {
63
63
  MigrationWithTx::migrate_v1_to_v2_atomic(&mut conn)?;
64
64
  MigrationWithTx::validate_migration(&mut conn)?;
65
65
  }
@@ -74,7 +74,7 @@ impl MigrationCommand {
74
74
  }
75
75
 
76
76
  fn migrate_from_python(&self) -> Result<()> {
77
- println!("⚠️ Migration from Python RuVector not yet implemented");
77
+ println!("⚠️ Migration from Python CodeSearch not yet implemented");
78
78
  if self.dry_run {
79
79
  println!("Would migrate from: {}", self.source_path.display());
80
80
  }
@@ -9,6 +9,8 @@ use serde::Serialize;
9
9
  use crate::query_v2::{QueryV2, SearchResult};
10
10
  use crate::paths::get_database_path;
11
11
  use crate::path_validator;
12
+ use codesearch::store_pgvector::PgvectorStore;
13
+ use codesearch::embeddings::EmbeddingsManager;
12
14
 
13
15
  #[derive(Debug, Clone)]
14
16
  pub enum OutputFormat {
@@ -27,11 +29,12 @@ pub struct QueryConfig {
27
29
  pub file_filter: Option<String>,
28
30
  }
29
31
 
30
- #[derive(Debug)]
31
32
  pub struct QueryCommand {
32
33
  project_dir: PathBuf,
33
34
  config: QueryConfig,
34
35
  query_v2: QueryV2,
36
+ pgvector_store: Option<PgvectorStore>,
37
+ embeddings_manager: Option<EmbeddingsManager>,
35
38
  }
36
39
 
37
40
  impl QueryCommand {
@@ -43,6 +46,7 @@ impl QueryCommand {
43
46
  output_format: OutputFormat,
44
47
  context_lines: usize,
45
48
  file_filter: Option<String>,
49
+ pg_url: Option<&str>,
46
50
  ) -> Result<Self> {
47
51
  // Canonicalize project_dir at the start for security
48
52
  let canonical_project_dir = path_validator::canonicalize(project_dir)?;
@@ -51,6 +55,28 @@ impl QueryCommand {
51
55
  let db_path = get_database_path()?;
52
56
  let query_v2 = QueryV2::new(&db_path)?;
53
57
 
58
+ // Initialize pgvector store if connection URL provided
59
+ let (pgvector_store, embeddings_manager) = if let Some(url) = pg_url {
60
+ info!("Initializing pgvector store for queries");
61
+ let rt = tokio::runtime::Runtime::new()?;
62
+ match rt.block_on(PgvectorStore::new(url)) {
63
+ Ok(store) => {
64
+ info!("Successfully connected to pgvector");
65
+ // Need embeddings manager to generate query embeddings
66
+ let index_path = crate::paths::get_codesearch_dir()?;
67
+ let embeddings_mgr = EmbeddingsManager::new(&index_path)?;
68
+ (Some(store), Some(embeddings_mgr))
69
+ }
70
+ Err(e) => {
71
+ warn!("Failed to connect to pgvector: {}. Using SQLite only.", e);
72
+ (None, None)
73
+ }
74
+ }
75
+ } else {
76
+ info!("No pg_url provided, using SQLite only");
77
+ (None, None)
78
+ };
79
+
54
80
  Ok(Self {
55
81
  project_dir: canonical_project_dir,
56
82
  config: QueryConfig {
@@ -62,6 +88,8 @@ impl QueryCommand {
62
88
  file_filter,
63
89
  },
64
90
  query_v2,
91
+ pgvector_store,
92
+ embeddings_manager,
65
93
  })
66
94
  }
67
95
 
@@ -72,8 +100,41 @@ impl QueryCommand {
72
100
  let max_results = self.config.max_results.unwrap_or(10);
73
101
  let threshold = self.config.threshold.unwrap_or(0.3);
74
102
 
75
- // Perform search with project root isolation
76
- let results = self.query_v2.search(&self.config.query, max_results, threshold, &self.project_dir)?;
103
+ // Perform search - use pgvector if available, otherwise SQLite
104
+ let results: Vec<SearchResult> = if let (Some(ref pgvector_store), Some(ref embeddings_mgr)) =
105
+ (&self.pgvector_store, &self.embeddings_manager) {
106
+ info!("Using pgvector for semantic search");
107
+
108
+ // Generate embedding for query
109
+ let query_texts: Vec<String> = vec![self.config.query.clone()];
110
+ let query_embeddings: Vec<Vec<f32>> = embeddings_mgr.generate_embeddings(&query_texts)?;
111
+ let query_embedding: &[f32] = &query_embeddings[0];
112
+
113
+ // Search pgvector
114
+ let rt = tokio::runtime::Runtime::new()?;
115
+ let project_root_str = self.project_dir.to_string_lossy().to_string();
116
+ let pg_results = rt.block_on(
117
+ pgvector_store.search_similar(
118
+ query_embedding,
119
+ max_results,
120
+ threshold,
121
+ Some(&project_root_str),
122
+ )
123
+ )?;
124
+
125
+ // Convert pgvector SearchResult to query_v2 SearchResult
126
+ pg_results.into_iter().map(|r| SearchResult {
127
+ entity_kind: r.entity_kind,
128
+ entity_name: r.entity_name,
129
+ file_path: r.file_path,
130
+ similarity: r.similarity,
131
+ line_start: Some(r.line_number),
132
+ line_end: None,
133
+ }).collect()
134
+ } else {
135
+ info!("Using SQLite for search");
136
+ self.query_v2.search(&self.config.query, max_results, threshold, &self.project_dir)?
137
+ };
77
138
 
78
139
  // Filter by file if specified
79
140
  let final_results: Vec<SearchResult> = if let Some(ref file_filter) = self.config.file_filter {