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.
- package/.claude/agents/AGENT_LIFECYCLE.md +1 -1
- package/.claude/agents/SHARED_PROTOCOL.md +33 -5
- package/.claude/agents/cfn-dev-team/analysts/analyst.md +4 -4
- package/.claude/agents/cfn-dev-team/analysts/root-cause-analyst.md +4 -4
- package/.claude/agents/cfn-dev-team/architecture/api-designer-persona.md +4 -4
- package/.claude/agents/cfn-dev-team/architecture/base-template-generator.md +4 -4
- package/.claude/agents/cfn-dev-team/architecture/goal-planner.md +4 -4
- package/.claude/agents/cfn-dev-team/architecture/system-architect.md +4 -4
- package/.claude/agents/cfn-dev-team/coordinators/cfn-frontend-coordinator.md +4 -4
- package/.claude/agents/cfn-dev-team/coordinators/handoff-coordinator.md +4 -4
- package/.claude/agents/cfn-dev-team/dev-ops/devops-engineer.md +4 -4
- package/.claude/agents/cfn-dev-team/dev-ops/docker-specialist.md +4 -4
- package/.claude/agents/cfn-dev-team/dev-ops/fly-io-specialist.md +418 -0
- package/.claude/agents/cfn-dev-team/dev-ops/github-commit-agent.md +4 -4
- package/.claude/agents/cfn-dev-team/developers/api-gateway-specialist.md +4 -4
- package/.claude/agents/cfn-dev-team/developers/backend-developer.md +4 -4
- package/.claude/agents/cfn-dev-team/developers/data/data-engineer.md +4 -4
- package/.claude/agents/cfn-dev-team/developers/database/database-architect.md +4 -4
- package/.claude/agents/cfn-dev-team/developers/database/mem0-specialist.md +579 -0
- package/.claude/agents/cfn-dev-team/developers/database/memgraph-specialist.md +722 -0
- package/.claude/agents/cfn-dev-team/developers/database/supabase-specialist.md +4 -4
- package/.claude/agents/cfn-dev-team/developers/frontend/mobile-dev.md +4 -4
- package/.claude/agents/cfn-dev-team/developers/frontend/react-frontend-engineer.md +4 -4
- package/.claude/agents/cfn-dev-team/developers/frontend/typescript-specialist.md +4 -4
- package/.claude/agents/cfn-dev-team/developers/frontend/ui-designer.md +4 -4
- package/.claude/agents/cfn-dev-team/developers/graphql-specialist.md +4 -4
- package/.claude/agents/cfn-dev-team/developers/rust-developer.md +4 -4
- package/.claude/agents/cfn-dev-team/documentation/agent-type-guidelines.md +4 -4
- package/.claude/agents/cfn-dev-team/documentation/api-documentation.md +4 -4
- package/.claude/agents/cfn-dev-team/documentation/pseudocode.md +5 -5
- package/.claude/agents/cfn-dev-team/documentation/specification-agent.md +5 -5
- package/.claude/agents/cfn-dev-team/product-owners/accessibility-advocate-persona.md +4 -4
- package/.claude/agents/cfn-dev-team/product-owners/cto-agent.md +4 -4
- package/.claude/agents/cfn-dev-team/product-owners/power-user-persona.md +4 -4
- package/.claude/agents/cfn-dev-team/product-owners/product-owner.md +4 -4
- package/.claude/agents/cfn-dev-team/reviewers/code-reviewer.md +4 -4
- package/.claude/agents/cfn-dev-team/reviewers/quality/code-quality-validator.md +4 -4
- package/.claude/agents/cfn-dev-team/reviewers/quality/cyclomatic-complexity-reducer.md +4 -4
- package/.claude/agents/cfn-dev-team/reviewers/quality/perf-analyzer.md +4 -4
- package/.claude/agents/cfn-dev-team/reviewers/quality/performance-benchmarker.md +4 -4
- package/.claude/agents/cfn-dev-team/reviewers/quality/quality-metrics.md +4 -4
- package/.claude/agents/cfn-dev-team/testers/api-testing-specialist.md +4 -4
- package/.claude/agents/cfn-dev-team/testers/chaos-engineering-specialist.md +4 -4
- package/.claude/agents/cfn-dev-team/testers/contract-tester.md +4 -4
- package/.claude/agents/cfn-dev-team/testers/e2e/playwright-tester.md +4 -4
- package/.claude/agents/cfn-dev-team/testers/integration-tester.md +4 -4
- package/.claude/agents/cfn-dev-team/testers/interaction-tester.md +4 -4
- package/.claude/agents/cfn-dev-team/testers/load-testing-specialist.md +4 -4
- package/.claude/agents/cfn-dev-team/testers/mutation-testing-specialist.md +4 -4
- package/.claude/agents/cfn-dev-team/testers/playwright-tester.md +4 -4
- package/.claude/agents/cfn-dev-team/{testing → testers}/test-validation-agent.md +4 -4
- package/.claude/agents/cfn-dev-team/testers/tester.md +39 -4
- package/.claude/agents/cfn-dev-team/testers/unit/tdd-london-unit-swarm.md +4 -4
- package/.claude/agents/cfn-dev-team/testers/validation/validation-production-validator.md +4 -4
- package/.claude/agents/cfn-dev-team/utility/agent-builder.md +7 -7
- package/.claude/agents/cfn-dev-team/utility/memory-leak-specialist.md +4 -4
- package/.claude/agents/cfn-dev-team/utility/researcher.md +4 -4
- package/.claude/agents/cfn-dev-team/utility/z-ai-specialist.md +4 -4
- package/.claude/agents/custom/claude-code-expert.md +1 -1
- package/.claude/agents/project-only-agents/npm-package-specialist.md +1 -1
- package/.claude/{agents/cfn-dev-team/utility → cfn-extras/agents}/context-curator.md +4 -4
- package/.claude/{agents/custom → cfn-extras/agents/custom-agents}/cfn-docker-expert.md +4 -4
- package/.claude/{agents/custom → cfn-extras/agents/custom-agents}/cfn-redis-operations.md +1 -1
- package/.claude/{agents/custom → cfn-extras/agents/custom-agents}/cfn-system-expert.md +4 -4
- package/.claude/{agents/custom → cfn-extras/agents/custom-agents}/trigger-dev-expert.md +4 -4
- package/.claude/{agents/cfn-dev-team/coordinators → cfn-extras/agents/deprecated-coordinators}/consensus-builder.md +4 -4
- package/.claude/{agents/cfn-dev-team/coordinators → cfn-extras/agents/deprecated-coordinators}/multi-sprint-coordinator.md +4 -4
- package/.claude/{agents → cfn-extras/agents/docker-team}/docker-coordinators/cfn-docker-v3-coordinator.md +1 -1
- package/.claude/{agents/cfn-dev-team/dev-ops → cfn-extras/agents}/kubernetes-specialist.md +4 -4
- package/.claude/{agents/cfn-dev-team/architecture → cfn-extras/agents}/planner.md +4 -4
- package/.claude/cfn-extras/skills/cfn-cerebras-coordinator/QUICKSTART.md +1 -1
- package/.claude/cfn-extras/skills/cfn-cerebras-coordinator/README.md +19 -19
- package/.claude/cfn-extras/skills/cfn-cerebras-coordinator/SKILL.md +7 -7
- package/.claude/cfn-extras/skills/cfn-cerebras-coordinator/TDD_COORDINATOR_OVERVIEW.md +3 -3
- package/.claude/cfn-extras/skills/cfn-cerebras-coordinator/TEST_RESULTS.md +3 -3
- package/.claude/cfn-extras/skills/cfn-cerebras-coordinator/coordinate-generation.sh +19 -19
- package/.claude/cfn-extras/skills/cfn-cerebras-coordinator/example-fix-scenario.md +4 -4
- package/.claude/cfn-extras/skills/cfn-cerebras-coordinator/example-usage.sh +1 -1
- package/.claude/cfn-extras/skills/cfn-cerebras-coordinator/feedback-logger.sh +5 -5
- package/.claude/cfn-extras/skills/cfn-cerebras-coordinator/fix-existing-code-v2.sh +2 -2
- package/.claude/cfn-extras/skills/cfn-cerebras-coordinator/fix-existing-code.sh +10 -10
- package/.claude/cfn-extras/skills/cfn-cerebras-coordinator/pattern-examples.md +3 -3
- package/.claude/cfn-extras/skills/cfn-cerebras-coordinator/query-patterns.sh +9 -9
- package/.claude/cfn-extras/skills/cfn-cerebras-coordinator/tdd-coordinator.sh +8 -8
- package/.claude/cfn-extras/skills/cfn-cerebras-coordinator/test-tdd-coordinator.sh +1 -1
- package/.claude/commands/README.md +1 -1
- package/.claude/commands/{cfn-ruvector → cfn-codesearch}/cfn-codebase-reindex.md +6 -6
- package/.claude/commands/{cfn-ruvector → cfn-codesearch}/cfn-codebase-search.md +8 -8
- package/.claude/commands/{cfn-ruvector → cfn-codesearch}/cfn-detect-stale-docs.md +3 -3
- package/.claude/commands/cfn-codesearch-search.md +36 -0
- package/.claude/commands/cfn-fix-errors.md +1 -1
- package/.claude/commands/cfn-loop-task.md +66 -2
- package/.claude/commands/cfn-update-search-index.md +2 -2
- package/.claude/hooks/cfn-SessionStart-cfn-build-codesearch.sh +24 -0
- package/.claude/hooks/cfn-bash-search-hook.sh +6 -6
- package/.claude/hooks/cfn-smart-search-hook.sh +15 -15
- package/.claude/hooks/cfn-subagent-stop.sh +9 -9
- package/.claude/hooks/post-commit-codebase-index +14 -14
- package/.claude/skills/{bulk-add-ruvector-instructions.sh → bulk-add-codesearch-instructions.sh} +14 -14
- package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/AGENT_INTEGRATION_PATTERNS.md +20 -20
- package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/AGENT_LIFECYCLE_INTEGRATION.md +12 -12
- package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/Cargo.toml +9 -4
- package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/EXTRACTION_EXAMPLES.md +6 -6
- package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/IMMEDIATE_ACTION_REQUIRED.md +9 -9
- package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/README.md +7 -7
- package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/SCHEMA_V2_IMPLEMENTATION.md +1 -1
- package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/SECURITY_FINDINGS_SUMMARY.txt +1 -1
- package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/SECURITY_IMPLEMENTATION.md +3 -3
- package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/SECURITY_TESTING_COMPLETION.md +5 -5
- package/.claude/skills/cfn-codesearch/SKILL.md +143 -0
- package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/analyze-agent-failures.sh +11 -11
- package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/cfn-integration.sh +29 -29
- package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/docs/EXECUTIVE_SUMMARY.txt +1 -1
- package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/docs/PHASE_4_QUERY_API.md +24 -24
- package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/docs/RUST_AST_EXTRACTOR_IMPLEMENTATION.md +7 -7
- package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/docs/TRANSACTION_MANAGEMENT.md +1 -1
- package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/docs/VALIDATION_FINDINGS.txt +1 -1
- package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/epic-ast-indexer.json +8 -8
- package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/index-code.sh +11 -11
- package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/index_all.sh +2 -2
- package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/ingest-agent-transcript.sh +10 -10
- package/.claude/skills/{cfn-local-ruvector-accelerator/init-local-ruvector.sh → cfn-codesearch/init-local-codesearch.sh} +16 -16
- package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/project-structure.md +10 -10
- package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/query-local.sh +6 -6
- package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/cli/cleanup.rs +1 -1
- package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/cli/index.rs +238 -9
- package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/cli/index_ast.rs +3 -3
- package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/cli/init.rs +19 -19
- package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/cli/migration.rs +5 -5
- package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/cli/query.rs +64 -3
- package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/cli/reset.rs +5 -5
- package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/embeddings.rs +19 -5
- package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/lib.rs +6 -4
- package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/main.rs +37 -27
- package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/migration_v2.rs +1 -1
- package/.claude/skills/cfn-codesearch/src/paths.rs +37 -0
- package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/query_v2.rs +3 -4
- package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/search_engine.rs +3 -3
- package/.claude/skills/cfn-codesearch/src/store_pgvector.rs +301 -0
- package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/store_v2.rs +12 -1
- package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/test-agent-lifecycle-integration.sh +6 -6
- package/.claude/skills/{cfn-local-ruvector-accelerator/test-local-ruvector.sh → cfn-codesearch/test-local-codesearch.sh} +7 -7
- package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/test_query_api.sh +2 -2
- package/.claude/skills/cfn-epic-creator/SKILL.md +110 -2
- package/.claude/skills/cfn-epic-creator/invoke.sh +120 -1
- package/.claude/skills/cfn-knowledge-base/lib/playbook/SKILL.md +1 -1
- package/.claude/skills/cfn-mdap-context-injection/SKILL.md +2 -2
- package/.claude/skills/cfn-mdap-context-injection/inject.sh +23 -23
- package/CLAUDE.md +3 -3
- package/package.json +11 -11
- package/readme/feature-status.md +411 -0
- package/.claude/agents/docker-ts-fixer.md +0 -65
- package/.claude/commands/cfn-ruvector-search.md +0 -36
- package/.claude/hooks/cfn-SessionStart-cfn-build-ruvector.sh +0 -24
- package/.claude/skills/cfn-local-ruvector-accelerator/.claude/hooks/SessionStart-cfn-build-ruvector.sh +0 -13
- package/.claude/skills/cfn-local-ruvector-accelerator/SKILL.md +0 -143
- package/.claude/skills/cfn-local-ruvector-accelerator/src/paths.rs +0 -31
- /package/.claude/{agents/custom → cfn-extras/agents/custom-agents}/cfn-loops-cli-expert.md +0 -0
- /package/.claude/{agents/csuite → cfn-extras/agents/custom-agents}/cto-agent.md +0 -0
- /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/Cargo.toml.backup +0 -0
- /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/embeddings_manager.py.backup +0 -0
- /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/index/index.bin +0 -0
- /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/index/metadata.json +0 -0
- /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/index-code.sh.backup +0 -0
- /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/query-agent-patterns.sh +0 -0
- /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/requirements.txt +0 -0
- /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/search_engine_v2.py.backup +0 -0
- /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/sqlite_store.py.backup +0 -0
- /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/cli/export.rs +0 -0
- /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/cli/find.rs +0 -0
- /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/cli/index_modified.rs +0 -0
- /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/cli/mod.rs +0 -0
- /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/cli/refs.rs +0 -0
- /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/cli/stats.rs +0 -0
- /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/extractors/mod.rs +0 -0
- /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/extractors/rust.rs +0 -0
- /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/extractors/rust_placeholder.rs +0 -0
- /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/extractors/text_fallback.rs +0 -0
- /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/extractors/typescript.rs +0 -0
- /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/extractors/typescript_full.rs +0 -0
- /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/main.rs.backup +0 -0
- /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/migration.rs +0 -0
- /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/migration_backup.rs +0 -0
- /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/migration_tx.rs +0 -0
- /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/path_validator.rs +0 -0
- /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/query_api.rs +0 -0
- /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/schema_v2.rs +0 -0
- /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/security_tests.rs +0 -0
- /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/sqlite_store.rs +0 -0
- /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/store_v2_backup.rs +0 -0
- /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/store_v2_fixed.rs +0 -0
- /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/store_v2_tx.rs +0 -0
- /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/test_schema.rs +0 -0
- /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/transaction_tests.rs +0 -0
- /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/test_ast_indexing.rs +0 -0
- /package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/test_schema.sql +0 -0
- /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
|
|
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/
|
|
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
|
|
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:
|
|
90
|
-
echo " Run: local-
|
|
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-
|
|
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(".
|
|
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
|
-
//! #
|
|
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-
|
|
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, .
|
|
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/
|
|
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
|
|
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
|
-
".
|
|
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 =
|
|
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:
|
|
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
|
}
|
package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/cli/index_ast.rs
RENAMED
|
@@ -62,8 +62,8 @@ impl AstIndexCommand {
|
|
|
62
62
|
patterns: Option<Vec<String>>,
|
|
63
63
|
force: bool,
|
|
64
64
|
) -> Result<Self> {
|
|
65
|
-
// Use local .
|
|
66
|
-
let index_path = project_dir.join(".
|
|
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 .
|
|
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
|
|
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
|
|
46
|
-
if
|
|
47
|
-
info!("
|
|
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
|
|
55
|
+
let codesearch_dir = get_codesearch_dir()?;
|
|
56
56
|
|
|
57
57
|
// Create directory if doesn't exist (idempotent)
|
|
58
|
-
if !
|
|
59
|
-
info!("Creating centralized
|
|
60
|
-
fs::create_dir_all(&
|
|
61
|
-
.context("Failed to create
|
|
62
|
-
fs::create_dir_all(
|
|
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(
|
|
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
|
|
68
|
+
info!("Using existing centralized CodeSearch directory: {}", codesearch_dir.display());
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
// Create configuration file if missing
|
|
72
|
-
if !
|
|
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 !
|
|
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
|
|
99
|
-
let config_path =
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
173
|
+
let embeddings_dir = get_codesearch_dir()?;
|
|
174
174
|
let _ = EmbeddingsManager::new(&embeddings_dir)?;
|
|
175
175
|
|
|
176
176
|
debug!("Embeddings manager initialized");
|
package/.claude/skills/{cfn-local-ruvector-accelerator → cfn-codesearch}/src/cli/migration.rs
RENAMED
|
@@ -7,7 +7,7 @@ use crate::migration_tx::MigrationWithTx;
|
|
|
7
7
|
|
|
8
8
|
#[derive(Debug, Clone)]
|
|
9
9
|
pub enum SourceType {
|
|
10
|
-
|
|
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::
|
|
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(".
|
|
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::
|
|
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
|
|
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
|
|
76
|
-
let results =
|
|
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 {
|