boost-skill-cli 1.0.308__tar.gz → 1.0.309__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 (569) hide show
  1. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/PKG-INFO +3 -1
  2. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/_version.py +2 -2
  3. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/commands/quality.py +6 -1
  4. boost_skill_cli-1.0.309/boost_cli/core/embed.py +270 -0
  5. boost_skill_cli-1.0.309/boost_cli/core/localembed.py +245 -0
  6. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_skill_cli.egg-info/PKG-INFO +3 -1
  7. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_skill_cli.egg-info/SOURCES.txt +4 -1
  8. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_skill_cli.egg-info/requires.txt +2 -0
  9. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/keyless-dense-tier-local-static-embeddings.md +9 -0
  10. boost_skill_cli-1.0.308/docs/roadmap/items/keyless-item.md → boost_skill_cli-1.0.309/docs/roadmap/items/keyless-semantic-search-for-everyone.md +52 -0
  11. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap.html +61 -2
  12. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/pyproject.toml +23 -1
  13. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_embed.py +7 -2
  14. boost_skill_cli-1.0.309/tests/unit/test_embed_local.py +264 -0
  15. boost_skill_cli-1.0.309/tests/unit/test_localembed.py +491 -0
  16. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_roadmap_fresh.py +21 -0
  17. boost_skill_cli-1.0.308/boost_cli/core/embed.py +0 -135
  18. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/.gitattributes +0 -0
  19. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/.gitignore +0 -0
  20. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/.gitleaks.toml +0 -0
  21. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/.htmlvalidate.json +0 -0
  22. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/.lighthouserc.json +0 -0
  23. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/.lycheeignore +0 -0
  24. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/.markdownlint-cli2.jsonc +0 -0
  25. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/.pre-commit-config.yaml +0 -0
  26. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/.stylelintrc.json +0 -0
  27. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/.vale/styles/boost/Terminology.yml +0 -0
  28. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/.vale/styles/config/vocabularies/boost/accept.txt +0 -0
  29. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/.vale.ini +0 -0
  30. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/CLAUDE.md +0 -0
  31. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/CODE_OF_CONDUCT.md +0 -0
  32. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/CONTRIBUTING.md +0 -0
  33. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/LICENSE +0 -0
  34. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/MANIFEST.in +0 -0
  35. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/Makefile +0 -0
  36. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/README.md +0 -0
  37. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/SECURITY.md +0 -0
  38. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost +0 -0
  39. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/__init__.py +0 -0
  40. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/__main__.py +0 -0
  41. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/cli.py +0 -0
  42. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/cliparse.py +0 -0
  43. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/commands/__init__.py +0 -0
  44. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/commands/_common.py +0 -0
  45. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/commands/bmad.py +0 -0
  46. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/commands/configuration.py +0 -0
  47. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/commands/discovery.py +0 -0
  48. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/commands/hooks.py +0 -0
  49. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/commands/info.py +0 -0
  50. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/commands/intelligence.py +0 -0
  51. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/commands/pkg.py +0 -0
  52. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/commands/run.py +0 -0
  53. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/commands/safety.py +0 -0
  54. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/commands/taps.py +0 -0
  55. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/commands/team.py +0 -0
  56. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/core/__init__.py +0 -0
  57. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/core/adapters.py +0 -0
  58. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/core/agents.py +0 -0
  59. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/core/ai.py +0 -0
  60. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/core/capabilities.py +0 -0
  61. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/core/catalog.py +0 -0
  62. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/core/claude_settings.py +0 -0
  63. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/core/config.py +0 -0
  64. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/core/dense.py +0 -0
  65. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/core/ed25519.py +0 -0
  66. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/core/faithfulness.py +0 -0
  67. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/core/frontmatter.py +0 -0
  68. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/core/gitutil.py +0 -0
  69. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/core/imperative.py +0 -0
  70. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/core/injectscan.py +0 -0
  71. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/core/installscan.py +0 -0
  72. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/core/integrity.py +0 -0
  73. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/core/journal.py +0 -0
  74. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/core/lockfile.py +0 -0
  75. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/core/logs.py +0 -0
  76. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/core/mcp.py +0 -0
  77. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/core/mcpdecl.py +0 -0
  78. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/core/mcphost.py +0 -0
  79. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/core/minisign.py +0 -0
  80. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/core/nethttp.py +0 -0
  81. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/core/output.py +0 -0
  82. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/core/paths.py +0 -0
  83. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/core/policy.py +0 -0
  84. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/core/projectlock.py +0 -0
  85. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/core/provenance.py +0 -0
  86. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/core/rag.py +0 -0
  87. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/core/registry.py +0 -0
  88. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/core/resolve.py +0 -0
  89. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/core/rules.py +0 -0
  90. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/core/scopes.py +0 -0
  91. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/core/secretscan.py +0 -0
  92. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/core/selfupdate.py +0 -0
  93. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/core/serve.py +0 -0
  94. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/core/stackprobe.py +0 -0
  95. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/core/staleness.py +0 -0
  96. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/core/store.py +0 -0
  97. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/core/trustaudit.py +0 -0
  98. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/core/typosquat.py +0 -0
  99. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/core/updatediff.py +0 -0
  100. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/core/util.py +0 -0
  101. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/core/workflows.py +0 -0
  102. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/data/registries.json +0 -0
  103. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/errors.py +0 -0
  104. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_cli/spin.py +0 -0
  105. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_skill_cli.egg-info/dependency_links.txt +0 -0
  106. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_skill_cli.egg-info/entry_points.txt +0 -0
  107. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/boost_skill_cli.egg-info/top_level.txt +0 -0
  108. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/codecov.yml +0 -0
  109. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/.claude/settings.local.json +0 -0
  110. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/DEBUGGING.md +0 -0
  111. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/adapters.html +0 -0
  112. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/architecture/README.md +0 -0
  113. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/architecture/c4-components-core.md +0 -0
  114. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/architecture/c4-containers.md +0 -0
  115. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/architecture/c4-context.md +0 -0
  116. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/architecture/c4-dynamic-install.md +0 -0
  117. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/carousel/gifs/distill.gif +0 -0
  118. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/carousel/gifs/doctor.gif +0 -0
  119. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/carousel/gifs/explain.gif +0 -0
  120. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/carousel/gifs/hooks.gif +0 -0
  121. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/carousel/gifs/install.gif +0 -0
  122. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/carousel/gifs/pulse.gif +0 -0
  123. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/carousel/gifs/search.gif +0 -0
  124. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/carousel/gifs/tap.gif +0 -0
  125. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/carousel/tapes/distill.tape +0 -0
  126. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/carousel/tapes/doctor.tape +0 -0
  127. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/carousel/tapes/explain.tape +0 -0
  128. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/carousel/tapes/hooks.tape +0 -0
  129. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/carousel/tapes/install.tape +0 -0
  130. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/carousel/tapes/pulse.tape +0 -0
  131. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/carousel/tapes/search.tape +0 -0
  132. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/carousel/tapes/tap.tape +0 -0
  133. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/carousel.html +0 -0
  134. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/commands.html +0 -0
  135. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/demo.gif +0 -0
  136. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/demo.tape +0 -0
  137. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/design-roadmap.html +0 -0
  138. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/eval.html +0 -0
  139. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/index.html +0 -0
  140. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/mcp-hub.html +0 -0
  141. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/rag-architecture.md +0 -0
  142. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/BOOST-D01.md +0 -0
  143. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/BOOST-D02.md +0 -0
  144. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/BOOST-D03.md +0 -0
  145. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/BOOST-D04.md +0 -0
  146. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/BOOST-D05.md +0 -0
  147. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/BOOST-D06.md +0 -0
  148. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/BOOST-D07.md +0 -0
  149. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/BOOST-D08.md +0 -0
  150. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/BOOST-D09.md +0 -0
  151. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/BOOST-D10.md +0 -0
  152. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/BOOST-D11.md +0 -0
  153. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/BOOST-D12.md +0 -0
  154. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/BOOST-D13.md +0 -0
  155. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/BOOST-D14.md +0 -0
  156. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/BOOST-D15.md +0 -0
  157. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/BOOST-D16.md +0 -0
  158. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/BOOST-D17.md +0 -0
  159. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/BOOST-D18.md +0 -0
  160. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/BOOST-D19.md +0 -0
  161. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/BOOST-D20.md +0 -0
  162. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/BOOST-D21.md +0 -0
  163. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/BOOST-D22.md +0 -0
  164. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/BOOST-D23.md +0 -0
  165. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/BOOST-D24.md +0 -0
  166. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/BOOST-D25.md +0 -0
  167. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/BOOST-D26.md +0 -0
  168. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/accessibility-audit-pa11y-ci-axe-core.md +0 -0
  169. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/actionlint-skips-shellcheck-silently.md +0 -0
  170. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/adapter-conformance-langgraph-leg-never-ran.md +0 -0
  171. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/ai-bridge-silent-failure-logging.md +0 -0
  172. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/ambiguous-tap-short-name-resolution.md +0 -0
  173. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/atomic-corruption-safe-lock-file-writes.md +0 -0
  174. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/atomic-skill-install-temp-dir-swap.md +0 -0
  175. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/autonomous-ship-workflow-and-isolated-worktree.md +0 -0
  176. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/bm25-index-is-one-json-blob.md +0 -0
  177. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/boost-run-live-agents.md +0 -0
  178. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/bring-commands-under-mutation-testing.md +0 -0
  179. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/broken-link-and-anchor-checking-lychee.md +0 -0
  180. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/browse-crashes-selecting-a-rule-or-workflow.md +0 -0
  181. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/build-provenance-slsa-attestations.md +0 -0
  182. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/cache-the-catalog-entry-set-across-rag-queries.md +0 -0
  183. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/capability-manifest-and-least-privilege-policy.md +0 -0
  184. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/ci-job-timeout-minutes.md +0 -0
  185. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/ci-summary-step-fails-itself.md +0 -0
  186. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/ci-time-is-now-runner-queueing.md +0 -0
  187. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/clean-env-install-smoke-pip-and-pipx.md +0 -0
  188. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/code-scanning-rule-can-be-restored.md +0 -0
  189. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/codeql-job-rename-stranded-merge-protection.md +0 -0
  190. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/command-carousel-page.md +0 -0
  191. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/command-reference-docs-site.md +0 -0
  192. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/complexity-and-dead-code-radar-xenon-vulture.md +0 -0
  193. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/consolidate-skill-staleness-drift-logic-into-cor.md +0 -0
  194. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/coverage-dashboard-codecov-free-for-oss.md +0 -0
  195. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/coverage-guided-fuzzing-atheris-oss-fuzz.md +0 -0
  196. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/crash-listing-branch-untested.md +0 -0
  197. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/crash-recorder-error-paths-core-logs-py.md +0 -0
  198. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/demo-cannot-open-its-own-pr.md +0 -0
  199. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/demo-gif-workflow-has-never-succeeded.md +0 -0
  200. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/dense-search-fallback-and-stale-tap-pruning.md +0 -0
  201. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/dependabot-missing-pip-ecosystem.md +0 -0
  202. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/dependabot-regeneration-drops-platform-pins.md +0 -0
  203. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/dependabot-root-pip-entry-duplicates-requirements.md +0 -0
  204. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/dependency-cve-gate-pip-audit.md +0 -0
  205. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/docsite-chrome-and-content-audit.md +0 -0
  206. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/docstring-coverage-interrogate.md +0 -0
  207. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/doctor-checks-rules-and-workflows.md +0 -0
  208. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/end-of-options-guard-on-git-commands.md +0 -0
  209. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/eval-corpus-cannot-see-real-retrieval.md +0 -0
  210. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/extension-free-tests-core-dense-py.md +0 -0
  211. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/extract-mcp-http-servers-out-of-configuration-py.md +0 -0
  212. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/finish-mutation-hardening-across-core.md +0 -0
  213. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/fix-self-update-version-detection-dead-branch.md +0 -0
  214. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/fork-safe-network-proxy-handler.md +0 -0
  215. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/framework-adapter-langgraph.md +0 -0
  216. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/framework-adapter-multi-agent.md +0 -0
  217. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/framework-adapters-boost-adapt.md +0 -0
  218. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/frontmatter-scalar-over-coercion.md +0 -0
  219. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/gemini-cli-agent-target.md +0 -0
  220. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/github-community-health-files.md +0 -0
  221. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/github-pages-deploy-is-broken-every-push.md +0 -0
  222. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/golden-set-statistical-power.md +0 -0
  223. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/hash-pinned-reproducible-toolchain-uv-lock.md +0 -0
  224. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/html-validation-html-validate.md +0 -0
  225. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/install-docs-never-mentioned-upgrading.md +0 -0
  226. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/install-from-path-bypasses-policy-and-pin-checks.md +0 -0
  227. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/install-resolves-skill-dependencies.md +0 -0
  228. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/install-scope-user-or-project.md +0 -0
  229. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/installed-skill-trust-audit.md +0 -0
  230. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/integrity-verification-boost-verify.md +0 -0
  231. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/internal-architecture-diagrams.md +0 -0
  232. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/invocation-pid-logging-for-crash-correlation.md +0 -0
  233. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/journal-rotation-race-and-handle-leak.md +0 -0
  234. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/layering-guard-import-linter.md +0 -0
  235. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/license-compliance-scanning.md +0 -0
  236. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/lighthouse-ci-on-the-pages-site.md +0 -0
  237. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/lint-tap-misscopes-rule-workflow-entries.md +0 -0
  238. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/list-rules-and-workflows.md +0 -0
  239. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/localize-the-stored-bm25-snippet.md +0 -0
  240. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/lock-invariant-cannot-parse-extras-pins.md +0 -0
  241. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/lockfile-enforcement-and-commit-pinning.md +0 -0
  242. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/log-timestamps-mislabeled-utc.md +0 -0
  243. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/lowest-version-resolution-uv-resolution-lowest-d.md +0 -0
  244. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/main-has-no-branch-protection.md +0 -0
  245. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/main-ruleset-ref-pattern-has-literal-quotes.md +0 -0
  246. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/make-lint-masks-actionlint-failures.md +0 -0
  247. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/make-the-roadmaps-discoverable.md +0 -0
  248. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/markdown-consistency-markdownlint-cli2.md +0 -0
  249. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/markdownlint-lints-the-fuzz-corpus.md +0 -0
  250. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/mcp-aware-skills.md +0 -0
  251. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/mcp-check-skills-before-starting-a-task.md +0 -0
  252. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/mcp-hub-diagram-node-text-overflow.md +0 -0
  253. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/mcp-install-skips-the-injection-scan.md +0 -0
  254. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/mcp-launch-objc-fork-safety.md +0 -0
  255. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/mcp-register-names-server-before-env.md +0 -0
  256. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/mcp-search-before-reinventing.md +0 -0
  257. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/mcp-servers-ignore-install-scope.md +0 -0
  258. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/mcp-startup-self-harden-fork-safety.md +0 -0
  259. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/memoize-config-load-in-process.md +0 -0
  260. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/merge-queue-would-deadlock-most-required-checks.md +0 -0
  261. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/merged-loop-branches-are-never-pruned.md +0 -0
  262. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/modernization-smells-refurb-pyupgrade.md +0 -0
  263. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/mutation-gate-was-the-whole-critical-path.md +0 -0
  264. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/mutation-hardening-core-frontmatter-py.md +0 -0
  265. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/mutation-hardening-core-gitutil-py.md +0 -0
  266. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/mutation-hardening-core-store-py.md +0 -0
  267. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/mutation-shard-floor-is-one-file.md +0 -0
  268. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/mypy-strict-mode-for-commands.md +0 -0
  269. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/near-duplicate-items-eat-the-result-slots.md +0 -0
  270. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/negative-limit-inverts-log-pulse-output.md +0 -0
  271. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/onboard-overwrites-generated-files-without-confirm.md +0 -0
  272. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/one-command-every-env-nox.md +0 -0
  273. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/one-commit-can-cut-two-releases.md +0 -0
  274. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/one-shared-atomic-write-helper.md +0 -0
  275. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/package-metadata-validation-twine-check-friends.md +0 -0
  276. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/patch-coverage-gate-diff-cover.md +0 -0
  277. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/path-traversal-unsanitized-rule-workflow-name.md +0 -0
  278. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/performance-regression-gate-pytest-benchmark.md +0 -0
  279. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/pin-the-lint-toolchain.md +0 -0
  280. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/post-deploy-always-defeated-by-skipped-setup.md +0 -0
  281. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/post-deploy-smoke-headless-load-check.md +0 -0
  282. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/pre-release-python-canary-3-14t-free-threaded.md +0 -0
  283. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/prerequisites-and-semantic-search-setup.md +0 -0
  284. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/project-scope-across-every-command.md +0 -0
  285. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/project-scope-symlink-escape-on-write.md +0 -0
  286. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/promote-nav-footer-into-the-shared-style-system.md +0 -0
  287. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/prompt-injection-scanning-of-skill-markdown.md +0 -0
  288. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/property-based-tests-hypothesis-on-the-parsers.md +0 -0
  289. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/prose-and-terminology-linting-vale.md +0 -0
  290. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/prune-ignored-dirs-during-scan-dir-walk.md +0 -0
  291. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/publish-gate-ignores-pip-audit-and-metadata.md +0 -0
  292. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/publish-trigger-was-reachable-from-a-fork.md +0 -0
  293. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/pytest-tmpdir-cve-blocked-by-py39-floor.md +0 -0
  294. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/quality-dashboard-sonarcloud-free-for-oss.md +0 -0
  295. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/ranx-significance-monitor.md +0 -0
  296. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/reconcile-the-theme-drift.md +0 -0
  297. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/refresh-the-marketing-surface.md +0 -0
  298. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/rel-time-tests-race-the-wall-clock.md +0 -0
  299. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/release-verifies-the-wrong-commit.md +0 -0
  300. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/required-checks-can-declare-a-check-that-deadlocks-prs.md +0 -0
  301. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/required-checks-config-drift.md +0 -0
  302. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/retrieval-quality-eval-harness.md +0 -0
  303. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/reuse-helpers-kill-minor-dead-work.md +0 -0
  304. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/roadmap-html-goes-stale-on-every-rebase.md +0 -0
  305. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/robust-tag-argument-parsing.md +0 -0
  306. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/ruff-016-widens-the-default-rule-set.md +0 -0
  307. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/rule-install-native-materialization.md +0 -0
  308. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/runner-egress-monitoring-stepsecurity-harden-run.md +0 -0
  309. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/runtime-explain-faithfulness-guardrail.md +0 -0
  310. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/sbom-aware-scanning-osv-scanner.md +0 -0
  311. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/sbom-declares-the-wrong-version.md +0 -0
  312. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/sbom-on-every-release-cyclonedx-syft.md +0 -0
  313. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/sbom-release-event-never-fires.md +0 -0
  314. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/scan-and-sync-rules-and-workflows.md +0 -0
  315. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/scheduled-toolchain-lock-regeneration.md +0 -0
  316. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/scorecard-findings-triage.md +0 -0
  317. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/second-type-checker-pyright.md +0 -0
  318. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/secret-and-pii-scanning-of-installed-skills.md +0 -0
  319. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/secret-scanning-gitleaks-push-protection.md +0 -0
  320. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/security-linting-bandit-via-ruff-s-rules.md +0 -0
  321. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/self-update-broken-for-pip-pipx-installs.md +0 -0
  322. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/serve-py-traversal-guards-untested.md +0 -0
  323. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/shift-left-gate-pre-commit-pre-commit-ci.md +0 -0
  324. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/single-imperative-rule-extractor.md +0 -0
  325. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/single-tech-stack-prober.md +0 -0
  326. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/split-oversized-command-modules.md +0 -0
  327. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/startup-and-import-time-budget-x-importtime.md +0 -0
  328. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/stop-re-serializing-entry-meta-on-every-search.md +0 -0
  329. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/structured-json-log-output-mode.md +0 -0
  330. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/supply-chain-posture-openssf-scorecard.md +0 -0
  331. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/surface-every-docs-page-from-the-guide.md +0 -0
  332. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/sync-deletes-unowned-broken-symlinks.md +0 -0
  333. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/sync-relinks-into-every-agent-ignoring-scope.md +0 -0
  334. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/tap-signing-and-provenance-sigstore-minisign.md +0 -0
  335. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/theme-asset-linting-stylelint-eslint.md +0 -0
  336. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/typo-detection-codespell.md +0 -0
  337. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/typosquat-and-name-confusion-detection.md +0 -0
  338. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/unify-tilde-two-copies-have-a-boundary-bug.md +0 -0
  339. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/uninstall-has-no-confirmation-prompt.md +0 -0
  340. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/untrack-generated-build-noise.md +0 -0
  341. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/update-diff-before-apply.md +0 -0
  342. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/update-refreshes-rules-and-workflows.md +0 -0
  343. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/update-reinstall-widens-agent-scope.md +0 -0
  344. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/visual-regression-pass-on-the-guide.md +0 -0
  345. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/widen-the-ruff-rule-surface-b-sim-c4-perf-ruf.md +0 -0
  346. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/windows-in-the-ci-matrix.md +0 -0
  347. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/wire-bdd-suite-into-ci.md +0 -0
  348. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/workflow-install-native-materialization.md +0 -0
  349. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/workflow-linting-actionlint.md +0 -0
  350. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/workflow-sast-zizmor.md +0 -0
  351. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/workspace-scope-install.md +0 -0
  352. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/docs/roadmap/items/zizmor-pin-is-a-yanked-release.md +0 -0
  353. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/eslint.config.mjs +0 -0
  354. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/evals/README.md +0 -0
  355. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/evals/__init__.py +0 -0
  356. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/evals/baseline.json +0 -0
  357. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/evals/faithfulness.py +0 -0
  358. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/evals/golden_set.json +0 -0
  359. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/evals/make_corpus.py +0 -0
  360. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/evals/make_golden.py +0 -0
  361. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/evals/metrics.py +0 -0
  362. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/evals/run_evals.py +0 -0
  363. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/examples/README.md +0 -0
  364. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/examples/adapt-demo.sh +0 -0
  365. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/examples/boost-run-prototype.sh +0 -0
  366. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/index.html +0 -0
  367. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/noxfile.py +0 -0
  368. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/requirements/coverage-tools.in +0 -0
  369. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/requirements/coverage-tools.txt +0 -0
  370. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/requirements/lint-tools.in +0 -0
  371. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/requirements/lint-tools.txt +0 -0
  372. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/requirements/mutation-tools.in +0 -0
  373. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/requirements/mutation-tools.txt +0 -0
  374. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/requirements/platform-pins.lock +0 -0
  375. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/requirements/release-tools.in +0 -0
  376. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/requirements/release-tools.txt +0 -0
  377. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/requirements/test-tools.in +0 -0
  378. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/requirements/test-tools.txt +0 -0
  379. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/scripts/a11y_check.py +0 -0
  380. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/scripts/bench_cli.sh +0 -0
  381. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/scripts/build_command_reference.py +0 -0
  382. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/scripts/build_registries.py +0 -0
  383. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/scripts/build_roadmap.py +0 -0
  384. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/scripts/check_anchors.py +0 -0
  385. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/scripts/check_licenses.py +0 -0
  386. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/scripts/check_required_checks.py +0 -0
  387. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/scripts/ensure_eval_corpus.sh +0 -0
  388. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/scripts/eval_explain.py +0 -0
  389. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/scripts/eval_gate.py +0 -0
  390. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/scripts/eval_recommend.py +0 -0
  391. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/scripts/eval_retrieval.py +0 -0
  392. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/scripts/eval_stats_summary.py +0 -0
  393. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/scripts/import_budget.py +0 -0
  394. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/scripts/lock_toolchain.py +0 -0
  395. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/scripts/mutation_gate.py +0 -0
  396. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/scripts/mutation_shards.py +0 -0
  397. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/scripts/mutation_weights.json +0 -0
  398. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/scripts/perf_gate.py +0 -0
  399. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/scripts/post_deploy_smoke.py +0 -0
  400. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/scripts/release_guard.py +0 -0
  401. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/scripts/release_preflight.py +0 -0
  402. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/setup.cfg +0 -0
  403. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/sonar-project.properties +0 -0
  404. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/style/README.md +0 -0
  405. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/style/boost.css +0 -0
  406. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/style/boost.js +0 -0
  407. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/style/demo.html +0 -0
  408. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/bdd/features/adapt.feature +0 -0
  409. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/bdd/features/browse.feature +0 -0
  410. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/bdd/features/count.feature +0 -0
  411. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/bdd/features/discover.feature +0 -0
  412. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/bdd/features/doctor.feature +0 -0
  413. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/bdd/features/environment.py +0 -0
  414. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/bdd/features/explain.feature +0 -0
  415. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/bdd/features/index.feature +0 -0
  416. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/bdd/features/install.feature +0 -0
  417. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/bdd/features/list.feature +0 -0
  418. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/bdd/features/mcp.feature +0 -0
  419. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/bdd/features/search.feature +0 -0
  420. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/bdd/features/steps/cli_steps.py +0 -0
  421. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/bdd/features/steps/discovery_steps.py +0 -0
  422. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/bdd/features/steps/mcp_steps.py +0 -0
  423. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/bdd/features/steps/quality_steps.py +0 -0
  424. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/conftest.py +0 -0
  425. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/eval/baseline.json +0 -0
  426. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/eval/explain.jsonl +0 -0
  427. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/eval/golden.jsonl +0 -0
  428. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/eval/recommend.jsonl +0 -0
  429. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/eval/taps.txt +0 -0
  430. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/functional/test_capabilities_policy.py +0 -0
  431. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/functional/test_cli_adapt.py +0 -0
  432. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/functional/test_cli_bmad.py +0 -0
  433. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/functional/test_cli_configuration.py +0 -0
  434. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/functional/test_cli_discovery.py +0 -0
  435. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/functional/test_cli_hooks.py +0 -0
  436. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/functional/test_cli_info.py +0 -0
  437. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/functional/test_cli_intelligence.py +0 -0
  438. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/functional/test_cli_pkg.py +0 -0
  439. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/functional/test_cli_quality.py +0 -0
  440. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/functional/test_cli_taps.py +0 -0
  441. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/functional/test_cli_team.py +0 -0
  442. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/functional/test_everyday_loop.py +0 -0
  443. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/functional/test_integrity_enforce.py +0 -0
  444. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/functional/test_property_parsers.py +0 -0
  445. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/functional/test_run.py +0 -0
  446. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/functional/test_tap_signing.py +0 -0
  447. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/functional/test_workspace_scope.py +0 -0
  448. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/fuzz/README.md +0 -0
  449. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/fuzz/corpus/frontmatter/01-typical.md +0 -0
  450. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/fuzz/corpus/frontmatter/02-lossy-version.md +0 -0
  451. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/fuzz/corpus/frontmatter/03-lossy-numbers.md +0 -0
  452. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/fuzz/corpus/frontmatter/04-lists.md +0 -0
  453. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/fuzz/corpus/frontmatter/05-nested.md +0 -0
  454. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/fuzz/corpus/frontmatter/06-empty-block.md +0 -0
  455. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/fuzz/corpus/frontmatter/07-unterminated.md +0 -0
  456. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/fuzz/corpus/frontmatter/08-none.md +0 -0
  457. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/fuzz/corpus/frontmatter/09-unbalanced-quote.md +0 -0
  458. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/fuzz/corpus/frontmatter/10-keywords.md +0 -0
  459. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/fuzz/corpus/frontmatter/11-crlf.md +0 -0
  460. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/fuzz/corpus/frontmatter/12-bom.md +0 -0
  461. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/fuzz/corpus/registry/01-shorthand.txt +0 -0
  462. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/fuzz/corpus/registry/02-https.txt +0 -0
  463. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/fuzz/corpus/registry/03-ssh.txt +0 -0
  464. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/fuzz/corpus/registry/04-traversal.txt +0 -0
  465. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/fuzz/corpus/registry/05-empty.txt +0 -0
  466. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/fuzz/corpus/registry/06-space.txt +0 -0
  467. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/fuzz/corpus/registry/07-slash.txt +0 -0
  468. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/fuzz/corpus/registry/08-bare-host.txt +0 -0
  469. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/fuzz/fuzz_frontmatter.py +0 -0
  470. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/fuzz/fuzz_registry.py +0 -0
  471. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/make_fixture.py +0 -0
  472. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/perf/test_benchmarks.py +0 -0
  473. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/smoke.sh +0 -0
  474. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_a11y_check.py +0 -0
  475. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_adapters.py +0 -0
  476. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_adapters_multi.py +0 -0
  477. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_adapters_runner.py +0 -0
  478. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_agents.py +0 -0
  479. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_ai.py +0 -0
  480. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_capabilities.py +0 -0
  481. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_catalog.py +0 -0
  482. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_check_anchors.py +0 -0
  483. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_check_licenses.py +0 -0
  484. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_claude_settings.py +0 -0
  485. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_cliparse.py +0 -0
  486. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_codeql_analysis_key.py +0 -0
  487. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_command_reference_fresh.py +0 -0
  488. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_community_health_files.py +0 -0
  489. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_config.py +0 -0
  490. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_dense.py +0 -0
  491. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_dense_fallback.py +0 -0
  492. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_dense_status.py +0 -0
  493. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_dependabot_config.py +0 -0
  494. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_docs_pages_linked.py +0 -0
  495. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_docsite_chrome.py +0 -0
  496. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_ed25519.py +0 -0
  497. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_errors_and_cli_table.py +0 -0
  498. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_eval_faithfulness.py +0 -0
  499. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_eval_gate.py +0 -0
  500. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_eval_metrics.py +0 -0
  501. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_eval_stats_summary.py +0 -0
  502. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_faithfulness.py +0 -0
  503. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_frontmatter.py +0 -0
  504. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_fuzz_targets.py +0 -0
  505. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_gitleaks_config.py +0 -0
  506. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_gitutil.py +0 -0
  507. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_imperative.py +0 -0
  508. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_import_budget.py +0 -0
  509. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_injectscan.py +0 -0
  510. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_installscan.py +0 -0
  511. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_integrity.py +0 -0
  512. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_journal.py +0 -0
  513. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_lockfile.py +0 -0
  514. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_logs.py +0 -0
  515. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_marketing_counts.py +0 -0
  516. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_mcp.py +0 -0
  517. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_mcp_install_scan.py +0 -0
  518. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_mcpdecl.py +0 -0
  519. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_mcphost.py +0 -0
  520. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_minisign.py +0 -0
  521. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_mutation_hardening.py +0 -0
  522. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_mutation_shards.py +0 -0
  523. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_mutation_subfile_shards.py +0 -0
  524. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_mutmut_source_paths.py +0 -0
  525. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_nethttp.py +0 -0
  526. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_output.py +0 -0
  527. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_paths.py +0 -0
  528. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_perf_gate.py +0 -0
  529. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_pkg_confusions.py +0 -0
  530. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_pkg_injection.py +0 -0
  531. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_pkg_secrets.py +0 -0
  532. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_platform_pins.py +0 -0
  533. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_policy.py +0 -0
  534. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_post_deploy_smoke.py +0 -0
  535. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_project_mcp_sidecar.py +0 -0
  536. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_projectlock.py +0 -0
  537. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_provenance.py +0 -0
  538. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_rag.py +0 -0
  539. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_registries_fresh.py +0 -0
  540. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_registry.py +0 -0
  541. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_registry_categories.py +0 -0
  542. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_release_guard.py +0 -0
  543. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_release_preflight.py +0 -0
  544. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_required_checks.py +0 -0
  545. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_resolve.py +0 -0
  546. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_rules.py +0 -0
  547. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_scopes.py +0 -0
  548. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_secretscan.py +0 -0
  549. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_selfupdate.py +0 -0
  550. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_serve.py +0 -0
  551. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_spin.py +0 -0
  552. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_stackprobe.py +0 -0
  553. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_staleness.py +0 -0
  554. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_store.py +0 -0
  555. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_token_parity.py +0 -0
  556. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_toolchain_lock.py +0 -0
  557. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_trustaudit.py +0 -0
  558. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_typosquat.py +0 -0
  559. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_updatediff.py +0 -0
  560. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_util.py +0 -0
  561. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_version.py +0 -0
  562. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_workflow_concurrency.py +0 -0
  563. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_workflow_timeouts.py +0 -0
  564. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/unit/test_workflows.py +0 -0
  565. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/visual/a11y_check.mjs +0 -0
  566. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/visual/console_check.mjs +0 -0
  567. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/visual/package-lock.json +0 -0
  568. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/visual/package.json +0 -0
  569. {boost_skill_cli-1.0.308 → boost_skill_cli-1.0.309}/tests/visual/visual_check.mjs +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: boost-skill-cli
3
- Version: 1.0.308
3
+ Version: 1.0.309
4
4
  Summary: boost — Homebrew for AI coding skills
5
5
  Author: Jonathan Reyes
6
6
  License: GNU GENERAL PUBLIC LICENSE
@@ -702,6 +702,8 @@ Description-Content-Type: text/markdown
702
702
  License-File: LICENSE
703
703
  Provides-Extra: rag
704
704
  Requires-Dist: sqlite-vec>=0.1.6; extra == "rag"
705
+ Requires-Dist: onnxruntime>=1.17; extra == "rag"
706
+ Requires-Dist: tokenizers>=0.15; extra == "rag"
705
707
  Provides-Extra: eval
706
708
  Requires-Dist: ranx>=0.3.20; extra == "eval"
707
709
  Requires-Dist: ragas<0.3,>=0.2; extra == "eval"
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '1.0.308'
22
- __version_tuple__ = version_tuple = (1, 0, 308)
21
+ __version__ = version = '1.0.309'
22
+ __version_tuple__ = version_tuple = (1, 0, 309)
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -412,7 +412,12 @@ def cmd_doctor(argv):
412
412
  # first missing link is ever reported, so these never chain.
413
413
  _DENSE_FIX = {
414
414
  "no-backend": "install the extra: `pip install 'boost-skill-cli[rag]'`",
415
- "no-key": "set VOYAGE_API_KEY or OPENAI_API_KEY",
415
+ # Names the keyless remedy first: since the [rag] extra carries a local
416
+ # embedding model, an API key is the quality ceiling, not the entry fee.
417
+ # This reason now means "no key AND no local backend", which in practice is
418
+ # a partial install or BOOST_NO_EMBED.
419
+ "no-key": ("reinstall the extra: `pip install 'boost-skill-cli[rag]'` "
420
+ "(or set VOYAGE_API_KEY / OPENAI_API_KEY for a larger model)"),
416
421
  "no-store": "build it: `boost reindex --dense`",
417
422
  "version-changed": "rebuild it: `boost reindex --dense --force`",
418
423
  "provider-changed": "rebuild it: `boost reindex --dense --force`",
@@ -0,0 +1,270 @@
1
+ """Optional dense-embedding bridge for RAG Phase 2.
2
+
3
+ Strategy mirrors ``core.ai``: prefer Voyage AI when ``VOYAGE_API_KEY`` is set,
4
+ else OpenAI when ``OPENAI_API_KEY`` is set, else a **local** ONNX model when the
5
+ ``[rag]`` extra is installed, else return ``None`` so every caller degrades to
6
+ the always-on BM25 engine. The API embeddings come over ``urllib`` — pure
7
+ stdlib, no client library. Anthropic exposes no embeddings endpoint, hence
8
+ Voyage (its recommended partner) and OpenAI.
9
+
10
+ Why a local provider exists
11
+ ---------------------------
12
+ Without one, dense search needed an account and a key, so in practice every
13
+ keyless user got BM25 — and BM25 answers "my app is slow" with bioinformatics
14
+ packages, because nothing in that query shares vocabulary with the docs. The
15
+ vector *store* was never the gated part: vectors already live on the user's own
16
+ machine in sqlite-vec, keyed on each tap's commit. The only API-bound step is
17
+ turning text into vectors.
18
+
19
+ That also rules out the obvious shortcut of shipping a prebuilt index instead:
20
+ answering a query means embedding *the query*, so a downloaded index is useless
21
+ without something local to embed with. A local model is the prerequisite, not
22
+ an alternative.
23
+
24
+ The chain order is load-bearing. Local is tried **last**, so a user who has
25
+ configured Voyage keeps voyage-4 rather than being silently downgraded to a
26
+ 384-dim local model. And because ``dense.py`` rebuilds whenever ``model`` or
27
+ ``dim`` changes, switching providers can never mix two embedding spaces in one
28
+ index.
29
+
30
+ ``BOOST_NO_EMBED=1`` is a hard kill-switch for all three, matching
31
+ ``BOOST_NO_AI``.
32
+ """
33
+ from __future__ import annotations
34
+
35
+ import contextlib
36
+ import json
37
+ import os
38
+ import urllib.error
39
+ import urllib.request
40
+ from typing import Any, List, Optional
41
+
42
+ from . import nethttp
43
+
44
+ VOYAGE_URL = "https://api.voyageai.com/v1/embeddings"
45
+ OPENAI_URL = "https://api.openai.com/v1/embeddings"
46
+
47
+ # model -> output dimension. Stored in the vector index so a provider/model
48
+ # switch is detected and forces a clean rebuild instead of mixing spaces.
49
+ # voyage-4 over voyage-3: same 1024-d default and same $/token, but the
50
+ # voyage-4 generation carries a 200M-token complimentary allowance where
51
+ # voyage-3 has none — so a full index build of a large corpus is free.
52
+ VOYAGE_MODEL = "voyage-4"
53
+ OPENAI_MODEL = "text-embedding-3-small"
54
+
55
+ # The keyless path. Small on purpose: skill docs are short and keyword-dense, so
56
+ # a 384-dim model closes most of the gap to a paid API and runs on CPU. Named
57
+ # with its full hub id because that is what ends up recorded in the index
58
+ # metadata — a bare "bge-small-en-v1.5" would collide with any other vendor's
59
+ # rebuild of it, and a rebuild produces different vectors. See core.localembed
60
+ # for the pinned revision and the (133 MB, not 30 MB) download it implies.
61
+ LOCAL_MODEL = "BAAI/bge-small-en-v1.5"
62
+ LOCAL_DIM = 384
63
+
64
+ _DIMS = {VOYAGE_MODEL: 1024, OPENAI_MODEL: 1536, LOCAL_MODEL: LOCAL_DIM}
65
+
66
+ # Cached backend class and model instance. Loading an ONNX model is expensive
67
+ # enough that doing it per query would make the local path unusable, and the
68
+ # import itself is retried-on-miss rather than repeated: `provider()` runs on
69
+ # effectively every retrieval call.
70
+ _BACKEND_MISSING = object()
71
+ # Deliberately untyped: the backend is core.localembed, imported lazily, so
72
+ # naming its type here would defeat the point of the lazy import.
73
+ _backend_cache: Any = None
74
+ _model_instance: Any = None
75
+
76
+
77
+ def enabled() -> bool:
78
+ """True unless the ``BOOST_NO_EMBED`` kill-switch is set."""
79
+ return not os.environ.get("BOOST_NO_EMBED")
80
+
81
+
82
+ def _load_backend():
83
+ """The local embedding class, or None when the ``[rag]`` extra is absent.
84
+
85
+ ``localembed`` keeps its own imports lazy for the import budget; this is the
86
+ seam the tests stub, so the unit suite passes with the extra uninstalled.
87
+ """
88
+ from . import localembed
89
+ return localembed if localembed.available() else None
90
+
91
+
92
+ def _backend() -> Any:
93
+ """``_load_backend`` memoised, including the negative result."""
94
+ global _backend_cache
95
+ if _backend_cache is None:
96
+ _backend_cache = _load_backend() or _BACKEND_MISSING
97
+ return None if _backend_cache is _BACKEND_MISSING else _backend_cache
98
+
99
+
100
+ def reset_local_cache() -> None:
101
+ """Drop the cached backend and model. For tests, and for a provider switch."""
102
+ global _backend_cache, _model_instance
103
+ _backend_cache = None
104
+ _model_instance = None
105
+ # Nothing to reset when the extra is absent.
106
+ with contextlib.suppress(Exception):
107
+ from . import localembed
108
+ localembed.reset()
109
+
110
+
111
+ def local_available() -> bool:
112
+ """True when the local embedding backend can be imported."""
113
+ return _backend() is not None
114
+
115
+
116
+ def provider() -> Optional[str]:
117
+ """The active provider, preferring a configured key, or None when nothing works.
118
+
119
+ Order matters: local comes **last** so configuring Voyage keeps voyage-4.
120
+ A fallback that preempted a paid key would silently downgrade every existing
121
+ keyed install to a smaller model.
122
+ """
123
+ if not enabled():
124
+ return None
125
+ if os.environ.get("VOYAGE_API_KEY"):
126
+ return "voyage"
127
+ if os.environ.get("OPENAI_API_KEY"):
128
+ return "openai"
129
+ if local_available():
130
+ return "local"
131
+ return None
132
+
133
+
134
+ def available() -> bool:
135
+ """True when embeddings are enabled and a provider key is present."""
136
+ return provider() is not None
137
+
138
+
139
+ def model() -> Optional[str]:
140
+ """The active provider's model name, or None when unconfigured."""
141
+ p = provider()
142
+ if p == "voyage":
143
+ return VOYAGE_MODEL
144
+ if p == "openai":
145
+ return OPENAI_MODEL
146
+ if p == "local":
147
+ return LOCAL_MODEL
148
+ return None
149
+
150
+
151
+ def dimension() -> Optional[int]:
152
+ """Output vector dimension of the active model, or None when
153
+
154
+ unconfigured. Stored in the index so a model switch forces a rebuild.
155
+ """
156
+ m = model()
157
+ return _DIMS.get(m) if m is not None else None
158
+
159
+
160
+ def fallback_note() -> str:
161
+ """The one-line hint shown when dense search degrades to BM25.
162
+
163
+ No longer asks for a key: with a local model in the ``[rag]`` extra the
164
+ extra alone is enough, and telling a user they need an API account when
165
+ they do not is worse than saying nothing.
166
+ """
167
+ if not enabled():
168
+ return "dense search is off (BOOST_NO_EMBED) — using the BM25 engine"
169
+ return ("dense search needs the `[rag]` extra — `pip install "
170
+ "boost-skill-cli[rag]`; using the BM25 full-content engine")
171
+
172
+
173
+ def embed(texts: List[str], input_type: Optional[str] = None,
174
+ timeout: int = 60) -> Optional[List[List[float]]]:
175
+ """Embed a batch of texts.
176
+
177
+ Returns one vector per input, ``[]`` for an empty batch, or ``None`` when no
178
+ provider is configured or the call fails (so callers degrade cleanly).
179
+ ``input_type`` ("query"/"document") is honored by Voyage and ignored by
180
+ OpenAI.
181
+ """
182
+ p = provider()
183
+ if p is None:
184
+ return None
185
+ if not texts:
186
+ return []
187
+ if p == "local":
188
+ return _embed_local(texts)
189
+ if p == "voyage":
190
+ body = {"input": texts.copy(), "model": VOYAGE_MODEL}
191
+ if input_type:
192
+ body["input_type"] = input_type
193
+ return _vectors(_post(VOYAGE_URL, os.environ["VOYAGE_API_KEY"],
194
+ body, timeout), len(texts))
195
+ body = {"input": texts.copy(), "model": OPENAI_MODEL}
196
+ return _vectors(_post(OPENAI_URL, os.environ["OPENAI_API_KEY"],
197
+ body, timeout), len(texts))
198
+
199
+
200
+ def _local_model():
201
+ """The loaded local model, or None if it cannot be built.
202
+
203
+ First use downloads the pinned weights and caches them under
204
+ ``~/.boost/cache/models``, so this can fail on a machine with no network.
205
+ That is a degrade, not an error: the caller floors to BM25 exactly as it
206
+ does when no key is set.
207
+ """
208
+ return _backend()
209
+
210
+
211
+ def _embed_local(texts: List[str]) -> Optional[List[List[float]]]:
212
+ """Embed locally. None on any failure, so the caller degrades to BM25.
213
+
214
+ Validated as strictly as the API path: a short batch would misalign vectors
215
+ against their chunks — every hit past the gap pointing at the wrong skill —
216
+ and a wrong-width row would either error inside sqlite-vec or quietly
217
+ corrupt the space, so both are rejected rather than stored.
218
+ """
219
+ backend = _local_model()
220
+ if backend is None:
221
+ return None
222
+ try:
223
+ rows = backend.encode(texts.copy())
224
+ except Exception: # inference failure degrades, never raises
225
+ return None
226
+ if rows is None or len(rows) != len(texts):
227
+ return None
228
+ out: List[List[float]] = []
229
+ for row in rows:
230
+ try:
231
+ vec = [float(x) for x in row]
232
+ except (TypeError, ValueError):
233
+ return None
234
+ if len(vec) != LOCAL_DIM:
235
+ return None
236
+ out.append(vec)
237
+ return out
238
+
239
+
240
+ def _post(url: str, key: str, payload: dict, timeout: int) -> Optional[dict]:
241
+ data = json.dumps(payload).encode("utf-8")
242
+ req = urllib.request.Request(url, data=data, headers={ # noqa: S310 url is a hardcoded VOYAGE_URL/OPENAI_URL constant
243
+ "Authorization": "Bearer %s" % key,
244
+ "Content-Type": "application/json",
245
+ })
246
+ try:
247
+ with nethttp.urlopen(req, timeout=timeout) as resp:
248
+ return json.loads(resp.read())
249
+ except (urllib.error.URLError, OSError, ValueError):
250
+ return None
251
+
252
+
253
+ def _vectors(obj: Optional[dict], n: int) -> Optional[List[List[float]]]:
254
+ """Pull ``data[].embedding`` out of an OpenAI-shaped response.
255
+
256
+ Both Voyage and OpenAI return ``{"data": [{"embedding": [...]}, ...]}``.
257
+ Returns None unless exactly ``n`` numeric vectors come back.
258
+ """
259
+ if not isinstance(obj, dict):
260
+ return None
261
+ data = obj.get("data")
262
+ if not isinstance(data, list) or len(data) != n:
263
+ return None
264
+ out: List[List[float]] = []
265
+ for item in data:
266
+ vec = item.get("embedding") if isinstance(item, dict) else None
267
+ if not isinstance(vec, list) or not vec:
268
+ return None
269
+ out.append([float(x) for x in vec])
270
+ return out
@@ -0,0 +1,245 @@
1
+ """The keyless local embedding backend: ONNX Runtime over a pinned BGE model.
2
+
3
+ ``core.embed`` owns the provider chain; this owns the one thing that chain was
4
+ missing — a way to turn text into vectors with no API key. It is reached only
5
+ through ``embed.provider() == "local"`` and, like every other optional path in
6
+ this codebase, returns ``None`` rather than raising so the caller floors to
7
+ BM25.
8
+
9
+ Why the model is fetched rather than vendored
10
+ ---------------------------------------------
11
+ The weights are 133 MB — far too large to ship in a wheel for a CLI whose whole
12
+ runtime is stdlib. So they are downloaded once, on first use, and cached under
13
+ ``~/.boost/cache/models``. That download is the one part of boost that reaches
14
+ for something big at runtime, so it is pinned the same way the toolchain lock
15
+ is: a fixed repository *revision*, an expected byte length, and a **sha256 that
16
+ is verified before the file is used**. A mismatch deletes the download and
17
+ degrades rather than loading whatever arrived.
18
+
19
+ (For the record, because the number circulates: the "~30 MB" figure often
20
+ quoted for bge-small is the *quantized* rebuild third parties publish, not
21
+ BAAI's own export. This uses the authoritative one — a signed-supply-chain
22
+ repo has no business pulling model weights from a re-uploader to save a
23
+ one-time download. Quantization is a later optimisation, and it changes the
24
+ vectors, so it would need its own eval.)
25
+
26
+ Pooling
27
+ -------
28
+ BGE is a CLS-pooled model: the sentence embedding is the first token's hidden
29
+ state, L2-normalised — *not* a mean over tokens. Using mean pooling here would
30
+ still produce 384 plausible-looking floats and quietly worse retrieval, which
31
+ is the kind of bug an eval catches and a unit test does not, so the choice is
32
+ stated here and asserted against a known-good pair in the tests.
33
+ """
34
+ from __future__ import annotations
35
+
36
+ import hashlib
37
+ import shutil
38
+ from pathlib import Path
39
+ from typing import List, Optional
40
+
41
+ from . import paths
42
+
43
+ # Pinned to a revision, not a branch: `main` moving would silently change every
44
+ # vector in every user's index, and the index only rebuilds when the *model
45
+ # name* changes — which it would not.
46
+ MODEL_REPO = "BAAI/bge-small-en-v1.5"
47
+ MODEL_REV = "5c38ec7c405ec4b44b94cc5a9bb96e735b38267a"
48
+ _BASE = "https://huggingface.co/%s/resolve/%s/" % (MODEL_REPO, MODEL_REV)
49
+
50
+ # path -> (bytes, sha256). Verified after download and again on every load, so
51
+ # a truncated or tampered cache cannot be used.
52
+ FILES = {
53
+ "onnx/model.onnx": (
54
+ 133093490,
55
+ "828e1496d7fabb79cfa4dcd84fa38625c0d3d21da474a00f08db0f559940cf35"),
56
+ "tokenizer.json": (
57
+ 711396,
58
+ "d241a60d5e8f04cc1b2b3e9ef7a4921b27bf526d9f6050ab90f9267a1f9e5c66"),
59
+ }
60
+
61
+ # BGE caps at 512 tokens; longer input is truncated rather than rejected, which
62
+ # matches how the chunker already feeds this.
63
+ MAX_TOKENS = 512
64
+
65
+ _session = None
66
+ _tokenizer = None
67
+
68
+
69
+ def _deps():
70
+ """(onnxruntime, tokenizers) or (None, None) when the extra is absent.
71
+
72
+ Imported inside the function: ``scripts/import_budget.py`` gates CLI
73
+ startup, and an ONNX runtime at module import would charge `boost --help`
74
+ for a feature it never uses.
75
+ """
76
+ try:
77
+ import onnxruntime
78
+ import tokenizers
79
+ except Exception: # any import failure means "no backend"
80
+ return None, None
81
+ return onnxruntime, tokenizers
82
+
83
+
84
+ def available() -> bool:
85
+ """True when the runtime and tokenizer libraries are importable."""
86
+ return _deps()[0] is not None
87
+
88
+
89
+ def model_dir() -> Path:
90
+ """Where the pinned weights are cached, keyed by revision."""
91
+ return paths.cache_dir() / "models" / MODEL_REV
92
+
93
+
94
+ def _verified(path: Path, size: int, digest: str) -> bool:
95
+ """True when `path` matches the pinned length and hash.
96
+
97
+ Length first because it is free and rules out the common case (a truncated
98
+ download) without reading 133 MB.
99
+ """
100
+ try:
101
+ if path.stat().st_size != size:
102
+ return False
103
+ h = hashlib.sha256()
104
+ with path.open("rb") as fh:
105
+ for block in iter(lambda: fh.read(1 << 20), b""):
106
+ h.update(block)
107
+ return h.hexdigest() == digest
108
+ except OSError:
109
+ return False
110
+
111
+
112
+ def _fetch(rel: str, dest: Path, size: int, digest: str) -> bool:
113
+ """Download one pinned file. False on any failure, leaving nothing behind.
114
+
115
+ Downloads to a temporary name and only renames after the hash matches, so
116
+ an interrupted fetch can never be mistaken for a complete one on the next
117
+ run.
118
+ """
119
+ from . import nethttp
120
+ tmp = dest.with_suffix(dest.suffix + ".part")
121
+ try:
122
+ dest.parent.mkdir(parents=True, exist_ok=True)
123
+ with nethttp.urlopen(_BASE + rel, timeout=600) as resp, \
124
+ tmp.open("wb") as out:
125
+ shutil.copyfileobj(resp, out, 1 << 20)
126
+ except Exception: # network/disk failure degrades to BM25
127
+ tmp.unlink(missing_ok=True)
128
+ return False
129
+ if not _verified(tmp, size, digest):
130
+ tmp.unlink(missing_ok=True)
131
+ return False
132
+ try:
133
+ tmp.replace(dest)
134
+ except OSError:
135
+ tmp.unlink(missing_ok=True)
136
+ return False
137
+ return True
138
+
139
+
140
+ def ensure_model() -> Optional[Path]:
141
+ """The verified model directory, downloading it once if needed, or None."""
142
+ root = model_dir()
143
+ for rel, (size, digest) in FILES.items():
144
+ dest = root / rel
145
+ if _verified(dest, size, digest):
146
+ continue
147
+ if not _fetch(rel, dest, size, digest):
148
+ return None
149
+ return root
150
+
151
+
152
+ def _load():
153
+ """Build and cache the session and tokenizer. False when unavailable."""
154
+ global _session, _tokenizer
155
+ if _session is not None and _tokenizer is not None:
156
+ return True
157
+ onnxruntime, tokenizers = _deps()
158
+ # Both, not just the first: they are returned as a pair and a partial
159
+ # install (onnxruntime present, tokenizers missing) would otherwise reach
160
+ # `tokenizers.Tokenizer` on a None.
161
+ if onnxruntime is None or tokenizers is None:
162
+ return False
163
+ root = ensure_model()
164
+ if root is None:
165
+ return False
166
+ try:
167
+ opts = onnxruntime.SessionOptions()
168
+ # A CLI embedding a handful of chunks gains nothing from spawning a
169
+ # thread per core, and an unbounded pool inside a `boost search` is a
170
+ # surprise on a shared machine.
171
+ opts.intra_op_num_threads = 1
172
+ opts.inter_op_num_threads = 1
173
+ session = onnxruntime.InferenceSession(
174
+ str(root / "onnx/model.onnx"), opts,
175
+ providers=["CPUExecutionProvider"])
176
+ tok = tokenizers.Tokenizer.from_file(str(root / "tokenizer.json"))
177
+ tok.enable_truncation(max_length=MAX_TOKENS)
178
+ tok.enable_padding()
179
+ except Exception: # a broken model degrades, never raises
180
+ return False
181
+ _session, _tokenizer = session, tok
182
+ return True
183
+
184
+
185
+ def reset() -> None:
186
+ """Drop the cached session and tokenizer. For tests."""
187
+ global _session, _tokenizer
188
+ _session = None
189
+ _tokenizer = None
190
+
191
+
192
+ def encode(texts: List[str]) -> Optional[List[List[float]]]:
193
+ """Embed `texts`, or None on any failure.
194
+
195
+ CLS pooling plus L2 normalisation, which is what BGE was trained for.
196
+ """
197
+ if not texts:
198
+ return []
199
+ if not _load():
200
+ return None
201
+ session, tok = _session, _tokenizer
202
+ if session is None or tok is None: # unreachable after _load(); for type narrowing
203
+ return None
204
+ try:
205
+ encoded = tok.encode_batch(texts.copy())
206
+ feed = {}
207
+ wanted = {i.name for i in session.get_inputs()}
208
+ cols = {
209
+ "input_ids": [e.ids for e in encoded],
210
+ "attention_mask": [e.attention_mask for e in encoded],
211
+ "token_type_ids": [e.type_ids for e in encoded],
212
+ }
213
+ for name, col in cols.items():
214
+ if name in wanted:
215
+ feed[name] = _as_i64(col)
216
+ return cls_pool(session.run(None, feed)[0])
217
+ except Exception: # inference failure degrades to BM25
218
+ return None
219
+
220
+
221
+ def cls_pool(out) -> List[List[float]]:
222
+ """Last hidden state -> one L2-normalised CLS vector per row.
223
+
224
+ Kept pure and separate from :func:`encode` so the part that decides *what a
225
+ sentence embedding is* can be tested without an ONNX runtime — it is the
226
+ step most likely to be silently wrong, since taking the mean instead of the
227
+ first token still yields plausible-looking vectors of the right width.
228
+
229
+ ``out`` is (batch, tokens, hidden); ``row[0]`` is the [CLS] token.
230
+ """
231
+ return [_normalise([float(x) for x in row[0]]) for row in out]
232
+
233
+
234
+ def _as_i64(rows):
235
+ """Token id matrix as the int64 array onnxruntime expects."""
236
+ import numpy
237
+ return numpy.array(rows, dtype=numpy.int64)
238
+
239
+
240
+ def _normalise(vec: List[float]) -> List[float]:
241
+ """L2-normalise, leaving an all-zero vector alone rather than dividing by 0."""
242
+ norm = sum(x * x for x in vec) ** 0.5
243
+ if not norm:
244
+ return vec
245
+ return [x / norm for x in vec]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: boost-skill-cli
3
- Version: 1.0.308
3
+ Version: 1.0.309
4
4
  Summary: boost — Homebrew for AI coding skills
5
5
  Author: Jonathan Reyes
6
6
  License: GNU GENERAL PUBLIC LICENSE
@@ -702,6 +702,8 @@ Description-Content-Type: text/markdown
702
702
  License-File: LICENSE
703
703
  Provides-Extra: rag
704
704
  Requires-Dist: sqlite-vec>=0.1.6; extra == "rag"
705
+ Requires-Dist: onnxruntime>=1.17; extra == "rag"
706
+ Requires-Dist: tokenizers>=0.15; extra == "rag"
705
707
  Provides-Extra: eval
706
708
  Requires-Dist: ranx>=0.3.20; extra == "eval"
707
709
  Requires-Dist: ragas<0.3,>=0.2; extra == "eval"
@@ -66,6 +66,7 @@ boost_cli/core/injectscan.py
66
66
  boost_cli/core/installscan.py
67
67
  boost_cli/core/integrity.py
68
68
  boost_cli/core/journal.py
69
+ boost_cli/core/localembed.py
69
70
  boost_cli/core/lockfile.py
70
71
  boost_cli/core/logs.py
71
72
  boost_cli/core/mcp.py
@@ -228,7 +229,7 @@ docs/roadmap/items/internal-architecture-diagrams.md
228
229
  docs/roadmap/items/invocation-pid-logging-for-crash-correlation.md
229
230
  docs/roadmap/items/journal-rotation-race-and-handle-leak.md
230
231
  docs/roadmap/items/keyless-dense-tier-local-static-embeddings.md
231
- docs/roadmap/items/keyless-item.md
232
+ docs/roadmap/items/keyless-semantic-search-for-everyone.md
232
233
  docs/roadmap/items/layering-guard-import-linter.md
233
234
  docs/roadmap/items/license-compliance-scanning.md
234
235
  docs/roadmap/items/lighthouse-ci-on-the-pages-site.md
@@ -488,6 +489,7 @@ tests/unit/test_docs_pages_linked.py
488
489
  tests/unit/test_docsite_chrome.py
489
490
  tests/unit/test_ed25519.py
490
491
  tests/unit/test_embed.py
492
+ tests/unit/test_embed_local.py
491
493
  tests/unit/test_errors_and_cli_table.py
492
494
  tests/unit/test_eval_faithfulness.py
493
495
  tests/unit/test_eval_gate.py
@@ -504,6 +506,7 @@ tests/unit/test_injectscan.py
504
506
  tests/unit/test_installscan.py
505
507
  tests/unit/test_integrity.py
506
508
  tests/unit/test_journal.py
509
+ tests/unit/test_localembed.py
507
510
  tests/unit/test_lockfile.py
508
511
  tests/unit/test_logs.py
509
512
  tests/unit/test_marketing_counts.py
@@ -14,3 +14,5 @@ pytest-benchmark>=4.0
14
14
 
15
15
  [rag]
16
16
  sqlite-vec>=0.1.6
17
+ onnxruntime>=1.17
18
+ tokenizers>=0.15
@@ -56,3 +56,12 @@ cannot go in the default wheel — the shipped runtime is 0.79 MB and every merg
56
56
  to main cuts a release, so +17.4 MB × ~24 releases/day exhausts PyPI's 10 GB
57
57
  project quota in under a month; it needs a separate, rarely-released data
58
58
  package behind an extra.
59
+ <b>Related, and partly overtaken:</b> [[keyless-semantic-search-for-everyone]] shipped a keyless
60
+ path using a <i>transformer</i> (BGE via ONNX Runtime, in the <code>[rag]</code> extra) while this
61
+ item was open. That does not settle the question this card asks &mdash; a static lookup table is
62
+ still far cheaper, and this card's discipline about not shipping a retrieval claim before the eval
63
+ still stands. What it does change is the baseline: "keyless" is no longer the differentiator, so the
64
+ case for a static model now rests on <b>cost</b> (~1&nbsp;ms and no runtime dependency, against a
65
+ measured 233&nbsp;ms cold and 34&nbsp;MB of wheels) rather than on availability. Status left alone
66
+ deliberately &mdash; this is another loop's item to own.
67
+