codebase-index 2.1.1__tar.gz → 2.1.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (420) hide show
  1. codebase_index-2.1.3/.claude/skills/codebase-index/.skill_version +1 -0
  2. {codebase_index-2.1.1 → codebase_index-2.1.3}/.claude-plugin/plugin.json +1 -1
  3. codebase_index-2.1.3/.codex/skills/codebase-index/.skill_version +1 -0
  4. codebase_index-2.1.3/.opencode/skills/codebase-index/.skill_version +1 -0
  5. {codebase_index-2.1.1 → codebase_index-2.1.3}/CHANGELOG.md +39 -1
  6. {codebase_index-2.1.1 → codebase_index-2.1.3}/PKG-INFO +2 -1
  7. {codebase_index-2.1.1 → codebase_index-2.1.3}/README.md +1 -0
  8. {codebase_index-2.1.1 → codebase_index-2.1.3}/docs/SCHEMA.md +2 -0
  9. {codebase_index-2.1.1 → codebase_index-2.1.3}/docs/installer.md +1 -1
  10. {codebase_index-2.1.1 → codebase_index-2.1.3}/hooks/hooks.json +1 -1
  11. {codebase_index-2.1.1 → codebase_index-2.1.3}/requirements.lock +1 -1
  12. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/__init__.py +1 -1
  13. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/cli.py +6 -5
  14. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/hooks.py +115 -37
  15. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/scaffold.py +10 -3
  16. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/storage/schema.sql +4 -0
  17. codebase_index-2.1.3/tests/test_hooks_guard.py +231 -0
  18. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_storage.py +29 -0
  19. codebase_index-2.1.1/.claude/skills/codebase-index/.skill_version +0 -1
  20. codebase_index-2.1.1/.codex/skills/codebase-index/.skill_version +0 -1
  21. codebase_index-2.1.1/.opencode/skills/codebase-index/.skill_version +0 -1
  22. codebase_index-2.1.1/tests/test_hooks_guard.py +0 -120
  23. {codebase_index-2.1.1 → codebase_index-2.1.3}/.claude/skills/codebase-index/SKILL.md +0 -0
  24. {codebase_index-2.1.1 → codebase_index-2.1.3}/.claude/skills/codebase-index/examples/hooks/settings.json +0 -0
  25. {codebase_index-2.1.1 → codebase_index-2.1.3}/.claude/skills/codebase-index/references/commands.md +0 -0
  26. {codebase_index-2.1.1 → codebase_index-2.1.3}/.claude/skills/codebase-index/references/memory.md +0 -0
  27. {codebase_index-2.1.1 → codebase_index-2.1.3}/.claude/skills/codebase-index/references/response-contract.md +0 -0
  28. {codebase_index-2.1.1 → codebase_index-2.1.3}/.claude/skills/codebase-index/scripts/cbx +0 -0
  29. {codebase_index-2.1.1 → codebase_index-2.1.3}/.claude/skills/codebase-index/scripts/cbx.ps1 +0 -0
  30. {codebase_index-2.1.1 → codebase_index-2.1.3}/.claude-plugin/marketplace.json +0 -0
  31. {codebase_index-2.1.1 → codebase_index-2.1.3}/.codex/skills/codebase-index/SKILL.md +0 -0
  32. {codebase_index-2.1.1 → codebase_index-2.1.3}/.codex/skills/codebase-index/examples/hooks/settings.json +0 -0
  33. {codebase_index-2.1.1 → codebase_index-2.1.3}/.codex/skills/codebase-index/references/commands.md +0 -0
  34. {codebase_index-2.1.1 → codebase_index-2.1.3}/.codex/skills/codebase-index/references/memory.md +0 -0
  35. {codebase_index-2.1.1 → codebase_index-2.1.3}/.codex/skills/codebase-index/references/response-contract.md +0 -0
  36. {codebase_index-2.1.1 → codebase_index-2.1.3}/.codex/skills/codebase-index/scripts/cbx +0 -0
  37. {codebase_index-2.1.1 → codebase_index-2.1.3}/.codex/skills/codebase-index/scripts/cbx.ps1 +0 -0
  38. {codebase_index-2.1.1 → codebase_index-2.1.3}/.editorconfig +0 -0
  39. {codebase_index-2.1.1 → codebase_index-2.1.3}/.gitattributes +0 -0
  40. {codebase_index-2.1.1 → codebase_index-2.1.3}/.github/ISSUE_TEMPLATE/benchmark_report.yml +0 -0
  41. {codebase_index-2.1.1 → codebase_index-2.1.3}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  42. {codebase_index-2.1.1 → codebase_index-2.1.3}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  43. {codebase_index-2.1.1 → codebase_index-2.1.3}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  44. {codebase_index-2.1.1 → codebase_index-2.1.3}/.github/ISSUE_TEMPLATE/language_support.yml +0 -0
  45. {codebase_index-2.1.1 → codebase_index-2.1.3}/.github/ISSUE_TEMPLATE/skill_listing_request.yml +0 -0
  46. {codebase_index-2.1.1 → codebase_index-2.1.3}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  47. {codebase_index-2.1.1 → codebase_index-2.1.3}/.github/SUPPORT.md +0 -0
  48. {codebase_index-2.1.1 → codebase_index-2.1.3}/.github/labels.yml +0 -0
  49. {codebase_index-2.1.1 → codebase_index-2.1.3}/.github/workflows/ci.yml +0 -0
  50. {codebase_index-2.1.1 → codebase_index-2.1.3}/.github/workflows/release.yml +0 -0
  51. {codebase_index-2.1.1 → codebase_index-2.1.3}/.gitignore +0 -0
  52. {codebase_index-2.1.1 → codebase_index-2.1.3}/.opencode/agents/codebase-index.md +0 -0
  53. {codebase_index-2.1.1 → codebase_index-2.1.3}/.opencode/commands/codebase-index.md +0 -0
  54. {codebase_index-2.1.1 → codebase_index-2.1.3}/.opencode/skills/codebase-index/SKILL.md +0 -0
  55. {codebase_index-2.1.1 → codebase_index-2.1.3}/.opencode/skills/codebase-index/examples/hooks/settings.json +0 -0
  56. {codebase_index-2.1.1 → codebase_index-2.1.3}/.opencode/skills/codebase-index/references/commands.md +0 -0
  57. {codebase_index-2.1.1 → codebase_index-2.1.3}/.opencode/skills/codebase-index/references/memory.md +0 -0
  58. {codebase_index-2.1.1 → codebase_index-2.1.3}/.opencode/skills/codebase-index/references/response-contract.md +0 -0
  59. {codebase_index-2.1.1 → codebase_index-2.1.3}/.opencode/skills/codebase-index/scripts/cbx +0 -0
  60. {codebase_index-2.1.1 → codebase_index-2.1.3}/.opencode/skills/codebase-index/scripts/cbx.ps1 +0 -0
  61. {codebase_index-2.1.1 → codebase_index-2.1.3}/AGENTS.md +0 -0
  62. {codebase_index-2.1.1 → codebase_index-2.1.3}/CODE_OF_CONDUCT.md +0 -0
  63. {codebase_index-2.1.1 → codebase_index-2.1.3}/CONTRIBUTING.md +0 -0
  64. {codebase_index-2.1.1 → codebase_index-2.1.3}/LICENSE +0 -0
  65. {codebase_index-2.1.1 → codebase_index-2.1.3}/ROADMAP.md +0 -0
  66. {codebase_index-2.1.1 → codebase_index-2.1.3}/SECURITY.md +0 -0
  67. {codebase_index-2.1.1 → codebase_index-2.1.3}/adapters/claude.ps1 +0 -0
  68. {codebase_index-2.1.1 → codebase_index-2.1.3}/adapters/claude.sh +0 -0
  69. {codebase_index-2.1.1 → codebase_index-2.1.3}/adapters/codex.ps1 +0 -0
  70. {codebase_index-2.1.1 → codebase_index-2.1.3}/adapters/codex.sh +0 -0
  71. {codebase_index-2.1.1 → codebase_index-2.1.3}/adapters/opencode.ps1 +0 -0
  72. {codebase_index-2.1.1 → codebase_index-2.1.3}/adapters/opencode.sh +0 -0
  73. {codebase_index-2.1.1 → codebase_index-2.1.3}/assets/architecture.svg +0 -0
  74. {codebase_index-2.1.1 → codebase_index-2.1.3}/assets/benchmark.svg +0 -0
  75. {codebase_index-2.1.1 → codebase_index-2.1.3}/assets/demo-terminal.svg +0 -0
  76. {codebase_index-2.1.1 → codebase_index-2.1.3}/assets/mark.png +0 -0
  77. {codebase_index-2.1.1 → codebase_index-2.1.3}/assets/social-preview.png +0 -0
  78. {codebase_index-2.1.1 → codebase_index-2.1.3}/bin/cbx +0 -0
  79. {codebase_index-2.1.1 → codebase_index-2.1.3}/bin/cbx.ps1 +0 -0
  80. {codebase_index-2.1.1 → codebase_index-2.1.3}/bin/codebase-index +0 -0
  81. {codebase_index-2.1.1 → codebase_index-2.1.3}/bin/codebase-index.ps1 +0 -0
  82. {codebase_index-2.1.1 → codebase_index-2.1.3}/docs/ARCHITECTURE.md +0 -0
  83. {codebase_index-2.1.1 → codebase_index-2.1.3}/docs/BENCHMARKS.md +0 -0
  84. {codebase_index-2.1.1 → codebase_index-2.1.3}/docs/COMMUNITY_AUDIT.md +0 -0
  85. {codebase_index-2.1.1 → codebase_index-2.1.3}/docs/COMMUNITY_LAUNCH.md +0 -0
  86. {codebase_index-2.1.1 → codebase_index-2.1.3}/docs/COMPARISON.md +0 -0
  87. {codebase_index-2.1.1 → codebase_index-2.1.3}/docs/DATABASE_SCHEMA.md +0 -0
  88. {codebase_index-2.1.1 → codebase_index-2.1.3}/docs/DEMO.md +0 -0
  89. {codebase_index-2.1.1 → codebase_index-2.1.3}/docs/DEVELOPMENT.md +0 -0
  90. {codebase_index-2.1.1 → codebase_index-2.1.3}/docs/FAQ.md +0 -0
  91. {codebase_index-2.1.1 → codebase_index-2.1.3}/docs/INSTALLATION.md +0 -0
  92. {codebase_index-2.1.1 → codebase_index-2.1.3}/docs/LANGUAGES.md +0 -0
  93. {codebase_index-2.1.1 → codebase_index-2.1.3}/docs/MCP.md +0 -0
  94. {codebase_index-2.1.1 → codebase_index-2.1.3}/docs/MEMORY.md +0 -0
  95. {codebase_index-2.1.1 → codebase_index-2.1.3}/docs/PRODUCT_UPGRADE_PLAN.md +0 -0
  96. {codebase_index-2.1.1 → codebase_index-2.1.3}/docs/QUICKSTART.md +0 -0
  97. {codebase_index-2.1.1 → codebase_index-2.1.3}/docs/RELEASE_CHECKLIST.md +0 -0
  98. {codebase_index-2.1.1 → codebase_index-2.1.3}/docs/RETRIEVAL.md +0 -0
  99. {codebase_index-2.1.1 → codebase_index-2.1.3}/docs/RETRIEVAL_PIPELINE.md +0 -0
  100. {codebase_index-2.1.1 → codebase_index-2.1.3}/docs/ROADMAP.md +0 -0
  101. {codebase_index-2.1.1 → codebase_index-2.1.3}/docs/SECURITY.md +0 -0
  102. {codebase_index-2.1.1 → codebase_index-2.1.3}/docs/SECURITY_MODEL.md +0 -0
  103. {codebase_index-2.1.1 → codebase_index-2.1.3}/docs/SKILL_DESIGN.md +0 -0
  104. {codebase_index-2.1.1 → codebase_index-2.1.3}/docs/demo.tape +0 -0
  105. {codebase_index-2.1.1 → codebase_index-2.1.3}/docs/superpowers/plans/2026-05-29-benchmark-index-improvements.md +0 -0
  106. {codebase_index-2.1.1 → codebase_index-2.1.3}/docs/superpowers/plans/2026-05-29-generalize-skill-research-discipline.md +0 -0
  107. {codebase_index-2.1.1 → codebase_index-2.1.3}/docs/superpowers/plans/2026-05-29-m1-storage-discovery.md +0 -0
  108. {codebase_index-2.1.1 → codebase_index-2.1.3}/docs/superpowers/plans/2026-05-29-m2-fts-lexical.md +0 -0
  109. {codebase_index-2.1.1 → codebase_index-2.1.3}/docs/superpowers/plans/2026-05-29-m3-treesitter-symbols.md +0 -0
  110. {codebase_index-2.1.1 → codebase_index-2.1.3}/docs/superpowers/plans/2026-05-29-m4-hybrid-search.md +0 -0
  111. {codebase_index-2.1.1 → codebase_index-2.1.3}/docs/superpowers/plans/2026-05-29-m5-graph-impact.md +0 -0
  112. {codebase_index-2.1.1 → codebase_index-2.1.3}/docs/superpowers/plans/2026-05-29-m6-embeddings-vector.md +0 -0
  113. {codebase_index-2.1.1 → codebase_index-2.1.3}/docs/superpowers/plans/2026-05-29-m7-5-plugin-one-command-install.md +0 -0
  114. {codebase_index-2.1.1 → codebase_index-2.1.3}/docs/superpowers/plans/2026-05-29-m7-skill-packaging.md +0 -0
  115. {codebase_index-2.1.1 → codebase_index-2.1.3}/docs/superpowers/plans/2026-05-29-m8-hooks-watch.md +0 -0
  116. {codebase_index-2.1.1 → codebase_index-2.1.3}/docs/superpowers/plans/2026-05-29-m9-release.md +0 -0
  117. {codebase_index-2.1.1 → codebase_index-2.1.3}/docs/superpowers/plans/2026-05-29-multilang-symbols-make-skill-win.md +0 -0
  118. {codebase_index-2.1.1 → codebase_index-2.1.3}/docs/superpowers/plans/2026-06-24-snippet-skeletonization.md +0 -0
  119. {codebase_index-2.1.1 → codebase_index-2.1.3}/docs/superpowers/specs/2026-05-29-plugin-one-command-install-design.md +0 -0
  120. {codebase_index-2.1.1 → codebase_index-2.1.3}/docs/superpowers/specs/2026-06-14-typed-framework-edges-design.md +0 -0
  121. {codebase_index-2.1.1 → codebase_index-2.1.3}/docs/superpowers/specs/2026-06-24-snippet-skeletonization-design.md +0 -0
  122. {codebase_index-2.1.1 → codebase_index-2.1.3}/docs/superpowers/specs/2026-09-10-evidence-memory-design.md +0 -0
  123. {codebase_index-2.1.1 → codebase_index-2.1.3}/examples/config.example.json +0 -0
  124. {codebase_index-2.1.1 → codebase_index-2.1.3}/examples/demo/EXPECTED_OUTPUT.md +0 -0
  125. {codebase_index-2.1.1 → codebase_index-2.1.3}/examples/demo/README.md +0 -0
  126. {codebase_index-2.1.1 → codebase_index-2.1.3}/examples/demo/run_demo.ps1 +0 -0
  127. {codebase_index-2.1.1 → codebase_index-2.1.3}/examples/demo/run_demo.sh +0 -0
  128. {codebase_index-2.1.1 → codebase_index-2.1.3}/examples/hooks/settings.json +0 -0
  129. {codebase_index-2.1.1 → codebase_index-2.1.3}/examples/queries.md +0 -0
  130. {codebase_index-2.1.1 → codebase_index-2.1.3}/examples/sample-queries.md +0 -0
  131. {codebase_index-2.1.1 → codebase_index-2.1.3}/examples/sample-retrieval-output.md +0 -0
  132. {codebase_index-2.1.1 → codebase_index-2.1.3}/install.ps1 +0 -0
  133. {codebase_index-2.1.1 → codebase_index-2.1.3}/install.sh +0 -0
  134. {codebase_index-2.1.1 → codebase_index-2.1.3}/lib/common.ps1 +0 -0
  135. {codebase_index-2.1.1 → codebase_index-2.1.3}/lib/common.sh +0 -0
  136. {codebase_index-2.1.1 → codebase_index-2.1.3}/pyproject.toml +0 -0
  137. {codebase_index-2.1.1 → codebase_index-2.1.3}/research/2.0-audit.md +0 -0
  138. {codebase_index-2.1.1 → codebase_index-2.1.3}/research/README.md +0 -0
  139. {codebase_index-2.1.1 → codebase_index-2.1.3}/research/__init__.py +0 -0
  140. {codebase_index-2.1.1 → codebase_index-2.1.3}/research/architecture.md +0 -0
  141. {codebase_index-2.1.1 → codebase_index-2.1.3}/research/build_indexes.py +0 -0
  142. {codebase_index-2.1.1 → codebase_index-2.1.3}/research/data/.gitignore +0 -0
  143. {codebase_index-2.1.1 → codebase_index-2.1.3}/research/diagnose_accretion.py +0 -0
  144. {codebase_index-2.1.1 → codebase_index-2.1.3}/research/diagnose_calibration.py +0 -0
  145. {codebase_index-2.1.1 → codebase_index-2.1.3}/research/diagnose_slots.py +0 -0
  146. {codebase_index-2.1.1 → codebase_index-2.1.3}/research/diagnose_structure.py +0 -0
  147. {codebase_index-2.1.1 → codebase_index-2.1.3}/research/experiment_memory.py +0 -0
  148. {codebase_index-2.1.1 → codebase_index-2.1.3}/research/experiments.md +0 -0
  149. {codebase_index-2.1.1 → codebase_index-2.1.3}/research/fit_gate.py +0 -0
  150. {codebase_index-2.1.1 → codebase_index-2.1.3}/research/fit_weights.py +0 -0
  151. {codebase_index-2.1.1 → codebase_index-2.1.3}/research/hypotheses.md +0 -0
  152. {codebase_index-2.1.1 → codebase_index-2.1.3}/research/novelty.md +0 -0
  153. {codebase_index-2.1.1 → codebase_index-2.1.3}/research/nucleus/__init__.py +0 -0
  154. {codebase_index-2.1.1 → codebase_index-2.1.3}/research/nucleus/baselines.py +0 -0
  155. {codebase_index-2.1.1 → codebase_index-2.1.3}/research/nucleus/evalrun.py +0 -0
  156. {codebase_index-2.1.1 → codebase_index-2.1.3}/research/nucleus/memory.py +0 -0
  157. {codebase_index-2.1.1 → codebase_index-2.1.3}/research/nucleus/relations.py +0 -0
  158. {codebase_index-2.1.1 → codebase_index-2.1.3}/research/nucleus/search.py +0 -0
  159. {codebase_index-2.1.1 → codebase_index-2.1.3}/research/related-work.md +0 -0
  160. {codebase_index-2.1.1 → codebase_index-2.1.3}/research/selection.md +0 -0
  161. {codebase_index-2.1.1 → codebase_index-2.1.3}/research/test_nucleus.py +0 -0
  162. {codebase_index-2.1.1 → codebase_index-2.1.3}/scripts/apply_labels.sh +0 -0
  163. {codebase_index-2.1.1 → codebase_index-2.1.3}/scripts/bootstrap.ps1 +0 -0
  164. {codebase_index-2.1.1 → codebase_index-2.1.3}/scripts/bootstrap.sh +0 -0
  165. {codebase_index-2.1.1 → codebase_index-2.1.3}/scripts/check_links.py +0 -0
  166. {codebase_index-2.1.1 → codebase_index-2.1.3}/scripts/check_versions.py +0 -0
  167. {codebase_index-2.1.1 → codebase_index-2.1.3}/scripts/gen_assets.py +0 -0
  168. {codebase_index-2.1.1 → codebase_index-2.1.3}/scripts/gen_benchmark_chart.py +0 -0
  169. {codebase_index-2.1.1 → codebase_index-2.1.3}/scripts/gen_terminal_svg.py +0 -0
  170. {codebase_index-2.1.1 → codebase_index-2.1.3}/scripts/release_notes.py +0 -0
  171. {codebase_index-2.1.1 → codebase_index-2.1.3}/scripts/release_smoke.py +0 -0
  172. {codebase_index-2.1.1 → codebase_index-2.1.3}/scripts/sync_skill_copies.py +0 -0
  173. {codebase_index-2.1.1 → codebase_index-2.1.3}/skill/SKILL.md +0 -0
  174. {codebase_index-2.1.1 → codebase_index-2.1.3}/skill/examples/basic-usage.md +0 -0
  175. {codebase_index-2.1.1 → codebase_index-2.1.3}/skill/examples/claude-md-example.md +0 -0
  176. {codebase_index-2.1.1 → codebase_index-2.1.3}/skill/examples/hooks-example.json +0 -0
  177. {codebase_index-2.1.1 → codebase_index-2.1.3}/skill/references/commands.md +0 -0
  178. {codebase_index-2.1.1 → codebase_index-2.1.3}/skill/references/memory.md +0 -0
  179. {codebase_index-2.1.1 → codebase_index-2.1.3}/skill/references/response-contract.md +0 -0
  180. {codebase_index-2.1.1 → codebase_index-2.1.3}/skill/scripts/bootstrap.py +0 -0
  181. {codebase_index-2.1.1 → codebase_index-2.1.3}/skill/scripts/cbx +0 -0
  182. {codebase_index-2.1.1 → codebase_index-2.1.3}/skill/scripts/cbx.ps1 +0 -0
  183. {codebase_index-2.1.1 → codebase_index-2.1.3}/skill/scripts/doctor.py +0 -0
  184. {codebase_index-2.1.1 → codebase_index-2.1.3}/skill/scripts/install.py +0 -0
  185. {codebase_index-2.1.1 → codebase_index-2.1.3}/skill/scripts/smoke_test.py +0 -0
  186. {codebase_index-2.1.1 → codebase_index-2.1.3}/skills/codebase-index/SKILL.md +0 -0
  187. {codebase_index-2.1.1 → codebase_index-2.1.3}/skills/codebase-index/references/commands.md +0 -0
  188. {codebase_index-2.1.1 → codebase_index-2.1.3}/skills/codebase-index/references/memory.md +0 -0
  189. {codebase_index-2.1.1 → codebase_index-2.1.3}/skills/codebase-index/references/response-contract.md +0 -0
  190. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/__main__.py +0 -0
  191. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/config.py +0 -0
  192. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/discovery/__init__.py +0 -0
  193. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/discovery/classify.py +0 -0
  194. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/discovery/gates.py +0 -0
  195. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/discovery/ignore.py +0 -0
  196. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/discovery/walker.py +0 -0
  197. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/doctor.py +0 -0
  198. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/embeddings/__init__.py +0 -0
  199. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/embeddings/backend.py +0 -0
  200. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/embeddings/external.py +0 -0
  201. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/embeddings/local.py +0 -0
  202. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/embeddings/noop.py +0 -0
  203. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/graph/__init__.py +0 -0
  204. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/graph/analysis.py +0 -0
  205. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/graph/builder.py +0 -0
  206. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/graph/expand.py +0 -0
  207. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/graph/export.py +0 -0
  208. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/graph/modules.py +0 -0
  209. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/graph/navigate.py +0 -0
  210. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/graph/retrieval.py +0 -0
  211. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/indexer/__init__.py +0 -0
  212. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/indexer/doc_chunks.py +0 -0
  213. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/indexer/freshness.py +0 -0
  214. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/indexer/pipeline.py +0 -0
  215. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/mcp/__init__.py +0 -0
  216. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/mcp/server.py +0 -0
  217. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/memory/__init__.py +0 -0
  218. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/memory/identity.py +0 -0
  219. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/memory/session.py +0 -0
  220. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/memory/store.py +0 -0
  221. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/memory/validate.py +0 -0
  222. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/models.py +0 -0
  223. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/output/__init__.py +0 -0
  224. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/output/json.py +0 -0
  225. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/output/markdown.py +0 -0
  226. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/output/redact.py +0 -0
  227. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/parsers/__init__.py +0 -0
  228. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/parsers/base.py +0 -0
  229. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/parsers/languages.py +0 -0
  230. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/parsers/line_chunker.py +0 -0
  231. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/parsers/symbol_chunks.py +0 -0
  232. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/parsers/treesitter.py +0 -0
  233. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/retrieval/__init__.py +0 -0
  234. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/retrieval/budget.py +0 -0
  235. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/retrieval/diversity.py +0 -0
  236. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/retrieval/features.py +0 -0
  237. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/retrieval/fusion.py +0 -0
  238. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/retrieval/fuzzy.py +0 -0
  239. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/retrieval/intent.py +0 -0
  240. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/retrieval/lexical.py +0 -0
  241. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/retrieval/pipeline.py +0 -0
  242. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/retrieval/priors.py +0 -0
  243. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/retrieval/rerank.py +0 -0
  244. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/retrieval/searchers.py +0 -0
  245. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/retrieval/skeleton.py +0 -0
  246. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/retrieval/tuning.py +0 -0
  247. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/retrieval/types.py +0 -0
  248. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/service.py +0 -0
  249. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/skill_template/SKILL.md +0 -0
  250. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/skill_template/examples/hooks/settings.json +0 -0
  251. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/skill_template/references/commands.md +0 -0
  252. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/skill_template/references/memory.md +0 -0
  253. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/skill_template/references/response-contract.md +0 -0
  254. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/skill_template/scripts/cbx +0 -0
  255. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/skill_template/scripts/cbx.ps1 +0 -0
  256. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/skill_update.py +0 -0
  257. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/storage/__init__.py +0 -0
  258. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/storage/db.py +0 -0
  259. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/storage/repo.py +0 -0
  260. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/watch/__init__.py +0 -0
  261. {codebase_index-2.1.1 → codebase_index-2.1.3}/src/codebase_index/watch/watcher.py +0 -0
  262. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/__init__.py +0 -0
  263. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/benchmark_honest.py +0 -0
  264. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/benchmark_honest_RESULTS.md +0 -0
  265. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/benchmark_honest_newtowny.txt +0 -0
  266. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/benchmark_public.py +0 -0
  267. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/benchmark_public_RESULTS.md +0 -0
  268. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/benchmark_real_repo.py +0 -0
  269. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/conftest.py +0 -0
  270. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/eval/README.md +0 -0
  271. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/eval/__init__.py +0 -0
  272. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/eval/baselines.py +0 -0
  273. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/eval/gen_queries.py +0 -0
  274. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/eval/harness.py +0 -0
  275. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/eval/memory_eval.py +0 -0
  276. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/eval/metrics.py +0 -0
  277. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/eval/queries/self_repo.yml +0 -0
  278. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/eval/queries/self_repo_git.yml +0 -0
  279. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/eval/results/1.10.0-perf.json +0 -0
  280. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/eval/results/1.10.0-retrieval-8corpus.txt +0 -0
  281. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/eval/results/2026-09-04-public-baselines.json +0 -0
  282. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/eval/results/2026-09-04-public-baselines.md +0 -0
  283. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/eval/results/2026-09-14-evidence-memory.json +0 -0
  284. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/eval/results/2026-09-14-evidence-memory.md +0 -0
  285. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/eval/results/2026-09-24-agent-pilot.md +0 -0
  286. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/eval/results/2026-09-24-retrieval-2.1.0.txt +0 -0
  287. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/eval/results/2026-09-24-terra-nl-queries.yml +0 -0
  288. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/eval/run_baselines.py +0 -0
  289. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/eval/run_eval.py +0 -0
  290. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/fixtures/README.md +0 -0
  291. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/fixtures/expected_answers.yml +0 -0
  292. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/fixtures/index-1.10.0/index.sqlite +0 -0
  293. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/fixtures/multilang/sample.go +0 -0
  294. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/fixtures/multilang/sample.java +0 -0
  295. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/fixtures/multilang/sample.rs +0 -0
  296. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/fixtures/sample_repo/.env +0 -0
  297. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/fixtures/sample_repo/.gitignore +0 -0
  298. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/fixtures/sample_repo/huge.json +0 -0
  299. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/fixtures/sample_repo/logo.png +0 -0
  300. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/fixtures/sample_repo/node_modules/leftpad/index.js +0 -0
  301. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/fixtures/sample_repo/secrets.pem +0 -0
  302. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/fixtures/sample_repo/src/api/service.py +0 -0
  303. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/fixtures/sample_repo/src/auth/token.py +0 -0
  304. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/fixtures/sample_repo/src/models/user.py +0 -0
  305. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/fixtures/sample_repo/src/schema.generated.ts +0 -0
  306. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/fixtures/sample_repo/web/app.ts +0 -0
  307. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/golden/architecture.json +0 -0
  308. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/golden/describe_refresh.json +0 -0
  309. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/golden/explain_auth.json +0 -0
  310. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/golden/impact_user_model.json +0 -0
  311. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/golden/mcp_architecture.json +0 -0
  312. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/golden/mcp_describe_symbol.json +0 -0
  313. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/golden/mcp_explain_code.json +0 -0
  314. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/golden/mcp_find_refs.json +0 -0
  315. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/golden/mcp_find_symbol.json +0 -0
  316. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/golden/mcp_healthcheck.json +0 -0
  317. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/golden/mcp_impact_of.json +0 -0
  318. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/golden/mcp_impact_of_diff.json +0 -0
  319. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/golden/mcp_index_stats.json +0 -0
  320. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/golden/mcp_path_between.json +0 -0
  321. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/golden/mcp_search_code.json +0 -0
  322. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/golden/path_renew_to_token.json +0 -0
  323. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/golden/refs_refresh_access_token.json +0 -0
  324. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/golden/search_token.json +0 -0
  325. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/golden/stats.json +0 -0
  326. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/golden/symbol_user.json +0 -0
  327. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/golden_utils.py +0 -0
  328. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/installer/smoke.ps1 +0 -0
  329. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/installer/smoke.sh +0 -0
  330. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_agent_ergonomics.py +0 -0
  331. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_analysis.py +0 -0
  332. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_benchmark_comparison.py +0 -0
  333. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_bootstrap.py +0 -0
  334. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_budget.py +0 -0
  335. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_chunker.py +0 -0
  336. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_classify.py +0 -0
  337. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_clean_cli.py +0 -0
  338. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_cli.py +0 -0
  339. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_cli_golden.py +0 -0
  340. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_compact_output.py +0 -0
  341. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_config.py +0 -0
  342. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_diff_impact.py +0 -0
  343. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_discovery.py +0 -0
  344. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_diversity.py +0 -0
  345. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_doc_chunks.py +0 -0
  346. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_doctor.py +0 -0
  347. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_embeddings_backend.py +0 -0
  348. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_embeddings_external.py +0 -0
  349. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_embeddings_local.py +0 -0
  350. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_eval_baselines.py +0 -0
  351. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_freshness.py +0 -0
  352. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_fusion.py +0 -0
  353. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_fuzzy.py +0 -0
  354. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_gen_queries.py +0 -0
  355. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_graph.py +0 -0
  356. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_graph_coverage.py +0 -0
  357. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_graph_export_cli.py +0 -0
  358. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_graph_retrieval.py +0 -0
  359. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_hooks_merge.py +0 -0
  360. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_hybrid_ranking.py +0 -0
  361. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_ignore.py +0 -0
  362. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_impact_cli.py +0 -0
  363. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_impact_decay.py +0 -0
  364. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_index_cli.py +0 -0
  365. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_init_cli.py +0 -0
  366. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_intent.py +0 -0
  367. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_languages.py +0 -0
  368. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_lexical.py +0 -0
  369. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_mcp_golden.py +0 -0
  370. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_mcp_server.py +0 -0
  371. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_memory_eval_smoke.py +0 -0
  372. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_memory_identity.py +0 -0
  373. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_memory_lifecycle.py +0 -0
  374. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_memory_session.py +0 -0
  375. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_memory_stale_context.py +0 -0
  376. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_memory_store.py +0 -0
  377. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_memory_surfaces.py +0 -0
  378. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_memory_validate.py +0 -0
  379. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_migration_1x.py +0 -0
  380. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_multilang_symbols.py +0 -0
  381. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_navigate.py +0 -0
  382. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_output.py +0 -0
  383. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_packaging.py +0 -0
  384. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_parse_guardrails.py +0 -0
  385. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_perf_smoke.py +0 -0
  386. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_pipeline.py +0 -0
  387. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_pipeline_search.py +0 -0
  388. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_pipeline_vectors.py +0 -0
  389. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_plugin_manifest.py +0 -0
  390. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_plugin_skill_parity.py +0 -0
  391. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_plugin_wrappers.py +0 -0
  392. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_priors.py +0 -0
  393. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_public_benchmark.py +0 -0
  394. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_qualified_refs.py +0 -0
  395. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_quality_benchmark.py +0 -0
  396. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_ranking_features.py +0 -0
  397. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_read_cap.py +0 -0
  398. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_redact.py +0 -0
  399. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_release_scripts.py +0 -0
  400. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_repo_search.py +0 -0
  401. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_rerank.py +0 -0
  402. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_retrieval_types.py +0 -0
  403. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_scaffold.py +0 -0
  404. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_search_cli.py +0 -0
  405. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_searchers.py +0 -0
  406. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_seeded_index.py +0 -0
  407. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_service.py +0 -0
  408. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_skeleton.py +0 -0
  409. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_skill_update.py +0 -0
  410. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_symbol_cli.py +0 -0
  411. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_symbol_ranking.py +0 -0
  412. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_symbol_refs.py +0 -0
  413. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_sync_skill_copies.py +0 -0
  414. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_treesitter.py +0 -0
  415. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_tuning_contract.py +0 -0
  416. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_update.py +0 -0
  417. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_update_cli.py +0 -0
  418. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_vector_search.py +0 -0
  419. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_vectors_storage.py +0 -0
  420. {codebase_index-2.1.1 → codebase_index-2.1.3}/tests/test_watcher.py +0 -0
@@ -3,7 +3,7 @@
3
3
  "name": "codebase-index",
4
4
  "displayName": "Codebase Index",
5
5
  "description": "Give Claude a precise local map of your codebase: find implementations, trace behavior, and predict change impact with file-line evidence.",
6
- "version": "2.1.1",
6
+ "version": "2.1.3",
7
7
  "author": {
8
8
  "name": "codebase-index contributors"
9
9
  },
@@ -6,6 +6,42 @@ All notable changes to this project are documented here. The format is based on
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [2.1.3] - 2026-11-02
10
+
11
+ ### Fixed
12
+
13
+ - Removing files from a large index no longer takes hours: `chunks.symbol_id` and
14
+ `symbols.parent_id` are now indexed, so a deleted symbol no longer costs a full scan
15
+ of both tables. Existing indexes gain the two indexes the next time they are opened,
16
+ with no rebuild.
17
+ - The `PreToolUse` guard now covers Claude Code's PowerShell tool:
18
+ - a `codebase-index` command run from PowerShell turns the guard off for the session,
19
+ and `Select-String` or `rg` code searches there are guarded like their Bash
20
+ equivalents. A `Select-String` that reads piped input is left alone, and here-string
21
+ bodies (`@'...'@`) are not scanned;
22
+ - `install-hooks` refreshes the matcher of an installed guard. Run it again after
23
+ upgrading; the plugin's hooks pick this up on their own.
24
+ - The guard no longer intercepts searches that cannot be answered by the index: those
25
+ over `.git` internals, binaries (`.exe`, `.dll`, `.jar`, `.sqlite` and the like), or
26
+ absolute paths outside the indexed repository. Nor does it intercept anything in a
27
+ directory without an index.
28
+
29
+ ## [2.1.2] - 2026-09-25
30
+
31
+ ### Fixed
32
+
33
+ - The `PreToolUse` guard no longer blocks work it should let through:
34
+ - the first `codebase-index` command of a session turns the guard off even when it
35
+ is the command that builds the index; before, a repository without an index kept
36
+ the guard on for the whole session. Session state now lives in the system temp
37
+ directory (`CBX_HOOK_STATE` overrides it) instead of inside the index;
38
+ - heredoc bodies (`cat > script.ps1 <<'EOF'`, `python - <<EOF`) are file content, not
39
+ commands, and are no longer scanned for `grep`/`Select-String`;
40
+ - a retry is matched by its search term, not by the whole tool call, so a rewritten
41
+ command or a new description for the same search goes through;
42
+ - a quoted alternation such as `grep "a\|b"` is read whole, and a search on its own
43
+ line of a multi-line command is recognised.
44
+
9
45
  ## [2.1.1] - 2026-09-25
10
46
 
11
47
  ### Added
@@ -886,7 +922,9 @@ Pooled over 305 queries (Python, Java, TypeScript), v1.8.0 → 1.9.0:
886
922
  - Hooks example + `watch` mode for keeping the index fresh without blocking the edit loop (M8).
887
923
  - `doctor`, `stats`, `clean` diagnostics/maintenance commands.
888
924
 
889
- [Unreleased]: https://github.com/denfry/codebase-index/compare/v2.1.1...HEAD
925
+ [Unreleased]: https://github.com/denfry/codebase-index/compare/v2.1.3...HEAD
926
+ [2.1.3]: https://github.com/denfry/codebase-index/compare/v2.1.2...v2.1.3
927
+ [2.1.2]: https://github.com/denfry/codebase-index/compare/v2.1.1...v2.1.2
890
928
  [2.1.1]: https://github.com/denfry/codebase-index/compare/v2.1.0...v2.1.1
891
929
  [2.1.0]: https://github.com/denfry/codebase-index/compare/v2.0.0...v2.1.0
892
930
  [2.0.0]: https://github.com/denfry/codebase-index/compare/v1.9.0...v2.0.0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codebase-index
3
- Version: 2.1.1
3
+ Version: 2.1.3
4
4
  Summary: A precise local codebase map for AI coding agents: find, trace, and predict with file-line evidence.
5
5
  Project-URL: Homepage, https://github.com/denfry/codebase-index
6
6
  Project-URL: Documentation, https://github.com/denfry/codebase-index/tree/main/docs
@@ -69,6 +69,7 @@ Description-Content-Type: text/markdown
69
69
  <img src="https://img.shields.io/badge/MCP-stdio%20server-3fb950" alt="MCP stdio server">
70
70
  <img src="https://img.shields.io/badge/network-off%20by%20default-3fb950" alt="No network by default">
71
71
  <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-8b949e" alt="MIT license"></a>
72
+ <a href="https://discord.gg/mVZcNUAGZt"><img src="https://img.shields.io/badge/Discord-Join%20the%20community-5865F2?logo=discord&logoColor=white" alt="Discord"></a>
72
73
  </p>
73
74
 
74
75
  <p align="center">
@@ -19,6 +19,7 @@
19
19
  <img src="https://img.shields.io/badge/MCP-stdio%20server-3fb950" alt="MCP stdio server">
20
20
  <img src="https://img.shields.io/badge/network-off%20by%20default-3fb950" alt="No network by default">
21
21
  <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-8b949e" alt="MIT license"></a>
22
+ <a href="https://discord.gg/mVZcNUAGZt"><img src="https://img.shields.io/badge/Discord-Join%20the%20community-5865F2?logo=discord&logoColor=white" alt="Discord"></a>
22
23
  </p>
23
24
 
24
25
  <p align="center">
@@ -44,6 +44,7 @@ CREATE TABLE chunks (
44
44
  symbol_names TEXT NOT NULL DEFAULT '' -- denormalized symbol name, FTS-indexed (mirrored by triggers)
45
45
  );
46
46
  CREATE INDEX idx_chunks_file ON chunks(file_id);
47
+ CREATE INDEX idx_chunks_symbol ON chunks(symbol_id);
47
48
 
48
49
  -- Symbols extracted via tree-sitter (definitions).
49
50
  CREATE TABLE symbols (
@@ -63,6 +64,7 @@ CREATE TABLE symbols (
63
64
  CREATE INDEX idx_symbols_name ON symbols(name);
64
65
  CREATE INDEX idx_symbols_file ON symbols(file_id);
65
66
  CREATE INDEX idx_symbols_kind ON symbols(kind);
67
+ CREATE INDEX idx_symbols_parent ON symbols(parent_id);
66
68
 
67
69
  -- Graph edges: imports / calls / references / inheritance / dependencies.
68
70
  -- src is always a known symbol or file; dst may be unresolved (dst_id NULL, dst_name kept).
@@ -110,7 +110,7 @@ pwsh ./install.ps1 -Target claude -InstallDir "D:\skills\codebase-index"
110
110
  **Pin to a branch or tag** (reproducibility and safety):
111
111
 
112
112
  ```sh
113
- sh install.sh --branch v2.1.1
113
+ sh install.sh --branch v2.1.3
114
114
  ```
115
115
 
116
116
  ---
@@ -17,7 +17,7 @@
17
17
  ],
18
18
  "PreToolUse": [
19
19
  {
20
- "matcher": "Grep|Bash",
20
+ "matcher": "Grep|Bash|PowerShell",
21
21
  "hooks": [
22
22
  {
23
23
  "type": "command",
@@ -1,3 +1,3 @@
1
- codebase-index @ https://github.com/denfry/codebase-index/archive/refs/tags/v2.1.1.tar.gz
1
+ codebase-index @ https://github.com/denfry/codebase-index/archive/refs/tags/v2.1.3.tar.gz
2
2
  tree-sitter==0.25.2
3
3
  tree-sitter-language-pack==1.8.1
@@ -4,4 +4,4 @@ Public surface is intentionally small; the CLI (`codebase_index.cli:app`) is the
4
4
  See docs/ARCHITECTURE.md for the module map.
5
5
  """
6
6
 
7
- __version__ = "2.1.1"
7
+ __version__ = "2.1.3"
@@ -1074,10 +1074,11 @@ def install_hooks(
1074
1074
  ) -> None:
1075
1075
  """Make Claude Code search through the index by default.
1076
1076
 
1077
- Adds a SessionStart note and a PreToolUse guard on Grep/Bash: the first code
1078
- search of a session, before any codebase-index command, is sent back with the
1079
- index command to run instead; repeating it lets it through. Both do nothing in
1080
- a directory without an index. Other hooks in the settings file are kept.
1077
+ Adds a SessionStart note and a PreToolUse guard on Grep, Bash and PowerShell: the
1078
+ first code search of a session, before any codebase-index command, is sent back
1079
+ with the index command to run instead; repeating it lets it through. Both do
1080
+ nothing in a directory without an index. Other hooks in the settings file are
1081
+ kept. Run it again after an upgrade to refresh an installed guard.
1081
1082
  """
1082
1083
  from .config import find_root
1083
1084
  from . import scaffold
@@ -1092,7 +1093,7 @@ def install_hooks(
1092
1093
  verb = "removed from"
1093
1094
  else:
1094
1095
  changed = scaffold.install_guard_hooks(path)
1095
- verb = "added to"
1096
+ verb = "added to or refreshed in"
1096
1097
  if changed:
1097
1098
  typer.echo(f"[install-hooks] {', '.join(changed)} {verb} {path}")
1098
1099
  else:
@@ -4,19 +4,23 @@ Two events, both no-ops outside a repository that has an index:
4
4
 
5
5
  - ``session-start`` adds one short note to the session context: this repository
6
6
  is indexed, and which commands answer code questions.
7
- - ``guard`` (PreToolUse on Grep and Bash) intercepts a code search the first time
7
+ - ``guard`` (PreToolUse on Grep, Bash and PowerShell) intercepts a code search the first time
8
8
  in a session, before any ``codebase-index`` command has run, and names the
9
- index command to use instead. It is a nudge, not a wall: repeating the same
10
- call lets it through, the first ``codebase-index`` command in the session turns
11
- the guard off, and searches over docs, logs or config are never intercepted.
9
+ index command to use instead. It is a nudge, not a wall: searching for the
10
+ same term again lets it through, the first ``codebase-index`` command in the
11
+ session turns the guard off (even one that has yet to build the index), and
12
+ searches over docs, logs or config, or inside heredoc and here-string bodies,
13
+ are never intercepted.
12
14
 
13
15
  Measured on a 5.9k-file monorepo, an agent spent 19% fewer tokens with the index
14
16
  than with grep (tests/eval/results/2026-09-24-agent-pilot.md), but agents reach
15
- for Grep out of habit. The guard runs on every Bash call, so this module imports
17
+ for Grep out of habit. The guard runs on every shell call, so this module imports
16
18
  only the standard library and does no index work beyond one small SQLite read.
17
19
 
18
20
  Entry point: ``codebase-index-hook <event>`` reads the hook JSON on stdin and
19
21
  prints the hook JSON reply (or nothing). ``CBX_GUARD=0`` disables the guard.
22
+ Per-session state lives in the system temp directory (``CBX_HOOK_STATE``
23
+ overrides it), so it exists before the repository has an index.
20
24
  """
21
25
 
22
26
  from __future__ import annotations
@@ -27,28 +31,48 @@ import os
27
31
  import re
28
32
  import sqlite3
29
33
  import sys
34
+ import tempfile
30
35
  import time
31
36
  from pathlib import Path
32
37
  from typing import Any, Optional
33
38
 
34
39
  INDEX_REL = Path(".claude") / "cache" / "codebase-index" / "index.sqlite"
35
- _STATE_DIR = "hook-sessions"
40
+ _STATE_DIR = "codebase-index-hooks"
36
41
  _STATE_TTL_S = 2 * 24 * 3600
42
+ SHELL_TOOLS = ("Bash", "PowerShell")
37
43
 
38
44
  # A shell segment that searches file contents: the first command of the segment
39
- # (after `&&`, `||`, `;` or the start), so `ps aux | grep x` is not a repo search.
45
+ # (after `&&`, `||`, `;`, a newline or the start), so `ps aux | grep x` is not a
46
+ # repo search. Quoted arguments may hold `|`, as in grep "a\|b".
40
47
  _SEARCH_CMD = re.compile(
41
- r"(?:^|&&|\|\||;)\s*(?:cd\s+\S+\s*&&\s*)?"
42
- r"(?P<cmd>git\s+grep|grep|egrep|fgrep|rg|ag|ack|findstr|Select-String)\b(?P<args>[^|;&]*)",
48
+ r"(?:^|&&|\|\||;|\n)[ \t]*(?:cd\s+\S+\s*&&\s*)?"
49
+ r"(?P<cmd>git\s+grep|grep|egrep|fgrep|rg|ag|ack|findstr|Select-String)\b"
50
+ r"""(?P<args>(?:"[^"\n]*"|'[^'\n]*'|[^|;&\n"'])*)""",
43
51
  re.IGNORECASE,
44
52
  )
53
+ # A heredoc body is file content (a script being written, stdin for python), not
54
+ # commands; an unterminated one runs to the end of the command.
55
+ _HEREDOC = re.compile(
56
+ r"""(?<!<)<<-?(?!<)[ \t]*(['"]?)([A-Za-z_][\w-]*)\1(?P<rest>[^\n]*)\n"""
57
+ r".*?(?:^[ \t]*\2[ \t]*$|\Z)",
58
+ re.DOTALL | re.MULTILINE,
59
+ )
60
+ # PowerShell's heredoc: the closing `'@` or `"@` starts its own line.
61
+ _HERE_STRING = re.compile(r"""@(['"])[ \t]*\r?\n.*?^\1@""", re.DOTALL | re.MULTILINE)
45
62
  _INDEX_CMD = re.compile(r"(?:^|[\s;&|/\\\"'])(?:codebase-index|cbx)(?:\.exe|\.ps1)?\s+\w")
46
- # Searches over prose, logs and config are what grep is for; leave them alone.
63
+ # Searches over prose, logs, config, binaries and git internals are what grep is for;
64
+ # leave them alone.
47
65
  _NON_CODE = re.compile(
48
- r"\.(?:md|mdx|rst|txt|log|ya?ml|json|toml|ini|cfg|conf|csv|xml|properties|lock|env|html?)\b"
49
- r"|--include=\*?\.(?:md|txt|log|ya?ml|json|toml)",
66
+ r"\.(?:md|mdx|rst|txt|log|ya?ml|json|toml|ini|cfg|conf|csv|xml|properties|lock|env|html?"
67
+ r"|exe|dll|so|jar|class|bin|sqlite|db)\b"
68
+ r"|--include=\*?\.(?:md|txt|log|ya?ml|json|toml)"
69
+ r"|(?:^|[\s'\"/\\])\.git[\\/]",
50
70
  re.IGNORECASE,
51
71
  )
72
+ # Shell words of a search's arguments: a quoted string or a bare word.
73
+ _WORD = re.compile(r""""([^"]*)"|'([^']*)'|(\S+)""")
74
+ # An absolute path: a drive (C:\, C:/), an MSYS drive or POSIX root (/c/, /), or home.
75
+ _ABS_PATH = re.compile(r"^(?:[A-Za-z]:[\\/]|/|~(?:[\\/]|$)|\$HOME\b|\$\{HOME\})")
52
76
  _NON_CODE_TYPES = {"md", "markdown", "txt", "log", "yaml", "yml", "json", "toml", "xml",
53
77
  "csv", "ini", "config"}
54
78
 
@@ -130,32 +154,38 @@ def guard(payload: dict) -> Optional[dict]:
130
154
  return None
131
155
  tool = payload.get("tool_name") or ""
132
156
  tool_input = payload.get("tool_input") or {}
133
- if tool not in ("Grep", "Bash"):
157
+ if tool != "Grep" and tool not in SHELL_TOOLS:
134
158
  return None
135
- root = find_index_root(_cwd(payload))
136
- if root is None:
137
- return None
138
- session = str(payload.get("session_id") or "default")
139
- state = _State(root, session)
159
+ state = _State(str(payload.get("session_id") or "default"))
140
160
 
141
- if tool == "Bash":
142
- command = str(tool_input.get("command") or "")
161
+ if tool in SHELL_TOOLS:
162
+ command = _HEREDOC.sub(lambda m: "<<" + m.group("rest"), str(tool_input.get("command") or ""))
163
+ if tool == "PowerShell":
164
+ command = _HERE_STRING.sub("''", command)
143
165
  if _INDEX_CMD.search(command):
166
+ # Checked before the index exists: the first search is what builds it.
144
167
  state.mark_used()
145
168
  return None
146
- pattern = _shell_search_pattern(command)
169
+ root = find_index_root(_cwd(payload))
170
+ if root is None:
171
+ return None
172
+ pattern = _shell_search_pattern(command, root)
147
173
  if pattern is None:
148
174
  return None
149
175
  else:
150
- if _grep_targets_non_code(tool_input):
176
+ root = find_index_root(_cwd(payload))
177
+ if root is None or _grep_targets_non_code(tool_input):
178
+ return None
179
+ target = str(tool_input.get("path") or "")
180
+ if target and _outside_repo([target], root):
151
181
  return None
152
182
  pattern = str(tool_input.get("pattern") or "")
153
183
 
154
184
  if state.used:
155
185
  return None
156
- fingerprint = hashlib.sha1(
157
- (tool + json.dumps(tool_input, sort_keys=True, default=str)).encode("utf-8")
158
- ).hexdigest()
186
+ # Keyed by the search term, not the whole call: a retry rarely repeats the
187
+ # command byte for byte (a new description, another pipe, a regenerated script).
188
+ fingerprint = hashlib.sha1(_term(pattern).lower().encode("utf-8")).hexdigest()
159
189
  if state.was_denied(fingerprint):
160
190
  return None # the retry after a nudge: the agent decided grep is right
161
191
  state.deny(fingerprint)
@@ -168,20 +198,63 @@ def guard(payload: dict) -> Optional[dict]:
168
198
  }
169
199
 
170
200
 
171
- def _shell_search_pattern(command: str) -> Optional[str]:
201
+ def _shell_search_pattern(command: str, root: Path) -> Optional[str]:
172
202
  """The search term of a content search in `command`, or None if there is none."""
173
203
  for match in _SEARCH_CMD.finditer(command):
174
204
  args = match.group("args")
175
205
  if _NON_CODE.search(args):
176
206
  continue
177
- quoted = re.search(r"""(['"])(.+?)\1""", args)
178
- if quoted:
179
- return quoted.group(2)
180
- words = [w for w in args.split() if not w.startswith("-")]
181
- return words[0] if words else ""
207
+ words = [next(g for g in m.groups() if g is not None) for m in _WORD.finditer(args)]
208
+ if match.group("cmd").lower() == "select-string":
209
+ pattern, paths = _select_string_terms(words)
210
+ else:
211
+ positional = [w for w in words if not w.startswith("-") and not w.isdigit()]
212
+ # The first positional word is the pattern, the rest are the paths searched.
213
+ paths = positional[1:]
214
+ quoted = re.search(r"""(['"])(.+?)\1""", args)
215
+ pattern = quoted.group(2) if quoted else (positional[0] if positional else "")
216
+ if not _outside_repo(paths, root):
217
+ return pattern
182
218
  return None
183
219
 
184
220
 
221
+ def _select_string_terms(words: list[str]) -> tuple[str, list[str]]:
222
+ """The pattern and paths of a Select-String call, named or positional."""
223
+ pattern: list[str] = []
224
+ paths: list[str] = []
225
+ positional: list[str] = []
226
+ target = None
227
+ for word in words:
228
+ if target is not None:
229
+ target.extend(word.split(",") if target is paths else [word])
230
+ target = None
231
+ elif word.lower() in ("-path", "-literalpath", "-lp"):
232
+ target = paths
233
+ elif word.lower() == "-pattern":
234
+ target = pattern
235
+ elif not word.startswith("-") and not word.isdigit():
236
+ positional.append(word)
237
+ if not pattern and positional:
238
+ pattern.append(positional.pop(0))
239
+ return (pattern[0] if pattern else ""), paths or positional
240
+
241
+
242
+ def _outside_repo(paths: list[str], root: Path) -> bool:
243
+ """True when every path is absolute and none lies inside the indexed repository."""
244
+ if not paths or not all(_ABS_PATH.match(p) for p in paths):
245
+ return False
246
+ base = os.path.normcase(os.path.abspath(root))
247
+ for raw in paths:
248
+ path = re.sub(r"^(?:~|\$HOME\b|\$\{HOME\})", lambda _m: str(Path.home()), raw)
249
+ msys = re.match(r"^/([a-zA-Z])(/.*)?$", path)
250
+ if os.name == "nt" and msys:
251
+ path = f"{msys.group(1)}:{msys.group(2) or '/'}"
252
+ full = os.path.normcase(os.path.abspath(path))
253
+ if full == base or full.startswith(base.rstrip(os.sep) + os.sep):
254
+ return False
255
+ return True
256
+
257
+
185
258
  def _grep_targets_non_code(tool_input: dict) -> bool:
186
259
  kind = str(tool_input.get("type") or "").lower()
187
260
  if kind in _NON_CODE_TYPES:
@@ -190,26 +263,31 @@ def _grep_targets_non_code(tool_input: dict) -> bool:
190
263
  return bool(_NON_CODE.search(target))
191
264
 
192
265
 
266
+ def _term(pattern: str) -> str:
267
+ """A regex search pattern as plain query words."""
268
+ return " ".join(re.sub(r"""[\\^$()\[\]{}|*+?"']""", " ", pattern).split())[:80]
269
+
270
+
193
271
  def _reason(pattern: str) -> str:
194
- term = re.sub(r"[\\^$()\[\]{}|*+?]", " ", pattern).strip() or "<what you are looking for>"
195
- term = " ".join(term.split())[:80]
272
+ term = _term(pattern) or "<what you are looking for>"
196
273
  return (
197
274
  "codebase-index: this repository is indexed, and the index answers code "
198
275
  "searches with ranked, numbered lines in fewer tokens than grep. Run it first:\n"
199
276
  f' codebase-index search "{term}" --compact # where / how\n'
200
277
  ' codebase-index refs "Owner.member" --compact # every call site, with callers\n'
201
278
  ' codebase-index symbol "Name" # a definition\n'
202
- "If the index does not answer, repeat this exact call and it will run. Once any "
203
- "codebase-index command has run in this session, searches are not intercepted."
279
+ "If the index does not answer, search for the same term again and it will run. "
280
+ "Once any codebase-index command has run in this session, searches are not "
281
+ "intercepted."
204
282
  )
205
283
 
206
284
 
207
285
  class _State:
208
286
  """Per-session guard state: whether the index was used, which calls were nudged."""
209
287
 
210
- def __init__(self, root: Path, session: str) -> None:
288
+ def __init__(self, session: str) -> None:
211
289
  safe = re.sub(r"[^A-Za-z0-9_.-]", "_", session)[:80] or "default"
212
- self.dir = root / INDEX_REL.parent / _STATE_DIR
290
+ self.dir = Path(os.environ.get("CBX_HOOK_STATE") or Path(tempfile.gettempdir()) / _STATE_DIR)
213
291
  self.path = self.dir / f"{safe}.json"
214
292
  self.data: dict[str, Any] = {"used": False, "denied": []}
215
293
  try:
@@ -292,7 +292,7 @@ GUARD_HOOKS: dict[str, dict] = {
292
292
  "timeout": 5}],
293
293
  },
294
294
  "PreToolUse": {
295
- "matcher": "Grep|Bash",
295
+ "matcher": "Grep|Bash|PowerShell",
296
296
  "hooks": [{"type": "command", "command": "codebase-index-hook guard", "timeout": 5}],
297
297
  },
298
298
  }
@@ -305,7 +305,9 @@ def _is_guard_entry(entry: dict) -> bool:
305
305
  def install_guard_hooks(settings_path: Path) -> list[str]:
306
306
  """Merge the index-first hooks into a Claude Code settings file.
307
307
 
308
- Idempotent, and leaves every other hook in place. Returns the events added.
308
+ Idempotent, and leaves every other hook in place. An installed guard gets the
309
+ current matcher, so upgrading only takes running this again. Returns the events
310
+ added or refreshed.
309
311
  """
310
312
  settings: dict = {}
311
313
  if settings_path.exists():
@@ -314,9 +316,14 @@ def install_guard_hooks(settings_path: Path) -> list[str]:
314
316
  added = []
315
317
  for event, entry in GUARD_HOOKS.items():
316
318
  entries = hooks.setdefault(event, [])
317
- if not any(_is_guard_entry(e) for e in entries):
319
+ installed = [e for e in entries if _is_guard_entry(e)]
320
+ if not installed:
318
321
  entries.append(json.loads(json.dumps(entry)))
319
322
  added.append(event)
323
+ elif "matcher" in entry and any(e.get("matcher") != entry["matcher"] for e in installed):
324
+ for existing in installed:
325
+ existing["matcher"] = entry["matcher"]
326
+ added.append(event)
320
327
  if added:
321
328
  settings_path.parent.mkdir(parents=True, exist_ok=True)
322
329
  settings_path.write_text(json.dumps(settings, indent=2) + "\n", encoding="utf-8")
@@ -35,6 +35,9 @@ CREATE TABLE IF NOT EXISTS symbols (
35
35
  CREATE INDEX IF NOT EXISTS idx_symbols_name ON symbols(name);
36
36
  CREATE INDEX IF NOT EXISTS idx_symbols_file ON symbols(file_id);
37
37
  CREATE INDEX IF NOT EXISTS idx_symbols_kind ON symbols(kind);
38
+ -- Every deleted symbol looks up its children for ON DELETE SET NULL here and on
39
+ -- chunks.symbol_id; without an index each lookup is a full table scan.
40
+ CREATE INDEX IF NOT EXISTS idx_symbols_parent ON symbols(parent_id);
38
41
 
39
42
  CREATE TABLE IF NOT EXISTS chunks (
40
43
  id INTEGER PRIMARY KEY,
@@ -52,6 +55,7 @@ CREATE TABLE IF NOT EXISTS chunks (
52
55
  symbol_names TEXT NOT NULL DEFAULT ''
53
56
  );
54
57
  CREATE INDEX IF NOT EXISTS idx_chunks_file ON chunks(file_id);
58
+ CREATE INDEX IF NOT EXISTS idx_chunks_symbol ON chunks(symbol_id);
55
59
 
56
60
  CREATE TABLE IF NOT EXISTS edges (
57
61
  id INTEGER PRIMARY KEY,