claude-code-workflow 6.3.18 → 6.3.20
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/CLAUDE.md +8 -5
- package/.claude/agents/action-planning-agent.md +26 -2
- package/.claude/agents/code-developer.md +132 -43
- package/.claude/agents/debug-explore-agent.md +434 -0
- package/.claude/agents/issue-plan-agent.md +31 -2
- package/.claude/agents/test-fix-agent.md +14 -0
- package/.claude/commands/issue/discover.md +41 -0
- package/.claude/commands/issue/execute.md +200 -19
- package/.claude/commands/issue/new.md +93 -3
- package/.claude/commands/issue/plan.md +9 -3
- package/.claude/commands/issue/queue.md +94 -39
- package/.claude/commands/memory/swagger-docs.md +773 -0
- package/.claude/commands/workflow/brainstorm/auto-parallel.md +21 -21
- package/.claude/commands/workflow/execute.md +54 -34
- package/.claude/commands/workflow/lite-execute.md +48 -164
- package/.claude/commands/workflow/lite-fix.md +4 -4
- package/.claude/commands/workflow/lite-plan.md +5 -5
- package/.claude/commands/workflow/plan.md +27 -27
- package/.claude/commands/workflow/review.md +42 -17
- package/.claude/commands/workflow/tdd-plan.md +25 -25
- package/.claude/commands/workflow/test-fix-gen.md +10 -10
- package/.claude/commands/workflow/test-gen.md +14 -14
- package/.claude/commands/workflow/ui-design/explore-auto.md +21 -21
- package/.claude/commands/workflow/ui-design/imitate-auto.md +24 -24
- package/.claude/skills/_shared/SKILL-DESIGN-SPEC.md +693 -0
- package/.claude/skills/ccw/SKILL.md +462 -0
- package/.claude/skills/ccw/index/command-capabilities.json +127 -0
- package/.claude/skills/ccw/index/intent-rules.json +136 -0
- package/.claude/skills/ccw/index/workflow-chains.json +451 -0
- package/.claude/skills/ccw/phases/actions/bugfix.md +218 -0
- package/.claude/skills/ccw/phases/actions/coupled.md +194 -0
- package/.claude/skills/ccw/phases/actions/docs.md +93 -0
- package/.claude/skills/ccw/phases/actions/full.md +154 -0
- package/.claude/skills/ccw/phases/actions/issue.md +201 -0
- package/.claude/skills/ccw/phases/actions/rapid.md +104 -0
- package/.claude/skills/ccw/phases/actions/review-fix.md +84 -0
- package/.claude/skills/ccw/phases/actions/tdd.md +66 -0
- package/.claude/skills/ccw/phases/actions/ui.md +79 -0
- package/.claude/skills/ccw/phases/orchestrator.md +435 -0
- package/.claude/skills/ccw/specs/intent-classification.md +336 -0
- package/.claude/skills/ccw-help/SKILL.md +177 -0
- package/.claude/skills/ccw-help/index/all-agents.json +82 -0
- package/.claude/skills/{command-guide → ccw-help}/index/all-commands.json +183 -73
- package/.claude/skills/{command-guide → ccw-help}/index/by-category.json +187 -73
- package/.claude/skills/{command-guide → ccw-help}/index/by-use-case.json +295 -185
- package/.claude/skills/{command-guide → ccw-help}/index/command-relationships.json +19 -166
- package/.claude/skills/{command-guide → ccw-help}/index/essential-commands.json +10 -10
- package/.claude/skills/ccw-help/scripts/analyze_commands.py +337 -0
- package/.claude/skills/code-reviewer/README.md +340 -0
- package/.claude/skills/code-reviewer/SKILL.md +308 -0
- package/.claude/skills/code-reviewer/phases/01-code-discovery.md +246 -0
- package/.claude/skills/code-reviewer/phases/02-security-analysis.md +442 -0
- package/.claude/skills/code-reviewer/phases/03-best-practices-review.md +36 -0
- package/.claude/skills/code-reviewer/phases/04-report-generation.md +278 -0
- package/.claude/skills/code-reviewer/specs/best-practices-requirements.md +346 -0
- package/.claude/skills/code-reviewer/specs/quality-standards.md +252 -0
- package/.claude/skills/code-reviewer/specs/security-requirements.md +243 -0
- package/.claude/skills/code-reviewer/templates/best-practice-finding.md +234 -0
- package/.claude/skills/code-reviewer/templates/report-template.md +316 -0
- package/.claude/skills/code-reviewer/templates/security-finding.md +161 -0
- package/.claude/skills/skill-generator/SKILL.md +187 -0
- package/.claude/skills/skill-generator/phases/01-requirements-discovery.md +239 -0
- package/.claude/skills/skill-generator/phases/02-structure-generation.md +207 -0
- package/.claude/skills/skill-generator/phases/03-phase-generation.md +802 -0
- package/.claude/skills/skill-generator/phases/04-specs-templates.md +328 -0
- package/.claude/skills/skill-generator/phases/05-validation.md +334 -0
- package/.claude/skills/skill-generator/specs/cli-integration.md +448 -0
- package/.claude/skills/skill-generator/specs/execution-modes.md +396 -0
- package/.claude/skills/skill-generator/specs/scripting-integration.md +265 -0
- package/.claude/skills/skill-generator/specs/skill-requirements.md +466 -0
- package/.claude/skills/skill-generator/templates/autonomous-action.md +517 -0
- package/.claude/skills/skill-generator/templates/autonomous-orchestrator.md +276 -0
- package/.claude/skills/skill-generator/templates/code-analysis-action.md +503 -0
- package/.claude/skills/skill-generator/templates/llm-action.md +355 -0
- package/.claude/skills/skill-generator/templates/script-bash.md +277 -0
- package/.claude/skills/skill-generator/templates/script-python.md +198 -0
- package/.claude/skills/skill-generator/templates/sequential-phase.md +441 -0
- package/.claude/skills/skill-generator/templates/skill-md.md +156 -0
- package/.claude/workflows/chinese-response.md +15 -28
- package/.claude/workflows/cli-templates/prompts/documentation/swagger-api.txt +266 -0
- package/.claude/workflows/cli-tools-usage.md +221 -177
- package/.claude/workflows/windows-platform.md +13 -10
- package/.codex/prompts/issue-execute.md +310 -82
- package/.codex/prompts/issue-queue.md +22 -0
- package/.codex/prompts/lite-execute.md +36 -11
- package/README.md +309 -305
- package/ccw/README.md +10 -4
- package/ccw/dist/cli.d.ts.map +1 -1
- package/ccw/dist/cli.js +4 -1
- package/ccw/dist/cli.js.map +1 -1
- package/ccw/dist/commands/cli.d.ts.map +1 -1
- package/ccw/dist/commands/cli.js +131 -34
- package/ccw/dist/commands/cli.js.map +1 -1
- package/ccw/dist/commands/issue.d.ts +152 -0
- package/ccw/dist/commands/issue.d.ts.map +1 -1
- package/ccw/dist/commands/issue.js +550 -85
- package/ccw/dist/commands/issue.js.map +1 -1
- package/ccw/dist/commands/serve.d.ts +1 -0
- package/ccw/dist/commands/serve.d.ts.map +1 -1
- package/ccw/dist/commands/serve.js +12 -5
- package/ccw/dist/commands/serve.js.map +1 -1
- package/ccw/dist/commands/stop.d.ts.map +1 -1
- package/ccw/dist/commands/stop.js +29 -5
- package/ccw/dist/commands/stop.js.map +1 -1
- package/ccw/dist/commands/tool.d.ts.map +1 -1
- package/ccw/dist/commands/tool.js +19 -2
- package/ccw/dist/commands/tool.js.map +1 -1
- package/ccw/dist/commands/view.d.ts +1 -0
- package/ccw/dist/commands/view.d.ts.map +1 -1
- package/ccw/dist/commands/view.js +10 -3
- package/ccw/dist/commands/view.js.map +1 -1
- package/ccw/dist/config/cli-settings-manager.d.ts +86 -0
- package/ccw/dist/config/cli-settings-manager.d.ts.map +1 -0
- package/ccw/dist/config/cli-settings-manager.js +392 -0
- package/ccw/dist/config/cli-settings-manager.js.map +1 -0
- package/ccw/dist/config/litellm-api-config-manager.d.ts +71 -5
- package/ccw/dist/config/litellm-api-config-manager.d.ts.map +1 -1
- package/ccw/dist/config/litellm-api-config-manager.js +290 -20
- package/ccw/dist/config/litellm-api-config-manager.js.map +1 -1
- package/ccw/dist/core/auth/csrf-manager.d.ts +18 -0
- package/ccw/dist/core/auth/csrf-manager.d.ts.map +1 -0
- package/ccw/dist/core/auth/csrf-manager.js +80 -0
- package/ccw/dist/core/auth/csrf-manager.js.map +1 -0
- package/ccw/dist/core/auth/csrf-middleware.d.ts +8 -0
- package/ccw/dist/core/auth/csrf-middleware.d.ts.map +1 -0
- package/ccw/dist/core/auth/csrf-middleware.js +141 -0
- package/ccw/dist/core/auth/csrf-middleware.js.map +1 -0
- package/ccw/dist/core/auth/middleware.d.ts +15 -0
- package/ccw/dist/core/auth/middleware.d.ts.map +1 -0
- package/ccw/dist/core/auth/middleware.js +76 -0
- package/ccw/dist/core/auth/middleware.js.map +1 -0
- package/ccw/dist/core/auth/token-manager.d.ts +41 -0
- package/ccw/dist/core/auth/token-manager.d.ts.map +1 -0
- package/ccw/dist/core/auth/token-manager.js +171 -0
- package/ccw/dist/core/auth/token-manager.js.map +1 -0
- package/ccw/dist/core/cache-manager.d.ts +6 -6
- package/ccw/dist/core/cache-manager.d.ts.map +1 -1
- package/ccw/dist/core/cache-manager.js +70 -48
- package/ccw/dist/core/cache-manager.js.map +1 -1
- package/ccw/dist/core/claude-freshness.d.ts.map +1 -1
- package/ccw/dist/core/claude-freshness.js +23 -3
- package/ccw/dist/core/claude-freshness.js.map +1 -1
- package/ccw/dist/core/core-memory-store.d.ts.map +1 -1
- package/ccw/dist/core/core-memory-store.js +2 -1
- package/ccw/dist/core/core-memory-store.js.map +1 -1
- package/ccw/dist/core/cors.d.ts +3 -0
- package/ccw/dist/core/cors.d.ts.map +1 -0
- package/ccw/dist/core/cors.js +10 -0
- package/ccw/dist/core/cors.js.map +1 -0
- package/ccw/dist/core/dashboard-generator-patch.js +0 -1
- package/ccw/dist/core/dashboard-generator-patch.js.map +1 -1
- package/ccw/dist/core/dashboard-generator.d.ts.map +1 -1
- package/ccw/dist/core/dashboard-generator.js +417 -416
- package/ccw/dist/core/dashboard-generator.js.map +1 -1
- package/ccw/dist/core/data-aggregator.js +2 -2
- package/ccw/dist/core/data-aggregator.js.map +1 -1
- package/ccw/dist/core/lite-scanner.d.ts +1 -1
- package/ccw/dist/core/lite-scanner.d.ts.map +1 -1
- package/ccw/dist/core/lite-scanner.js +130 -127
- package/ccw/dist/core/lite-scanner.js.map +1 -1
- package/ccw/dist/core/routes/auth-routes.d.ts +12 -0
- package/ccw/dist/core/routes/auth-routes.d.ts.map +1 -0
- package/ccw/dist/core/routes/auth-routes.js +80 -0
- package/ccw/dist/core/routes/auth-routes.js.map +1 -0
- package/ccw/dist/core/routes/ccw-routes.d.ts +1 -14
- package/ccw/dist/core/routes/ccw-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/ccw-routes.js +9 -4
- package/ccw/dist/core/routes/ccw-routes.js.map +1 -1
- package/ccw/dist/core/routes/claude-routes.d.ts +1 -14
- package/ccw/dist/core/routes/claude-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/claude-routes.js +98 -39
- package/ccw/dist/core/routes/claude-routes.js.map +1 -1
- package/ccw/dist/core/routes/cli-routes.d.ts +14 -12
- package/ccw/dist/core/routes/cli-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/cli-routes.js +122 -43
- package/ccw/dist/core/routes/cli-routes.js.map +1 -1
- package/ccw/dist/core/routes/cli-settings-routes.d.ts +11 -0
- package/ccw/dist/core/routes/cli-settings-routes.d.ts.map +1 -0
- package/ccw/dist/core/routes/cli-settings-routes.js +204 -0
- package/ccw/dist/core/routes/cli-settings-routes.js.map +1 -0
- package/ccw/dist/core/routes/codexlens/config-handlers.d.ts +6 -0
- package/ccw/dist/core/routes/codexlens/config-handlers.d.ts.map +1 -0
- package/ccw/dist/core/routes/codexlens/config-handlers.js +1195 -0
- package/ccw/dist/core/routes/codexlens/config-handlers.js.map +1 -0
- package/ccw/dist/core/routes/codexlens/index-handlers.d.ts +10 -0
- package/ccw/dist/core/routes/codexlens/index-handlers.d.ts.map +1 -0
- package/ccw/dist/core/routes/codexlens/index-handlers.js +322 -0
- package/ccw/dist/core/routes/codexlens/index-handlers.js.map +1 -0
- package/ccw/dist/core/routes/codexlens/semantic-handlers.d.ts +6 -0
- package/ccw/dist/core/routes/codexlens/semantic-handlers.d.ts.map +1 -0
- package/ccw/dist/core/routes/codexlens/semantic-handlers.js +865 -0
- package/ccw/dist/core/routes/codexlens/semantic-handlers.js.map +1 -0
- package/ccw/dist/core/routes/codexlens/utils.d.ts +23 -0
- package/ccw/dist/core/routes/codexlens/utils.d.ts.map +1 -0
- package/ccw/dist/core/routes/codexlens/utils.js +85 -0
- package/ccw/dist/core/routes/codexlens/utils.js.map +1 -0
- package/ccw/dist/core/routes/codexlens/watcher-handlers.d.ts +13 -0
- package/ccw/dist/core/routes/codexlens/watcher-handlers.d.ts.map +1 -0
- package/ccw/dist/core/routes/codexlens/watcher-handlers.js +235 -0
- package/ccw/dist/core/routes/codexlens/watcher-handlers.js.map +1 -0
- package/ccw/dist/core/routes/codexlens-routes.d.ts +2 -11
- package/ccw/dist/core/routes/codexlens-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/codexlens-routes.js +10 -981
- package/ccw/dist/core/routes/codexlens-routes.js.map +1 -1
- package/ccw/dist/core/routes/discovery-routes.d.ts +1 -35
- package/ccw/dist/core/routes/discovery-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/discovery-routes.js +25 -0
- package/ccw/dist/core/routes/discovery-routes.js.map +1 -1
- package/ccw/dist/core/routes/files-routes.d.ts +1 -14
- package/ccw/dist/core/routes/files-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/files-routes.js +57 -14
- package/ccw/dist/core/routes/files-routes.js.map +1 -1
- package/ccw/dist/core/routes/graph-routes.d.ts +1 -14
- package/ccw/dist/core/routes/graph-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/graph-routes.js +36 -37
- package/ccw/dist/core/routes/graph-routes.js.map +1 -1
- package/ccw/dist/core/routes/help-routes.d.ts +1 -14
- package/ccw/dist/core/routes/help-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/help-routes.js +5 -0
- package/ccw/dist/core/routes/help-routes.js.map +1 -1
- package/ccw/dist/core/routes/hooks-routes.d.ts +4 -14
- package/ccw/dist/core/routes/hooks-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/hooks-routes.js +43 -21
- package/ccw/dist/core/routes/hooks-routes.js.map +1 -1
- package/ccw/dist/core/routes/issue-routes.d.ts +1 -34
- package/ccw/dist/core/routes/issue-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/issue-routes.js +24 -0
- package/ccw/dist/core/routes/issue-routes.js.map +1 -1
- package/ccw/dist/core/routes/litellm-api-routes.d.ts +1 -14
- package/ccw/dist/core/routes/litellm-api-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/litellm-api-routes.js +513 -48
- package/ccw/dist/core/routes/litellm-api-routes.js.map +1 -1
- package/ccw/dist/core/routes/litellm-routes.d.ts +1 -14
- package/ccw/dist/core/routes/litellm-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/litellm-routes.js +28 -11
- package/ccw/dist/core/routes/litellm-routes.js.map +1 -1
- package/ccw/dist/core/routes/mcp-routes.d.ts +1 -14
- package/ccw/dist/core/routes/mcp-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/mcp-routes.js +99 -30
- package/ccw/dist/core/routes/mcp-routes.js.map +1 -1
- package/ccw/dist/core/routes/mcp-templates-db.d.ts.map +1 -1
- package/ccw/dist/core/routes/mcp-templates-db.js +30 -31
- package/ccw/dist/core/routes/mcp-templates-db.js.map +1 -1
- package/ccw/dist/core/routes/memory-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/memory-routes.js +74 -24
- package/ccw/dist/core/routes/memory-routes.js.map +1 -1
- package/ccw/dist/core/routes/nav-status-routes.d.ts +3 -0
- package/ccw/dist/core/routes/nav-status-routes.d.ts.map +1 -0
- package/ccw/dist/core/routes/nav-status-routes.js +217 -0
- package/ccw/dist/core/routes/nav-status-routes.js.map +1 -0
- package/ccw/dist/core/routes/rules-routes.d.ts +1 -14
- package/ccw/dist/core/routes/rules-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/rules-routes.js +481 -58
- package/ccw/dist/core/routes/rules-routes.js.map +1 -1
- package/ccw/dist/core/routes/session-routes.d.ts +1 -14
- package/ccw/dist/core/routes/session-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/session-routes.js +15 -3
- package/ccw/dist/core/routes/session-routes.js.map +1 -1
- package/ccw/dist/core/routes/skills-routes.d.ts +1 -14
- package/ccw/dist/core/routes/skills-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/skills-routes.js +394 -112
- package/ccw/dist/core/routes/skills-routes.js.map +1 -1
- package/ccw/dist/core/routes/status-routes.d.ts +1 -14
- package/ccw/dist/core/routes/status-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/status-routes.js +4 -0
- package/ccw/dist/core/routes/status-routes.js.map +1 -1
- package/ccw/dist/core/routes/system-routes.d.ts +4 -10
- package/ccw/dist/core/routes/system-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/system-routes.js +6 -4
- package/ccw/dist/core/routes/system-routes.js.map +1 -1
- package/ccw/dist/core/routes/types.d.ts +19 -0
- package/ccw/dist/core/routes/types.d.ts.map +1 -0
- package/ccw/dist/core/routes/types.js +2 -0
- package/ccw/dist/core/routes/types.js.map +1 -0
- package/ccw/dist/core/server.d.ts.map +1 -1
- package/ccw/dist/core/server.js +206 -29
- package/ccw/dist/core/server.js.map +1 -1
- package/ccw/dist/core/services/api-key-tester.d.ts +42 -0
- package/ccw/dist/core/services/api-key-tester.d.ts.map +1 -0
- package/ccw/dist/core/services/api-key-tester.js +126 -0
- package/ccw/dist/core/services/api-key-tester.js.map +1 -0
- package/ccw/dist/core/services/health-check-service.d.ts +88 -0
- package/ccw/dist/core/services/health-check-service.d.ts.map +1 -0
- package/ccw/dist/core/services/health-check-service.js +293 -0
- package/ccw/dist/core/services/health-check-service.js.map +1 -0
- package/ccw/dist/core/websocket.d.ts +9 -7
- package/ccw/dist/core/websocket.d.ts.map +1 -1
- package/ccw/dist/core/websocket.js +9 -4
- package/ccw/dist/core/websocket.js.map +1 -1
- package/ccw/dist/tools/claude-cli-tools.d.ts +152 -28
- package/ccw/dist/tools/claude-cli-tools.d.ts.map +1 -1
- package/ccw/dist/tools/claude-cli-tools.js +490 -100
- package/ccw/dist/tools/claude-cli-tools.js.map +1 -1
- package/ccw/dist/tools/cli-config-manager.d.ts +24 -8
- package/ccw/dist/tools/cli-config-manager.d.ts.map +1 -1
- package/ccw/dist/tools/cli-config-manager.js +76 -156
- package/ccw/dist/tools/cli-config-manager.js.map +1 -1
- package/ccw/dist/tools/cli-executor-core.d.ts +85 -0
- package/ccw/dist/tools/cli-executor-core.d.ts.map +1 -0
- package/ccw/dist/tools/cli-executor-core.js +1310 -0
- package/ccw/dist/tools/cli-executor-core.js.map +1 -0
- package/ccw/dist/tools/cli-executor-state.d.ts +241 -0
- package/ccw/dist/tools/cli-executor-state.d.ts.map +1 -0
- package/ccw/dist/tools/cli-executor-state.js +392 -0
- package/ccw/dist/tools/cli-executor-state.js.map +1 -0
- package/ccw/dist/tools/cli-executor-utils.d.ts +36 -0
- package/ccw/dist/tools/cli-executor-utils.d.ts.map +1 -0
- package/ccw/dist/tools/cli-executor-utils.js +298 -0
- package/ccw/dist/tools/cli-executor-utils.js.map +1 -0
- package/ccw/dist/tools/cli-executor.d.ts +3 -377
- package/ccw/dist/tools/cli-executor.d.ts.map +1 -1
- package/ccw/dist/tools/cli-executor.js +3 -1884
- package/ccw/dist/tools/cli-executor.js.map +1 -1
- package/ccw/dist/tools/cli-history-store.d.ts +2 -0
- package/ccw/dist/tools/cli-history-store.d.ts.map +1 -1
- package/ccw/dist/tools/cli-history-store.js.map +1 -1
- package/ccw/dist/tools/cli-output-converter.d.ts +192 -0
- package/ccw/dist/tools/cli-output-converter.d.ts.map +1 -0
- package/ccw/dist/tools/cli-output-converter.js +1047 -0
- package/ccw/dist/tools/cli-output-converter.js.map +1 -0
- package/ccw/dist/tools/cli-prompt-builder.d.ts +113 -0
- package/ccw/dist/tools/cli-prompt-builder.d.ts.map +1 -0
- package/ccw/dist/tools/cli-prompt-builder.js +363 -0
- package/ccw/dist/tools/cli-prompt-builder.js.map +1 -0
- package/ccw/dist/tools/codex-lens.d.ts +15 -1
- package/ccw/dist/tools/codex-lens.d.ts.map +1 -1
- package/ccw/dist/tools/codex-lens.js +289 -55
- package/ccw/dist/tools/codex-lens.js.map +1 -1
- package/ccw/dist/tools/detect-changed-modules.d.ts.map +1 -1
- package/ccw/dist/tools/detect-changed-modules.js +22 -4
- package/ccw/dist/tools/detect-changed-modules.js.map +1 -1
- package/ccw/dist/tools/index.d.ts.map +1 -1
- package/ccw/dist/tools/index.js +2 -0
- package/ccw/dist/tools/index.js.map +1 -1
- package/ccw/dist/tools/litellm-client.d.ts.map +1 -1
- package/ccw/dist/tools/litellm-client.js +10 -4
- package/ccw/dist/tools/litellm-client.js.map +1 -1
- package/ccw/dist/tools/litellm-executor.d.ts +2 -4
- package/ccw/dist/tools/litellm-executor.d.ts.map +1 -1
- package/ccw/dist/tools/litellm-executor.js +39 -8
- package/ccw/dist/tools/litellm-executor.js.map +1 -1
- package/ccw/dist/tools/native-session-discovery.d.ts +2 -0
- package/ccw/dist/tools/native-session-discovery.d.ts.map +1 -1
- package/ccw/dist/tools/native-session-discovery.js +197 -1
- package/ccw/dist/tools/native-session-discovery.js.map +1 -1
- package/ccw/dist/tools/session-manager.d.ts.map +1 -1
- package/ccw/dist/tools/session-manager.js +79 -0
- package/ccw/dist/tools/session-manager.js.map +1 -1
- package/ccw/dist/tools/skill-context-loader.d.ts +15 -0
- package/ccw/dist/tools/skill-context-loader.d.ts.map +1 -0
- package/ccw/dist/tools/skill-context-loader.js +198 -0
- package/ccw/dist/tools/skill-context-loader.js.map +1 -0
- package/ccw/dist/tools/smart-search.d.ts +8 -3
- package/ccw/dist/tools/smart-search.d.ts.map +1 -1
- package/ccw/dist/tools/smart-search.js +378 -75
- package/ccw/dist/tools/smart-search.js.map +1 -1
- package/ccw/dist/types/cli-settings.d.ts +86 -0
- package/ccw/dist/types/cli-settings.d.ts.map +1 -0
- package/ccw/dist/types/cli-settings.js +54 -0
- package/ccw/dist/types/cli-settings.js.map +1 -0
- package/ccw/dist/types/litellm-api-config.d.ts +40 -1
- package/ccw/dist/types/litellm-api-config.d.ts.map +1 -1
- package/ccw/dist/utils/exec-constants.d.ts +25 -0
- package/ccw/dist/utils/exec-constants.d.ts.map +1 -0
- package/ccw/dist/utils/exec-constants.js +25 -0
- package/ccw/dist/utils/exec-constants.js.map +1 -0
- package/ccw/dist/utils/path-resolver.d.ts +1 -0
- package/ccw/dist/utils/path-resolver.d.ts.map +1 -1
- package/ccw/dist/utils/path-resolver.js +48 -3
- package/ccw/dist/utils/path-resolver.js.map +1 -1
- package/ccw/dist/utils/path-validator.d.ts.map +1 -1
- package/ccw/dist/utils/path-validator.js +25 -6
- package/ccw/dist/utils/path-validator.js.map +1 -1
- package/ccw/dist/utils/python-utils.d.ts.map +1 -1
- package/ccw/dist/utils/python-utils.js +27 -7
- package/ccw/dist/utils/python-utils.js.map +1 -1
- package/ccw/dist/utils/shell-escape.d.ts +8 -0
- package/ccw/dist/utils/shell-escape.d.ts.map +1 -0
- package/ccw/dist/utils/shell-escape.js +24 -0
- package/ccw/dist/utils/shell-escape.js.map +1 -0
- package/ccw/dist/utils/uv-manager.d.ts +167 -0
- package/ccw/dist/utils/uv-manager.d.ts.map +1 -0
- package/ccw/dist/utils/uv-manager.js +644 -0
- package/ccw/dist/utils/uv-manager.js.map +1 -0
- package/ccw/src/cli.ts +4 -1
- package/ccw/src/commands/cli.ts +132 -34
- package/ccw/src/commands/issue.ts +605 -91
- package/ccw/src/commands/serve.ts +15 -5
- package/ccw/src/commands/stop.ts +32 -5
- package/ccw/src/commands/tool.ts +17 -2
- package/ccw/src/commands/view.ts +13 -3
- package/ccw/src/config/cli-settings-manager.ts +460 -0
- package/ccw/src/config/litellm-api-config-manager.ts +392 -57
- package/ccw/src/core/auth/csrf-manager.ts +104 -0
- package/ccw/src/core/auth/csrf-middleware.ts +159 -0
- package/ccw/src/core/auth/middleware.ts +94 -0
- package/ccw/src/core/auth/token-manager.ts +219 -0
- package/ccw/src/core/cache-manager.ts +64 -52
- package/ccw/src/core/claude-freshness.ts +26 -6
- package/ccw/src/core/core-memory-store.ts +2 -1
- package/ccw/src/core/cors.ts +10 -0
- package/ccw/src/core/dashboard-generator-patch.ts +47 -48
- package/ccw/src/core/dashboard-generator.ts +797 -744
- package/ccw/src/core/data-aggregator.ts +667 -667
- package/ccw/src/core/lite-scanner.ts +156 -140
- package/ccw/src/core/routes/auth-routes.ts +98 -0
- package/ccw/src/core/routes/ccw-routes.ts +10 -20
- package/ccw/src/core/routes/claude-routes.ts +101 -51
- package/ccw/src/core/routes/cli-routes.ts +152 -55
- package/ccw/src/core/routes/cli-settings-routes.ts +232 -0
- package/ccw/src/core/routes/codexlens/README.md +37 -0
- package/ccw/src/core/routes/codexlens/config-handlers.ts +1269 -0
- package/ccw/src/core/routes/codexlens/index-handlers.ts +354 -0
- package/ccw/src/core/routes/codexlens/semantic-handlers.ts +931 -0
- package/ccw/src/core/routes/codexlens/utils.ts +96 -0
- package/ccw/src/core/routes/codexlens/watcher-handlers.ts +265 -0
- package/ccw/src/core/routes/codexlens-routes.ts +11 -1044
- package/ccw/src/core/routes/discovery-routes.ts +1 -12
- package/ccw/src/core/routes/files-routes.ts +112 -40
- package/ccw/src/core/routes/graph-routes.ts +39 -46
- package/ccw/src/core/routes/help-routes.ts +2 -12
- package/ccw/src/core/routes/hooks-routes.ts +83 -44
- package/ccw/src/core/routes/issue-routes.ts +1 -12
- package/ccw/src/core/routes/litellm-api-routes.ts +574 -60
- package/ccw/src/core/routes/litellm-routes.ts +35 -27
- package/ccw/src/core/routes/mcp-routes.ts +157 -60
- package/ccw/src/core/routes/mcp-routes.ts.backup +549 -550
- package/ccw/src/core/routes/mcp-templates-db.ts +267 -268
- package/ccw/src/core/routes/memory-routes.ts +76 -22
- package/ccw/src/core/routes/nav-status-routes.ts +231 -0
- package/ccw/src/core/routes/rules-routes.ts +600 -81
- package/ccw/src/core/routes/session-routes.ts +28 -22
- package/ccw/src/core/routes/skills-routes.ts +452 -132
- package/ccw/src/core/routes/status-routes.ts +1 -12
- package/ccw/src/core/routes/system-routes.ts +15 -22
- package/ccw/src/core/routes/types.ts +25 -0
- package/ccw/src/core/server.ts +657 -468
- package/ccw/src/core/services/api-key-tester.ts +160 -0
- package/ccw/src/core/services/health-check-service.ts +366 -0
- package/ccw/src/core/websocket.ts +20 -12
- package/ccw/src/templates/dashboard-css/01-base.css +109 -0
- package/ccw/src/templates/dashboard-css/10-cli-status.css +202 -0
- package/ccw/src/templates/dashboard-css/21-cli-toolmgmt.css +308 -0
- package/ccw/src/templates/dashboard-css/30-core-memory.css +20 -0
- package/ccw/src/templates/dashboard-css/31-api-settings.css +751 -14
- package/ccw/src/templates/dashboard-css/33-cli-stream-viewer.css +230 -2
- package/ccw/src/templates/dashboard-js/api.js +5 -0
- package/ccw/src/templates/dashboard-js/components/cli-status.js +279 -107
- package/ccw/src/templates/dashboard-js/components/cli-stream-viewer.js +262 -20
- package/ccw/src/templates/dashboard-js/components/hook-manager.js +105 -5
- package/ccw/src/templates/dashboard-js/components/mcp-manager.js +317 -0
- package/ccw/src/templates/dashboard-js/components/navigation.js +45 -0
- package/ccw/src/templates/dashboard-js/components/notifications.js +128 -0
- package/ccw/src/templates/dashboard-js/i18n.js +4448 -3983
- package/ccw/src/templates/dashboard-js/main.js +71 -0
- package/ccw/src/templates/dashboard-js/services.js +289 -0
- package/ccw/src/templates/dashboard-js/views/api-settings.js +5613 -3361
- package/ccw/src/templates/dashboard-js/views/claude-manager.js +1 -7
- package/ccw/src/templates/dashboard-js/views/cli-manager.js +581 -87
- package/ccw/src/templates/dashboard-js/views/codexlens-manager.js +6101 -1965
- package/ccw/src/templates/dashboard-js/views/core-memory.js +129 -20
- package/ccw/src/templates/dashboard-js/views/hook-manager.js +17 -3
- package/ccw/src/templates/dashboard-js/views/mcp-manager.js +63 -0
- package/ccw/src/templates/dashboard-js/views/project-overview.js +182 -37
- package/ccw/src/templates/dashboard-js/views/rules-manager.js +26 -3
- package/ccw/src/templates/dashboard-js/views/skills-manager.js +2 -42
- package/ccw/src/templates/dashboard.html +6 -0
- package/ccw/src/tools/README.md +29 -0
- package/ccw/src/tools/claude-cli-tools.ts +640 -125
- package/ccw/src/tools/cli-config-manager.ts +102 -172
- package/ccw/src/tools/cli-executor-core.ts +1533 -0
- package/ccw/src/tools/cli-executor-state.ts +560 -0
- package/ccw/src/tools/cli-executor-utils.ts +349 -0
- package/ccw/src/tools/cli-executor.ts +3 -2309
- package/ccw/src/tools/cli-history-store.ts +2 -0
- package/ccw/src/tools/cli-output-converter.ts +1237 -0
- package/ccw/src/tools/cli-prompt-builder.ts +487 -0
- package/ccw/src/tools/codex-lens.ts +324 -59
- package/ccw/src/tools/detect-changed-modules.ts +24 -6
- package/ccw/src/tools/index.ts +2 -0
- package/ccw/src/tools/litellm-client.ts +10 -4
- package/ccw/src/tools/litellm-executor.ts +146 -114
- package/ccw/src/tools/native-session-discovery.ts +209 -1
- package/ccw/src/tools/session-manager.ts +88 -0
- package/ccw/src/tools/skill-context-loader.ts +213 -0
- package/ccw/src/tools/smart-search.ts +427 -76
- package/ccw/src/types/cli-settings.ts +137 -0
- package/ccw/src/types/litellm-api-config.ts +55 -1
- package/ccw/src/utils/exec-constants.ts +24 -0
- package/ccw/src/utils/path-resolver.ts +49 -3
- package/ccw/src/utils/path-validator.ts +28 -6
- package/ccw/src/utils/python-utils.ts +140 -121
- package/ccw/src/utils/shell-escape.ts +30 -0
- package/ccw/src/utils/uv-manager.ts +796 -0
- package/ccw-litellm/src/ccw_litellm/__pycache__/__init__.cpython-310.pyc +0 -0
- package/ccw-litellm/src/ccw_litellm/__pycache__/__init__.cpython-312.pyc +0 -0
- package/ccw-litellm/src/ccw_litellm/clients/__pycache__/__init__.cpython-310.pyc +0 -0
- package/ccw-litellm/src/ccw_litellm/clients/__pycache__/__init__.cpython-312.pyc +0 -0
- package/ccw-litellm/src/ccw_litellm/clients/__pycache__/litellm_embedder.cpython-310.pyc +0 -0
- package/ccw-litellm/src/ccw_litellm/clients/__pycache__/litellm_embedder.cpython-312.pyc +0 -0
- package/ccw-litellm/src/ccw_litellm/clients/__pycache__/litellm_embedder.cpython-313.pyc +0 -0
- package/ccw-litellm/src/ccw_litellm/clients/__pycache__/litellm_llm.cpython-310.pyc +0 -0
- package/ccw-litellm/src/ccw_litellm/clients/__pycache__/litellm_llm.cpython-312.pyc +0 -0
- package/ccw-litellm/src/ccw_litellm/clients/__pycache__/litellm_llm.cpython-313.pyc +0 -0
- package/ccw-litellm/src/ccw_litellm/clients/litellm_embedder.py +270 -251
- package/ccw-litellm/src/ccw_litellm/clients/litellm_llm.py +33 -0
- package/ccw-litellm/src/ccw_litellm/config/__pycache__/__init__.cpython-310.pyc +0 -0
- package/ccw-litellm/src/ccw_litellm/config/__pycache__/__init__.cpython-312.pyc +0 -0
- package/ccw-litellm/src/ccw_litellm/config/__pycache__/loader.cpython-310.pyc +0 -0
- package/ccw-litellm/src/ccw_litellm/config/__pycache__/loader.cpython-312.pyc +0 -0
- package/ccw-litellm/src/ccw_litellm/config/__pycache__/loader.cpython-313.pyc +0 -0
- package/ccw-litellm/src/ccw_litellm/config/__pycache__/models.cpython-310.pyc +0 -0
- package/ccw-litellm/src/ccw_litellm/config/__pycache__/models.cpython-312.pyc +0 -0
- package/ccw-litellm/src/ccw_litellm/config/__pycache__/models.cpython-313.pyc +0 -0
- package/ccw-litellm/src/ccw_litellm/config/loader.py +343 -316
- package/ccw-litellm/src/ccw_litellm/config/models.py +162 -130
- package/ccw-litellm/src/ccw_litellm/interfaces/__pycache__/__init__.cpython-310.pyc +0 -0
- package/ccw-litellm/src/ccw_litellm/interfaces/__pycache__/__init__.cpython-312.pyc +0 -0
- package/ccw-litellm/src/ccw_litellm/interfaces/__pycache__/embedder.cpython-310.pyc +0 -0
- package/ccw-litellm/src/ccw_litellm/interfaces/__pycache__/embedder.cpython-312.pyc +0 -0
- package/ccw-litellm/src/ccw_litellm/interfaces/__pycache__/llm.cpython-310.pyc +0 -0
- package/ccw-litellm/src/ccw_litellm/interfaces/__pycache__/llm.cpython-312.pyc +0 -0
- package/codex-lens/pyproject.toml +43 -0
- package/codex-lens/src/codexlens/__pycache__/__init__.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/__pycache__/__init__.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/__pycache__/__main__.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/__pycache__/__main__.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/__pycache__/config.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/__pycache__/config.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/__pycache__/config.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/__pycache__/entities.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/__pycache__/entities.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/__pycache__/entities.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/__pycache__/env_config.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/__pycache__/env_config.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/__pycache__/env_config.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/__pycache__/errors.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/__pycache__/errors.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/cli/__pycache__/__init__.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/cli/__pycache__/__init__.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/cli/__pycache__/commands.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/cli/__pycache__/commands.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/cli/__pycache__/commands.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/cli/__pycache__/embedding_manager.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/cli/__pycache__/embedding_manager.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/cli/__pycache__/embedding_manager.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/cli/__pycache__/model_manager.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/cli/__pycache__/model_manager.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/cli/__pycache__/model_manager.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/cli/__pycache__/output.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/cli/__pycache__/output.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/cli/commands.py +4416 -2295
- package/codex-lens/src/codexlens/cli/embedding_manager.py +777 -15
- package/codex-lens/src/codexlens/cli/model_manager.py +676 -0
- package/codex-lens/src/codexlens/config.py +356 -12
- package/codex-lens/src/codexlens/entities.py +4 -1
- package/codex-lens/src/codexlens/env_config.py +304 -0
- package/codex-lens/src/codexlens/indexing/__init__.py +23 -1
- package/codex-lens/src/codexlens/indexing/__pycache__/__init__.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/indexing/__pycache__/embedding.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/indexing/__pycache__/symbol_extractor.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/indexing/embedding.py +582 -0
- package/codex-lens/src/codexlens/indexing/symbol_extractor.py +62 -28
- package/codex-lens/src/codexlens/parsers/__pycache__/__init__.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/parsers/__pycache__/__init__.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/parsers/__pycache__/factory.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/parsers/__pycache__/factory.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/parsers/__pycache__/factory.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/parsers/__pycache__/tokenizer.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/parsers/__pycache__/tokenizer.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/parsers/__pycache__/treesitter_parser.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/parsers/__pycache__/treesitter_parser.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/parsers/__pycache__/treesitter_parser.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/parsers/factory.py +139 -10
- package/codex-lens/src/codexlens/parsers/treesitter_parser.py +487 -13
- package/codex-lens/src/codexlens/search/__pycache__/__init__.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/search/__pycache__/__init__.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/search/__pycache__/binary_searcher.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/search/__pycache__/chain_search.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/search/__pycache__/chain_search.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/search/__pycache__/chain_search.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/search/__pycache__/enrichment.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/search/__pycache__/graph_expander.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/search/__pycache__/hybrid_search.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/search/__pycache__/hybrid_search.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/search/__pycache__/hybrid_search.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/search/__pycache__/ranking.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/search/__pycache__/ranking.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/search/__pycache__/ranking.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/search/binary_searcher.py +277 -0
- package/codex-lens/src/codexlens/search/chain_search.py +1652 -8
- package/codex-lens/src/codexlens/search/enrichment.py +21 -0
- package/codex-lens/src/codexlens/search/graph_expander.py +264 -0
- package/codex-lens/src/codexlens/search/hybrid_search.py +772 -37
- package/codex-lens/src/codexlens/search/ranking.py +397 -8
- package/codex-lens/src/codexlens/semantic/SPLADE_IMPLEMENTATION.md +225 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/__init__.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/__init__.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/ann_index.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/ann_index.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/ann_index.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/base.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/base.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/chunker.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/chunker.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/chunker.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/embedder.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/embedder.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/factory.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/factory.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/factory.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/gpu_support.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/gpu_support.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/gpu_support.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/litellm_embedder.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/litellm_embedder.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/litellm_embedder.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/reranker.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/splade_encoder.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/splade_encoder.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/splade_encoder.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/vector_store.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/vector_store.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/vector_store.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/ann_index.py +654 -0
- package/codex-lens/src/codexlens/semantic/chunker.py +328 -23
- package/codex-lens/src/codexlens/semantic/factory.py +63 -3
- package/codex-lens/src/codexlens/semantic/gpu_support.py +19 -2
- package/codex-lens/src/codexlens/semantic/litellm_embedder.py +144 -144
- package/codex-lens/src/codexlens/semantic/reranker/__init__.py +25 -0
- package/codex-lens/src/codexlens/semantic/reranker/__pycache__/__init__.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/reranker/__pycache__/__init__.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/reranker/__pycache__/__init__.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/reranker/__pycache__/api_reranker.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/reranker/__pycache__/api_reranker.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/reranker/__pycache__/api_reranker.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/reranker/__pycache__/base.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/reranker/__pycache__/base.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/reranker/__pycache__/base.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/reranker/__pycache__/factory.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/reranker/__pycache__/factory.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/reranker/__pycache__/factory.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/reranker/__pycache__/fastembed_reranker.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/reranker/__pycache__/fastembed_reranker.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/reranker/__pycache__/fastembed_reranker.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/reranker/__pycache__/legacy.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/reranker/__pycache__/legacy.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/reranker/__pycache__/legacy.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/reranker/__pycache__/litellm_reranker.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/reranker/__pycache__/onnx_reranker.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/reranker/__pycache__/onnx_reranker.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/reranker/__pycache__/onnx_reranker.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/reranker/api_reranker.py +403 -0
- package/codex-lens/src/codexlens/semantic/reranker/base.py +46 -0
- package/codex-lens/src/codexlens/semantic/reranker/factory.py +159 -0
- package/codex-lens/src/codexlens/semantic/reranker/fastembed_reranker.py +257 -0
- package/codex-lens/src/codexlens/semantic/reranker/legacy.py +91 -0
- package/codex-lens/src/codexlens/semantic/reranker/litellm_reranker.py +214 -0
- package/codex-lens/src/codexlens/semantic/reranker/onnx_reranker.py +268 -0
- package/codex-lens/src/codexlens/semantic/splade_encoder.py +567 -0
- package/codex-lens/src/codexlens/semantic/vector_store.py +472 -352
- package/codex-lens/src/codexlens/storage/__init__.py +3 -0
- package/codex-lens/src/codexlens/storage/__pycache__/__init__.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/__init__.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/__init__.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/dir_index.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/dir_index.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/dir_index.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/global_index.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/global_index.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/index_tree.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/index_tree.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/index_tree.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/merkle_tree.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/path_mapper.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/path_mapper.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/registry.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/registry.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/splade_index.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/splade_index.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/splade_index.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/sqlite_store.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/sqlite_store.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/sqlite_store.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/sqlite_utils.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/sqlite_utils.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/vector_meta_store.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/vector_meta_store.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/vector_meta_store.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/dir_index.py +310 -12
- package/codex-lens/src/codexlens/storage/index_tree.py +240 -25
- package/codex-lens/src/codexlens/storage/merkle_tree.py +136 -0
- package/codex-lens/src/codexlens/storage/migrations/__pycache__/__init__.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/storage/migrations/__pycache__/__init__.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/storage/migrations/__pycache__/migration_006_enhance_relationships.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/migrations/__pycache__/migration_007_add_graph_neighbors.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/storage/migrations/__pycache__/migration_007_add_graph_neighbors.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/storage/migrations/__pycache__/migration_007_add_graph_neighbors.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/migrations/__pycache__/migration_008_add_merkle_hashes.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/migrations/__pycache__/migration_009_add_splade.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/migrations/__pycache__/migration_010_add_multi_vector_chunks.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/migrations/migration_006_enhance_relationships.py +37 -0
- package/codex-lens/src/codexlens/storage/migrations/migration_007_add_graph_neighbors.py +47 -0
- package/codex-lens/src/codexlens/storage/migrations/migration_008_add_merkle_hashes.py +81 -0
- package/codex-lens/src/codexlens/storage/migrations/migration_009_add_splade.py +103 -0
- package/codex-lens/src/codexlens/storage/migrations/migration_010_add_multi_vector_chunks.py +162 -0
- package/codex-lens/src/codexlens/storage/splade_index.py +578 -0
- package/codex-lens/src/codexlens/storage/sqlite_store.py +508 -184
- package/codex-lens/src/codexlens/storage/vector_meta_store.py +415 -0
- package/codex-lens/src/codexlens/watcher/__init__.py +17 -0
- package/codex-lens/src/codexlens/watcher/__pycache__/__init__.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/watcher/__pycache__/__init__.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/watcher/__pycache__/__init__.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/watcher/__pycache__/events.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/watcher/__pycache__/events.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/watcher/__pycache__/events.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/watcher/__pycache__/file_watcher.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/watcher/__pycache__/file_watcher.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/watcher/__pycache__/file_watcher.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/watcher/__pycache__/incremental_indexer.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/watcher/__pycache__/incremental_indexer.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/watcher/__pycache__/incremental_indexer.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/watcher/__pycache__/manager.cpython-310.pyc +0 -0
- package/codex-lens/src/codexlens/watcher/__pycache__/manager.cpython-312.pyc +0 -0
- package/codex-lens/src/codexlens/watcher/__pycache__/manager.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/watcher/events.py +82 -0
- package/codex-lens/src/codexlens/watcher/file_watcher.py +347 -0
- package/codex-lens/src/codexlens/watcher/incremental_indexer.py +369 -0
- package/codex-lens/src/codexlens/watcher/manager.py +255 -0
- package/package.json +4 -1
- package/.claude/commands/workflow/docs/analyze.md +0 -1467
- package/.claude/commands/workflow/docs/copyright.md +0 -1265
- package/.claude/skills/command-guide/SKILL.md +0 -388
- package/.claude/skills/command-guide/UPDATE-GUIDELINE.md +0 -592
- package/.claude/skills/command-guide/guides/cli-tools-guide.md +0 -410
- package/.claude/skills/command-guide/guides/examples.md +0 -537
- package/.claude/skills/command-guide/guides/getting-started.md +0 -242
- package/.claude/skills/command-guide/guides/implementation-details.md +0 -1010
- package/.claude/skills/command-guide/guides/index-structure.md +0 -326
- package/.claude/skills/command-guide/guides/troubleshooting.md +0 -92
- package/.claude/skills/command-guide/guides/ui-design-workflow-guide.md +0 -316
- package/.claude/skills/command-guide/guides/workflow-patterns.md +0 -662
- package/.claude/skills/command-guide/reference/agents/action-planning-agent.md +0 -855
- package/.claude/skills/command-guide/reference/agents/cli-execution-agent.md +0 -267
- package/.claude/skills/command-guide/reference/agents/cli-explore-agent.md +0 -182
- package/.claude/skills/command-guide/reference/agents/cli-lite-planning-agent.md +0 -446
- package/.claude/skills/command-guide/reference/agents/cli-planning-agent.md +0 -558
- package/.claude/skills/command-guide/reference/agents/code-developer.md +0 -311
- package/.claude/skills/command-guide/reference/agents/conceptual-planning-agent.md +0 -308
- package/.claude/skills/command-guide/reference/agents/context-search-agent.md +0 -581
- package/.claude/skills/command-guide/reference/agents/doc-generator.md +0 -330
- package/.claude/skills/command-guide/reference/agents/memory-bridge.md +0 -94
- package/.claude/skills/command-guide/reference/agents/test-context-search-agent.md +0 -400
- package/.claude/skills/command-guide/reference/agents/test-fix-agent.md +0 -344
- package/.claude/skills/command-guide/reference/agents/ui-design-agent.md +0 -593
- package/.claude/skills/command-guide/reference/agents/universal-executor.md +0 -131
- package/.claude/skills/command-guide/reference/commands/cli/cli-init.md +0 -440
- package/.claude/skills/command-guide/reference/commands/enhance-prompt.md +0 -93
- package/.claude/skills/command-guide/reference/commands/memory/code-map-memory.md +0 -687
- package/.claude/skills/command-guide/reference/commands/memory/docs-full-cli.md +0 -471
- package/.claude/skills/command-guide/reference/commands/memory/docs-related-cli.md +0 -386
- package/.claude/skills/command-guide/reference/commands/memory/docs.md +0 -616
- package/.claude/skills/command-guide/reference/commands/memory/load-skill-memory.md +0 -182
- package/.claude/skills/command-guide/reference/commands/memory/load.md +0 -240
- package/.claude/skills/command-guide/reference/commands/memory/skill-memory.md +0 -525
- package/.claude/skills/command-guide/reference/commands/memory/style-skill-memory.md +0 -396
- package/.claude/skills/command-guide/reference/commands/memory/tech-research.md +0 -314
- package/.claude/skills/command-guide/reference/commands/memory/update-full.md +0 -332
- package/.claude/skills/command-guide/reference/commands/memory/update-related.md +0 -332
- package/.claude/skills/command-guide/reference/commands/memory/workflow-skill-memory.md +0 -517
- package/.claude/skills/command-guide/reference/commands/task/breakdown.md +0 -204
- package/.claude/skills/command-guide/reference/commands/task/create.md +0 -152
- package/.claude/skills/command-guide/reference/commands/task/execute.md +0 -270
- package/.claude/skills/command-guide/reference/commands/task/replan.md +0 -437
- package/.claude/skills/command-guide/reference/commands/version.md +0 -254
- package/.claude/skills/command-guide/reference/commands/workflow/action-plan-verify.md +0 -447
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/api-designer.md +0 -585
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/artifacts.md +0 -452
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/auto-parallel.md +0 -443
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/data-architect.md +0 -220
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/product-manager.md +0 -200
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/product-owner.md +0 -200
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/scrum-master.md +0 -200
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/subject-matter-expert.md +0 -200
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/synthesis.md +0 -398
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/system-architect.md +0 -387
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/ui-designer.md +0 -221
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/ux-expert.md +0 -221
- package/.claude/skills/command-guide/reference/commands/workflow/execute.md +0 -465
- package/.claude/skills/command-guide/reference/commands/workflow/init.md +0 -164
- package/.claude/skills/command-guide/reference/commands/workflow/lite-execute.md +0 -748
- package/.claude/skills/command-guide/reference/commands/workflow/lite-fix.md +0 -664
- package/.claude/skills/command-guide/reference/commands/workflow/lite-plan.md +0 -645
- package/.claude/skills/command-guide/reference/commands/workflow/plan.md +0 -551
- package/.claude/skills/command-guide/reference/commands/workflow/replan.md +0 -515
- package/.claude/skills/command-guide/reference/commands/workflow/review-fix.md +0 -606
- package/.claude/skills/command-guide/reference/commands/workflow/review-module-cycle.md +0 -765
- package/.claude/skills/command-guide/reference/commands/workflow/review-session-cycle.md +0 -776
- package/.claude/skills/command-guide/reference/commands/workflow/review.md +0 -298
- package/.claude/skills/command-guide/reference/commands/workflow/session/complete.md +0 -547
- package/.claude/skills/command-guide/reference/commands/workflow/session/list.md +0 -114
- package/.claude/skills/command-guide/reference/commands/workflow/session/resume.md +0 -77
- package/.claude/skills/command-guide/reference/commands/workflow/session/start.md +0 -257
- package/.claude/skills/command-guide/reference/commands/workflow/tdd-plan.md +0 -460
- package/.claude/skills/command-guide/reference/commands/workflow/tdd-verify.md +0 -400
- package/.claude/skills/command-guide/reference/commands/workflow/test-cycle-execute.md +0 -498
- package/.claude/skills/command-guide/reference/commands/workflow/test-fix-gen.md +0 -699
- package/.claude/skills/command-guide/reference/commands/workflow/test-gen.md +0 -529
- package/.claude/skills/command-guide/reference/commands/workflow/tools/conflict-resolution.md +0 -766
- package/.claude/skills/command-guide/reference/commands/workflow/tools/context-gather.md +0 -433
- package/.claude/skills/command-guide/reference/commands/workflow/tools/task-generate-agent.md +0 -487
- package/.claude/skills/command-guide/reference/commands/workflow/tools/task-generate-tdd.md +0 -518
- package/.claude/skills/command-guide/reference/commands/workflow/tools/tdd-coverage-analysis.md +0 -309
- package/.claude/skills/command-guide/reference/commands/workflow/tools/test-concept-enhanced.md +0 -163
- package/.claude/skills/command-guide/reference/commands/workflow/tools/test-context-gather.md +0 -232
- package/.claude/skills/command-guide/reference/commands/workflow/tools/test-task-generate.md +0 -254
- package/.claude/skills/command-guide/reference/commands/workflow/ui-design/animation-extract.md +0 -1150
- package/.claude/skills/command-guide/reference/commands/workflow/ui-design/codify-style.md +0 -652
- package/.claude/skills/command-guide/reference/commands/workflow/ui-design/design-sync.md +0 -454
- package/.claude/skills/command-guide/reference/commands/workflow/ui-design/explore-auto.md +0 -678
- package/.claude/skills/command-guide/reference/commands/workflow/ui-design/generate.md +0 -504
- package/.claude/skills/command-guide/reference/commands/workflow/ui-design/imitate-auto.md +0 -745
- package/.claude/skills/command-guide/reference/commands/workflow/ui-design/import-from-code.md +0 -537
- package/.claude/skills/command-guide/reference/commands/workflow/ui-design/layout-extract.md +0 -788
- package/.claude/skills/command-guide/reference/commands/workflow/ui-design/reference-page-generator.md +0 -356
- package/.claude/skills/command-guide/reference/commands/workflow/ui-design/style-extract.md +0 -773
- package/.claude/skills/command-guide/scripts/analyze_commands.py +0 -502
- package/.claude/skills/command-guide/scripts/update-index.sh +0 -130
- package/.claude/skills/command-guide/templates/issue-bug.md +0 -104
- package/.claude/skills/command-guide/templates/issue-diagnosis.md +0 -275
- package/.claude/skills/command-guide/templates/issue-feature.md +0 -97
- package/.claude/skills/command-guide/templates/issue-question.md +0 -141
|
@@ -9,89 +9,96 @@ Optimized for high-performance similarity search using:
|
|
|
9
9
|
|
|
10
10
|
from __future__ import annotations
|
|
11
11
|
|
|
12
|
-
import json
|
|
13
|
-
import logging
|
|
14
|
-
import sys
|
|
15
|
-
import sqlite3
|
|
16
|
-
import threading
|
|
17
|
-
from pathlib import Path
|
|
18
|
-
from typing import Any, Dict, List, Optional, Tuple
|
|
19
|
-
|
|
20
|
-
from codexlens.entities import SearchResult, SemanticChunk
|
|
21
|
-
from codexlens.errors import StorageError
|
|
22
|
-
|
|
23
|
-
try:
|
|
24
|
-
import numpy as np
|
|
25
|
-
NUMPY_AVAILABLE = True
|
|
26
|
-
except ImportError:
|
|
27
|
-
np = None # type: ignore[assignment]
|
|
28
|
-
NUMPY_AVAILABLE = False
|
|
29
|
-
|
|
30
|
-
# Try to import ANN index (optional hnswlib dependency)
|
|
31
|
-
try:
|
|
32
|
-
from codexlens.semantic.ann_index import
|
|
12
|
+
import json
|
|
13
|
+
import logging
|
|
14
|
+
import sys
|
|
15
|
+
import sqlite3
|
|
16
|
+
import threading
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
from typing import Any, Dict, List, Optional, Tuple
|
|
19
|
+
|
|
20
|
+
from codexlens.entities import SearchResult, SemanticChunk
|
|
21
|
+
from codexlens.errors import StorageError
|
|
22
|
+
|
|
23
|
+
try:
|
|
24
|
+
import numpy as np
|
|
25
|
+
NUMPY_AVAILABLE = True
|
|
26
|
+
except ImportError:
|
|
27
|
+
np = None # type: ignore[assignment]
|
|
28
|
+
NUMPY_AVAILABLE = False
|
|
29
|
+
|
|
30
|
+
# Try to import ANN index (optional hnswlib dependency)
|
|
31
|
+
try:
|
|
32
|
+
from codexlens.semantic.ann_index import (
|
|
33
|
+
ANNIndex,
|
|
34
|
+
BinaryANNIndex,
|
|
35
|
+
create_ann_index,
|
|
36
|
+
HNSWLIB_AVAILABLE,
|
|
37
|
+
)
|
|
33
38
|
except ImportError:
|
|
34
39
|
HNSWLIB_AVAILABLE = False
|
|
35
40
|
ANNIndex = None
|
|
41
|
+
BinaryANNIndex = None
|
|
42
|
+
create_ann_index = None
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
logger = logging.getLogger(__name__)
|
|
46
|
+
|
|
47
|
+
# Epsilon used to guard against floating point precision edge cases (e.g., near-zero norms).
|
|
48
|
+
EPSILON = 1e-10
|
|
49
|
+
|
|
50
|
+
# SQLite INTEGER PRIMARY KEY uses signed 64-bit rowids.
|
|
51
|
+
SQLITE_INTEGER_MAX = (1 << 63) - 1
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def _validate_chunk_id_range(start_id: int, count: int) -> None:
|
|
55
|
+
"""Validate that a batch insert can safely generate sequential chunk IDs."""
|
|
56
|
+
if count <= 0:
|
|
57
|
+
return
|
|
58
|
+
|
|
59
|
+
last_id = start_id + count - 1
|
|
60
|
+
if last_id > sys.maxsize or last_id > SQLITE_INTEGER_MAX:
|
|
61
|
+
raise ValueError(
|
|
62
|
+
"Chunk ID range overflow: "
|
|
63
|
+
f"start_id={start_id}, count={count} would allocate up to {last_id}, "
|
|
64
|
+
f"exceeding limits (sys.maxsize={sys.maxsize}, sqlite_max={SQLITE_INTEGER_MAX}). "
|
|
65
|
+
"Consider cleaning up the index database or creating a new index database."
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def _validate_sql_placeholders(placeholders: str, expected_count: int) -> None:
|
|
70
|
+
"""Validate the placeholder string used for a parameterized SQL IN clause."""
|
|
71
|
+
expected = ",".join("?" * expected_count)
|
|
72
|
+
if placeholders != expected:
|
|
73
|
+
raise ValueError(
|
|
74
|
+
"Invalid SQL placeholders for IN clause. "
|
|
75
|
+
f"Expected {expected_count} '?' placeholders."
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def _cosine_similarity(a: List[float], b: List[float]) -> float:
|
|
80
|
+
"""Compute cosine similarity between two vectors."""
|
|
81
|
+
if not NUMPY_AVAILABLE:
|
|
82
|
+
raise ImportError("numpy required for vector operations")
|
|
83
|
+
|
|
84
|
+
a_arr = np.array(a)
|
|
85
|
+
b_arr = np.array(b)
|
|
86
|
+
|
|
87
|
+
norm_a = np.linalg.norm(a_arr)
|
|
88
|
+
norm_b = np.linalg.norm(b_arr)
|
|
89
|
+
|
|
90
|
+
# Use epsilon tolerance to avoid division by (near-)zero due to floating point precision.
|
|
91
|
+
if norm_a < EPSILON or norm_b < EPSILON:
|
|
92
|
+
return 0.0
|
|
93
|
+
|
|
94
|
+
denom = norm_a * norm_b
|
|
95
|
+
if denom < EPSILON:
|
|
96
|
+
return 0.0
|
|
36
97
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
EPSILON = 1e-10
|
|
42
|
-
|
|
43
|
-
# SQLite INTEGER PRIMARY KEY uses signed 64-bit rowids.
|
|
44
|
-
SQLITE_INTEGER_MAX = (1 << 63) - 1
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
def _validate_chunk_id_range(start_id: int, count: int) -> None:
|
|
48
|
-
"""Validate that a batch insert can safely generate sequential chunk IDs."""
|
|
49
|
-
if count <= 0:
|
|
50
|
-
return
|
|
51
|
-
|
|
52
|
-
last_id = start_id + count - 1
|
|
53
|
-
if last_id > sys.maxsize or last_id > SQLITE_INTEGER_MAX:
|
|
54
|
-
raise ValueError(
|
|
55
|
-
"Chunk ID range overflow: "
|
|
56
|
-
f"start_id={start_id}, count={count} would allocate up to {last_id}, "
|
|
57
|
-
f"exceeding limits (sys.maxsize={sys.maxsize}, sqlite_max={SQLITE_INTEGER_MAX}). "
|
|
58
|
-
"Consider cleaning up the index database or creating a new index database."
|
|
59
|
-
)
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
def _validate_sql_placeholders(placeholders: str, expected_count: int) -> None:
|
|
63
|
-
"""Validate the placeholder string used for a parameterized SQL IN clause."""
|
|
64
|
-
expected = ",".join("?" * expected_count)
|
|
65
|
-
if placeholders != expected:
|
|
66
|
-
raise ValueError(
|
|
67
|
-
"Invalid SQL placeholders for IN clause. "
|
|
68
|
-
f"Expected {expected_count} '?' placeholders."
|
|
69
|
-
)
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
def _cosine_similarity(a: List[float], b: List[float]) -> float:
|
|
73
|
-
"""Compute cosine similarity between two vectors."""
|
|
74
|
-
if not NUMPY_AVAILABLE:
|
|
75
|
-
raise ImportError("numpy required for vector operations")
|
|
76
|
-
|
|
77
|
-
a_arr = np.array(a)
|
|
78
|
-
b_arr = np.array(b)
|
|
79
|
-
|
|
80
|
-
norm_a = np.linalg.norm(a_arr)
|
|
81
|
-
norm_b = np.linalg.norm(b_arr)
|
|
82
|
-
|
|
83
|
-
# Use epsilon tolerance to avoid division by (near-)zero due to floating point precision.
|
|
84
|
-
if norm_a < EPSILON or norm_b < EPSILON:
|
|
85
|
-
return 0.0
|
|
86
|
-
|
|
87
|
-
denom = norm_a * norm_b
|
|
88
|
-
if denom < EPSILON:
|
|
89
|
-
return 0.0
|
|
90
|
-
|
|
91
|
-
return float(np.dot(a_arr, b_arr) / denom)
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
class VectorStore:
|
|
98
|
+
return float(np.dot(a_arr, b_arr) / denom)
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
class VectorStore:
|
|
95
102
|
"""SQLite-based vector storage with HNSW-accelerated similarity search.
|
|
96
103
|
|
|
97
104
|
Performance optimizations:
|
|
@@ -106,12 +113,12 @@ class VectorStore:
|
|
|
106
113
|
# Default embedding dimension (used when creating new index)
|
|
107
114
|
DEFAULT_DIM = 768
|
|
108
115
|
|
|
109
|
-
def __init__(self, db_path: str | Path) -> None:
|
|
110
|
-
if not NUMPY_AVAILABLE:
|
|
111
|
-
raise ImportError(
|
|
112
|
-
"Semantic search dependencies not available. "
|
|
113
|
-
"Install with: pip install codexlens[semantic]"
|
|
114
|
-
)
|
|
116
|
+
def __init__(self, db_path: str | Path) -> None:
|
|
117
|
+
if not NUMPY_AVAILABLE:
|
|
118
|
+
raise ImportError(
|
|
119
|
+
"Semantic search dependencies not available. "
|
|
120
|
+
"Install with: pip install codexlens[semantic]"
|
|
121
|
+
)
|
|
115
122
|
|
|
116
123
|
self.db_path = Path(db_path)
|
|
117
124
|
self.db_path.parent.mkdir(parents=True, exist_ok=True)
|
|
@@ -148,6 +155,7 @@ class VectorStore:
|
|
|
148
155
|
content TEXT NOT NULL,
|
|
149
156
|
embedding BLOB NOT NULL,
|
|
150
157
|
metadata TEXT,
|
|
158
|
+
category TEXT DEFAULT 'code',
|
|
151
159
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
152
160
|
)
|
|
153
161
|
""")
|
|
@@ -155,6 +163,10 @@ class VectorStore:
|
|
|
155
163
|
CREATE INDEX IF NOT EXISTS idx_chunks_file
|
|
156
164
|
ON semantic_chunks(file_path)
|
|
157
165
|
""")
|
|
166
|
+
conn.execute("""
|
|
167
|
+
CREATE INDEX IF NOT EXISTS idx_chunks_category
|
|
168
|
+
ON semantic_chunks(category)
|
|
169
|
+
""")
|
|
158
170
|
# Model configuration table - tracks which model generated the embeddings
|
|
159
171
|
conn.execute("""
|
|
160
172
|
CREATE TABLE IF NOT EXISTS embeddings_config (
|
|
@@ -170,6 +182,8 @@ class VectorStore:
|
|
|
170
182
|
|
|
171
183
|
# Migration: Add backend column to existing tables
|
|
172
184
|
self._migrate_backend_column(conn)
|
|
185
|
+
# Migration: Add category column
|
|
186
|
+
self._migrate_category_column(conn)
|
|
173
187
|
|
|
174
188
|
conn.commit()
|
|
175
189
|
|
|
@@ -190,6 +204,28 @@ class VectorStore:
|
|
|
190
204
|
ADD COLUMN backend TEXT NOT NULL DEFAULT 'fastembed'
|
|
191
205
|
""")
|
|
192
206
|
|
|
207
|
+
def _migrate_category_column(self, conn: sqlite3.Connection) -> None:
|
|
208
|
+
"""Add category column to existing semantic_chunks table if not present.
|
|
209
|
+
|
|
210
|
+
Args:
|
|
211
|
+
conn: Active SQLite connection
|
|
212
|
+
"""
|
|
213
|
+
# Check if category column exists
|
|
214
|
+
cursor = conn.execute("PRAGMA table_info(semantic_chunks)")
|
|
215
|
+
columns = [row[1] for row in cursor.fetchall()]
|
|
216
|
+
|
|
217
|
+
if 'category' not in columns:
|
|
218
|
+
logger.info("Migrating semantic_chunks table: adding category column")
|
|
219
|
+
conn.execute("""
|
|
220
|
+
ALTER TABLE semantic_chunks
|
|
221
|
+
ADD COLUMN category TEXT DEFAULT 'code'
|
|
222
|
+
""")
|
|
223
|
+
# Create index for fast category filtering
|
|
224
|
+
conn.execute("""
|
|
225
|
+
CREATE INDEX IF NOT EXISTS idx_chunks_category
|
|
226
|
+
ON semantic_chunks(category)
|
|
227
|
+
""")
|
|
228
|
+
|
|
193
229
|
def _init_ann_index(self) -> None:
|
|
194
230
|
"""Initialize ANN index (lazy loading from existing data)."""
|
|
195
231
|
if not HNSWLIB_AVAILABLE:
|
|
@@ -338,14 +374,14 @@ class VectorStore:
|
|
|
338
374
|
]
|
|
339
375
|
self._embedding_matrix = np.vstack(embeddings)
|
|
340
376
|
|
|
341
|
-
# Pre-compute norms for faster similarity calculation
|
|
342
|
-
self._embedding_norms = np.linalg.norm(
|
|
343
|
-
self._embedding_matrix, axis=1, keepdims=True
|
|
344
|
-
)
|
|
345
|
-
# Avoid division by zero
|
|
346
|
-
self._embedding_norms = np.where(
|
|
347
|
-
self._embedding_norms == 0, EPSILON, self._embedding_norms
|
|
348
|
-
)
|
|
377
|
+
# Pre-compute norms for faster similarity calculation
|
|
378
|
+
self._embedding_norms = np.linalg.norm(
|
|
379
|
+
self._embedding_matrix, axis=1, keepdims=True
|
|
380
|
+
)
|
|
381
|
+
# Avoid division by zero
|
|
382
|
+
self._embedding_norms = np.where(
|
|
383
|
+
self._embedding_norms == 0, EPSILON, self._embedding_norms
|
|
384
|
+
)
|
|
349
385
|
|
|
350
386
|
return True
|
|
351
387
|
|
|
@@ -383,9 +419,16 @@ class VectorStore:
|
|
|
383
419
|
self._ann_index = None
|
|
384
420
|
return False
|
|
385
421
|
|
|
386
|
-
def add_chunk(
|
|
422
|
+
def add_chunk(
|
|
423
|
+
self, chunk: SemanticChunk, file_path: str, category: str = "code"
|
|
424
|
+
) -> int:
|
|
387
425
|
"""Add a single chunk with its embedding.
|
|
388
426
|
|
|
427
|
+
Args:
|
|
428
|
+
chunk: SemanticChunk with embedding
|
|
429
|
+
file_path: Path to the source file
|
|
430
|
+
category: File category ('code' or 'doc'), default 'code'
|
|
431
|
+
|
|
389
432
|
Returns:
|
|
390
433
|
The inserted chunk ID.
|
|
391
434
|
"""
|
|
@@ -399,10 +442,10 @@ class VectorStore:
|
|
|
399
442
|
with sqlite3.connect(self.db_path) as conn:
|
|
400
443
|
cursor = conn.execute(
|
|
401
444
|
"""
|
|
402
|
-
INSERT INTO semantic_chunks (file_path, content, embedding, metadata)
|
|
403
|
-
VALUES (?, ?, ?, ?)
|
|
445
|
+
INSERT INTO semantic_chunks (file_path, content, embedding, metadata, category)
|
|
446
|
+
VALUES (?, ?, ?, ?, ?)
|
|
404
447
|
""",
|
|
405
|
-
(file_path, chunk.content, embedding_blob, metadata_json)
|
|
448
|
+
(file_path, chunk.content, embedding_blob, metadata_json, category)
|
|
406
449
|
)
|
|
407
450
|
conn.commit()
|
|
408
451
|
chunk_id = cursor.lastrowid or 0
|
|
@@ -420,9 +463,16 @@ class VectorStore:
|
|
|
420
463
|
self._invalidate_cache()
|
|
421
464
|
return chunk_id
|
|
422
465
|
|
|
423
|
-
def add_chunks(
|
|
466
|
+
def add_chunks(
|
|
467
|
+
self, chunks: List[SemanticChunk], file_path: str, category: str = "code"
|
|
468
|
+
) -> List[int]:
|
|
424
469
|
"""Add multiple chunks with embeddings (batch insert).
|
|
425
470
|
|
|
471
|
+
Args:
|
|
472
|
+
chunks: List of SemanticChunk objects with embeddings
|
|
473
|
+
file_path: Path to the source file
|
|
474
|
+
category: File category ('code' or 'doc'), default 'code'
|
|
475
|
+
|
|
426
476
|
Returns:
|
|
427
477
|
List of inserted chunk IDs.
|
|
428
478
|
"""
|
|
@@ -438,7 +488,7 @@ class VectorStore:
|
|
|
438
488
|
embedding_arr = np.array(chunk.embedding, dtype=np.float32)
|
|
439
489
|
embedding_blob = embedding_arr.tobytes()
|
|
440
490
|
metadata_json = json.dumps(chunk.metadata) if chunk.metadata else None
|
|
441
|
-
batch_data.append((file_path, chunk.content, embedding_blob, metadata_json))
|
|
491
|
+
batch_data.append((file_path, chunk.content, embedding_blob, metadata_json, category))
|
|
442
492
|
embeddings_list.append(embedding_arr)
|
|
443
493
|
|
|
444
494
|
# Batch insert to SQLite
|
|
@@ -449,8 +499,8 @@ class VectorStore:
|
|
|
449
499
|
|
|
450
500
|
conn.executemany(
|
|
451
501
|
"""
|
|
452
|
-
INSERT INTO semantic_chunks (file_path, content, embedding, metadata)
|
|
453
|
-
VALUES (?, ?, ?, ?)
|
|
502
|
+
INSERT INTO semantic_chunks (file_path, content, embedding, metadata, category)
|
|
503
|
+
VALUES (?, ?, ?, ?, ?)
|
|
454
504
|
""",
|
|
455
505
|
batch_data
|
|
456
506
|
)
|
|
@@ -472,11 +522,12 @@ class VectorStore:
|
|
|
472
522
|
self._invalidate_cache()
|
|
473
523
|
return ids
|
|
474
524
|
|
|
475
|
-
def add_chunks_batch(
|
|
476
|
-
self,
|
|
477
|
-
chunks_with_paths: List[Tuple[SemanticChunk, str]],
|
|
478
|
-
update_ann: bool = True,
|
|
479
|
-
auto_save_ann: bool = True,
|
|
525
|
+
def add_chunks_batch(
|
|
526
|
+
self,
|
|
527
|
+
chunks_with_paths: List[Tuple[SemanticChunk, str]],
|
|
528
|
+
update_ann: bool = True,
|
|
529
|
+
auto_save_ann: bool = True,
|
|
530
|
+
categories: Optional[List[str]] = None,
|
|
480
531
|
) -> List[int]:
|
|
481
532
|
"""Batch insert chunks from multiple files in a single transaction.
|
|
482
533
|
|
|
@@ -487,19 +538,28 @@ class VectorStore:
|
|
|
487
538
|
update_ann: If True, update ANN index with new vectors (default: True)
|
|
488
539
|
auto_save_ann: If True, save ANN index after update (default: True).
|
|
489
540
|
Set to False for bulk inserts to reduce I/O overhead.
|
|
541
|
+
categories: Optional list of categories per chunk. If None, defaults to 'code'.
|
|
542
|
+
If provided, must match length of chunks_with_paths.
|
|
490
543
|
|
|
491
|
-
Returns:
|
|
492
|
-
List of inserted chunk IDs
|
|
493
|
-
"""
|
|
494
|
-
if not chunks_with_paths:
|
|
495
|
-
return []
|
|
496
|
-
|
|
497
|
-
batch_size = len(chunks_with_paths)
|
|
498
|
-
|
|
499
|
-
#
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
544
|
+
Returns:
|
|
545
|
+
List of inserted chunk IDs
|
|
546
|
+
"""
|
|
547
|
+
if not chunks_with_paths:
|
|
548
|
+
return []
|
|
549
|
+
|
|
550
|
+
batch_size = len(chunks_with_paths)
|
|
551
|
+
|
|
552
|
+
# Validate categories if provided
|
|
553
|
+
if categories is not None and len(categories) != batch_size:
|
|
554
|
+
raise ValueError(
|
|
555
|
+
f"categories length ({len(categories)}) must match "
|
|
556
|
+
f"chunks_with_paths length ({batch_size})"
|
|
557
|
+
)
|
|
558
|
+
|
|
559
|
+
# Prepare batch data
|
|
560
|
+
batch_data = []
|
|
561
|
+
embeddings_list = []
|
|
562
|
+
for i, (chunk, file_path) in enumerate(chunks_with_paths):
|
|
503
563
|
if chunk.embedding is None:
|
|
504
564
|
raise ValueError("All chunks must have embeddings")
|
|
505
565
|
# Optimize: avoid repeated np.array() if already numpy
|
|
@@ -509,55 +569,57 @@ class VectorStore:
|
|
|
509
569
|
embedding_arr = np.array(chunk.embedding, dtype=np.float32)
|
|
510
570
|
embedding_blob = embedding_arr.tobytes()
|
|
511
571
|
metadata_json = json.dumps(chunk.metadata) if chunk.metadata else None
|
|
512
|
-
|
|
572
|
+
category = categories[i] if categories else "code"
|
|
573
|
+
batch_data.append((file_path, chunk.content, embedding_blob, metadata_json, category))
|
|
513
574
|
embeddings_list.append(embedding_arr)
|
|
514
575
|
|
|
515
|
-
# Batch insert to SQLite in single transaction
|
|
516
|
-
with sqlite3.connect(self.db_path) as conn:
|
|
517
|
-
# Get starting ID before insert
|
|
518
|
-
row = conn.execute("SELECT MAX(id) FROM semantic_chunks").fetchone()
|
|
519
|
-
start_id = (row[0] or 0) + 1
|
|
520
|
-
|
|
521
|
-
_validate_chunk_id_range(start_id, batch_size)
|
|
522
|
-
|
|
523
|
-
conn.executemany(
|
|
524
|
-
"""
|
|
525
|
-
INSERT INTO semantic_chunks (file_path, content, embedding, metadata)
|
|
526
|
-
VALUES (?, ?, ?, ?)
|
|
576
|
+
# Batch insert to SQLite in single transaction
|
|
577
|
+
with sqlite3.connect(self.db_path) as conn:
|
|
578
|
+
# Get starting ID before insert
|
|
579
|
+
row = conn.execute("SELECT MAX(id) FROM semantic_chunks").fetchone()
|
|
580
|
+
start_id = (row[0] or 0) + 1
|
|
581
|
+
|
|
582
|
+
_validate_chunk_id_range(start_id, batch_size)
|
|
583
|
+
|
|
584
|
+
conn.executemany(
|
|
585
|
+
"""
|
|
586
|
+
INSERT INTO semantic_chunks (file_path, content, embedding, metadata, category)
|
|
587
|
+
VALUES (?, ?, ?, ?, ?)
|
|
527
588
|
""",
|
|
528
589
|
batch_data
|
|
529
|
-
)
|
|
530
|
-
conn.commit()
|
|
531
|
-
# Calculate inserted IDs based on starting ID
|
|
532
|
-
ids = list(range(start_id, start_id + batch_size))
|
|
533
|
-
|
|
534
|
-
# Handle ANN index updates
|
|
535
|
-
if embeddings_list and update_ann and self._ensure_ann_index(len(embeddings_list[0])):
|
|
536
|
-
with self._ann_write_lock:
|
|
537
|
-
# In bulk insert mode, accumulate for later batch update
|
|
538
|
-
if self._bulk_insert_mode:
|
|
539
|
-
self._bulk_insert_ids.extend(ids)
|
|
540
|
-
self._bulk_insert_embeddings.extend(embeddings_list)
|
|
541
|
-
else:
|
|
542
|
-
# Normal mode: update immediately
|
|
543
|
-
try:
|
|
544
|
-
embeddings_matrix = np.vstack(embeddings_list)
|
|
545
|
-
self._ann_index.add_vectors(ids, embeddings_matrix)
|
|
546
|
-
if auto_save_ann:
|
|
547
|
-
self._ann_index.save()
|
|
548
|
-
except Exception as e:
|
|
549
|
-
logger.warning("Failed to add batch to ANN index: %s", e)
|
|
590
|
+
)
|
|
591
|
+
conn.commit()
|
|
592
|
+
# Calculate inserted IDs based on starting ID
|
|
593
|
+
ids = list(range(start_id, start_id + batch_size))
|
|
594
|
+
|
|
595
|
+
# Handle ANN index updates
|
|
596
|
+
if embeddings_list and update_ann and self._ensure_ann_index(len(embeddings_list[0])):
|
|
597
|
+
with self._ann_write_lock:
|
|
598
|
+
# In bulk insert mode, accumulate for later batch update
|
|
599
|
+
if self._bulk_insert_mode:
|
|
600
|
+
self._bulk_insert_ids.extend(ids)
|
|
601
|
+
self._bulk_insert_embeddings.extend(embeddings_list)
|
|
602
|
+
else:
|
|
603
|
+
# Normal mode: update immediately
|
|
604
|
+
try:
|
|
605
|
+
embeddings_matrix = np.vstack(embeddings_list)
|
|
606
|
+
self._ann_index.add_vectors(ids, embeddings_matrix)
|
|
607
|
+
if auto_save_ann:
|
|
608
|
+
self._ann_index.save()
|
|
609
|
+
except Exception as e:
|
|
610
|
+
logger.warning("Failed to add batch to ANN index: %s", e)
|
|
550
611
|
|
|
551
612
|
# Invalidate cache after modification
|
|
552
613
|
self._invalidate_cache()
|
|
553
614
|
return ids
|
|
554
615
|
|
|
555
|
-
def add_chunks_batch_numpy(
|
|
556
|
-
self,
|
|
557
|
-
chunks_with_paths: List[Tuple[SemanticChunk, str]],
|
|
558
|
-
embeddings_matrix: np.ndarray,
|
|
559
|
-
update_ann: bool = True,
|
|
616
|
+
def add_chunks_batch_numpy(
|
|
617
|
+
self,
|
|
618
|
+
chunks_with_paths: List[Tuple[SemanticChunk, str]],
|
|
619
|
+
embeddings_matrix: np.ndarray,
|
|
620
|
+
update_ann: bool = True,
|
|
560
621
|
auto_save_ann: bool = True,
|
|
622
|
+
categories: Optional[List[str]] = None,
|
|
561
623
|
) -> List[int]:
|
|
562
624
|
"""Batch insert chunks with pre-computed numpy embeddings matrix.
|
|
563
625
|
|
|
@@ -569,19 +631,27 @@ class VectorStore:
|
|
|
569
631
|
embeddings_matrix: Pre-computed embeddings as (N, D) numpy array
|
|
570
632
|
update_ann: If True, update ANN index with new vectors (default: True)
|
|
571
633
|
auto_save_ann: If True, save ANN index after update (default: True)
|
|
634
|
+
categories: Optional list of categories per chunk. If None, defaults to 'code'.
|
|
635
|
+
|
|
636
|
+
Returns:
|
|
637
|
+
List of inserted chunk IDs
|
|
638
|
+
"""
|
|
639
|
+
if not chunks_with_paths:
|
|
640
|
+
return []
|
|
572
641
|
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
f"{
|
|
642
|
+
batch_size = len(chunks_with_paths)
|
|
643
|
+
|
|
644
|
+
if len(chunks_with_paths) != embeddings_matrix.shape[0]:
|
|
645
|
+
raise ValueError(
|
|
646
|
+
f"Mismatch: {len(chunks_with_paths)} chunks but "
|
|
647
|
+
f"{embeddings_matrix.shape[0]} embeddings"
|
|
648
|
+
)
|
|
649
|
+
|
|
650
|
+
# Validate categories if provided
|
|
651
|
+
if categories is not None and len(categories) != batch_size:
|
|
652
|
+
raise ValueError(
|
|
653
|
+
f"categories length ({len(categories)}) must match "
|
|
654
|
+
f"chunks_with_paths length ({batch_size})"
|
|
585
655
|
)
|
|
586
656
|
|
|
587
657
|
# Ensure float32 format
|
|
@@ -593,49 +663,50 @@ class VectorStore:
|
|
|
593
663
|
embedding_arr = embeddings_matrix[i]
|
|
594
664
|
embedding_blob = embedding_arr.tobytes()
|
|
595
665
|
metadata_json = json.dumps(chunk.metadata) if chunk.metadata else None
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
666
|
+
category = categories[i] if categories else "code"
|
|
667
|
+
batch_data.append((file_path, chunk.content, embedding_blob, metadata_json, category))
|
|
668
|
+
|
|
669
|
+
# Batch insert to SQLite in single transaction
|
|
670
|
+
with sqlite3.connect(self.db_path) as conn:
|
|
671
|
+
# Get starting ID before insert
|
|
672
|
+
row = conn.execute("SELECT MAX(id) FROM semantic_chunks").fetchone()
|
|
673
|
+
start_id = (row[0] or 0) + 1
|
|
674
|
+
|
|
675
|
+
_validate_chunk_id_range(start_id, batch_size)
|
|
676
|
+
|
|
677
|
+
conn.executemany(
|
|
678
|
+
"""
|
|
679
|
+
INSERT INTO semantic_chunks (file_path, content, embedding, metadata, category)
|
|
680
|
+
VALUES (?, ?, ?, ?, ?)
|
|
610
681
|
""",
|
|
611
682
|
batch_data
|
|
612
|
-
)
|
|
613
|
-
conn.commit()
|
|
614
|
-
# Calculate inserted IDs based on starting ID
|
|
615
|
-
ids = list(range(start_id, start_id + batch_size))
|
|
616
|
-
|
|
617
|
-
# Handle ANN index updates
|
|
618
|
-
if update_ann and self._ensure_ann_index(embeddings_matrix.shape[1]):
|
|
619
|
-
with self._ann_write_lock:
|
|
620
|
-
# In bulk insert mode, accumulate for later batch update
|
|
621
|
-
if self._bulk_insert_mode:
|
|
622
|
-
self._bulk_insert_ids.extend(ids)
|
|
623
|
-
# Split matrix into individual arrays for accumulation
|
|
624
|
-
self._bulk_insert_embeddings.extend([embeddings_matrix[i] for i in range(len(ids))])
|
|
625
|
-
else:
|
|
626
|
-
# Normal mode: update immediately
|
|
627
|
-
try:
|
|
628
|
-
self._ann_index.add_vectors(ids, embeddings_matrix)
|
|
629
|
-
if auto_save_ann:
|
|
630
|
-
self._ann_index.save()
|
|
631
|
-
except Exception as e:
|
|
632
|
-
logger.warning("Failed to add batch to ANN index: %s", e)
|
|
683
|
+
)
|
|
684
|
+
conn.commit()
|
|
685
|
+
# Calculate inserted IDs based on starting ID
|
|
686
|
+
ids = list(range(start_id, start_id + batch_size))
|
|
687
|
+
|
|
688
|
+
# Handle ANN index updates
|
|
689
|
+
if update_ann and self._ensure_ann_index(embeddings_matrix.shape[1]):
|
|
690
|
+
with self._ann_write_lock:
|
|
691
|
+
# In bulk insert mode, accumulate for later batch update
|
|
692
|
+
if self._bulk_insert_mode:
|
|
693
|
+
self._bulk_insert_ids.extend(ids)
|
|
694
|
+
# Split matrix into individual arrays for accumulation
|
|
695
|
+
self._bulk_insert_embeddings.extend([embeddings_matrix[i] for i in range(len(ids))])
|
|
696
|
+
else:
|
|
697
|
+
# Normal mode: update immediately
|
|
698
|
+
try:
|
|
699
|
+
self._ann_index.add_vectors(ids, embeddings_matrix)
|
|
700
|
+
if auto_save_ann:
|
|
701
|
+
self._ann_index.save()
|
|
702
|
+
except Exception as e:
|
|
703
|
+
logger.warning("Failed to add batch to ANN index: %s", e)
|
|
633
704
|
|
|
634
705
|
# Invalidate cache after modification
|
|
635
706
|
self._invalidate_cache()
|
|
636
707
|
return ids
|
|
637
708
|
|
|
638
|
-
def begin_bulk_insert(self) -> None:
|
|
709
|
+
def begin_bulk_insert(self) -> None:
|
|
639
710
|
"""Begin bulk insert mode - disable ANN auto-update for better performance.
|
|
640
711
|
|
|
641
712
|
Usage:
|
|
@@ -651,45 +722,45 @@ class VectorStore:
|
|
|
651
722
|
for batch in batches:
|
|
652
723
|
store.add_chunks_batch(batch)
|
|
653
724
|
"""
|
|
654
|
-
with self._ann_write_lock:
|
|
655
|
-
self._bulk_insert_mode = True
|
|
656
|
-
self._bulk_insert_ids.clear()
|
|
657
|
-
self._bulk_insert_embeddings.clear()
|
|
658
|
-
logger.debug("Entered bulk insert mode")
|
|
659
|
-
|
|
660
|
-
def end_bulk_insert(self) -> None:
|
|
725
|
+
with self._ann_write_lock:
|
|
726
|
+
self._bulk_insert_mode = True
|
|
727
|
+
self._bulk_insert_ids.clear()
|
|
728
|
+
self._bulk_insert_embeddings.clear()
|
|
729
|
+
logger.debug("Entered bulk insert mode")
|
|
730
|
+
|
|
731
|
+
def end_bulk_insert(self) -> None:
|
|
661
732
|
"""End bulk insert mode and rebuild ANN index from accumulated data.
|
|
662
733
|
|
|
663
734
|
This method should be called after all bulk inserts are complete to
|
|
664
735
|
update the ANN index in a single batch operation.
|
|
665
736
|
"""
|
|
666
|
-
with self._ann_write_lock:
|
|
667
|
-
if not self._bulk_insert_mode:
|
|
668
|
-
logger.warning("end_bulk_insert called but not in bulk insert mode")
|
|
669
|
-
return
|
|
670
|
-
|
|
671
|
-
self._bulk_insert_mode = False
|
|
672
|
-
bulk_ids = list(self._bulk_insert_ids)
|
|
673
|
-
bulk_embeddings = list(self._bulk_insert_embeddings)
|
|
674
|
-
self._bulk_insert_ids.clear()
|
|
675
|
-
self._bulk_insert_embeddings.clear()
|
|
676
|
-
|
|
677
|
-
# Update ANN index with accumulated data.
|
|
678
|
-
if bulk_ids and bulk_embeddings:
|
|
679
|
-
if self._ensure_ann_index(len(bulk_embeddings[0])):
|
|
680
|
-
with self._ann_write_lock:
|
|
681
|
-
try:
|
|
682
|
-
embeddings_matrix = np.vstack(bulk_embeddings)
|
|
683
|
-
self._ann_index.add_vectors(bulk_ids, embeddings_matrix)
|
|
684
|
-
self._ann_index.save()
|
|
685
|
-
logger.info(
|
|
686
|
-
"Bulk insert complete: added %d vectors to ANN index",
|
|
687
|
-
len(bulk_ids),
|
|
688
|
-
)
|
|
689
|
-
except Exception as e:
|
|
690
|
-
logger.error("Failed to update ANN index after bulk insert: %s", e)
|
|
691
|
-
|
|
692
|
-
logger.debug("Exited bulk insert mode")
|
|
737
|
+
with self._ann_write_lock:
|
|
738
|
+
if not self._bulk_insert_mode:
|
|
739
|
+
logger.warning("end_bulk_insert called but not in bulk insert mode")
|
|
740
|
+
return
|
|
741
|
+
|
|
742
|
+
self._bulk_insert_mode = False
|
|
743
|
+
bulk_ids = list(self._bulk_insert_ids)
|
|
744
|
+
bulk_embeddings = list(self._bulk_insert_embeddings)
|
|
745
|
+
self._bulk_insert_ids.clear()
|
|
746
|
+
self._bulk_insert_embeddings.clear()
|
|
747
|
+
|
|
748
|
+
# Update ANN index with accumulated data.
|
|
749
|
+
if bulk_ids and bulk_embeddings:
|
|
750
|
+
if self._ensure_ann_index(len(bulk_embeddings[0])):
|
|
751
|
+
with self._ann_write_lock:
|
|
752
|
+
try:
|
|
753
|
+
embeddings_matrix = np.vstack(bulk_embeddings)
|
|
754
|
+
self._ann_index.add_vectors(bulk_ids, embeddings_matrix)
|
|
755
|
+
self._ann_index.save()
|
|
756
|
+
logger.info(
|
|
757
|
+
"Bulk insert complete: added %d vectors to ANN index",
|
|
758
|
+
len(bulk_ids),
|
|
759
|
+
)
|
|
760
|
+
except Exception as e:
|
|
761
|
+
logger.error("Failed to update ANN index after bulk insert: %s", e)
|
|
762
|
+
|
|
763
|
+
logger.debug("Exited bulk insert mode")
|
|
693
764
|
|
|
694
765
|
class BulkInsertContext:
|
|
695
766
|
"""Context manager for bulk insert operations."""
|
|
@@ -752,108 +823,114 @@ class VectorStore:
|
|
|
752
823
|
self._invalidate_cache()
|
|
753
824
|
return deleted
|
|
754
825
|
|
|
755
|
-
def search_similar(
|
|
756
|
-
self,
|
|
757
|
-
query_embedding: List[float],
|
|
758
|
-
top_k: int = 10,
|
|
759
|
-
min_score: float = 0.0,
|
|
760
|
-
return_full_content: bool = True,
|
|
761
|
-
|
|
762
|
-
|
|
826
|
+
def search_similar(
|
|
827
|
+
self,
|
|
828
|
+
query_embedding: List[float],
|
|
829
|
+
top_k: int = 10,
|
|
830
|
+
min_score: float = 0.0,
|
|
831
|
+
return_full_content: bool = True,
|
|
832
|
+
category: Optional[str] = None,
|
|
833
|
+
) -> List[SearchResult]:
|
|
834
|
+
"""Find chunks most similar to query embedding.
|
|
763
835
|
|
|
764
836
|
Uses HNSW index for O(log N) search when available, falls back to
|
|
765
837
|
brute-force NumPy search otherwise.
|
|
766
838
|
|
|
767
|
-
Args:
|
|
768
|
-
query_embedding: Query vector.
|
|
769
|
-
top_k: Maximum results to return.
|
|
770
|
-
min_score: Minimum cosine similarity score in [0.0, 1.0].
|
|
771
|
-
return_full_content: If True, return full code block content.
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
and self._ann_index
|
|
839
|
+
Args:
|
|
840
|
+
query_embedding: Query vector.
|
|
841
|
+
top_k: Maximum results to return.
|
|
842
|
+
min_score: Minimum cosine similarity score in [0.0, 1.0].
|
|
843
|
+
return_full_content: If True, return full code block content.
|
|
844
|
+
category: Optional category filter ('code' or 'doc'). If None, returns all.
|
|
845
|
+
|
|
846
|
+
Returns:
|
|
847
|
+
List of SearchResult ordered by similarity (highest first).
|
|
848
|
+
"""
|
|
849
|
+
query_vec = np.array(query_embedding, dtype=np.float32)
|
|
850
|
+
|
|
851
|
+
if not 0.0 <= min_score <= 1.0:
|
|
852
|
+
raise ValueError(
|
|
853
|
+
f"Invalid min_score: {min_score}. Must be within [0.0, 1.0] for cosine similarity."
|
|
854
|
+
)
|
|
855
|
+
|
|
856
|
+
# Try HNSW search first (O(log N))
|
|
857
|
+
if (
|
|
858
|
+
HNSWLIB_AVAILABLE
|
|
859
|
+
and self._ann_index is not None
|
|
860
|
+
and self._ann_index.is_loaded
|
|
788
861
|
and self._ann_index.count() > 0
|
|
789
862
|
):
|
|
790
863
|
try:
|
|
791
864
|
return self._search_with_ann(
|
|
792
|
-
query_vec, top_k, min_score, return_full_content
|
|
865
|
+
query_vec, top_k, min_score, return_full_content, category
|
|
793
866
|
)
|
|
794
867
|
except Exception as e:
|
|
795
868
|
logger.warning("ANN search failed, falling back to brute-force: %s", e)
|
|
796
869
|
|
|
797
870
|
# Fallback to brute-force search (O(N))
|
|
798
871
|
return self._search_brute_force(
|
|
799
|
-
query_vec, top_k, min_score, return_full_content
|
|
872
|
+
query_vec, top_k, min_score, return_full_content, category
|
|
800
873
|
)
|
|
801
874
|
|
|
802
|
-
def _search_with_ann(
|
|
803
|
-
self,
|
|
804
|
-
query_vec: np.ndarray,
|
|
805
|
-
top_k: int,
|
|
806
|
-
min_score: float,
|
|
807
|
-
return_full_content: bool,
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
875
|
+
def _search_with_ann(
|
|
876
|
+
self,
|
|
877
|
+
query_vec: np.ndarray,
|
|
878
|
+
top_k: int,
|
|
879
|
+
min_score: float,
|
|
880
|
+
return_full_content: bool,
|
|
881
|
+
category: Optional[str] = None,
|
|
882
|
+
) -> List[SearchResult]:
|
|
883
|
+
"""Search using HNSW index (O(log N)).
|
|
884
|
+
|
|
885
|
+
Args:
|
|
886
|
+
query_vec: Query vector as numpy array
|
|
887
|
+
top_k: Maximum results to return
|
|
888
|
+
min_score: Minimum cosine similarity score in [0.0, 1.0]
|
|
889
|
+
return_full_content: If True, return full code block content
|
|
890
|
+
category: Optional category filter ('code' or 'doc')
|
|
816
891
|
|
|
817
892
|
Returns:
|
|
818
893
|
List of SearchResult ordered by similarity (highest first)
|
|
819
894
|
"""
|
|
820
895
|
# Limit top_k to available vectors to prevent hnswlib error
|
|
821
896
|
ann_count = self._ann_index.count()
|
|
822
|
-
|
|
897
|
+
# When category filtering, fetch more candidates to compensate for filtering
|
|
898
|
+
fetch_k = top_k * 3 if category else top_k
|
|
899
|
+
effective_top_k = min(fetch_k, ann_count) if ann_count > 0 else 0
|
|
823
900
|
|
|
824
901
|
if effective_top_k == 0:
|
|
825
902
|
return []
|
|
826
903
|
|
|
827
|
-
# HNSW search returns (ids, distances)
|
|
828
|
-
# For cosine space: distance = 1 - similarity
|
|
829
|
-
ids, distances = self._ann_index.search(query_vec, effective_top_k)
|
|
830
|
-
|
|
831
|
-
if ids is None or distances is None:
|
|
832
|
-
logger.debug(
|
|
833
|
-
"ANN search returned null results (ids=%s, distances=%s)",
|
|
834
|
-
ids,
|
|
835
|
-
distances,
|
|
836
|
-
)
|
|
837
|
-
return []
|
|
838
|
-
|
|
839
|
-
if len(ids) == 0 or len(distances) == 0:
|
|
840
|
-
logger.debug(
|
|
841
|
-
"ANN search returned empty results (ids=%s, distances=%s)",
|
|
842
|
-
ids,
|
|
843
|
-
distances,
|
|
844
|
-
)
|
|
845
|
-
return []
|
|
846
|
-
|
|
847
|
-
if len(ids) != len(distances):
|
|
848
|
-
logger.warning(
|
|
849
|
-
"ANN search returned mismatched result lengths (%d ids, %d distances)",
|
|
850
|
-
len(ids),
|
|
851
|
-
len(distances),
|
|
852
|
-
)
|
|
853
|
-
return []
|
|
854
|
-
|
|
855
|
-
# Convert distances to similarity scores
|
|
856
|
-
scores = [1.0 - d for d in distances]
|
|
904
|
+
# HNSW search returns (ids, distances)
|
|
905
|
+
# For cosine space: distance = 1 - similarity
|
|
906
|
+
ids, distances = self._ann_index.search(query_vec, effective_top_k)
|
|
907
|
+
|
|
908
|
+
if ids is None or distances is None:
|
|
909
|
+
logger.debug(
|
|
910
|
+
"ANN search returned null results (ids=%s, distances=%s)",
|
|
911
|
+
ids,
|
|
912
|
+
distances,
|
|
913
|
+
)
|
|
914
|
+
return []
|
|
915
|
+
|
|
916
|
+
if len(ids) == 0 or len(distances) == 0:
|
|
917
|
+
logger.debug(
|
|
918
|
+
"ANN search returned empty results (ids=%s, distances=%s)",
|
|
919
|
+
ids,
|
|
920
|
+
distances,
|
|
921
|
+
)
|
|
922
|
+
return []
|
|
923
|
+
|
|
924
|
+
if len(ids) != len(distances):
|
|
925
|
+
logger.warning(
|
|
926
|
+
"ANN search returned mismatched result lengths (%d ids, %d distances)",
|
|
927
|
+
len(ids),
|
|
928
|
+
len(distances),
|
|
929
|
+
)
|
|
930
|
+
return []
|
|
931
|
+
|
|
932
|
+
# Convert distances to similarity scores
|
|
933
|
+
scores = [1.0 - d for d in distances]
|
|
857
934
|
|
|
858
935
|
# Filter by min_score
|
|
859
936
|
filtered = [
|
|
@@ -868,23 +945,29 @@ class VectorStore:
|
|
|
868
945
|
top_ids = [f[0] for f in filtered]
|
|
869
946
|
top_scores = [f[1] for f in filtered]
|
|
870
947
|
|
|
871
|
-
# Fetch content from SQLite
|
|
872
|
-
|
|
948
|
+
# Fetch content from SQLite with category filtering
|
|
949
|
+
results = self._fetch_results_by_ids(
|
|
950
|
+
top_ids, top_scores, return_full_content, category
|
|
951
|
+
)
|
|
952
|
+
# Apply final limit after category filtering
|
|
953
|
+
return results[:top_k]
|
|
873
954
|
|
|
874
|
-
def _search_brute_force(
|
|
875
|
-
self,
|
|
876
|
-
query_vec: np.ndarray,
|
|
877
|
-
top_k: int,
|
|
878
|
-
min_score: float,
|
|
879
|
-
return_full_content: bool,
|
|
880
|
-
|
|
881
|
-
|
|
955
|
+
def _search_brute_force(
|
|
956
|
+
self,
|
|
957
|
+
query_vec: np.ndarray,
|
|
958
|
+
top_k: int,
|
|
959
|
+
min_score: float,
|
|
960
|
+
return_full_content: bool,
|
|
961
|
+
category: Optional[str] = None,
|
|
962
|
+
) -> List[SearchResult]:
|
|
963
|
+
"""Brute-force search using NumPy (O(N) fallback).
|
|
882
964
|
|
|
883
|
-
Args:
|
|
884
|
-
query_vec: Query vector as numpy array
|
|
885
|
-
top_k: Maximum results to return
|
|
886
|
-
min_score: Minimum cosine similarity score in [0.0, 1.0]
|
|
887
|
-
return_full_content: If True, return full code block content
|
|
965
|
+
Args:
|
|
966
|
+
query_vec: Query vector as numpy array
|
|
967
|
+
top_k: Maximum results to return
|
|
968
|
+
min_score: Minimum cosine similarity score in [0.0, 1.0]
|
|
969
|
+
return_full_content: If True, return full code block content
|
|
970
|
+
category: Optional category filter ('code' or 'doc')
|
|
888
971
|
|
|
889
972
|
Returns:
|
|
890
973
|
List of SearchResult ordered by similarity (highest first)
|
|
@@ -919,27 +1002,31 @@ class VectorStore:
|
|
|
919
1002
|
if len(valid_indices) == 0:
|
|
920
1003
|
return []
|
|
921
1004
|
|
|
922
|
-
#
|
|
1005
|
+
# When category filtering, fetch more candidates to compensate for filtering
|
|
1006
|
+
fetch_k = top_k * 3 if category else top_k
|
|
1007
|
+
|
|
1008
|
+
# Sort by score descending and take top candidates
|
|
923
1009
|
valid_scores = scores[valid_indices]
|
|
924
|
-
sorted_order = np.argsort(valid_scores)[::-1][:
|
|
1010
|
+
sorted_order = np.argsort(valid_scores)[::-1][:fetch_k]
|
|
925
1011
|
top_indices = valid_indices[sorted_order]
|
|
926
1012
|
top_scores = valid_scores[sorted_order]
|
|
927
1013
|
|
|
928
1014
|
# Get chunk IDs for top results
|
|
929
1015
|
top_ids = [self._chunk_ids[i] for i in top_indices]
|
|
930
1016
|
|
|
931
|
-
# Fetch content only for top-k results (lazy loading)
|
|
1017
|
+
# Fetch content only for top-k results (lazy loading) with category filtering
|
|
932
1018
|
results = self._fetch_results_by_ids(
|
|
933
|
-
top_ids, top_scores.tolist(), return_full_content
|
|
1019
|
+
top_ids, top_scores.tolist(), return_full_content, category
|
|
934
1020
|
)
|
|
935
|
-
|
|
936
|
-
return results
|
|
1021
|
+
# Apply final limit after category filtering
|
|
1022
|
+
return results[:top_k]
|
|
937
1023
|
|
|
938
1024
|
def _fetch_results_by_ids(
|
|
939
1025
|
self,
|
|
940
1026
|
chunk_ids: List[int],
|
|
941
1027
|
scores: List[float],
|
|
942
1028
|
return_full_content: bool,
|
|
1029
|
+
category: Optional[str] = None,
|
|
943
1030
|
) -> List[SearchResult]:
|
|
944
1031
|
"""Fetch full result data for specific chunk IDs.
|
|
945
1032
|
|
|
@@ -947,29 +1034,40 @@ class VectorStore:
|
|
|
947
1034
|
chunk_ids: List of chunk IDs to fetch.
|
|
948
1035
|
scores: Corresponding similarity scores.
|
|
949
1036
|
return_full_content: Whether to include full content.
|
|
1037
|
+
category: Optional category filter ('code' or 'doc').
|
|
950
1038
|
|
|
951
1039
|
Returns:
|
|
952
1040
|
List of SearchResult objects.
|
|
953
1041
|
"""
|
|
954
|
-
if not chunk_ids:
|
|
955
|
-
return []
|
|
956
|
-
|
|
957
|
-
# Build parameterized query for IN clause
|
|
958
|
-
placeholders = ",".join("?" * len(chunk_ids))
|
|
959
|
-
_validate_sql_placeholders(placeholders, len(chunk_ids))
|
|
960
|
-
|
|
961
|
-
# SQL injection prevention:
|
|
962
|
-
# - Only a validated placeholders string (commas + '?') is interpolated into the query.
|
|
963
|
-
# - User-provided values are passed separately via sqlite3 parameters.
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
1042
|
+
if not chunk_ids:
|
|
1043
|
+
return []
|
|
1044
|
+
|
|
1045
|
+
# Build parameterized query for IN clause
|
|
1046
|
+
placeholders = ",".join("?" * len(chunk_ids))
|
|
1047
|
+
_validate_sql_placeholders(placeholders, len(chunk_ids))
|
|
1048
|
+
|
|
1049
|
+
# SQL injection prevention:
|
|
1050
|
+
# - Only a validated placeholders string (commas + '?') is interpolated into the query.
|
|
1051
|
+
# - User-provided values are passed separately via sqlite3 parameters.
|
|
1052
|
+
# - Category filter is added as a separate parameter
|
|
1053
|
+
if category:
|
|
1054
|
+
query = """
|
|
1055
|
+
SELECT id, file_path, content, metadata
|
|
1056
|
+
FROM semantic_chunks
|
|
1057
|
+
WHERE id IN ({placeholders}) AND category = ?
|
|
1058
|
+
""".format(placeholders=placeholders)
|
|
1059
|
+
params = list(chunk_ids) + [category]
|
|
1060
|
+
else:
|
|
1061
|
+
query = """
|
|
1062
|
+
SELECT id, file_path, content, metadata
|
|
1063
|
+
FROM semantic_chunks
|
|
1064
|
+
WHERE id IN ({placeholders})
|
|
1065
|
+
""".format(placeholders=placeholders)
|
|
1066
|
+
params = chunk_ids
|
|
969
1067
|
|
|
970
1068
|
with sqlite3.connect(self.db_path) as conn:
|
|
971
1069
|
conn.execute("PRAGMA mmap_size = 30000000000")
|
|
972
|
-
rows = conn.execute(query,
|
|
1070
|
+
rows = conn.execute(query, params).fetchall()
|
|
973
1071
|
|
|
974
1072
|
# Build ID -> row mapping
|
|
975
1073
|
id_to_row = {r[0]: r for r in rows}
|
|
@@ -1026,6 +1124,28 @@ class VectorStore:
|
|
|
1026
1124
|
row = conn.execute("SELECT COUNT(*) FROM semantic_chunks").fetchone()
|
|
1027
1125
|
return row[0] if row else 0
|
|
1028
1126
|
|
|
1127
|
+
def get_all_chunks(self) -> List[SemanticChunk]:
|
|
1128
|
+
"""Get all chunks from the store.
|
|
1129
|
+
|
|
1130
|
+
Returns:
|
|
1131
|
+
List of SemanticChunk objects with id and content.
|
|
1132
|
+
"""
|
|
1133
|
+
with sqlite3.connect(self.db_path) as conn:
|
|
1134
|
+
conn.row_factory = sqlite3.Row
|
|
1135
|
+
rows = conn.execute(
|
|
1136
|
+
"SELECT id, file_path, content, metadata FROM semantic_chunks"
|
|
1137
|
+
).fetchall()
|
|
1138
|
+
|
|
1139
|
+
chunks = []
|
|
1140
|
+
for row in rows:
|
|
1141
|
+
chunks.append(SemanticChunk(
|
|
1142
|
+
id=row["id"],
|
|
1143
|
+
content=row["content"],
|
|
1144
|
+
file_path=row["file_path"],
|
|
1145
|
+
metadata=json.loads(row["metadata"]) if row["metadata"] else None,
|
|
1146
|
+
))
|
|
1147
|
+
return chunks
|
|
1148
|
+
|
|
1029
1149
|
def clear_cache(self) -> None:
|
|
1030
1150
|
"""Manually clear the embedding cache."""
|
|
1031
1151
|
self._invalidate_cache()
|