boost-skill-cli 1.0.449__tar.gz → 1.0.451__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 (702) hide show
  1. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/.vale/styles/config/vocabularies/boost/accept.txt +5 -2
  2. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/CLAUDE.md +1 -1
  3. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/PKG-INFO +29 -4
  4. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/README.md +28 -3
  5. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/_version.py +2 -2
  6. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/cli.py +1 -0
  7. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/commands/configuration.py +31 -3
  8. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/commands/taps.py +64 -0
  9. boost_skill_cli-1.0.451/boost_cli/core/catalogbundle.py +265 -0
  10. boost_skill_cli-1.0.451/boost_cli/core/selfupdate.py +268 -0
  11. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_skill_cli.egg-info/PKG-INFO +29 -4
  12. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_skill_cli.egg-info/SOURCES.txt +5 -0
  13. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/DEBUGGING.md +36 -0
  14. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/carousel.html +2 -2
  15. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/commands.html +15 -2
  16. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/index.html +4 -3
  17. boost_skill_cli-1.0.451/docs/roadmap/items/self-update-claims-up-to-date-without-asking.md +52 -0
  18. boost_skill_cli-1.0.451/docs/roadmap/items/shareable-catalogue-bundle.md +65 -0
  19. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap.html +111 -1
  20. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/conftest.py +4 -0
  21. boost_skill_cli-1.0.451/tests/functional/test_cli_catalog.py +190 -0
  22. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/functional/test_cli_configuration.py +70 -4
  23. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/functional/test_everyday_loop.py +1 -1
  24. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/smoke.sh +1 -0
  25. boost_skill_cli-1.0.451/tests/unit/test_catalogbundle.py +405 -0
  26. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_errors_and_cli_table.py +6 -6
  27. boost_skill_cli-1.0.451/tests/unit/test_selfupdate.py +529 -0
  28. boost_skill_cli-1.0.449/boost_cli/core/selfupdate.py +0 -137
  29. boost_skill_cli-1.0.449/tests/unit/test_selfupdate.py +0 -265
  30. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/.gitattributes +0 -0
  31. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/.gitignore +0 -0
  32. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/.gitleaks.toml +0 -0
  33. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/.htmlvalidate.json +0 -0
  34. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/.lighthouserc.json +0 -0
  35. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/.lycheeignore +0 -0
  36. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/.markdownlint-cli2.jsonc +0 -0
  37. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/.pre-commit-config.yaml +0 -0
  38. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/.stylelintrc.json +0 -0
  39. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/.vale/styles/boost/Terminology.yml +0 -0
  40. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/.vale.ini +0 -0
  41. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/CODE_OF_CONDUCT.md +0 -0
  42. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/CONTRIBUTING.md +0 -0
  43. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/LICENSE +0 -0
  44. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/MANIFEST.in +0 -0
  45. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/Makefile +0 -0
  46. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/SECURITY.md +0 -0
  47. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost +0 -0
  48. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/__init__.py +0 -0
  49. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/__main__.py +0 -0
  50. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/cliparse.py +0 -0
  51. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/commands/__init__.py +0 -0
  52. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/commands/_common.py +0 -0
  53. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/commands/bmad.py +0 -0
  54. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/commands/discovery.py +0 -0
  55. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/commands/hooks.py +0 -0
  56. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/commands/info.py +0 -0
  57. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/commands/intelligence.py +0 -0
  58. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/commands/pkg.py +0 -0
  59. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/commands/quality.py +0 -0
  60. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/commands/run.py +0 -0
  61. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/commands/safety.py +0 -0
  62. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/commands/team.py +0 -0
  63. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/__init__.py +0 -0
  64. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/adapters.py +0 -0
  65. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/agents.py +0 -0
  66. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/ai.py +0 -0
  67. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/bmad.py +0 -0
  68. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/bootstrap.py +0 -0
  69. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/builtin.py +0 -0
  70. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/capabilities.py +0 -0
  71. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/catalog.py +0 -0
  72. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/chat.py +0 -0
  73. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/claude_settings.py +0 -0
  74. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/complete.py +0 -0
  75. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/config.py +0 -0
  76. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/dense.py +0 -0
  77. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/ed25519.py +0 -0
  78. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/embed.py +0 -0
  79. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/faithfulness.py +0 -0
  80. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/frontmatter.py +0 -0
  81. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/gitutil.py +0 -0
  82. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/imperative.py +0 -0
  83. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/injectscan.py +0 -0
  84. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/installscan.py +0 -0
  85. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/integrity.py +0 -0
  86. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/journal.py +0 -0
  87. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/localembed.py +0 -0
  88. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/lockfile.py +0 -0
  89. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/logs.py +0 -0
  90. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/mcp.py +0 -0
  91. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/mcpdecl.py +0 -0
  92. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/mcphost.py +0 -0
  93. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/minisign.py +0 -0
  94. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/nethttp.py +0 -0
  95. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/output.py +0 -0
  96. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/paths.py +0 -0
  97. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/policy.py +0 -0
  98. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/projectlock.py +0 -0
  99. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/provenance.py +0 -0
  100. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/rag.py +0 -0
  101. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/registry.py +0 -0
  102. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/resolve.py +0 -0
  103. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/rules.py +0 -0
  104. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/scopes.py +0 -0
  105. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/secretscan.py +0 -0
  106. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/serve.py +0 -0
  107. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/stackprobe.py +0 -0
  108. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/staleness.py +0 -0
  109. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/store.py +0 -0
  110. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/trustaudit.py +0 -0
  111. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/typosquat.py +0 -0
  112. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/updatediff.py +0 -0
  113. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/util.py +0 -0
  114. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/core/workflows.py +0 -0
  115. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/data/registries.json +0 -0
  116. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/data/rules/boost-first.mdc +0 -0
  117. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/errors.py +0 -0
  118. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_cli/spin.py +0 -0
  119. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_langchain/__init__.py +0 -0
  120. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_langchain/_compat.py +0 -0
  121. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_langchain/graph.py +0 -0
  122. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_langchain/loader.py +0 -0
  123. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_langchain/py.typed +0 -0
  124. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_langchain/retriever.py +0 -0
  125. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_skill_cli.egg-info/dependency_links.txt +0 -0
  126. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_skill_cli.egg-info/entry_points.txt +0 -0
  127. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_skill_cli.egg-info/requires.txt +0 -0
  128. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/boost_skill_cli.egg-info/top_level.txt +0 -0
  129. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/codecov.yml +0 -0
  130. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/.claude/settings.local.json +0 -0
  131. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/adapters.html +0 -0
  132. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/architecture/README.md +0 -0
  133. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/architecture/c4-components-core.md +0 -0
  134. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/architecture/c4-containers.md +0 -0
  135. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/architecture/c4-context.md +0 -0
  136. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/architecture/c4-dynamic-install.md +0 -0
  137. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/carousel/gifs/distill.gif +0 -0
  138. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/carousel/gifs/doctor.gif +0 -0
  139. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/carousel/gifs/explain.gif +0 -0
  140. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/carousel/gifs/hooks.gif +0 -0
  141. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/carousel/gifs/install.gif +0 -0
  142. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/carousel/gifs/pulse.gif +0 -0
  143. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/carousel/gifs/search.gif +0 -0
  144. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/carousel/gifs/tap.gif +0 -0
  145. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/carousel/tapes/distill.tape +0 -0
  146. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/carousel/tapes/doctor.tape +0 -0
  147. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/carousel/tapes/explain.tape +0 -0
  148. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/carousel/tapes/hooks.tape +0 -0
  149. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/carousel/tapes/install.tape +0 -0
  150. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/carousel/tapes/pulse.tape +0 -0
  151. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/carousel/tapes/search.tape +0 -0
  152. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/carousel/tapes/tap.tape +0 -0
  153. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/chat.html +0 -0
  154. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/demo-index.json +0 -0
  155. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/demo.gif +0 -0
  156. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/demo.html +0 -0
  157. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/demo.tape +0 -0
  158. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/design-roadmap.html +0 -0
  159. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/eval-latest.json +0 -0
  160. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/eval.html +0 -0
  161. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/langchain.html +0 -0
  162. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/mcp-hub.html +0 -0
  163. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/rag-architecture.md +0 -0
  164. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/BOOST-D01.md +0 -0
  165. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/BOOST-D02.md +0 -0
  166. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/BOOST-D03.md +0 -0
  167. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/BOOST-D04.md +0 -0
  168. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/BOOST-D05.md +0 -0
  169. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/BOOST-D06.md +0 -0
  170. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/BOOST-D07.md +0 -0
  171. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/BOOST-D08.md +0 -0
  172. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/BOOST-D09.md +0 -0
  173. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/BOOST-D10.md +0 -0
  174. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/BOOST-D11.md +0 -0
  175. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/BOOST-D12.md +0 -0
  176. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/BOOST-D13.md +0 -0
  177. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/BOOST-D14.md +0 -0
  178. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/BOOST-D15.md +0 -0
  179. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/BOOST-D16.md +0 -0
  180. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/BOOST-D17.md +0 -0
  181. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/BOOST-D18.md +0 -0
  182. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/BOOST-D19.md +0 -0
  183. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/BOOST-D20.md +0 -0
  184. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/BOOST-D21.md +0 -0
  185. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/BOOST-D22.md +0 -0
  186. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/BOOST-D23.md +0 -0
  187. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/BOOST-D24.md +0 -0
  188. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/BOOST-D25.md +0 -0
  189. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/BOOST-D26.md +0 -0
  190. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/a11y-sweep-flakes-on-color-contrast.md +0 -0
  191. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/accessibility-audit-pa11y-ci-axe-core.md +0 -0
  192. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/actionlint-skips-shellcheck-silently.md +0 -0
  193. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/adapter-conformance-langgraph-leg-never-ran.md +0 -0
  194. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/agents-field-records-the-request-not-the-links.md +0 -0
  195. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/ai-bridge-silent-failure-logging.md +0 -0
  196. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/ambiguous-tap-short-name-resolution.md +0 -0
  197. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/atomic-corruption-safe-lock-file-writes.md +0 -0
  198. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/atomic-skill-install-temp-dir-swap.md +0 -0
  199. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/autonomous-ship-workflow-and-isolated-worktree.md +0 -0
  200. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/bm25-index-is-one-json-blob.md +0 -0
  201. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/bmad-autopilot-one-command-persona-routing.md +0 -0
  202. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/boost-first-carried-the-losing-trigger.md +0 -0
  203. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/boost-first-rule.md +0 -0
  204. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/boost-langchain-publishing.md +0 -0
  205. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/boost-run-live-agents.md +0 -0
  206. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/bring-commands-under-mutation-testing.md +0 -0
  207. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/broken-link-and-anchor-checking-lychee.md +0 -0
  208. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/browse-crashes-selecting-a-rule-or-workflow.md +0 -0
  209. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/build-provenance-slsa-attestations.md +0 -0
  210. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/cache-the-catalog-entry-set-across-rag-queries.md +0 -0
  211. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/capability-manifest-and-least-privilege-policy.md +0 -0
  212. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/chat-cites-sources-by-a-number-it-never-prints.md +0 -0
  213. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/chat-command-grounded-conversational-search.md +0 -0
  214. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/ci-job-timeout-minutes.md +0 -0
  215. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/ci-summary-step-fails-itself.md +0 -0
  216. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/ci-time-is-now-runner-queueing.md +0 -0
  217. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/clean-env-install-smoke-pip-and-pipx.md +0 -0
  218. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/code-scanning-rule-can-be-restored.md +0 -0
  219. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/codeql-job-rename-stranded-merge-protection.md +0 -0
  220. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/command-carousel-page.md +0 -0
  221. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/command-reference-docs-site.md +0 -0
  222. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/completions-complete-only-command-names.md +0 -0
  223. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/complexity-and-dead-code-radar-xenon-vulture.md +0 -0
  224. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/consolidate-skill-staleness-drift-logic-into-cor.md +0 -0
  225. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/coverage-dashboard-codecov-free-for-oss.md +0 -0
  226. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/coverage-guided-fuzzing-atheris-oss-fuzz.md +0 -0
  227. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/crash-listing-branch-untested.md +0 -0
  228. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/crash-recorder-error-paths-core-logs-py.md +0 -0
  229. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/demo-cannot-open-its-own-pr.md +0 -0
  230. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/demo-gif-workflow-has-never-succeeded.md +0 -0
  231. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/demo-workflow-cancels-other-prs.md +0 -0
  232. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/dense-search-fallback-and-stale-tap-pruning.md +0 -0
  233. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/dependabot-missing-pip-ecosystem.md +0 -0
  234. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/dependabot-regeneration-drops-platform-pins.md +0 -0
  235. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/dependabot-root-pip-entry-duplicates-requirements.md +0 -0
  236. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/dependabot-splits-multi-path-action-repos.md +0 -0
  237. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/dependency-cve-gate-pip-audit.md +0 -0
  238. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/discover-searches-github-not-a-stale-sample.md +0 -0
  239. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/docsite-chrome-and-content-audit.md +0 -0
  240. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/docstring-coverage-interrogate.md +0 -0
  241. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/doctor-checks-rules-and-workflows.md +0 -0
  242. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/dry-run-promised-a-link-nobody-makes.md +0 -0
  243. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/efficiency-registries-ponytail-caveman.md +0 -0
  244. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/end-of-options-guard-on-git-commands.md +0 -0
  245. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/est-items-counts-agent-mirrors-as-items.md +0 -0
  246. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/eval-corpus-cannot-see-real-retrieval.md +0 -0
  247. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/eval-corpus-is-96x-smaller-than-a-real-install.md +0 -0
  248. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/eval-corpus-is-one-strangers-repo.md +0 -0
  249. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/eval-corpus-pins-have-no-refresh-path.md +0 -0
  250. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/eval-corpus-was-not-actually-pinned.md +0 -0
  251. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/eval-deduped-ranked-lists-by-name.md +0 -0
  252. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/eval-stats-could-never-publish.md +0 -0
  253. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/expanded-card-bodies-overflow.md +0 -0
  254. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/extension-free-tests-core-dense-py.md +0 -0
  255. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/extract-mcp-http-servers-out-of-configuration-py.md +0 -0
  256. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/finish-mutation-hardening-across-core.md +0 -0
  257. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/fix-self-update-version-detection-dead-branch.md +0 -0
  258. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/fork-safe-network-proxy-handler.md +0 -0
  259. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/framework-adapter-langgraph.md +0 -0
  260. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/framework-adapter-multi-agent.md +0 -0
  261. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/framework-adapters-boost-adapt.md +0 -0
  262. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/frontmatter-scalar-over-coercion.md +0 -0
  263. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/gemini-agent-frontmatter-sanitizer.md +0 -0
  264. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/gemini-cli-agent-target.md +0 -0
  265. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/github-community-health-files.md +0 -0
  266. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/github-pages-deploy-is-broken-every-push.md +0 -0
  267. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/golden-set-grades-by-name-not-by-skill.md +0 -0
  268. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/golden-set-statistical-power.md +0 -0
  269. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/hash-pinned-reproducible-toolchain-uv-lock.md +0 -0
  270. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/heal-deleted-links-it-never-made.md +0 -0
  271. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/html-validation-html-validate.md +0 -0
  272. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/info-rejects-the-qualified-name-it-recommends.md +0 -0
  273. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/install-docs-never-mentioned-upgrading.md +0 -0
  274. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/install-from-path-bypasses-policy-and-pin-checks.md +0 -0
  275. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/install-path-disambiguation.md +0 -0
  276. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/install-resolves-skill-dependencies.md +0 -0
  277. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/install-scope-user-or-project.md +0 -0
  278. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/installed-skill-trust-audit.md +0 -0
  279. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/integrity-verification-boost-verify.md +0 -0
  280. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/internal-architecture-diagrams.md +0 -0
  281. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/invocation-pid-logging-for-crash-correlation.md +0 -0
  282. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/journal-rotation-race-and-handle-leak.md +0 -0
  283. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/keyless-dense-tier-local-static-embeddings.md +0 -0
  284. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/keyless-semantic-search-for-everyone.md +0 -0
  285. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/langchain-in-the-wheel.md +0 -0
  286. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/langchain-integration-explainer-page.md +0 -0
  287. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/langchain-langgraph-langsmith-integration.md +0 -0
  288. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/langchain-retriever-metadata-and-k-floor.md +0 -0
  289. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/layering-guard-import-linter.md +0 -0
  290. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/license-compliance-scanning.md +0 -0
  291. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/lighthouse-ci-on-the-pages-site.md +0 -0
  292. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/lighthouse-scored-a-page-nobody-is-served.md +0 -0
  293. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/lint-tap-misscopes-rule-workflow-entries.md +0 -0
  294. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/list-rules-and-workflows.md +0 -0
  295. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/localize-the-stored-bm25-snippet.md +0 -0
  296. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/lock-invariant-cannot-parse-extras-pins.md +0 -0
  297. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/lockfile-enforcement-and-commit-pinning.md +0 -0
  298. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/log-timestamps-mislabeled-utc.md +0 -0
  299. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/lowest-version-resolution-uv-resolution-lowest-d.md +0 -0
  300. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/main-has-no-branch-protection.md +0 -0
  301. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/main-ruleset-ref-pattern-has-literal-quotes.md +0 -0
  302. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/make-lint-masks-actionlint-failures.md +0 -0
  303. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/make-the-roadmaps-discoverable.md +0 -0
  304. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/markdown-consistency-markdownlint-cli2.md +0 -0
  305. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/markdownlint-lints-the-fuzz-corpus.md +0 -0
  306. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/mcp-already-covered-defeater.md +0 -0
  307. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/mcp-aware-skills.md +0 -0
  308. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/mcp-check-skills-before-starting-a-task.md +0 -0
  309. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/mcp-hub-diagram-node-text-overflow.md +0 -0
  310. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/mcp-install-skips-the-injection-scan.md +0 -0
  311. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/mcp-launch-objc-fork-safety.md +0 -0
  312. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/mcp-one-benefit-nameable-task.md +0 -0
  313. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/mcp-register-names-server-before-env.md +0 -0
  314. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/mcp-search-before-reinventing.md +0 -0
  315. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/mcp-search-cost-was-understated.md +0 -0
  316. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/mcp-search-hid-which-ranking-ran.md +0 -0
  317. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/mcp-servers-ignore-install-scope.md +0 -0
  318. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/mcp-startup-self-harden-fork-safety.md +0 -0
  319. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/mcp-zero-setup-and-three-kinds.md +0 -0
  320. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/memoize-config-load-in-process.md +0 -0
  321. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/merge-queue-would-deadlock-most-required-checks.md +0 -0
  322. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/merged-loop-branches-are-never-pruned.md +0 -0
  323. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/modernization-smells-refurb-pyupgrade.md +0 -0
  324. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/mutation-gate-was-the-whole-critical-path.md +0 -0
  325. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/mutation-hardening-core-frontmatter-py.md +0 -0
  326. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/mutation-hardening-core-gitutil-py.md +0 -0
  327. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/mutation-hardening-core-store-py.md +0 -0
  328. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/mutation-shard-floor-is-one-file.md +0 -0
  329. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/mypy-strict-mode-for-commands.md +0 -0
  330. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/near-duplicate-items-eat-the-result-slots.md +0 -0
  331. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/negative-limit-inverts-log-pulse-output.md +0 -0
  332. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/onboard-overwrites-generated-files-without-confirm.md +0 -0
  333. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/one-command-every-env-nox.md +0 -0
  334. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/one-commit-can-cut-two-releases.md +0 -0
  335. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/one-dead-tap-broke-every-update.md +0 -0
  336. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/one-shared-atomic-write-helper.md +0 -0
  337. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/package-metadata-validation-twine-check-friends.md +0 -0
  338. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/patch-coverage-gate-diff-cover.md +0 -0
  339. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/path-traversal-unsanitized-rule-workflow-name.md +0 -0
  340. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/pep585-604-modernization-sweep.md +0 -0
  341. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/performance-regression-gate-pytest-benchmark.md +0 -0
  342. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/pin-the-lint-toolchain.md +0 -0
  343. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/post-deploy-always-defeated-by-skipped-setup.md +0 -0
  344. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/post-deploy-smoke-headless-load-check.md +0 -0
  345. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/pre-release-python-canary-3-14t-free-threaded.md +0 -0
  346. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/prerequisites-and-semantic-search-setup.md +0 -0
  347. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/project-scope-across-every-command.md +0 -0
  348. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/project-scope-symlink-escape-on-write.md +0 -0
  349. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/promote-nav-footer-into-the-shared-style-system.md +0 -0
  350. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/prompt-injection-scanning-of-skill-markdown.md +0 -0
  351. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/property-based-tests-hypothesis-on-the-parsers.md +0 -0
  352. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/prose-and-terminology-linting-vale.md +0 -0
  353. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/prune-ignored-dirs-during-scan-dir-walk.md +0 -0
  354. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/publish-gate-ignores-pip-audit-and-metadata.md +0 -0
  355. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/publish-trigger-was-reachable-from-a-fork.md +0 -0
  356. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/pytest-tmpdir-cve-blocked-by-py39-floor.md +0 -0
  357. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/python-floor-moves-to-312.md +0 -0
  358. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/quality-dashboard-sonarcloud-free-for-oss.md +0 -0
  359. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/ragas-unpin-when-upstream-ships.md +0 -0
  360. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/ranx-significance-monitor.md +0 -0
  361. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/reconcile-the-theme-drift.md +0 -0
  362. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/refresh-the-marketing-surface.md +0 -0
  363. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/rel-time-tests-race-the-wall-clock.md +0 -0
  364. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/release-verifies-the-wrong-commit.md +0 -0
  365. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/required-checks-can-declare-a-check-that-deadlocks-prs.md +0 -0
  366. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/required-checks-config-drift.md +0 -0
  367. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/resolve-vendored-duplicate-copies.md +0 -0
  368. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/retrieval-quality-eval-harness.md +0 -0
  369. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/reuse-helpers-kill-minor-dead-work.md +0 -0
  370. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/roadmap-html-goes-stale-on-every-rebase.md +0 -0
  371. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/roadmap-page-weight-grows-without-bound.md +0 -0
  372. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/roadmap-perf-budget-has-no-local-guard.md +0 -0
  373. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/robust-tag-argument-parsing.md +0 -0
  374. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/ruff-016-widens-the-default-rule-set.md +0 -0
  375. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/rule-install-native-materialization.md +0 -0
  376. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/rules-install-but-cannot-be-governed.md +0 -0
  377. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/runner-egress-monitoring-stepsecurity-harden-run.md +0 -0
  378. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/runtime-explain-faithfulness-guardrail.md +0 -0
  379. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/sbom-aware-scanning-osv-scanner.md +0 -0
  380. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/sbom-declares-the-wrong-version.md +0 -0
  381. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/sbom-on-every-release-cyclonedx-syft.md +0 -0
  382. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/sbom-release-event-never-fires.md +0 -0
  383. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/scan-and-sync-rules-and-workflows.md +0 -0
  384. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/scheduled-toolchain-lock-regeneration.md +0 -0
  385. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/scorecard-findings-triage.md +0 -0
  386. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/scripts-under-the-lint-gate.md +0 -0
  387. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/search-never-notices-a-new-tap.md +0 -0
  388. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/second-type-checker-pyright.md +0 -0
  389. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/secret-and-pii-scanning-of-installed-skills.md +0 -0
  390. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/secret-scanning-gitleaks-push-protection.md +0 -0
  391. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/security-linting-bandit-via-ruff-s-rules.md +0 -0
  392. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/self-update-broken-for-pip-pipx-installs.md +0 -0
  393. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/serve-404-reflected-the-request.md +0 -0
  394. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/serve-is-a-searchable-catalogue.md +0 -0
  395. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/serve-py-traversal-guards-untested.md +0 -0
  396. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/shards-pipeline-never-produced-a-shard.md +0 -0
  397. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/shift-left-gate-pre-commit-pre-commit-ci.md +0 -0
  398. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/single-imperative-rule-extractor.md +0 -0
  399. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/single-tech-stack-prober.md +0 -0
  400. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/split-oversized-command-modules.md +0 -0
  401. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/startup-and-import-time-budget-x-importtime.md +0 -0
  402. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/stop-re-serializing-entry-meta-on-every-search.md +0 -0
  403. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/structured-json-log-output-mode.md +0 -0
  404. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/supply-chain-posture-openssf-scorecard.md +0 -0
  405. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/surface-every-docs-page-from-the-guide.md +0 -0
  406. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/sync-could-not-repair-a-gutted-skill.md +0 -0
  407. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/sync-deletes-unowned-broken-symlinks.md +0 -0
  408. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/sync-relinks-into-every-agent-ignoring-scope.md +0 -0
  409. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/tap-signing-and-provenance-sigstore-minisign.md +0 -0
  410. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/theme-asset-linting-stylelint-eslint.md +0 -0
  411. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/tool-call-eval-tier.md +0 -0
  412. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/typo-detection-codespell.md +0 -0
  413. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/typosquat-and-name-confusion-detection.md +0 -0
  414. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/unify-tilde-two-copies-have-a-boundary-bug.md +0 -0
  415. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/uninstall-has-no-confirmation-prompt.md +0 -0
  416. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/untrack-generated-build-noise.md +0 -0
  417. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/unwatched-crons-hid-a-real-fuzz-crash.md +0 -0
  418. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/update-advertises-a-flag-it-rejects.md +0 -0
  419. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/update-diff-before-apply.md +0 -0
  420. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/update-refreshed-rules-without-a-gate.md +0 -0
  421. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/update-refreshes-rules-and-workflows.md +0 -0
  422. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/update-reinstall-widens-agent-scope.md +0 -0
  423. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/visual-regression-pass-on-the-guide.md +0 -0
  424. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/widen-the-ruff-rule-surface-b-sim-c4-perf-ruf.md +0 -0
  425. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/windows-in-the-ci-matrix.md +0 -0
  426. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/wire-bdd-suite-into-ci.md +0 -0
  427. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/workflow-install-native-materialization.md +0 -0
  428. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/workflow-linting-actionlint.md +0 -0
  429. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/workflow-sast-zizmor.md +0 -0
  430. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/workspace-scope-install.md +0 -0
  431. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/zip-strict-audit.md +0 -0
  432. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/zizmor-ignores-drift-and-make-lint-never-ran-it.md +0 -0
  433. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/docs/roadmap/items/zizmor-pin-is-a-yanked-release.md +0 -0
  434. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/eslint.config.mjs +0 -0
  435. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/evals/README.md +0 -0
  436. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/evals/__init__.py +0 -0
  437. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/evals/baseline.json +0 -0
  438. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/evals/faithfulness.py +0 -0
  439. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/evals/golden_set.json +0 -0
  440. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/evals/make_corpus.py +0 -0
  441. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/evals/make_golden.py +0 -0
  442. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/evals/metrics.py +0 -0
  443. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/evals/publish_golden_dataset.py +0 -0
  444. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/evals/run_evals.py +0 -0
  445. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/examples/README.md +0 -0
  446. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/examples/adapt-demo.sh +0 -0
  447. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/examples/boost-run-prototype.sh +0 -0
  448. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/index.html +0 -0
  449. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/noxfile.py +0 -0
  450. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/pyproject.toml +0 -0
  451. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/requirements/coverage-tools.in +0 -0
  452. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/requirements/coverage-tools.txt +0 -0
  453. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/requirements/lint-tools.in +0 -0
  454. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/requirements/lint-tools.txt +0 -0
  455. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/requirements/mutation-tools.in +0 -0
  456. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/requirements/mutation-tools.txt +0 -0
  457. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/requirements/platform-pins.lock +0 -0
  458. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/requirements/release-tools.in +0 -0
  459. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/requirements/release-tools.txt +0 -0
  460. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/requirements/test-tools.in +0 -0
  461. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/requirements/test-tools.txt +0 -0
  462. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/scripts/a11y_check.py +0 -0
  463. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/scripts/bench_cli.sh +0 -0
  464. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/scripts/build_command_reference.py +0 -0
  465. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/scripts/build_demo_index.py +0 -0
  466. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/scripts/build_registries.py +0 -0
  467. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/scripts/build_roadmap.py +0 -0
  468. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/scripts/build_scale_corpus.py +0 -0
  469. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/scripts/check_anchors.py +0 -0
  470. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/scripts/check_licenses.py +0 -0
  471. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/scripts/check_required_checks.py +0 -0
  472. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/scripts/ensure_eval_corpus.sh +0 -0
  473. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/scripts/eval_corpus.py +0 -0
  474. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/scripts/eval_explain.py +0 -0
  475. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/scripts/eval_gate.py +0 -0
  476. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/scripts/eval_recommend.py +0 -0
  477. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/scripts/eval_retrieval.py +0 -0
  478. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/scripts/eval_stats_summary.py +0 -0
  479. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/scripts/import_budget.py +0 -0
  480. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/scripts/lock_toolchain.py +0 -0
  481. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/scripts/measure_registry.py +0 -0
  482. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/scripts/mutation_gate.py +0 -0
  483. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/scripts/mutation_shards.py +0 -0
  484. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/scripts/mutation_weights.json +0 -0
  485. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/scripts/page_budget.py +0 -0
  486. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/scripts/perf_gate.py +0 -0
  487. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/scripts/post_deploy_smoke.py +0 -0
  488. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/scripts/publish_eval_json.py +0 -0
  489. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/scripts/release_guard.py +0 -0
  490. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/scripts/release_preflight.py +0 -0
  491. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/scripts/serve_docs.py +0 -0
  492. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/setup.cfg +0 -0
  493. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/sonar-project.properties +0 -0
  494. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/style/README.md +0 -0
  495. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/style/boost.css +0 -0
  496. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/style/boost.js +0 -0
  497. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/style/demo.html +0 -0
  498. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/bdd/features/adapt.feature +0 -0
  499. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/bdd/features/browse.feature +0 -0
  500. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/bdd/features/count.feature +0 -0
  501. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/bdd/features/discover.feature +0 -0
  502. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/bdd/features/doctor.feature +0 -0
  503. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/bdd/features/environment.py +0 -0
  504. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/bdd/features/explain.feature +0 -0
  505. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/bdd/features/index.feature +0 -0
  506. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/bdd/features/install.feature +0 -0
  507. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/bdd/features/list.feature +0 -0
  508. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/bdd/features/mcp.feature +0 -0
  509. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/bdd/features/search.feature +0 -0
  510. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/bdd/features/steps/cli_steps.py +0 -0
  511. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/bdd/features/steps/discovery_steps.py +0 -0
  512. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/bdd/features/steps/mcp_steps.py +0 -0
  513. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/bdd/features/steps/quality_steps.py +0 -0
  514. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/eval/baseline.json +0 -0
  515. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/eval/explain.jsonl +0 -0
  516. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/eval/golden-natural.jsonl +0 -0
  517. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/eval/golden.jsonl +0 -0
  518. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/eval/recommend.jsonl +0 -0
  519. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/eval/taps-scale.txt +0 -0
  520. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/eval/taps.txt +0 -0
  521. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/functional/test_capabilities_policy.py +0 -0
  522. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/functional/test_cli_adapt.py +0 -0
  523. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/functional/test_cli_bmad.py +0 -0
  524. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/functional/test_cli_chat.py +0 -0
  525. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/functional/test_cli_discovery.py +0 -0
  526. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/functional/test_cli_hooks.py +0 -0
  527. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/functional/test_cli_info.py +0 -0
  528. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/functional/test_cli_intelligence.py +0 -0
  529. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/functional/test_cli_pkg.py +0 -0
  530. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/functional/test_cli_quality.py +0 -0
  531. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/functional/test_cli_taps.py +0 -0
  532. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/functional/test_cli_team.py +0 -0
  533. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/functional/test_integrity_enforce.py +0 -0
  534. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/functional/test_kind_conformance.py +0 -0
  535. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/functional/test_property_parsers.py +0 -0
  536. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/functional/test_run.py +0 -0
  537. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/functional/test_tap_signing.py +0 -0
  538. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/functional/test_workspace_scope.py +0 -0
  539. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/fuzz/README.md +0 -0
  540. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/fuzz/corpus/frontmatter/01-typical.md +0 -0
  541. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/fuzz/corpus/frontmatter/02-lossy-version.md +0 -0
  542. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/fuzz/corpus/frontmatter/03-lossy-numbers.md +0 -0
  543. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/fuzz/corpus/frontmatter/04-lists.md +0 -0
  544. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/fuzz/corpus/frontmatter/05-nested.md +0 -0
  545. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/fuzz/corpus/frontmatter/06-empty-block.md +0 -0
  546. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/fuzz/corpus/frontmatter/07-unterminated.md +0 -0
  547. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/fuzz/corpus/frontmatter/08-none.md +0 -0
  548. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/fuzz/corpus/frontmatter/09-unbalanced-quote.md +0 -0
  549. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/fuzz/corpus/frontmatter/10-keywords.md +0 -0
  550. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/fuzz/corpus/frontmatter/11-crlf.md +0 -0
  551. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/fuzz/corpus/frontmatter/12-bom.md +0 -0
  552. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/fuzz/corpus/registry/01-shorthand.txt +0 -0
  553. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/fuzz/corpus/registry/02-https.txt +0 -0
  554. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/fuzz/corpus/registry/03-ssh.txt +0 -0
  555. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/fuzz/corpus/registry/04-traversal.txt +0 -0
  556. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/fuzz/corpus/registry/05-empty.txt +0 -0
  557. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/fuzz/corpus/registry/06-space.txt +0 -0
  558. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/fuzz/corpus/registry/07-slash.txt +0 -0
  559. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/fuzz/corpus/registry/08-bare-host.txt +0 -0
  560. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/fuzz/fuzz_frontmatter.py +0 -0
  561. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/fuzz/fuzz_registry.py +0 -0
  562. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/langchain/conftest.py +0 -0
  563. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/langchain/test_graph.py +0 -0
  564. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/langchain/test_loader.py +0 -0
  565. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/langchain/test_retriever.py +0 -0
  566. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/make_fixture.py +0 -0
  567. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/perf/test_benchmarks.py +0 -0
  568. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_a11y_check.py +0 -0
  569. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_action_pin_lockstep.py +0 -0
  570. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_adapters.py +0 -0
  571. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_adapters_multi.py +0 -0
  572. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_adapters_runner.py +0 -0
  573. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_agents.py +0 -0
  574. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_ai.py +0 -0
  575. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_bmad_core.py +0 -0
  576. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_boost_first_offer.py +0 -0
  577. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_bootstrap.py +0 -0
  578. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_builtin.py +0 -0
  579. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_capabilities.py +0 -0
  580. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_catalog.py +0 -0
  581. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_chat.py +0 -0
  582. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_check_anchors.py +0 -0
  583. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_check_licenses.py +0 -0
  584. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_claude_settings.py +0 -0
  585. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_cliparse.py +0 -0
  586. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_codeql_analysis_key.py +0 -0
  587. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_command_reference_fresh.py +0 -0
  588. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_community_health_files.py +0 -0
  589. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_complete.py +0 -0
  590. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_config.py +0 -0
  591. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_content_dedupe.py +0 -0
  592. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_dedup_trust.py +0 -0
  593. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_demo_index.py +0 -0
  594. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_dense.py +0 -0
  595. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_dense_fallback.py +0 -0
  596. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_dense_fix_hint.py +0 -0
  597. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_dense_shard_real_schema.py +0 -0
  598. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_dense_shard_unreadable_vectors.py +0 -0
  599. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_dense_shards.py +0 -0
  600. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_dense_status.py +0 -0
  601. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_dependabot_config.py +0 -0
  602. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_docs_pages_linked.py +0 -0
  603. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_docsite_chrome.py +0 -0
  604. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_ed25519.py +0 -0
  605. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_embed.py +0 -0
  606. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_embed_local.py +0 -0
  607. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_entry_key.py +0 -0
  608. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_eval_baseline.py +0 -0
  609. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_eval_corpus.py +0 -0
  610. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_eval_faithfulness.py +0 -0
  611. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_eval_gate.py +0 -0
  612. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_eval_grading.py +0 -0
  613. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_eval_metrics.py +0 -0
  614. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_eval_stats_summary.py +0 -0
  615. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_failure_alerting_covers_unattended.py +0 -0
  616. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_faithfulness.py +0 -0
  617. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_frontmatter.py +0 -0
  618. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_fuzz_targets.py +0 -0
  619. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_gemini_agent_sanitize.py +0 -0
  620. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_gitleaks_config.py +0 -0
  621. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_gitutil.py +0 -0
  622. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_gitutil_lfs.py +0 -0
  623. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_imperative.py +0 -0
  624. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_import_budget.py +0 -0
  625. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_injectscan.py +0 -0
  626. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_installscan.py +0 -0
  627. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_integrity.py +0 -0
  628. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_journal.py +0 -0
  629. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_langchain_packaging.py +0 -0
  630. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_link_ownership.py +0 -0
  631. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_localembed.py +0 -0
  632. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_localembed_e2e.py +0 -0
  633. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_lockfile.py +0 -0
  634. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_logs.py +0 -0
  635. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_marketing_counts.py +0 -0
  636. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_mcp.py +0 -0
  637. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_mcp_install_scan.py +0 -0
  638. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_mcpdecl.py +0 -0
  639. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_mcphost.py +0 -0
  640. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_measure_registry.py +0 -0
  641. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_minisign.py +0 -0
  642. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_mutation_hardening.py +0 -0
  643. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_mutation_shards.py +0 -0
  644. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_mutation_subfile_shards.py +0 -0
  645. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_mutmut_source_paths.py +0 -0
  646. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_nethttp.py +0 -0
  647. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_output.py +0 -0
  648. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_page_budget.py +0 -0
  649. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_paths.py +0 -0
  650. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_perf_gate.py +0 -0
  651. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_pkg_confusions.py +0 -0
  652. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_pkg_injection.py +0 -0
  653. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_pkg_secrets.py +0 -0
  654. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_platform_pins.py +0 -0
  655. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_policy.py +0 -0
  656. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_post_deploy_smoke.py +0 -0
  657. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_project_mcp_sidecar.py +0 -0
  658. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_projectlock.py +0 -0
  659. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_provenance.py +0 -0
  660. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_publish_golden_dataset.py +0 -0
  661. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_rag.py +0 -0
  662. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_rag_fusion.py +0 -0
  663. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_registries_fresh.py +0 -0
  664. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_registry.py +0 -0
  665. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_registry_categories.py +0 -0
  666. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_registry_control_chars.py +0 -0
  667. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_release_guard.py +0 -0
  668. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_release_preflight.py +0 -0
  669. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_required_checks.py +0 -0
  670. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_resolve.py +0 -0
  671. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_roadmap_fresh.py +0 -0
  672. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_rules.py +0 -0
  673. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_scale_corpus.py +0 -0
  674. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_scopes.py +0 -0
  675. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_secretscan.py +0 -0
  676. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_serve.py +0 -0
  677. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_serve_docs.py +0 -0
  678. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_shards_matrix.py +0 -0
  679. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_smoke_covers_every_command.py +0 -0
  680. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_spin.py +0 -0
  681. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_stackprobe.py +0 -0
  682. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_staleness.py +0 -0
  683. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_store.py +0 -0
  684. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_sync_repairs_gutted_skill.py +0 -0
  685. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_token_parity.py +0 -0
  686. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_toolchain_lock.py +0 -0
  687. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_trustaudit.py +0 -0
  688. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_typosquat.py +0 -0
  689. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_updatediff.py +0 -0
  690. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_util.py +0 -0
  691. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_version.py +0 -0
  692. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_workflow_concurrency.py +0 -0
  693. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_workflow_concurrency_groups.py +0 -0
  694. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_workflow_push_has_credentials.py +0 -0
  695. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_workflow_timeouts.py +0 -0
  696. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_workflows.py +0 -0
  697. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/unit/test_zizmor_ignores_still_anchor.py +0 -0
  698. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/visual/a11y_check.mjs +0 -0
  699. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/visual/console_check.mjs +0 -0
  700. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/visual/package-lock.json +0 -0
  701. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/visual/package.json +0 -0
  702. {boost_skill_cli-1.0.449 → boost_skill_cli-1.0.451}/tests/visual/visual_check.mjs +0 -0
@@ -33,6 +33,7 @@ gitignored
33
33
  GitOps
34
34
  glassmorphic
35
35
  Grafana
36
+ gzipped
36
37
  hardcode
37
38
  Helm
38
39
  hotspots
@@ -55,6 +56,7 @@ onboards
55
56
  OpenShift
56
57
  overclaiming
57
58
  Pinecone
59
+ pipx
58
60
  PrestaShop
59
61
  Pulumi
60
62
  pytest
@@ -65,12 +67,12 @@ reindex
65
67
  repo
66
68
  repo's
67
69
  repos
68
- rerank
69
70
  Rerank
71
+ rerank
70
72
  reranking
71
73
  ruleset
72
- rulesets
73
74
  Rulesets
75
+ rulesets
74
76
  sandboxed
75
77
  sandboxing
76
78
  Shopify
@@ -98,6 +100,7 @@ unlinking
98
100
  unregister
99
101
  unstaged
100
102
  untap
103
+ uv
101
104
  Vaadin
102
105
  vendored
103
106
  vendoring
@@ -233,7 +233,7 @@ for both — edit items, run `build_roadmap.py`, never touch the HTML by hand.
233
233
  ## Architecture
234
234
 
235
235
  **CLI dispatch.** `boost_cli/cli.py` holds `COMMANDS`, the single
236
- source-of-truth list of `(name, group, module, summary)` for all 78 commands.
236
+ source-of-truth list of `(name, group, module, summary)` for all 79 commands.
237
237
  Each command is implemented as `def cmd_<name_with_underscores>(argv) -> int`
238
238
  inside `boost_cli/commands/<module>.py`, and `_dispatch` imports that module
239
239
  lazily on invocation — so `boost --help` stays instant and command modules are
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: boost-skill-cli
3
- Version: 1.0.449
3
+ Version: 1.0.451
4
4
  Summary: boost — Homebrew for AI coding skills
5
5
  Author: Jonathan Reyes
6
6
  License: GNU GENERAL PUBLIC LICENSE
@@ -854,6 +854,31 @@ boost tap --catalog --category rag # RAG / vector-search skill packs
854
854
  boost tap --catalog --category security # filter by category
855
855
  ```
856
856
 
857
+ ### Share the catalogue instead of re-tapping it
858
+
859
+ Tapping is the slowest thing a new install does, and the expensive artifact is
860
+ not the valuable one. On a machine with **458 registries** tapped, the shallow
861
+ clones are **12 GB** — while the catalogue they produce, the JSON boost actually
862
+ searches, is **10.9 MB** gzipped. So hand someone the catalogue:
863
+
864
+ ```bash
865
+ boost catalog --export catalogue.tgz # 458 taps · 59,972 entries · 10.9 MB
866
+ boost catalog --show catalogue.tgz # what is in it, without importing
867
+ boost catalog --import catalogue.tgz # on the other machine
868
+ ```
869
+
870
+ Measured on a fresh `HOME`: import takes **0.3 s**, `boost reindex` a further
871
+ **3.8 s**, and `boost search` then returns real hits over all 59,972 items with
872
+ **zero repositories cloned**. `install` still clones — but only the one registry
873
+ the skill you chose actually lives in, instead of all 458 up front.
874
+
875
+ Bundles carry catalogue JSON and nothing else. The derived indexes are excluded
876
+ (they are 3.8 GB of a 3.9 GB cache directory and rebuild in seconds), and
877
+ vectors are excluded because they are only valid inside the embedding space that
878
+ made them — `boost reindex --export-shard` is the path for those, with the
879
+ provenance checks a bundle deliberately does not try to carry. Import **merges**,
880
+ so it never silently drops taps the receiving machine already had.
881
+
857
882
  boost indexes three item kinds out of the same registries: `SKILL.md` **skills**,
858
883
  `.mdc`/`.cursorrules`/`.windsurfrules` **rules**, and command/agent **workflows**
859
884
  (Markdown under `commands/`·`agents/`·`workflows/`, or carrying subagent
@@ -946,7 +971,7 @@ boost doctor # sanity check: broken links, lock drift, stale taps
946
971
  boost bundle dump > Boostfile # everyone else runs: boost bundle install
947
972
  ```
948
973
 
949
- ## 78 commands, organized into 8 groups
974
+ ## 79 commands, organized into 8 groups
950
975
 
951
976
  `boost --help` prints the full grouped command list; for a visual tour see
952
977
  [`docs/index.html`](docs/index.html), and for every flag of every command see
@@ -1160,8 +1185,8 @@ Four layers, all enforced (`make check` runs the full set; CI runs the same thin
1160
1185
 
1161
1186
  | Layer | What it does | Gate |
1162
1187
  |---|---|---|
1163
- | `make test` | pytest across `tests/unit/` (every core module) and `tests/functional/` (drives all 78 commands in-process against sandboxed homes) | **≥80% line coverage** of `boost_cli` (`fail_under` in pyproject.toml) |
1164
- | `make smoke` | `tests/smoke.sh` — 174 checks run through the actual `./boost` shim (`--online` also hits real registries) | all pass |
1188
+ | `make test` | pytest across `tests/unit/` (every core module) and `tests/functional/` (drives all 79 commands in-process against sandboxed homes) | **≥80% line coverage** of `boost_cli` (`fail_under` in pyproject.toml) |
1189
+ | `make smoke` | `tests/smoke.sh` — 175 checks run through the actual `./boost` shim (`--online` also hits real registries) | all pass |
1165
1190
  | `make mutation` | [mutmut] mutates `boost_cli/core` (~9,900 mutants) and reruns the unit suite against each one | **≥80% killed** (`scripts/mutation_gate.py`) |
1166
1191
  | `make evals` | scores the search ranker on a graded golden set — recall@5/@10, MRR, nDCG@5/@10 | **metric floors + no statistically significant regression** (`scripts/eval_gate.py`) |
1167
1192
 
@@ -136,6 +136,31 @@ boost tap --catalog --category rag # RAG / vector-search skill packs
136
136
  boost tap --catalog --category security # filter by category
137
137
  ```
138
138
 
139
+ ### Share the catalogue instead of re-tapping it
140
+
141
+ Tapping is the slowest thing a new install does, and the expensive artifact is
142
+ not the valuable one. On a machine with **458 registries** tapped, the shallow
143
+ clones are **12 GB** — while the catalogue they produce, the JSON boost actually
144
+ searches, is **10.9 MB** gzipped. So hand someone the catalogue:
145
+
146
+ ```bash
147
+ boost catalog --export catalogue.tgz # 458 taps · 59,972 entries · 10.9 MB
148
+ boost catalog --show catalogue.tgz # what is in it, without importing
149
+ boost catalog --import catalogue.tgz # on the other machine
150
+ ```
151
+
152
+ Measured on a fresh `HOME`: import takes **0.3 s**, `boost reindex` a further
153
+ **3.8 s**, and `boost search` then returns real hits over all 59,972 items with
154
+ **zero repositories cloned**. `install` still clones — but only the one registry
155
+ the skill you chose actually lives in, instead of all 458 up front.
156
+
157
+ Bundles carry catalogue JSON and nothing else. The derived indexes are excluded
158
+ (they are 3.8 GB of a 3.9 GB cache directory and rebuild in seconds), and
159
+ vectors are excluded because they are only valid inside the embedding space that
160
+ made them — `boost reindex --export-shard` is the path for those, with the
161
+ provenance checks a bundle deliberately does not try to carry. Import **merges**,
162
+ so it never silently drops taps the receiving machine already had.
163
+
139
164
  boost indexes three item kinds out of the same registries: `SKILL.md` **skills**,
140
165
  `.mdc`/`.cursorrules`/`.windsurfrules` **rules**, and command/agent **workflows**
141
166
  (Markdown under `commands/`·`agents/`·`workflows/`, or carrying subagent
@@ -228,7 +253,7 @@ boost doctor # sanity check: broken links, lock drift, stale taps
228
253
  boost bundle dump > Boostfile # everyone else runs: boost bundle install
229
254
  ```
230
255
 
231
- ## 78 commands, organized into 8 groups
256
+ ## 79 commands, organized into 8 groups
232
257
 
233
258
  `boost --help` prints the full grouped command list; for a visual tour see
234
259
  [`docs/index.html`](docs/index.html), and for every flag of every command see
@@ -442,8 +467,8 @@ Four layers, all enforced (`make check` runs the full set; CI runs the same thin
442
467
 
443
468
  | Layer | What it does | Gate |
444
469
  |---|---|---|
445
- | `make test` | pytest across `tests/unit/` (every core module) and `tests/functional/` (drives all 78 commands in-process against sandboxed homes) | **≥80% line coverage** of `boost_cli` (`fail_under` in pyproject.toml) |
446
- | `make smoke` | `tests/smoke.sh` — 174 checks run through the actual `./boost` shim (`--online` also hits real registries) | all pass |
470
+ | `make test` | pytest across `tests/unit/` (every core module) and `tests/functional/` (drives all 79 commands in-process against sandboxed homes) | **≥80% line coverage** of `boost_cli` (`fail_under` in pyproject.toml) |
471
+ | `make smoke` | `tests/smoke.sh` — 175 checks run through the actual `./boost` shim (`--online` also hits real registries) | all pass |
447
472
  | `make mutation` | [mutmut] mutates `boost_cli/core` (~9,900 mutants) and reruns the unit suite against each one | **≥80% killed** (`scripts/mutation_gate.py`) |
448
473
  | `make evals` | scores the search ranker on a graded golden set — recall@5/@10, MRR, nDCG@5/@10 | **metric floors + no statistically significant regression** (`scripts/eval_gate.py`) |
449
474
 
@@ -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.449'
22
- __version_tuple__ = version_tuple = (1, 0, 449)
21
+ __version__ = version = '1.0.451'
22
+ __version_tuple__ = version_tuple = (1, 0, 451)
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -87,6 +87,7 @@ COMMANDS = [
87
87
  ("untap", "tap", "taps", "Remove a registry tap"),
88
88
  ("taps", "tap", "taps", "List all configured registry taps"),
89
89
  ("outdated", "tap", "taps", "Show skills with available updates"),
90
+ ("catalog", "tap", "taps", "Share the tapped catalogue so others skip the clone"),
90
91
  # Intelligence (8)
91
92
  ("chat", "ai", "intelligence", "Ask about skills in plain language (RAG-grounded)"),
92
93
  ("distill", "ai", "intelligence", "Merge multiple skills into one deduplicated skill"),
@@ -1498,12 +1498,40 @@ def _self_update_package(method: str, dry_run: bool) -> int:
1498
1498
  journal.log("self-update", new or old, previous=old, method=method)
1499
1499
  if new and new != old:
1500
1500
  out.ok("boost v%s → v%s" % (old, new))
1501
- elif new:
1502
- out.ok("already up to date (v%s)" % new)
1503
- else:
1501
+ return 0
1502
+ if not new:
1504
1503
  # The upgrade succeeded but we never saw a version — say exactly that
1505
1504
  # rather than claim one.
1506
1505
  out.ok("upgraded via %s; run `boost --version` to confirm" % method)
1506
+ return 0
1507
+ return _report_no_op(method, new)
1508
+
1509
+
1510
+ def _report_no_op(method: str, here: str) -> int:
1511
+ """Explain a manager that exited 0 without moving the version.
1512
+
1513
+ "The version did not change" is not "you are on the latest release", and
1514
+ boost used to print the second on evidence for only the first. When the
1515
+ index pip resolved against was stale, that told a user who was a release
1516
+ behind that they were current — so ask PyPI which it is, and let the three
1517
+ possible answers say three different things.
1518
+ """
1519
+ latest = selfupdate.latest_version()
1520
+ if latest is None:
1521
+ # Offline. Report only what was observed; claiming "up to date" here is
1522
+ # the same unearned claim with a different cause.
1523
+ out.ok("boost is unchanged (v%s); could not reach PyPI to confirm it is "
1524
+ "the latest" % here)
1525
+ return 0
1526
+ if selfupdate.is_behind(here, latest):
1527
+ raise BoostError(
1528
+ "%s exited 0 but boost is still v%s — PyPI has v%s"
1529
+ % (method, here, latest),
1530
+ hint="no newer candidate was offered: either the index it resolved "
1531
+ "against was stale, or this environment's python is too old "
1532
+ "for the new wheel. Pin it with `%s`"
1533
+ % " ".join(selfupdate.force_command(method, latest)))
1534
+ out.ok("already up to date (v%s)" % here)
1507
1535
  return 0
1508
1536
 
1509
1537
 
@@ -5,6 +5,7 @@ import argparse
5
5
  import hashlib
6
6
  import json
7
7
  from contextlib import suppress
8
+ from pathlib import Path
8
9
 
9
10
  from .. import cliparse, spin
10
11
  from ..core import (
@@ -317,3 +318,66 @@ def cmd_outdated(argv) -> int:
317
318
  out.dim("%d outdated · `boost update` upgrades (pinned items stay put)"
318
319
  % len(results))
319
320
  return 0
321
+
322
+
323
+ def cmd_catalog(argv) -> int:
324
+ """boost catalog --export FILE | --import FILE [--json]"""
325
+ p = cliparse.parser(
326
+ prog="boost catalog",
327
+ description="Share the tapped catalogue so others skip the clone")
328
+ mode = p.add_mutually_exclusive_group(required=True)
329
+ mode.add_argument("--export", metavar="FILE",
330
+ help="write every tapped registry's catalogue to FILE")
331
+ mode.add_argument("--import", metavar="FILE", dest="import_",
332
+ help="merge a catalogue bundle into this machine")
333
+ mode.add_argument("--show", metavar="FILE",
334
+ help="describe a bundle without importing it")
335
+ p.add_argument("--json", action="store_true", dest="as_json",
336
+ help="machine-readable output")
337
+ args = p.parse_args(argv)
338
+
339
+ from ..core import catalogbundle
340
+
341
+ if args.show:
342
+ manifest = catalogbundle.read_manifest(Path(args.show))
343
+ if args.as_json:
344
+ print(json.dumps(manifest, indent=2))
345
+ return 0
346
+ out.heading("catalogue bundle %s" % args.show)
347
+ out.info("built %s · %d taps · %s entries"
348
+ % (manifest.get("generated", "?"),
349
+ len(manifest.get("taps") or []),
350
+ "{:,}".format(int(manifest.get("entries") or 0))))
351
+ rows = [(t.get("name", "?"), str(t.get("entries", "?")),
352
+ (t.get("commit") or "")[:7])
353
+ for t in (manifest.get("taps") or [])[:20]]
354
+ if rows:
355
+ out.table(rows, headers=("TAP", "ENTRIES", "COMMIT"))
356
+ return 0
357
+
358
+ if args.export:
359
+ stats = catalogbundle.export_bundle(Path(args.export))
360
+ if args.as_json:
361
+ print(json.dumps(stats, indent=2))
362
+ return 0
363
+ out.ok("packed %d taps · %s entries · %.1f MB → %s"
364
+ % (stats["taps"], "{:,}".format(stats["entries"]),
365
+ stats["bytes"] / 1e6, stats["path"]))
366
+ if stats["skipped"]:
367
+ # Configured but not yet built. Named rather than counted: the
368
+ # reader needs to know WHICH registry the receiver will not get.
369
+ out.warn("skipped %d tap(s) with no built catalogue: %s"
370
+ % (len(stats["skipped"]), ", ".join(stats["skipped"][:5])))
371
+ out.dim("the receiver runs `boost catalog --import <file>` — no clone, "
372
+ "no re-tap")
373
+ return 0
374
+
375
+ stats = catalogbundle.import_bundle(Path(args.import_))
376
+ if args.as_json:
377
+ print(json.dumps(stats, indent=2))
378
+ return 0
379
+ out.ok("imported %d catalogue file(s) · %s entries · %d new tap(s)"
380
+ % (stats["files"], "{:,}".format(stats["entries"]), stats["added"]))
381
+ out.dim("`boost search` works now; `boost install` clones just the one "
382
+ "registry it needs")
383
+ return 0
@@ -0,0 +1,265 @@
1
+ """A portable catalogue bundle: everything `boost tap` produces, minus the clone.
2
+
3
+ WHY THIS EXISTS. `boost tap --defaults` is the slowest thing a new install does,
4
+ and almost none of the cost is the part anyone needs. Measured on a real
5
+ machine with **459 registries tapped**: the shallow clones are **12 GB**, while
6
+ the catalogue they produce — the JSON boost actually searches — is **101.1 MB**,
7
+ and **11.1 MB** gzipped. Search works from that catalogue with no clone present
8
+ at all.
9
+
10
+ So the expensive artifact is not the valuable one, and the valuable one fits in
11
+ an email. This module packs it.
12
+
13
+ WHAT IS DELIBERATELY NOT IN IT.
14
+
15
+ * The **derived indexes**. `rag_index.json`, `rag_postings.sqlite` and
16
+ `rag_vectors.sqlite` are 3.8 GB of that machine's 3.9 GB cache directory, and
17
+ they rebuild from the catalogue in seconds. Vectors additionally are only
18
+ meaningful inside the embedding space that produced them, which is why
19
+ `dense.export_shard` carries provider/model/dim/commit and `import_shard`
20
+ refuses a mismatch. This format carries none of that and must not pretend to:
21
+ shards are the reviewed path for vectors.
22
+ * The **repositories**. A bundle makes a catalogue searchable, not installable —
23
+ `install` copies files out of a clone. Every tap's URL rides in the manifest
24
+ precisely so the receiving machine can clone the one repo it ends up wanting,
25
+ instead of all 459 up front.
26
+
27
+ The archive is a gzipped tar of `manifest.json` plus `catalog/<safe_name>.json`,
28
+ one per tap, byte-identical to what `catalog.build_cache` wrote.
29
+
30
+ SECURITY. A bundle is a file people send each other, which makes it untrusted
31
+ input in the most ordinary way there is, and tar member names are the classic
32
+ path-traversal vector. Extraction here never lets the archive choose a
33
+ destination: member names are validated, then the bytes are written to a path
34
+ this module builds from the basename. See `_safe_members`.
35
+ """
36
+ from __future__ import annotations
37
+
38
+ import json
39
+ import tarfile
40
+ import time
41
+ from pathlib import Path
42
+
43
+ from ..errors import BoostError
44
+ from . import config, paths, registry
45
+
46
+ #: Bump when the layout changes incompatibly. An importer that cannot say what
47
+ #: it is looking at cannot refuse anything.
48
+ BUNDLE_FORMAT = 1
49
+
50
+ MANIFEST_NAME = "manifest.json"
51
+ #: Every catalogue file lives under this prefix; anything else is refused.
52
+ CATALOG_PREFIX = "catalog/"
53
+
54
+ #: Caps, so a hostile archive cannot exhaust the disk. Both are generous
55
+ #: against real data — the 459-tap export is 460 members and its largest
56
+ #: catalogue file is 14 MB — and both are monkeypatched low in the tests,
57
+ #: because a limit nothing ever reaches is a limit nothing has tested.
58
+ MAX_MEMBERS = 5000
59
+ MAX_MEMBER_BYTES = 256 * 1024 * 1024
60
+
61
+ def export_bundle(dest: Path) -> dict:
62
+ """Pack every tapped registry's catalogue into ``dest``. Returns stats.
63
+
64
+ Driven by the **tap list**, not by a scan of the cache directory, and that
65
+ is what keeps the derived indexes out rather than any filename filter: a
66
+ file only becomes a candidate by being named ``<safe_name>.json`` for a
67
+ configured tap, so ``rag_vectors.sqlite`` is never considered in the first
68
+ place. It also means a stale catalogue left behind by an untapped registry
69
+ is not exported. An earlier revision carried an ``_is_catalogue_file``
70
+ predicate for this and never called it — dead code that made the
71
+ accompanying test pass for a reason that had nothing to do with the filter.
72
+
73
+ A configured tap with no cache file yet is **skipped, not fatal**: taps are
74
+ built one at a time, and refusing to export the other 458 because one is
75
+ mid-build would make this unusable exactly when it is most wanted. The
76
+ skipped names come back in the stats so the caller can say so.
77
+
78
+ Exporting nothing raises instead, because an empty bundle is
79
+ indistinguishable from a working one until someone imports it.
80
+ """
81
+ dest = Path(dest)
82
+ taps = registry.list_taps()
83
+ packed: list[dict] = []
84
+ skipped: list[str] = []
85
+ entries = 0
86
+
87
+ for tap in taps:
88
+ cache_file = paths.cache_dir() / ("%s.json" % tap.safe_name)
89
+ if not cache_file.is_file():
90
+ skipped.append(tap.name)
91
+ continue
92
+ try:
93
+ data = json.loads(cache_file.read_text(encoding="utf-8"))
94
+ except (OSError, json.JSONDecodeError):
95
+ skipped.append(tap.name)
96
+ continue
97
+ count = len(data.get("skills") or [])
98
+ entries += count
99
+ packed.append({"name": tap.name, "url": tap.url,
100
+ "curated": tap.curated,
101
+ "commit": str(data.get("commit") or ""),
102
+ "entries": count,
103
+ "file": "%s.json" % tap.safe_name})
104
+
105
+ if not packed:
106
+ raise BoostError(
107
+ "nothing to export — no tapped registry has a built catalogue",
108
+ hint="tap a registry first, e.g. `boost tap --defaults`")
109
+
110
+ manifest = {
111
+ "format": BUNDLE_FORMAT,
112
+ "generated": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()),
113
+ "taps": packed,
114
+ "entries": entries,
115
+ }
116
+
117
+ dest.parent.mkdir(parents=True, exist_ok=True)
118
+ try:
119
+ with tarfile.open(dest, "w:gz") as tar:
120
+ _add_bytes(tar, MANIFEST_NAME,
121
+ json.dumps(manifest, indent=1).encode("utf-8"))
122
+ for row in packed:
123
+ src = paths.cache_dir() / row["file"]
124
+ tar.add(str(src), arcname=CATALOG_PREFIX + row["file"])
125
+ except OSError as exc:
126
+ raise BoostError("cannot write bundle %s: %s" % (dest, exc)) from exc
127
+
128
+ return {"path": str(dest), "taps": len(packed), "entries": entries,
129
+ "skipped": skipped, "bytes": dest.stat().st_size}
130
+
131
+
132
+ def _add_bytes(tar: tarfile.TarFile, name: str, data: bytes) -> None:
133
+ """Add an in-memory file to ``tar`` (used for the manifest)."""
134
+ import io
135
+ info = tarfile.TarInfo(name)
136
+ info.size = len(data)
137
+ info.mtime = 0 # reproducible: same catalogue, same bytes
138
+ tar.addfile(info, io.BytesIO(data))
139
+
140
+
141
+ def read_manifest(src: Path) -> dict:
142
+ """The manifest of ``src``, without extracting anything else."""
143
+ src = Path(src)
144
+ if not src.is_file():
145
+ raise BoostError("no such bundle: %s" % src)
146
+ try:
147
+ with tarfile.open(src, "r:gz") as tar:
148
+ member = tar.getmember(MANIFEST_NAME)
149
+ if not member.isfile():
150
+ raise BoostError("bundle manifest is not a file: %s" % src)
151
+ handle = tar.extractfile(member)
152
+ if handle is None:
153
+ raise BoostError("bundle manifest is unreadable: %s" % src)
154
+ return json.loads(handle.read().decode("utf-8"))
155
+ except KeyError as exc:
156
+ raise BoostError(
157
+ "%s is not a boost catalogue bundle (no %s)" % (src, MANIFEST_NAME),
158
+ hint="create one with `boost catalog --export <file>`") from exc
159
+ except (tarfile.TarError, OSError) as exc:
160
+ raise BoostError("cannot read bundle %s: %s" % (src, exc)) from exc
161
+ except (json.JSONDecodeError, UnicodeDecodeError) as exc:
162
+ raise BoostError("bundle manifest is malformed: %s" % exc) from exc
163
+
164
+
165
+ def _safe_members(tar: tarfile.TarFile) -> list[tarfile.TarInfo]:
166
+ """The catalogue members of ``tar``, or raise naming what was rejected.
167
+
168
+ The archive never chooses a destination. A member is accepted only when it
169
+ is a regular file directly under ``catalog/`` whose name is a plain
170
+ basename — no separators, no ``..``, no leading ``/``, no symlink or device
171
+ entry — and the caller then writes it to a path built from that basename.
172
+ Validating the name and *also* discarding it is deliberate: a check that
173
+ feeds its input forward is one refactor away from being decorative.
174
+ """
175
+ members = tar.getmembers()
176
+ if len(members) > MAX_MEMBERS:
177
+ raise BoostError(
178
+ "bundle has %d members, over the %d cap"
179
+ % (len(members), MAX_MEMBERS),
180
+ hint="this is not a catalogue export — check where it came from")
181
+
182
+ picked: list[tarfile.TarInfo] = []
183
+ for member in members:
184
+ if member.name == MANIFEST_NAME:
185
+ continue
186
+ if not member.isfile():
187
+ # Symlinks and hardlinks are how an archive writes outside its own
188
+ # tree without any name containing "..".
189
+ raise BoostError(
190
+ "bundle contains a non-regular entry: %s" % member.name,
191
+ hint="a catalogue bundle holds only JSON files")
192
+ if not member.name.startswith(CATALOG_PREFIX):
193
+ raise BoostError(
194
+ "bundle contains an entry outside %s: %s"
195
+ % (CATALOG_PREFIX, member.name))
196
+ leaf = member.name[len(CATALOG_PREFIX):]
197
+ if (not leaf or leaf != Path(leaf).name or leaf.startswith(".")
198
+ or "/" in leaf or "\\" in leaf or not leaf.endswith(".json")):
199
+ raise BoostError(
200
+ "bundle contains an unsafe member name: %s" % member.name)
201
+ if member.size > MAX_MEMBER_BYTES:
202
+ raise BoostError(
203
+ "bundle member %s is %d bytes, over the %d cap"
204
+ % (member.name, member.size, MAX_MEMBER_BYTES))
205
+ picked.append(member)
206
+ return picked
207
+
208
+
209
+ def import_bundle(src: Path) -> dict:
210
+ """Restore a catalogue bundle into this machine. Returns stats.
211
+
212
+ **Merges, never replaces.** The receiving machine may already have taps of
213
+ its own, and silently dropping them would be a worse outcome than the slow
214
+ tap this feature exists to avoid. A tap already configured keeps its
215
+ existing entry; its catalogue file is overwritten, which is the point.
216
+ """
217
+ src = Path(src)
218
+ manifest = read_manifest(src)
219
+
220
+ fmt = manifest.get("format")
221
+ if fmt != BUNDLE_FORMAT:
222
+ raise BoostError(
223
+ "bundle format %r is not supported (this boost reads %d)"
224
+ % (fmt, BUNDLE_FORMAT),
225
+ hint="upgrade boost, or re-export the bundle with this version")
226
+
227
+ paths.ensure_dirs()
228
+ written = 0
229
+ try:
230
+ with tarfile.open(src, "r:gz") as tar:
231
+ members = _safe_members(tar)
232
+ for member in members:
233
+ handle = tar.extractfile(member)
234
+ if handle is None:
235
+ continue
236
+ leaf = Path(member.name).name
237
+ # The destination is built here, from the basename, so the
238
+ # archive cannot influence it even if a check above is wrong.
239
+ target = paths.cache_dir() / leaf
240
+ target.write_bytes(handle.read(MAX_MEMBER_BYTES + 1))
241
+ written += 1
242
+ except (tarfile.TarError, OSError) as exc:
243
+ raise BoostError("cannot read bundle %s: %s" % (src, exc)) from exc
244
+
245
+ cfg = config.load()
246
+ existing = cfg.get("taps") or []
247
+ if not isinstance(existing, list):
248
+ existing = []
249
+ known = {t.get("name") for t in existing if isinstance(t, dict)}
250
+ added = 0
251
+ for row in manifest.get("taps") or []:
252
+ name = row.get("name")
253
+ if not name or name in known:
254
+ continue
255
+ existing.append({"name": name, "url": row.get("url", ""),
256
+ "curated": bool(row.get("curated"))})
257
+ known.add(name)
258
+ added += 1
259
+ cfg["taps"] = existing
260
+ config.save(cfg)
261
+
262
+ return {"path": str(src), "taps": len(manifest.get("taps") or []),
263
+ "added": added, "files": written,
264
+ "entries": int(manifest.get("entries") or 0),
265
+ "generated": manifest.get("generated", "")}