boost-skill-cli 1.0.207__tar.gz → 1.0.208__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 (396) hide show
  1. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/.vale/styles/config/vocabularies/boost/accept.txt +1 -0
  2. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/CONTRIBUTING.md +22 -1
  3. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/Makefile +11 -2
  4. {boost_skill_cli-1.0.207/boost_skill_cli.egg-info → boost_skill_cli-1.0.208}/PKG-INFO +1 -1
  5. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/_version.py +2 -2
  6. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/commands/info.py +6 -0
  7. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/commands/pkg.py +69 -0
  8. boost_skill_cli-1.0.208/boost_cli/core/mcpdecl.py +193 -0
  9. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/core/store.py +29 -0
  10. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208/boost_skill_cli.egg-info}/PKG-INFO +1 -1
  11. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_skill_cli.egg-info/SOURCES.txt +13 -0
  12. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/commands.html +4 -3
  13. boost_skill_cli-1.0.208/docs/roadmap/items/hash-pinned-reproducible-toolchain-uv-lock.md +31 -0
  14. boost_skill_cli-1.0.208/docs/roadmap/items/mcp-aware-skills.md +32 -0
  15. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap.html +33 -15
  16. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/noxfile.py +15 -4
  17. boost_skill_cli-1.0.208/requirements/coverage-tools.in +11 -0
  18. boost_skill_cli-1.0.208/requirements/coverage-tools.txt +344 -0
  19. boost_skill_cli-1.0.207/requirements/lint-tools.txt → boost_skill_cli-1.0.208/requirements/lint-tools.in +12 -8
  20. boost_skill_cli-1.0.208/requirements/lint-tools.txt +593 -0
  21. boost_skill_cli-1.0.208/requirements/mutation-tools.in +16 -0
  22. boost_skill_cli-1.0.208/requirements/mutation-tools.txt +567 -0
  23. boost_skill_cli-1.0.208/requirements/release-tools.in +17 -0
  24. boost_skill_cli-1.0.208/requirements/release-tools.txt +773 -0
  25. boost_skill_cli-1.0.208/requirements/test-tools.in +16 -0
  26. boost_skill_cli-1.0.208/requirements/test-tools.txt +391 -0
  27. boost_skill_cli-1.0.208/scripts/lock_toolchain.py +153 -0
  28. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/setup.cfg +2 -0
  29. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/functional/test_cli_pkg.py +151 -0
  30. boost_skill_cli-1.0.208/tests/unit/test_mcpdecl.py +355 -0
  31. boost_skill_cli-1.0.208/tests/unit/test_toolchain_lock.py +137 -0
  32. boost_skill_cli-1.0.207/docs/roadmap/items/hash-pinned-reproducible-toolchain-uv-lock.md +0 -20
  33. boost_skill_cli-1.0.207/docs/roadmap/items/mcp-aware-skills.md +0 -25
  34. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/.gitattributes +0 -0
  35. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/.gitignore +0 -0
  36. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/.gitleaks.toml +0 -0
  37. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/.htmlvalidate.json +0 -0
  38. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/.lighthouserc.json +0 -0
  39. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/.lycheeignore +0 -0
  40. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/.markdownlint-cli2.jsonc +0 -0
  41. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/.pre-commit-config.yaml +0 -0
  42. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/.stylelintrc.json +0 -0
  43. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/.vale/styles/boost/Terminology.yml +0 -0
  44. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/.vale.ini +0 -0
  45. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/CLAUDE.md +0 -0
  46. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/LICENSE +0 -0
  47. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/MANIFEST.in +0 -0
  48. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/README.md +0 -0
  49. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/SECURITY.md +0 -0
  50. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost +0 -0
  51. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/__init__.py +0 -0
  52. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/__main__.py +0 -0
  53. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/cli.py +0 -0
  54. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/cliparse.py +0 -0
  55. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/commands/__init__.py +0 -0
  56. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/commands/_common.py +0 -0
  57. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/commands/bmad.py +0 -0
  58. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/commands/configuration.py +0 -0
  59. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/commands/discovery.py +0 -0
  60. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/commands/hooks.py +0 -0
  61. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/commands/intelligence.py +0 -0
  62. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/commands/quality.py +0 -0
  63. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/commands/run.py +0 -0
  64. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/commands/safety.py +0 -0
  65. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/commands/taps.py +0 -0
  66. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/commands/team.py +0 -0
  67. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/core/__init__.py +0 -0
  68. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/core/adapters.py +0 -0
  69. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/core/agents.py +0 -0
  70. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/core/ai.py +0 -0
  71. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/core/capabilities.py +0 -0
  72. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/core/catalog.py +0 -0
  73. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/core/claude_settings.py +0 -0
  74. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/core/config.py +0 -0
  75. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/core/dense.py +0 -0
  76. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/core/ed25519.py +0 -0
  77. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/core/embed.py +0 -0
  78. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/core/faithfulness.py +0 -0
  79. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/core/frontmatter.py +0 -0
  80. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/core/gitutil.py +0 -0
  81. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/core/imperative.py +0 -0
  82. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/core/injectscan.py +0 -0
  83. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/core/integrity.py +0 -0
  84. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/core/journal.py +0 -0
  85. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/core/lockfile.py +0 -0
  86. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/core/logs.py +0 -0
  87. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/core/mcp.py +0 -0
  88. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/core/minisign.py +0 -0
  89. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/core/nethttp.py +0 -0
  90. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/core/output.py +0 -0
  91. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/core/paths.py +0 -0
  92. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/core/policy.py +0 -0
  93. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/core/projectlock.py +0 -0
  94. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/core/provenance.py +0 -0
  95. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/core/rag.py +0 -0
  96. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/core/registry.py +0 -0
  97. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/core/resolve.py +0 -0
  98. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/core/rules.py +0 -0
  99. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/core/scopes.py +0 -0
  100. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/core/secretscan.py +0 -0
  101. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/core/serve.py +0 -0
  102. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/core/stackprobe.py +0 -0
  103. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/core/staleness.py +0 -0
  104. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/core/trustaudit.py +0 -0
  105. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/core/typosquat.py +0 -0
  106. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/core/updatediff.py +0 -0
  107. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/core/util.py +0 -0
  108. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/core/workflows.py +0 -0
  109. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/data/registries.json +0 -0
  110. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/errors.py +0 -0
  111. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_cli/spin.py +0 -0
  112. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_skill_cli.egg-info/dependency_links.txt +0 -0
  113. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_skill_cli.egg-info/entry_points.txt +0 -0
  114. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_skill_cli.egg-info/requires.txt +0 -0
  115. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/boost_skill_cli.egg-info/top_level.txt +0 -0
  116. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/.claude/settings.local.json +0 -0
  117. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/DEBUGGING.md +0 -0
  118. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/adapters.html +0 -0
  119. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/demo.gif +0 -0
  120. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/demo.tape +0 -0
  121. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/design-roadmap.html +0 -0
  122. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/eval.html +0 -0
  123. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/index.html +0 -0
  124. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/mcp-hub.html +0 -0
  125. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/rag-architecture.md +0 -0
  126. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/BOOST-D01.md +0 -0
  127. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/BOOST-D02.md +0 -0
  128. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/BOOST-D03.md +0 -0
  129. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/BOOST-D04.md +0 -0
  130. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/BOOST-D05.md +0 -0
  131. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/BOOST-D06.md +0 -0
  132. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/BOOST-D07.md +0 -0
  133. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/BOOST-D08.md +0 -0
  134. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/BOOST-D09.md +0 -0
  135. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/BOOST-D10.md +0 -0
  136. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/BOOST-D11.md +0 -0
  137. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/BOOST-D12.md +0 -0
  138. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/BOOST-D13.md +0 -0
  139. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/BOOST-D14.md +0 -0
  140. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/BOOST-D15.md +0 -0
  141. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/BOOST-D16.md +0 -0
  142. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/BOOST-D17.md +0 -0
  143. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/BOOST-D18.md +0 -0
  144. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/BOOST-D19.md +0 -0
  145. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/BOOST-D20.md +0 -0
  146. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/BOOST-D21.md +0 -0
  147. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/BOOST-D22.md +0 -0
  148. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/BOOST-D23.md +0 -0
  149. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/BOOST-D24.md +0 -0
  150. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/BOOST-D25.md +0 -0
  151. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/BOOST-D26.md +0 -0
  152. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/accessibility-audit-pa11y-ci-axe-core.md +0 -0
  153. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/atomic-corruption-safe-lock-file-writes.md +0 -0
  154. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/atomic-skill-install-temp-dir-swap.md +0 -0
  155. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/autonomous-ship-workflow-and-isolated-worktree.md +0 -0
  156. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/boost-run-live-agents.md +0 -0
  157. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/bring-commands-under-mutation-testing.md +0 -0
  158. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/broken-link-and-anchor-checking-lychee.md +0 -0
  159. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/browse-crashes-selecting-a-rule-or-workflow.md +0 -0
  160. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/build-provenance-slsa-attestations.md +0 -0
  161. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/cache-the-catalog-entry-set-across-rag-queries.md +0 -0
  162. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/capability-manifest-and-least-privilege-policy.md +0 -0
  163. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/clean-env-install-smoke-pip-and-pipx.md +0 -0
  164. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/command-reference-docs-site.md +0 -0
  165. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/complexity-and-dead-code-radar-xenon-vulture.md +0 -0
  166. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/consolidate-skill-staleness-drift-logic-into-cor.md +0 -0
  167. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/coverage-dashboard-codecov-free-for-oss.md +0 -0
  168. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/coverage-guided-fuzzing-atheris-oss-fuzz.md +0 -0
  169. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/crash-recorder-error-paths-core-logs-py.md +0 -0
  170. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/dependency-cve-gate-pip-audit.md +0 -0
  171. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/docsite-chrome-and-content-audit.md +0 -0
  172. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/docstring-coverage-interrogate.md +0 -0
  173. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/doctor-checks-rules-and-workflows.md +0 -0
  174. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/end-of-options-guard-on-git-commands.md +0 -0
  175. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/extension-free-tests-core-dense-py.md +0 -0
  176. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/extract-mcp-http-servers-out-of-configuration-py.md +0 -0
  177. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/finish-mutation-hardening-across-core.md +0 -0
  178. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/fix-self-update-version-detection-dead-branch.md +0 -0
  179. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/fork-safe-network-proxy-handler.md +0 -0
  180. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/framework-adapter-langgraph.md +0 -0
  181. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/framework-adapter-multi-agent.md +0 -0
  182. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/framework-adapters-boost-adapt.md +0 -0
  183. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/frontmatter-scalar-over-coercion.md +0 -0
  184. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/github-pages-deploy-is-broken-every-push.md +0 -0
  185. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/golden-set-statistical-power.md +0 -0
  186. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/html-validation-html-validate.md +0 -0
  187. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/install-resolves-skill-dependencies.md +0 -0
  188. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/install-scope-user-or-project.md +0 -0
  189. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/installed-skill-trust-audit.md +0 -0
  190. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/integrity-verification-boost-verify.md +0 -0
  191. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/invocation-pid-logging-for-crash-correlation.md +0 -0
  192. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/layering-guard-import-linter.md +0 -0
  193. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/lighthouse-ci-on-the-pages-site.md +0 -0
  194. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/list-rules-and-workflows.md +0 -0
  195. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/localize-the-stored-bm25-snippet.md +0 -0
  196. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/lockfile-enforcement-and-commit-pinning.md +0 -0
  197. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/log-timestamps-mislabeled-utc.md +0 -0
  198. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/lowest-version-resolution-uv-resolution-lowest-d.md +0 -0
  199. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/make-the-roadmaps-discoverable.md +0 -0
  200. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/markdown-consistency-markdownlint-cli2.md +0 -0
  201. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/mcp-hub-diagram-node-text-overflow.md +0 -0
  202. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/mcp-launch-objc-fork-safety.md +0 -0
  203. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/mcp-register-names-server-before-env.md +0 -0
  204. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/mcp-search-before-reinventing.md +0 -0
  205. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/mcp-startup-self-harden-fork-safety.md +0 -0
  206. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/memoize-config-load-in-process.md +0 -0
  207. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/modernization-smells-refurb-pyupgrade.md +0 -0
  208. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/mutation-hardening-core-frontmatter-py.md +0 -0
  209. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/mutation-hardening-core-gitutil-py.md +0 -0
  210. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/mutation-hardening-core-store-py.md +0 -0
  211. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/one-command-every-env-nox.md +0 -0
  212. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/one-shared-atomic-write-helper.md +0 -0
  213. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/package-metadata-validation-twine-check-friends.md +0 -0
  214. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/patch-coverage-gate-diff-cover.md +0 -0
  215. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/performance-regression-gate-pytest-benchmark.md +0 -0
  216. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/pin-the-lint-toolchain.md +0 -0
  217. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/post-deploy-smoke-headless-load-check.md +0 -0
  218. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/pre-release-python-canary-3-14t-free-threaded.md +0 -0
  219. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/project-scope-across-every-command.md +0 -0
  220. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/project-scope-symlink-escape-on-write.md +0 -0
  221. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/promote-nav-footer-into-the-shared-style-system.md +0 -0
  222. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/prompt-injection-scanning-of-skill-markdown.md +0 -0
  223. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/property-based-tests-hypothesis-on-the-parsers.md +0 -0
  224. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/prose-and-terminology-linting-vale.md +0 -0
  225. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/prune-ignored-dirs-during-scan-dir-walk.md +0 -0
  226. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/quality-dashboard-sonarcloud-free-for-oss.md +0 -0
  227. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/ranx-significance-monitor.md +0 -0
  228. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/reconcile-the-theme-drift.md +0 -0
  229. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/refresh-the-marketing-surface.md +0 -0
  230. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/retrieval-quality-eval-harness.md +0 -0
  231. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/reuse-helpers-kill-minor-dead-work.md +0 -0
  232. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/robust-tag-argument-parsing.md +0 -0
  233. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/rule-install-native-materialization.md +0 -0
  234. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/runner-egress-monitoring-stepsecurity-harden-run.md +0 -0
  235. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/runtime-explain-faithfulness-guardrail.md +0 -0
  236. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/sbom-aware-scanning-osv-scanner.md +0 -0
  237. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/sbom-on-every-release-cyclonedx-syft.md +0 -0
  238. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/scan-and-sync-rules-and-workflows.md +0 -0
  239. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/second-type-checker-pyright.md +0 -0
  240. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/secret-and-pii-scanning-of-installed-skills.md +0 -0
  241. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/secret-scanning-gitleaks-push-protection.md +0 -0
  242. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/security-linting-bandit-via-ruff-s-rules.md +0 -0
  243. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/shift-left-gate-pre-commit-pre-commit-ci.md +0 -0
  244. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/single-imperative-rule-extractor.md +0 -0
  245. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/single-tech-stack-prober.md +0 -0
  246. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/split-oversized-command-modules.md +0 -0
  247. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/startup-and-import-time-budget-x-importtime.md +0 -0
  248. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/stop-re-serializing-entry-meta-on-every-search.md +0 -0
  249. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/supply-chain-posture-openssf-scorecard.md +0 -0
  250. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/surface-every-docs-page-from-the-guide.md +0 -0
  251. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/tap-signing-and-provenance-sigstore-minisign.md +0 -0
  252. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/theme-asset-linting-stylelint-eslint.md +0 -0
  253. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/typo-detection-codespell.md +0 -0
  254. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/typosquat-and-name-confusion-detection.md +0 -0
  255. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/unify-tilde-two-copies-have-a-boundary-bug.md +0 -0
  256. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/untrack-generated-build-noise.md +0 -0
  257. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/update-diff-before-apply.md +0 -0
  258. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/update-refreshes-rules-and-workflows.md +0 -0
  259. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/visual-regression-pass-on-the-guide.md +0 -0
  260. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/widen-the-ruff-rule-surface-b-sim-c4-perf-ruf.md +0 -0
  261. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/windows-in-the-ci-matrix.md +0 -0
  262. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/workflow-install-native-materialization.md +0 -0
  263. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/workflow-linting-actionlint.md +0 -0
  264. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/workflow-sast-zizmor.md +0 -0
  265. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/docs/roadmap/items/workspace-scope-install.md +0 -0
  266. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/eslint.config.mjs +0 -0
  267. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/examples/README.md +0 -0
  268. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/examples/adapt-demo.sh +0 -0
  269. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/examples/boost-run-prototype.sh +0 -0
  270. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/index.html +0 -0
  271. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/pyproject.toml +0 -0
  272. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/scripts/bench_cli.sh +0 -0
  273. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/scripts/build_command_reference.py +0 -0
  274. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/scripts/build_registries.py +0 -0
  275. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/scripts/build_roadmap.py +0 -0
  276. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/scripts/check_anchors.py +0 -0
  277. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/scripts/ensure_eval_corpus.sh +0 -0
  278. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/scripts/eval_explain.py +0 -0
  279. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/scripts/eval_recommend.py +0 -0
  280. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/scripts/eval_retrieval.py +0 -0
  281. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/scripts/eval_stats_summary.py +0 -0
  282. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/scripts/import_budget.py +0 -0
  283. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/scripts/mutation_gate.py +0 -0
  284. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/scripts/perf_gate.py +0 -0
  285. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/style/README.md +0 -0
  286. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/style/boost.css +0 -0
  287. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/style/boost.js +0 -0
  288. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/style/demo.html +0 -0
  289. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/bdd/features/adapt.feature +0 -0
  290. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/bdd/features/browse.feature +0 -0
  291. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/bdd/features/count.feature +0 -0
  292. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/bdd/features/discover.feature +0 -0
  293. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/bdd/features/doctor.feature +0 -0
  294. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/bdd/features/environment.py +0 -0
  295. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/bdd/features/explain.feature +0 -0
  296. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/bdd/features/index.feature +0 -0
  297. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/bdd/features/install.feature +0 -0
  298. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/bdd/features/list.feature +0 -0
  299. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/bdd/features/mcp.feature +0 -0
  300. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/bdd/features/search.feature +0 -0
  301. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/bdd/features/steps/cli_steps.py +0 -0
  302. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/bdd/features/steps/discovery_steps.py +0 -0
  303. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/bdd/features/steps/mcp_steps.py +0 -0
  304. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/bdd/features/steps/quality_steps.py +0 -0
  305. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/conftest.py +0 -0
  306. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/eval/baseline.json +0 -0
  307. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/eval/explain.jsonl +0 -0
  308. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/eval/golden.jsonl +0 -0
  309. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/eval/recommend.jsonl +0 -0
  310. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/eval/taps.txt +0 -0
  311. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/functional/test_capabilities_policy.py +0 -0
  312. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/functional/test_cli_adapt.py +0 -0
  313. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/functional/test_cli_bmad.py +0 -0
  314. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/functional/test_cli_configuration.py +0 -0
  315. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/functional/test_cli_discovery.py +0 -0
  316. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/functional/test_cli_hooks.py +0 -0
  317. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/functional/test_cli_info.py +0 -0
  318. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/functional/test_cli_intelligence.py +0 -0
  319. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/functional/test_cli_quality.py +0 -0
  320. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/functional/test_cli_taps.py +0 -0
  321. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/functional/test_cli_team.py +0 -0
  322. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/functional/test_everyday_loop.py +0 -0
  323. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/functional/test_integrity_enforce.py +0 -0
  324. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/functional/test_property_parsers.py +0 -0
  325. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/functional/test_run.py +0 -0
  326. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/functional/test_tap_signing.py +0 -0
  327. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/functional/test_workspace_scope.py +0 -0
  328. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/make_fixture.py +0 -0
  329. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/perf/test_benchmarks.py +0 -0
  330. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/smoke.sh +0 -0
  331. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_adapters.py +0 -0
  332. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_adapters_multi.py +0 -0
  333. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_adapters_runner.py +0 -0
  334. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_agents.py +0 -0
  335. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_ai.py +0 -0
  336. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_capabilities.py +0 -0
  337. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_catalog.py +0 -0
  338. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_check_anchors.py +0 -0
  339. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_claude_settings.py +0 -0
  340. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_cliparse.py +0 -0
  341. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_command_reference_fresh.py +0 -0
  342. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_config.py +0 -0
  343. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_dense.py +0 -0
  344. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_dense_fallback.py +0 -0
  345. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_docs_pages_linked.py +0 -0
  346. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_docsite_chrome.py +0 -0
  347. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_ed25519.py +0 -0
  348. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_embed.py +0 -0
  349. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_errors_and_cli_table.py +0 -0
  350. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_eval_stats_summary.py +0 -0
  351. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_faithfulness.py +0 -0
  352. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_frontmatter.py +0 -0
  353. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_gitleaks_config.py +0 -0
  354. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_gitutil.py +0 -0
  355. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_imperative.py +0 -0
  356. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_import_budget.py +0 -0
  357. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_injectscan.py +0 -0
  358. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_integrity.py +0 -0
  359. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_journal.py +0 -0
  360. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_lockfile.py +0 -0
  361. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_logs.py +0 -0
  362. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_mcp.py +0 -0
  363. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_minisign.py +0 -0
  364. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_mutation_hardening.py +0 -0
  365. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_nethttp.py +0 -0
  366. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_output.py +0 -0
  367. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_paths.py +0 -0
  368. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_perf_gate.py +0 -0
  369. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_pkg_confusions.py +0 -0
  370. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_pkg_injection.py +0 -0
  371. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_pkg_secrets.py +0 -0
  372. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_policy.py +0 -0
  373. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_projectlock.py +0 -0
  374. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_provenance.py +0 -0
  375. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_rag.py +0 -0
  376. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_registries_fresh.py +0 -0
  377. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_registry.py +0 -0
  378. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_resolve.py +0 -0
  379. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_roadmap_fresh.py +0 -0
  380. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_rules.py +0 -0
  381. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_scopes.py +0 -0
  382. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_secretscan.py +0 -0
  383. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_serve.py +0 -0
  384. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_spin.py +0 -0
  385. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_stackprobe.py +0 -0
  386. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_staleness.py +0 -0
  387. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_store.py +0 -0
  388. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_token_parity.py +0 -0
  389. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_trustaudit.py +0 -0
  390. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_typosquat.py +0 -0
  391. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_updatediff.py +0 -0
  392. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_util.py +0 -0
  393. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_version.py +0 -0
  394. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/unit/test_workflows.py +0 -0
  395. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/visual/package.json +0 -0
  396. {boost_skill_cli-1.0.207 → boost_skill_cli-1.0.208}/tests/visual/visual_check.mjs +0 -0
@@ -56,6 +56,7 @@ tempdir
56
56
  toggleable
57
57
  Tokenization
58
58
  tokenization
59
+ toolchain
59
60
  toolkits
60
61
  traceback
61
62
  tracebacks
@@ -7,12 +7,31 @@ so contributing is mostly about keeping the quality gates green.
7
7
 
8
8
  ```bash
9
9
  git clone https://github.com/jonnyeclectic/boost && cd boost
10
- make venv # pytest, coverage, mutmut, ruff, mypy — runtime stays stdlib-only
10
+ make venv # every gate tool, hash-pinned — runtime stays stdlib-only
11
11
  ```
12
12
 
13
13
  Every test runs against a throwaway `$HOME`, so nothing touches your real
14
14
  agent configs.
15
15
 
16
+ ### The toolchain is hash-pinned
17
+
18
+ `make venv` and every CI job install from the generated
19
+ [`requirements/*.txt`](requirements/), which pin an exact version **and every
20
+ artifact's sha256** for the full transitive closure — pip enforces those hashes,
21
+ so a yanked or tampered dependency fails the install instead of silently
22
+ changing a build. Your venv and the CI runner get identical bytes.
23
+
24
+ To change a tool, edit the `.in` file and regenerate:
25
+
26
+ ```bash
27
+ python3 scripts/lock_toolchain.py # rewrite the .txt files
28
+ python3 scripts/lock_toolchain.py --upgrade # re-resolve to newest allowed
29
+ python3 scripts/lock_toolchain.py --check # what `make lint` runs
30
+ ```
31
+
32
+ Commit both the `.in` and the regenerated `.txt`; a stale lock fails `make lint`.
33
+ Regenerating needs `uv` (installed by `make venv`); *installing* never does.
34
+
16
35
  ### Reproduce the whole gate — `nox`
17
36
 
18
37
  [`noxfile.py`](noxfile.py) runs the exact gate the CI jobs run, in isolated
@@ -58,6 +77,8 @@ auto-fixes straight back onto the branch.
58
77
  | `lint-imports` | layering: `core/` imports no `commands/`/`cli`; CLI depends inward |
59
78
  | `vulture` | dead-code radar: no unused imports / unreachable code (confidence ≥80) |
60
79
  | `xenon` | complexity ratchet: aggregate cyclomatic complexity can't regress (avg ≤B) |
80
+ | `refurb boost_cli` | modernization smells the ruff families miss, zero findings |
81
+ | `scripts/lock_toolchain.py --check` | the hash-pinned toolchain matches its `.in` declarations |
61
82
 
62
83
  ## Ground rules
63
84
 
@@ -12,10 +12,18 @@ EVAL_HOME := $(CURDIR)/.eval-home
12
12
 
13
13
  .PHONY: venv test unit functional smoke coverage patch-coverage mutation lint check demo clean-test eval eval-ai eval-rec eval-stats eval-explain audit dist-check bdd bench bench-cli
14
14
 
15
+ # Every tool comes from a hash-pinned requirements/*.txt — the same files CI
16
+ # installs (see scripts/lock_toolchain.py). pip enforces the hashes, so a dev
17
+ # venv and a CI runner resolve to identical bytes. mutation-tools.txt is a
18
+ # superset of test-tools.txt, so installing it alone covers both; the two are
19
+ # never layered because pip enforces hashes across the whole resolution.
15
20
  venv:
16
21
  python3 -m venv $(VENV)
17
- $(VENV)/bin/pip -q install pytest pytest-cov coverage mutmut hypothesis diff-cover
18
- $(VENV)/bin/pip -q install -r requirements/lint-tools.txt # pinned; CI installs the same set
22
+ $(VENV)/bin/pip -q install -r requirements/mutation-tools.txt
23
+ $(VENV)/bin/pip -q install -r requirements/coverage-tools.txt
24
+ $(VENV)/bin/pip -q install -r requirements/lint-tools.txt
25
+ $(VENV)/bin/pip -q install -r requirements/release-tools.txt
26
+ $(VENV)/bin/pip -q install uv # regenerates the locks; not itself locked
19
27
 
20
28
  unit:
21
29
  $(PYTEST) tests/unit -q
@@ -57,6 +65,7 @@ lint:
57
65
  $(PY) scripts/build_registries.py --check
58
66
  $(PY) scripts/build_roadmap.py --check
59
67
  $(PY) scripts/build_command_reference.py --check
68
+ $(PY) scripts/lock_toolchain.py --check
60
69
  $(PY) scripts/import_budget.py
61
70
  $(PY) scripts/perf_gate.py
62
71
  $(PY) scripts/check_anchors.py
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: boost-skill-cli
3
- Version: 1.0.207
3
+ Version: 1.0.208
4
4
  Summary: boost — Homebrew for AI coding skills
5
5
  Author: Jonathan Reyes
6
6
  License: GNU GENERAL PUBLIC LICENSE
@@ -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.207'
22
- __version_tuple__ = version_tuple = (1, 0, 207)
21
+ __version__ = version = '1.0.208'
22
+ __version_tuple__ = version_tuple = (1, 0, 208)
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -239,6 +239,7 @@ def cmd_info(argv):
239
239
  declared_caps = sorted(capabilities.declared(meta))
240
240
  detected_extra = sorted(capabilities.detect(skill_text)
241
241
  - set(declared_caps)) if skill_text else []
242
+ mcp_servers = store.declared_mcp_servers(skill_dir) if skill_dir else []
242
243
  score = size = files = None
243
244
  if skill_dir:
244
245
  score, _notes = util.score_skill(skill_dir)
@@ -249,6 +250,7 @@ def cmd_info(argv):
249
250
  "name": name, "description": desc,
250
251
  "installed": lock, "project": plock,
251
252
  "capabilities": declared_caps, "detected_capabilities": detected_extra,
253
+ "mcp_servers": [r["name"] for r in mcp_servers],
252
254
  "latest": (cat or {}).get("version"),
253
255
  "tap": (lock or plock or cat or {}).get("tap"),
254
256
  "store": str(sdir) if lock and sdir.is_dir() else None,
@@ -322,6 +324,10 @@ def cmd_info(argv):
322
324
  # under-declaration signal a reviewer wants to see.
323
325
  out.kv("detected", out.role(", ".join(detected_extra) + " (not declared)",
324
326
  "warn"))
327
+ if mcp_servers:
328
+ # A skill that needs an MCP server is useless without it, so this belongs
329
+ # next to capabilities: both answer "what does this expect of my setup?"
330
+ out.kv("mcp servers", ", ".join(r["name"] for r in mcp_servers))
325
331
  if score is not None:
326
332
  out.kv("quality", "%d/100" % score)
327
333
  out.kv("size", util.human_size(size))
@@ -109,6 +109,67 @@ def _warn_secrets(res: store.InstallResult) -> None:
109
109
  out.warn(" L%d [%s] %s" % (f.line, f.severity, f.description))
110
110
 
111
111
 
112
+ def _offer_mcp(res: store.InstallResult) -> None:
113
+ """Surface the MCP servers a just-installed skill needs, and offer to wire them.
114
+
115
+ A skill that only works paired with an MCP server used to install "cleanly"
116
+ and then fail in the agent for a reason nothing surfaced. Now the requirement
117
+ is stated at install time, and boost offers to run the registration for the
118
+ servers that came with a runnable spec.
119
+
120
+ Advisory, never fatal: a declined prompt, a missing ``claude`` CLI or a failed
121
+ registration all leave the skill installed. Suppressed entirely by
122
+ ``--no-mcp``, which sets ``BOOST_NO_MCP_OFFER``.
123
+ """
124
+ rows = res.mcp_servers
125
+ if not rows or os.environ.get("BOOST_NO_MCP_OFFER"):
126
+ return
127
+ from ..core import mcpdecl
128
+ out.info("")
129
+ out.warn("%s needs %s to work:" % (res.name, _plural(len(rows), "MCP server")))
130
+ for row in rows:
131
+ how = ("`%s`" % row["spec"]["command"] if row["spec"]
132
+ and row["spec"].get("command") else "no command declared")
133
+ out.info(" %s %s" % (out.c(row["name"], out.BOLD),
134
+ out.role(how, "muted")))
135
+ wirable = mcpdecl.registrable(rows)
136
+ if not wirable:
137
+ # Name-only declarations: boost will not invent a command line.
138
+ out.dim(" install these yourself, then `boost mcp register`")
139
+ return
140
+ if not out.confirm("register %s with Claude Code now?"
141
+ % _plural(len(wirable), "server"), default=False):
142
+ out.dim(" skipped — `claude mcp add …` when you're ready")
143
+ return
144
+ for row in wirable:
145
+ _register_mcp_server(row["name"], row["spec"])
146
+
147
+
148
+ def _register_mcp_server(name: str, spec: dict) -> None:
149
+ """Run one `claude mcp add` for a skill-declared server. Never raises."""
150
+ import subprocess
151
+ from ..core import mcpdecl
152
+ argv = mcpdecl.register_argv(name, spec)
153
+ if not shutil.which("claude"):
154
+ out.warn("`claude` CLI not found — run this yourself:")
155
+ out.info(" " + " ".join(argv))
156
+ return
157
+ try:
158
+ proc = subprocess.run(argv, capture_output=True, text=True, timeout=60)
159
+ except (OSError, subprocess.TimeoutExpired) as e:
160
+ out.warn("could not register %s: %s" % (name, e))
161
+ out.info(" run it yourself: " + " ".join(argv))
162
+ return
163
+ if proc.returncode != 0:
164
+ tail = (proc.stderr or "").strip().splitlines()
165
+ out.warn("could not register %s: %s"
166
+ % (name, tail[-1] if tail else "unknown error"))
167
+ out.info(" run it yourself: " + " ".join(argv))
168
+ return
169
+ out.ok("registered MCP server %s" % name)
170
+ journal.log("mcp-register", name)
171
+
172
+
112
173
  def _report_result(res: store.InstallResult) -> None:
113
174
  """The canonical three-line install report."""
114
175
  if res.kind in ("rule", "workflow"):
@@ -141,6 +202,7 @@ def _report_result(res: store.InstallResult) -> None:
141
202
  out.ok("lock updated (.skill-lock.json)")
142
203
  _warn_injection(res)
143
204
  _warn_secrets(res)
205
+ _offer_mcp(res)
144
206
 
145
207
 
146
208
  def _boostfile_text(skills: Dict[str, dict], via: str = "boost bundle dump") -> str:
@@ -238,8 +300,15 @@ def cmd_install(argv: List[str]) -> int:
238
300
  help="show what would happen without changing anything")
239
301
  ap.add_argument("--no-deps", action="store_true",
240
302
  help="install only the named skills, not their `requires:`")
303
+ ap.add_argument("--no-mcp", action="store_true",
304
+ help="don't offer to register MCP servers a skill declares")
241
305
  args = ap.parse_args(argv)
242
306
  args.scope = args.scope or scopes.SCOPE_USER
307
+ if args.no_mcp:
308
+ # An env flag rather than threading a parameter through _report_result's
309
+ # eight call sites: the offer is a leaf-level side effect, and this keeps
310
+ # every other install path (update, reinstall, team, MCP tool) unchanged.
311
+ os.environ["BOOST_NO_MCP_OFFER"] = "1"
243
312
  only = _check_agents(args.agent)
244
313
  multi = len(args.names) > 1
245
314
  entries, failed = [], 0
@@ -0,0 +1,193 @@
1
+ """What MCP servers does a skill need, and how do we wire them?
2
+
3
+ Mining boost's catalog surfaces a recurring shape: skills that only work paired
4
+ with a Model Context Protocol server (``manage-mcp-servers``, ``mcp-builder``,
5
+ ``mcp-integration`` and dozens more). boost already *is* an MCP server and
6
+ registers itself with ``boost mcp register`` — but a skill had no way to say
7
+ "I need server Y," so installing one left the user to discover that by hand.
8
+
9
+ Two declaration forms, both deliberately **flat**:
10
+
11
+ * ``mcp: github, playwright`` in SKILL.md frontmatter (a comma string or a YAML
12
+ block list) — just the names, reusing the exact contract ``requires:`` and
13
+ ``conflicts:`` already use.
14
+ * a bundled ``.mcp.json`` in the skill directory — the standard MCP shape
15
+ (``{"mcpServers": {name: {command, args, env}}}``), carrying full specs.
16
+
17
+ Why flat, and not the nested ``mcp:`` mapping the roadmap card sketched:
18
+ :mod:`boost_cli.core.frontmatter` is a stdlib-only YAML *subset* with no nested
19
+ mapping support, and it does not fail loudly on one — it hoists the inner keys to
20
+ top level and clobbers their siblings. A nested block parses to
21
+ ``{'mcp': '', 'servers': [...], 'command': 'npx'}``, silently corrupting the
22
+ entry's metadata. Teaching the parser nested mappings would change the shape of
23
+ every catalog entry's ``meta`` (and every consumer of it), so the declaration
24
+ meets the parser where it already works and the full specs live in the standard
25
+ sidecar file that needs no parser at all.
26
+
27
+ Everything here is pure and I/O-free, like :mod:`boost_cli.core.resolve` and
28
+ :mod:`boost_cli.core.staleness`: callers read the files and pass text in, so
29
+ every branch of the *decision* is unit-testable and reachable by the mutation
30
+ gate.
31
+ """
32
+ from __future__ import annotations
33
+
34
+ import json
35
+ from typing import Dict, List, Optional, Tuple
36
+
37
+ # The frontmatter key a skill uses to name the servers it needs.
38
+ DECL_KEY = "mcp"
39
+
40
+ # The sidecar file a skill bundles to carry full server specs. Standard MCP
41
+ # filename and shape, so an author can lift the file straight from a server's
42
+ # own README.
43
+ SIDECAR = ".mcp.json"
44
+
45
+ # Top-level key inside .mcp.json, per the MCP config convention.
46
+ SERVERS_KEY = "mcpServers"
47
+
48
+ # Ownership tag written alongside a server boost registered, mirroring
49
+ # claude_settings.MARKER. Without it an uninstall could not tell a
50
+ # boost-registered server from one the user configured by hand, so it would
51
+ # either strip the user's config or leak boost's.
52
+ MARKER_KEY = "x-boost-skill"
53
+
54
+
55
+ def declared_names(meta: Optional[dict]) -> List[str]:
56
+ """Server names a skill's frontmatter declares, de-duped, order preserved.
57
+
58
+ Accepts a YAML list or a comma-separated string and drops blanks — the same
59
+ contract ``requires:``/``conflicts:`` use, so an author who knows one knows
60
+ this one. A missing/empty/``False`` value means "declares nothing".
61
+ """
62
+ val = (meta or {}).get(DECL_KEY)
63
+ if val in (None, "", False):
64
+ return []
65
+ raw = ([str(x) for x in val] if isinstance(val, list)
66
+ else str(val).split(","))
67
+ out: List[str] = []
68
+ for item in raw:
69
+ name = item.strip()
70
+ if name and name not in out:
71
+ out.append(name)
72
+ return out
73
+
74
+
75
+ def parse_sidecar(text: Optional[str]) -> Dict[str, dict]:
76
+ """``{name: spec}`` from a bundled ``.mcp.json``'s text.
77
+
78
+ Tolerant by design: unreadable JSON, a non-object document, a missing or
79
+ non-object ``mcpServers`` key, and non-object individual specs all read as
80
+ "no specs". A malformed sidecar must never make an otherwise-fine install
81
+ fail — the skill still works, the user just does not get the wiring offer.
82
+ """
83
+ if not text:
84
+ return {}
85
+ try:
86
+ doc = json.loads(text)
87
+ except (ValueError, TypeError):
88
+ return {}
89
+ if not isinstance(doc, dict):
90
+ return {}
91
+ servers = doc.get(SERVERS_KEY)
92
+ if not isinstance(servers, dict):
93
+ return {}
94
+ return {str(k): v for k, v in servers.items()
95
+ if k and isinstance(v, dict)}
96
+
97
+
98
+ def servers_for(meta: Optional[dict], sidecar_text: Optional[str] = None,
99
+ ) -> List[dict]:
100
+ """Every MCP server a skill needs, as ``{"name", "spec", "source"}`` rows.
101
+
102
+ Merges the two declaration forms. A name in *both* uses the sidecar's spec —
103
+ the frontmatter only names a server, so a bundled spec is strictly more
104
+ information. ``spec`` is ``None`` for a name-only declaration, which the
105
+ caller renders as "you need this, here is no command to run it" rather than
106
+ offering a registration it cannot perform.
107
+
108
+ ``source`` is ``"sidecar"`` or ``"frontmatter"``, so output can tell the user
109
+ where a requirement came from when the two disagree. Rows are sorted by name
110
+ for deterministic output.
111
+ """
112
+ specs = parse_sidecar(sidecar_text)
113
+ rows: Dict[str, dict] = {
114
+ name: {"name": name, "spec": spec, "source": "sidecar"}
115
+ for name, spec in specs.items()}
116
+ for name in declared_names(meta):
117
+ if name not in rows:
118
+ rows[name] = {"name": name, "spec": None, "source": "frontmatter"}
119
+ return [rows[k] for k in sorted(rows)]
120
+
121
+
122
+ def registrable(rows) -> List[dict]:
123
+ """The rows boost can actually wire up — those carrying a runnable spec.
124
+
125
+ A spec is runnable when it names a ``command``. Anything else (a name-only
126
+ frontmatter declaration, or a sidecar entry describing a remote/URL server
127
+ boost has no launcher for) is reported to the user but never auto-registered:
128
+ boost will not invent a command line on an author's behalf.
129
+ """
130
+ return [r for r in rows
131
+ if isinstance(r.get("spec"), dict)
132
+ and str(r["spec"].get("command") or "").strip()]
133
+
134
+
135
+ def register_argv(name: str, spec: dict, *, scope: str = "user") -> List[str]:
136
+ """The ``claude mcp add`` argv that registers one declared server.
137
+
138
+ Mirrors ``cmd_mcp``'s invariant exactly: the server **name** precedes every
139
+ ``-e`` flag, and a bare ``--`` separates boost's flags from the server's own
140
+ command and arguments. Getting that order wrong makes the CLI read the
141
+ command as another flag value, which is why it is pinned by a test.
142
+ """
143
+ argv = ["claude", "mcp", "add", name, "--scope", scope]
144
+ env = spec.get("env")
145
+ if isinstance(env, dict):
146
+ for key in sorted(env):
147
+ argv += ["-e", "%s=%s" % (key, env[key])]
148
+ argv.extend(("--", str(spec["command"])))
149
+ args = spec.get("args")
150
+ if isinstance(args, list):
151
+ argv += [str(a) for a in args]
152
+ return argv
153
+
154
+
155
+ def merge_into(existing: Optional[dict], rows, skill: str) -> Tuple[dict, List[str]]:
156
+ """Add ``rows``' specs to an ``.mcp.json`` document -> ``(doc, added)``.
157
+
158
+ Returns a **new** document rather than mutating the caller's, and never
159
+ overwrites a server the user already configured: a name already present is
160
+ left exactly as-is and omitted from ``added``. Each entry boost does add
161
+ carries a :data:`MARKER_KEY` naming the skill that asked for it, so a later
162
+ uninstall can remove precisely what boost wrote and nothing else.
163
+ """
164
+ doc = dict(existing) if isinstance(existing, dict) else {}
165
+ servers = dict(doc.get(SERVERS_KEY) or {})
166
+ added: List[str] = []
167
+ for row in registrable(rows):
168
+ name = row["name"]
169
+ if name in servers:
170
+ continue
171
+ entry = dict(row["spec"])
172
+ entry[MARKER_KEY] = skill
173
+ servers[name] = entry
174
+ added.append(name)
175
+ doc[SERVERS_KEY] = servers
176
+ return doc, added
177
+
178
+
179
+ def strip_owned(existing: Optional[dict], skill: str) -> Tuple[dict, List[str]]:
180
+ """Remove the servers boost registered for ``skill`` -> ``(doc, removed)``.
181
+
182
+ Only entries whose :data:`MARKER_KEY` names this skill are removed, so a
183
+ server the user configured by hand — or one another skill still needs —
184
+ survives an uninstall untouched.
185
+ """
186
+ doc = dict(existing) if isinstance(existing, dict) else {}
187
+ servers = dict(doc.get(SERVERS_KEY) or {})
188
+ removed = [name for name, spec in servers.items()
189
+ if isinstance(spec, dict) and spec.get(MARKER_KEY) == skill]
190
+ for name in removed:
191
+ del servers[name]
192
+ doc[SERVERS_KEY] = servers
193
+ return doc, sorted(removed)
@@ -5,6 +5,7 @@ install(): copy skill dir from a tap clone -> store, symlink into every
5
5
  """
6
6
  from __future__ import annotations
7
7
 
8
+ import contextlib
8
9
  import os
9
10
  import re
10
11
  import shutil
@@ -33,6 +34,10 @@ class InstallResult:
33
34
  # CLAUDE.md block), not a SKILL.md tree — carry the raw source so the caller
34
35
  # scans exactly what it installed instead of a non-existent SKILL.md.
35
36
  scan_text: Optional[str] = None
37
+ # MCP servers the skill declares (mcpdecl.servers_for rows). Detected here
38
+ # but never acted on: core stays non-interactive, so the command layer owns
39
+ # the offer to register them — same split as `conflicts` and `score`.
40
+ mcp_servers: List[dict] = field(default_factory=list)
36
41
 
37
42
 
38
43
  def skill_store_dir(name: str) -> Path:
@@ -149,6 +154,28 @@ def _remove_backup(backup: Path) -> None:
149
154
  shutil.rmtree(backup, ignore_errors=True)
150
155
 
151
156
 
157
+ def declared_mcp_servers(skill_dir) -> List[dict]:
158
+ """MCP servers an installed skill declares — ``mcpdecl.servers_for`` rows.
159
+
160
+ Reads the installed copy's ``SKILL.md`` frontmatter and its bundled
161
+ ``.mcp.json`` sidecar, if either is present. Best-effort by design: an
162
+ unreadable file yields no rows rather than failing an install that has
163
+ otherwise already succeeded.
164
+ """
165
+ from . import frontmatter, mcpdecl
166
+ skill_dir = Path(skill_dir)
167
+ meta: dict = {}
168
+ with contextlib.suppress(OSError):
169
+ text = (skill_dir / "SKILL.md").read_text(encoding="utf-8",
170
+ errors="replace")
171
+ meta, _body = frontmatter.parse(text)
172
+ sidecar = None
173
+ with contextlib.suppress(OSError):
174
+ sidecar = (skill_dir / mcpdecl.SIDECAR).read_text(encoding="utf-8",
175
+ errors="replace")
176
+ return mcpdecl.servers_for(meta, sidecar)
177
+
178
+
152
179
  def _enforce_capability_policy(name: str, skill_md: Path) -> None:
153
180
  """Raise if the skill's declared/detected capabilities are denied by policy.
154
181
 
@@ -245,6 +272,7 @@ def install(entry: dict, force: bool = False,
245
272
  res = link_agents(name, only=only_agents)
246
273
  res.upgraded = existing is not None
247
274
  res.score, _ = util.score_skill(dest)
275
+ res.mcp_servers = declared_mcp_servers(dest)
248
276
 
249
277
  tap = registry.get(entry["tap"])
250
278
  from . import gitutil
@@ -696,6 +724,7 @@ def install_from_path(src_dir: Path, name: Optional[str] = None,
696
724
  _copy_skill(src_dir, dest)
697
725
  res = link_agents(name, only=only_agents)
698
726
  res.score, _ = util.score_skill(dest)
727
+ res.mcp_servers = declared_mcp_servers(dest)
699
728
  now = util.now_iso()
700
729
  existing = lockfile.get_skill(name)
701
730
  lockfile.set_skill(name, {
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: boost-skill-cli
3
- Version: 1.0.207
3
+ Version: 1.0.208
4
4
  Summary: boost — Homebrew for AI coding skills
5
5
  Author: Jonathan Reyes
6
6
  License: GNU GENERAL PUBLIC LICENSE
@@ -65,6 +65,7 @@ boost_cli/core/journal.py
65
65
  boost_cli/core/lockfile.py
66
66
  boost_cli/core/logs.py
67
67
  boost_cli/core/mcp.py
68
+ boost_cli/core/mcpdecl.py
68
69
  boost_cli/core/minisign.py
69
70
  boost_cli/core/nethttp.py
70
71
  boost_cli/core/output.py
@@ -251,7 +252,16 @@ docs/roadmap/items/workspace-scope-install.md
251
252
  examples/README.md
252
253
  examples/adapt-demo.sh
253
254
  examples/boost-run-prototype.sh
255
+ requirements/coverage-tools.in
256
+ requirements/coverage-tools.txt
257
+ requirements/lint-tools.in
254
258
  requirements/lint-tools.txt
259
+ requirements/mutation-tools.in
260
+ requirements/mutation-tools.txt
261
+ requirements/release-tools.in
262
+ requirements/release-tools.txt
263
+ requirements/test-tools.in
264
+ requirements/test-tools.txt
255
265
  scripts/bench_cli.sh
256
266
  scripts/build_command_reference.py
257
267
  scripts/build_registries.py
@@ -263,6 +273,7 @@ scripts/eval_recommend.py
263
273
  scripts/eval_retrieval.py
264
274
  scripts/eval_stats_summary.py
265
275
  scripts/import_budget.py
276
+ scripts/lock_toolchain.py
266
277
  scripts/mutation_gate.py
267
278
  scripts/perf_gate.py
268
279
  style/README.md
@@ -344,6 +355,7 @@ tests/unit/test_journal.py
344
355
  tests/unit/test_lockfile.py
345
356
  tests/unit/test_logs.py
346
357
  tests/unit/test_mcp.py
358
+ tests/unit/test_mcpdecl.py
347
359
  tests/unit/test_minisign.py
348
360
  tests/unit/test_mutation_hardening.py
349
361
  tests/unit/test_nethttp.py
@@ -370,6 +382,7 @@ tests/unit/test_stackprobe.py
370
382
  tests/unit/test_staleness.py
371
383
  tests/unit/test_store.py
372
384
  tests/unit/test_token_parity.py
385
+ tests/unit/test_toolchain_lock.py
373
386
  tests/unit/test_trustaudit.py
374
387
  tests/unit/test_typosquat.py
375
388
  tests/unit/test_updatediff.py
@@ -99,7 +99,7 @@
99
99
  <input id="q" type="search" placeholder="Filter 78 commands…" autocomplete="off" aria-label="Filter commands">
100
100
  <div class="group" data-group="pkg">
101
101
  <div class="group-h">Install &amp; lifecycle</div>
102
- <a class="cmd-link" href="#cmd-install" data-search="install install a skill from a tap registry --force --agent a --scope {user,project} --local --global --dry-run --no-deps name">install</a>
102
+ <a class="cmd-link" href="#cmd-install" data-search="install install a skill from a tap registry --force --agent a --scope {user,project} --local --global --dry-run --no-deps --no-mcp name">install</a>
103
103
  <a class="cmd-link" href="#cmd-uninstall" data-search="uninstall remove an installed skill, rule, workflow, or config --local name">uninstall</a>
104
104
  <a class="cmd-link" href="#cmd-sync" data-search="sync reconcile installed skills &amp; symlinks against the lock file --diff --prune --json">sync</a>
105
105
  <a class="cmd-link" href="#cmd-update" data-search="update sync taps or update installed skills --taps-only tap">update</a>
@@ -206,10 +206,10 @@
206
206
  <p class="lead">All <b>78</b> commands, generated from the CLI itself —
207
207
  run <code>boost &lt;command&gt; --help</code> for the same in your terminal.</p>
208
208
  <h2 class="group-h" id="grp-pkg">Install &amp; lifecycle</h2>
209
- <section class="cmd" id="cmd-install" data-search="install install a skill from a tap registry --force --agent a --scope {user,project} --local --global --dry-run --no-deps name">
209
+ <section class="cmd" id="cmd-install" data-search="install install a skill from a tap registry --force --agent a --scope {user,project} --local --global --dry-run --no-deps --no-mcp name">
210
210
  <h3><span class="cname">install</span><span class="gtag">pkg</span></h3>
211
211
  <p class="summary">Install a skill from a tap registry</p>
212
- <pre class="syn">boost install [--force] [--agent A] [--scope {user,project}] [--local] [--global] [--dry-run] [--no-deps] NAME [NAME ...]</pre>
212
+ <pre class="syn">boost install [--force] [--agent A] [--scope {user,project}] [--local] [--global] [--dry-run] [--no-deps] [--no-mcp] NAME [NAME ...]</pre>
213
213
  <div class="args-h">Arguments</div>
214
214
  <div class="args">
215
215
  <div class="arg"><code>NAME</code><span>skill name, optionally qualified as tap:skill</span></div>
@@ -223,6 +223,7 @@
223
223
  <div class="arg"><code>--global</code><span>into your user config (= --scope user, default)</span></div>
224
224
  <div class="arg"><code>--dry-run</code><span>show what would happen without changing anything</span></div>
225
225
  <div class="arg"><code>--no-deps</code><span>install only the named skills, not their `requires:`</span></div>
226
+ <div class="arg"><code>--no-mcp</code><span>don&#x27;t offer to register MCP servers a skill declares</span></div>
226
227
  </div>
227
228
  </section>
228
229
  <section class="cmd" id="cmd-uninstall" data-search="uninstall remove an installed skill, rule, workflow, or config --local name">
@@ -0,0 +1,31 @@
1
+ ---
2
+ id: hash-pinned-reproducible-toolchain-uv-lock
3
+ board: code
4
+ section: compat
5
+ status: shipped
6
+ category: Security · Repro
7
+ complexity: M
8
+ impact: Med
9
+ wow: 3
10
+ note: supply-chain repro
11
+ order: 7
12
+ owner: loop/hashed-toolchain
13
+ pr: 234
14
+ title: Hash-pinned, reproducible toolchain — <code>requirements/*.txt</code>
15
+ ---
16
+ Every dev/CI tool was resolved at install time, so two runs of the same gate could
17
+ install different bytes — and only <code>requirements/lint-tools.txt</code> pinned
18
+ anything at all (added after ruff 0.16.0 reddened the gate with no code change).
19
+ Now every tool comes from a generated, hash-pinned
20
+ <code>requirements/*.txt</code>: exact versions <em>plus</em> a sha256 for every
21
+ artifact in the transitive closure, which pip enforces on install, so a yanked or
22
+ tampered dependency fails loudly instead of silently changing a build.
23
+ <code>scripts/lock_toolchain.py</code> regenerates from the <code>.in</code>
24
+ declarations and <code>--check</code> gates drift in <code>make lint</code>; a new
25
+ Dependabot <code>pip</code> entry keeps the locks from rotting. One file per
26
+ consumer, because pip enforces hashes across a whole resolution — and
27
+ <code>test-tools</code> resolves <em>universally</em>, so one file covers the
28
+ 3 OS &#215; 3 Python matrix without dragging 3.12/3.14 back to the 3.9 floor's
29
+ versions. The opt-in <code>[eval]</code> extra stays out on purpose: locking its
30
+ deliberately-old langchain stack into a scannable file would re-expose the pin
31
+ <code>osv-scanner.yml</code> is PR-diff-scoped to avoid.
@@ -0,0 +1,32 @@
1
+ ---
2
+ id: mcp-aware-skills
3
+ board: code
4
+ section: dx
5
+ status: shipped
6
+ category: Interop · MCP
7
+ complexity: L
8
+ impact: Med
9
+ wow: 4
10
+ note: skills that need a server
11
+ order: 46
12
+ owner: loop/mcp-aware-skills
13
+ pr: 235
14
+ title: MCP-aware skills — declare and wire an <code>.mcp.json</code> on install
15
+ ---
16
+ Mining boost's catalog surfaces a recurring shape: skills that only work paired
17
+ with a Model Context Protocol server (<code>manage-mcp-servers</code>,
18
+ <code>mcp-integration</code>, <code>mcp-builder</code> and dozens more). boost
19
+ already <em>is</em> an MCP server and registers itself, but a skill could not say
20
+ "I need server Y", so it installed cleanly and then failed in the agent for a
21
+ reason nothing surfaced. Now a skill declares <code>mcp: github, playwright</code>
22
+ in frontmatter and/or bundles a standard <code>.mcp.json</code>; on install boost
23
+ states the requirement and offers to register the servers that came with a
24
+ runnable spec, the same way <code>boost mcp register</code> wires boost itself.
25
+ <code>boost info</code> lists them beside <code>capabilities:</code>, and
26
+ <code>--no-mcp</code> opts out. Deliberately <em>flat</em>, not the nested
27
+ <code>mcp:</code> block first sketched: boost's frontmatter parser is a stdlib
28
+ YAML subset that does not fail loudly on a nested mapping — it hoists the inner
29
+ keys to top level and clobbers their siblings — so the declaration meets the
30
+ parser where it already works and full specs live in the sidecar that needs no
31
+ parser at all. The decision layer is <code>core/mcpdecl.py</code>, pure and
32
+ I/O-free like <code>core/resolve.py</code>.