boost-skill-cli 1.0.306__tar.gz → 1.0.307__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 (559) hide show
  1. {boost_skill_cli-1.0.306/boost_skill_cli.egg-info → boost_skill_cli-1.0.307}/PKG-INFO +1 -1
  2. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/_version.py +2 -2
  3. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/commands/pkg.py +42 -6
  4. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/core/store.py +99 -0
  5. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307/boost_skill_cli.egg-info}/PKG-INFO +1 -1
  6. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_skill_cli.egg-info/SOURCES.txt +1 -0
  7. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/mcp-servers-ignore-install-scope.md +29 -3
  8. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap.html +27 -1
  9. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/functional/test_workspace_scope.py +63 -0
  10. boost_skill_cli-1.0.307/tests/unit/test_project_mcp_sidecar.py +187 -0
  11. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/.gitattributes +0 -0
  12. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/.gitignore +0 -0
  13. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/.gitleaks.toml +0 -0
  14. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/.htmlvalidate.json +0 -0
  15. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/.lighthouserc.json +0 -0
  16. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/.lycheeignore +0 -0
  17. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/.markdownlint-cli2.jsonc +0 -0
  18. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/.pre-commit-config.yaml +0 -0
  19. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/.stylelintrc.json +0 -0
  20. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/.vale/styles/boost/Terminology.yml +0 -0
  21. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/.vale/styles/config/vocabularies/boost/accept.txt +0 -0
  22. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/.vale.ini +0 -0
  23. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/CLAUDE.md +0 -0
  24. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/CODE_OF_CONDUCT.md +0 -0
  25. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/CONTRIBUTING.md +0 -0
  26. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/LICENSE +0 -0
  27. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/MANIFEST.in +0 -0
  28. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/Makefile +0 -0
  29. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/README.md +0 -0
  30. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/SECURITY.md +0 -0
  31. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost +0 -0
  32. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/__init__.py +0 -0
  33. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/__main__.py +0 -0
  34. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/cli.py +0 -0
  35. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/cliparse.py +0 -0
  36. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/commands/__init__.py +0 -0
  37. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/commands/_common.py +0 -0
  38. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/commands/bmad.py +0 -0
  39. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/commands/configuration.py +0 -0
  40. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/commands/discovery.py +0 -0
  41. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/commands/hooks.py +0 -0
  42. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/commands/info.py +0 -0
  43. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/commands/intelligence.py +0 -0
  44. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/commands/quality.py +0 -0
  45. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/commands/run.py +0 -0
  46. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/commands/safety.py +0 -0
  47. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/commands/taps.py +0 -0
  48. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/commands/team.py +0 -0
  49. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/core/__init__.py +0 -0
  50. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/core/adapters.py +0 -0
  51. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/core/agents.py +0 -0
  52. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/core/ai.py +0 -0
  53. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/core/capabilities.py +0 -0
  54. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/core/catalog.py +0 -0
  55. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/core/claude_settings.py +0 -0
  56. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/core/config.py +0 -0
  57. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/core/dense.py +0 -0
  58. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/core/ed25519.py +0 -0
  59. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/core/embed.py +0 -0
  60. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/core/faithfulness.py +0 -0
  61. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/core/frontmatter.py +0 -0
  62. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/core/gitutil.py +0 -0
  63. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/core/imperative.py +0 -0
  64. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/core/injectscan.py +0 -0
  65. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/core/installscan.py +0 -0
  66. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/core/integrity.py +0 -0
  67. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/core/journal.py +0 -0
  68. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/core/lockfile.py +0 -0
  69. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/core/logs.py +0 -0
  70. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/core/mcp.py +0 -0
  71. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/core/mcpdecl.py +0 -0
  72. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/core/mcphost.py +0 -0
  73. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/core/minisign.py +0 -0
  74. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/core/nethttp.py +0 -0
  75. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/core/output.py +0 -0
  76. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/core/paths.py +0 -0
  77. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/core/policy.py +0 -0
  78. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/core/projectlock.py +0 -0
  79. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/core/provenance.py +0 -0
  80. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/core/rag.py +0 -0
  81. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/core/registry.py +0 -0
  82. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/core/resolve.py +0 -0
  83. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/core/rules.py +0 -0
  84. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/core/scopes.py +0 -0
  85. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/core/secretscan.py +0 -0
  86. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/core/selfupdate.py +0 -0
  87. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/core/serve.py +0 -0
  88. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/core/stackprobe.py +0 -0
  89. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/core/staleness.py +0 -0
  90. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/core/trustaudit.py +0 -0
  91. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/core/typosquat.py +0 -0
  92. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/core/updatediff.py +0 -0
  93. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/core/util.py +0 -0
  94. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/core/workflows.py +0 -0
  95. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/data/registries.json +0 -0
  96. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/errors.py +0 -0
  97. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_cli/spin.py +0 -0
  98. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_skill_cli.egg-info/dependency_links.txt +0 -0
  99. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_skill_cli.egg-info/entry_points.txt +0 -0
  100. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_skill_cli.egg-info/requires.txt +0 -0
  101. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/boost_skill_cli.egg-info/top_level.txt +0 -0
  102. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/codecov.yml +0 -0
  103. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/.claude/settings.local.json +0 -0
  104. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/DEBUGGING.md +0 -0
  105. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/adapters.html +0 -0
  106. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/architecture/README.md +0 -0
  107. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/architecture/c4-components-core.md +0 -0
  108. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/architecture/c4-containers.md +0 -0
  109. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/architecture/c4-context.md +0 -0
  110. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/architecture/c4-dynamic-install.md +0 -0
  111. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/carousel/gifs/distill.gif +0 -0
  112. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/carousel/gifs/doctor.gif +0 -0
  113. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/carousel/gifs/explain.gif +0 -0
  114. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/carousel/gifs/hooks.gif +0 -0
  115. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/carousel/gifs/install.gif +0 -0
  116. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/carousel/gifs/pulse.gif +0 -0
  117. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/carousel/gifs/search.gif +0 -0
  118. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/carousel/gifs/tap.gif +0 -0
  119. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/carousel/tapes/distill.tape +0 -0
  120. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/carousel/tapes/doctor.tape +0 -0
  121. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/carousel/tapes/explain.tape +0 -0
  122. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/carousel/tapes/hooks.tape +0 -0
  123. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/carousel/tapes/install.tape +0 -0
  124. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/carousel/tapes/pulse.tape +0 -0
  125. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/carousel/tapes/search.tape +0 -0
  126. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/carousel/tapes/tap.tape +0 -0
  127. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/carousel.html +0 -0
  128. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/commands.html +0 -0
  129. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/demo.gif +0 -0
  130. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/demo.tape +0 -0
  131. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/design-roadmap.html +0 -0
  132. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/eval.html +0 -0
  133. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/index.html +0 -0
  134. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/mcp-hub.html +0 -0
  135. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/rag-architecture.md +0 -0
  136. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/BOOST-D01.md +0 -0
  137. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/BOOST-D02.md +0 -0
  138. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/BOOST-D03.md +0 -0
  139. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/BOOST-D04.md +0 -0
  140. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/BOOST-D05.md +0 -0
  141. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/BOOST-D06.md +0 -0
  142. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/BOOST-D07.md +0 -0
  143. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/BOOST-D08.md +0 -0
  144. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/BOOST-D09.md +0 -0
  145. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/BOOST-D10.md +0 -0
  146. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/BOOST-D11.md +0 -0
  147. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/BOOST-D12.md +0 -0
  148. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/BOOST-D13.md +0 -0
  149. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/BOOST-D14.md +0 -0
  150. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/BOOST-D15.md +0 -0
  151. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/BOOST-D16.md +0 -0
  152. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/BOOST-D17.md +0 -0
  153. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/BOOST-D18.md +0 -0
  154. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/BOOST-D19.md +0 -0
  155. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/BOOST-D20.md +0 -0
  156. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/BOOST-D21.md +0 -0
  157. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/BOOST-D22.md +0 -0
  158. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/BOOST-D23.md +0 -0
  159. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/BOOST-D24.md +0 -0
  160. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/BOOST-D25.md +0 -0
  161. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/BOOST-D26.md +0 -0
  162. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/accessibility-audit-pa11y-ci-axe-core.md +0 -0
  163. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/actionlint-skips-shellcheck-silently.md +0 -0
  164. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/adapter-conformance-langgraph-leg-never-ran.md +0 -0
  165. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/ai-bridge-silent-failure-logging.md +0 -0
  166. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/ambiguous-tap-short-name-resolution.md +0 -0
  167. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/atomic-corruption-safe-lock-file-writes.md +0 -0
  168. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/atomic-skill-install-temp-dir-swap.md +0 -0
  169. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/autonomous-ship-workflow-and-isolated-worktree.md +0 -0
  170. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/boost-run-live-agents.md +0 -0
  171. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/bring-commands-under-mutation-testing.md +0 -0
  172. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/broken-link-and-anchor-checking-lychee.md +0 -0
  173. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/browse-crashes-selecting-a-rule-or-workflow.md +0 -0
  174. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/build-provenance-slsa-attestations.md +0 -0
  175. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/cache-the-catalog-entry-set-across-rag-queries.md +0 -0
  176. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/capability-manifest-and-least-privilege-policy.md +0 -0
  177. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/ci-job-timeout-minutes.md +0 -0
  178. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/ci-summary-step-fails-itself.md +0 -0
  179. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/ci-time-is-now-runner-queueing.md +0 -0
  180. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/clean-env-install-smoke-pip-and-pipx.md +0 -0
  181. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/code-scanning-rule-can-be-restored.md +0 -0
  182. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/codeql-job-rename-stranded-merge-protection.md +0 -0
  183. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/command-carousel-page.md +0 -0
  184. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/command-reference-docs-site.md +0 -0
  185. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/complexity-and-dead-code-radar-xenon-vulture.md +0 -0
  186. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/consolidate-skill-staleness-drift-logic-into-cor.md +0 -0
  187. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/coverage-dashboard-codecov-free-for-oss.md +0 -0
  188. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/coverage-guided-fuzzing-atheris-oss-fuzz.md +0 -0
  189. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/crash-listing-branch-untested.md +0 -0
  190. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/crash-recorder-error-paths-core-logs-py.md +0 -0
  191. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/demo-cannot-open-its-own-pr.md +0 -0
  192. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/demo-gif-workflow-has-never-succeeded.md +0 -0
  193. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/dense-search-fallback-and-stale-tap-pruning.md +0 -0
  194. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/dependabot-missing-pip-ecosystem.md +0 -0
  195. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/dependabot-regeneration-drops-platform-pins.md +0 -0
  196. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/dependabot-root-pip-entry-duplicates-requirements.md +0 -0
  197. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/dependency-cve-gate-pip-audit.md +0 -0
  198. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/docsite-chrome-and-content-audit.md +0 -0
  199. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/docstring-coverage-interrogate.md +0 -0
  200. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/doctor-checks-rules-and-workflows.md +0 -0
  201. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/end-of-options-guard-on-git-commands.md +0 -0
  202. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/extension-free-tests-core-dense-py.md +0 -0
  203. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/extract-mcp-http-servers-out-of-configuration-py.md +0 -0
  204. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/finish-mutation-hardening-across-core.md +0 -0
  205. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/fix-self-update-version-detection-dead-branch.md +0 -0
  206. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/fork-safe-network-proxy-handler.md +0 -0
  207. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/framework-adapter-langgraph.md +0 -0
  208. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/framework-adapter-multi-agent.md +0 -0
  209. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/framework-adapters-boost-adapt.md +0 -0
  210. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/frontmatter-scalar-over-coercion.md +0 -0
  211. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/gemini-cli-agent-target.md +0 -0
  212. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/github-community-health-files.md +0 -0
  213. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/github-pages-deploy-is-broken-every-push.md +0 -0
  214. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/golden-set-statistical-power.md +0 -0
  215. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/hash-pinned-reproducible-toolchain-uv-lock.md +0 -0
  216. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/html-validation-html-validate.md +0 -0
  217. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/install-docs-never-mentioned-upgrading.md +0 -0
  218. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/install-from-path-bypasses-policy-and-pin-checks.md +0 -0
  219. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/install-resolves-skill-dependencies.md +0 -0
  220. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/install-scope-user-or-project.md +0 -0
  221. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/installed-skill-trust-audit.md +0 -0
  222. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/integrity-verification-boost-verify.md +0 -0
  223. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/internal-architecture-diagrams.md +0 -0
  224. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/invocation-pid-logging-for-crash-correlation.md +0 -0
  225. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/journal-rotation-race-and-handle-leak.md +0 -0
  226. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/keyless-item.md +0 -0
  227. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/layering-guard-import-linter.md +0 -0
  228. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/license-compliance-scanning.md +0 -0
  229. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/lighthouse-ci-on-the-pages-site.md +0 -0
  230. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/lint-tap-misscopes-rule-workflow-entries.md +0 -0
  231. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/list-rules-and-workflows.md +0 -0
  232. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/localize-the-stored-bm25-snippet.md +0 -0
  233. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/lock-invariant-cannot-parse-extras-pins.md +0 -0
  234. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/lockfile-enforcement-and-commit-pinning.md +0 -0
  235. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/log-timestamps-mislabeled-utc.md +0 -0
  236. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/lowest-version-resolution-uv-resolution-lowest-d.md +0 -0
  237. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/main-has-no-branch-protection.md +0 -0
  238. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/main-ruleset-ref-pattern-has-literal-quotes.md +0 -0
  239. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/make-lint-masks-actionlint-failures.md +0 -0
  240. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/make-the-roadmaps-discoverable.md +0 -0
  241. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/markdown-consistency-markdownlint-cli2.md +0 -0
  242. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/markdownlint-lints-the-fuzz-corpus.md +0 -0
  243. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/mcp-aware-skills.md +0 -0
  244. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/mcp-check-skills-before-starting-a-task.md +0 -0
  245. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/mcp-hub-diagram-node-text-overflow.md +0 -0
  246. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/mcp-install-skips-the-injection-scan.md +0 -0
  247. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/mcp-launch-objc-fork-safety.md +0 -0
  248. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/mcp-register-names-server-before-env.md +0 -0
  249. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/mcp-search-before-reinventing.md +0 -0
  250. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/mcp-startup-self-harden-fork-safety.md +0 -0
  251. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/memoize-config-load-in-process.md +0 -0
  252. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/merge-queue-would-deadlock-most-required-checks.md +0 -0
  253. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/merged-loop-branches-are-never-pruned.md +0 -0
  254. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/modernization-smells-refurb-pyupgrade.md +0 -0
  255. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/mutation-gate-was-the-whole-critical-path.md +0 -0
  256. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/mutation-hardening-core-frontmatter-py.md +0 -0
  257. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/mutation-hardening-core-gitutil-py.md +0 -0
  258. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/mutation-hardening-core-store-py.md +0 -0
  259. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/mutation-shard-floor-is-one-file.md +0 -0
  260. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/mypy-strict-mode-for-commands.md +0 -0
  261. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/negative-limit-inverts-log-pulse-output.md +0 -0
  262. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/onboard-overwrites-generated-files-without-confirm.md +0 -0
  263. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/one-command-every-env-nox.md +0 -0
  264. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/one-commit-can-cut-two-releases.md +0 -0
  265. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/one-shared-atomic-write-helper.md +0 -0
  266. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/package-metadata-validation-twine-check-friends.md +0 -0
  267. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/patch-coverage-gate-diff-cover.md +0 -0
  268. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/path-traversal-unsanitized-rule-workflow-name.md +0 -0
  269. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/performance-regression-gate-pytest-benchmark.md +0 -0
  270. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/pin-the-lint-toolchain.md +0 -0
  271. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/post-deploy-always-defeated-by-skipped-setup.md +0 -0
  272. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/post-deploy-smoke-headless-load-check.md +0 -0
  273. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/pre-release-python-canary-3-14t-free-threaded.md +0 -0
  274. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/project-scope-across-every-command.md +0 -0
  275. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/project-scope-symlink-escape-on-write.md +0 -0
  276. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/promote-nav-footer-into-the-shared-style-system.md +0 -0
  277. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/prompt-injection-scanning-of-skill-markdown.md +0 -0
  278. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/property-based-tests-hypothesis-on-the-parsers.md +0 -0
  279. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/prose-and-terminology-linting-vale.md +0 -0
  280. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/prune-ignored-dirs-during-scan-dir-walk.md +0 -0
  281. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/publish-gate-ignores-pip-audit-and-metadata.md +0 -0
  282. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/publish-trigger-was-reachable-from-a-fork.md +0 -0
  283. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/pytest-tmpdir-cve-blocked-by-py39-floor.md +0 -0
  284. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/quality-dashboard-sonarcloud-free-for-oss.md +0 -0
  285. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/ranx-significance-monitor.md +0 -0
  286. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/reconcile-the-theme-drift.md +0 -0
  287. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/refresh-the-marketing-surface.md +0 -0
  288. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/rel-time-tests-race-the-wall-clock.md +0 -0
  289. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/release-verifies-the-wrong-commit.md +0 -0
  290. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/required-checks-can-declare-a-check-that-deadlocks-prs.md +0 -0
  291. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/required-checks-config-drift.md +0 -0
  292. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/retrieval-quality-eval-harness.md +0 -0
  293. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/reuse-helpers-kill-minor-dead-work.md +0 -0
  294. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/roadmap-html-goes-stale-on-every-rebase.md +0 -0
  295. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/robust-tag-argument-parsing.md +0 -0
  296. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/ruff-016-widens-the-default-rule-set.md +0 -0
  297. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/rule-install-native-materialization.md +0 -0
  298. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/runner-egress-monitoring-stepsecurity-harden-run.md +0 -0
  299. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/runtime-explain-faithfulness-guardrail.md +0 -0
  300. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/sbom-aware-scanning-osv-scanner.md +0 -0
  301. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/sbom-declares-the-wrong-version.md +0 -0
  302. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/sbom-on-every-release-cyclonedx-syft.md +0 -0
  303. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/sbom-release-event-never-fires.md +0 -0
  304. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/scan-and-sync-rules-and-workflows.md +0 -0
  305. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/scheduled-toolchain-lock-regeneration.md +0 -0
  306. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/scorecard-findings-triage.md +0 -0
  307. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/second-type-checker-pyright.md +0 -0
  308. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/secret-and-pii-scanning-of-installed-skills.md +0 -0
  309. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/secret-scanning-gitleaks-push-protection.md +0 -0
  310. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/security-linting-bandit-via-ruff-s-rules.md +0 -0
  311. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/self-update-broken-for-pip-pipx-installs.md +0 -0
  312. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/serve-py-traversal-guards-untested.md +0 -0
  313. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/shift-left-gate-pre-commit-pre-commit-ci.md +0 -0
  314. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/single-imperative-rule-extractor.md +0 -0
  315. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/single-tech-stack-prober.md +0 -0
  316. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/split-oversized-command-modules.md +0 -0
  317. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/startup-and-import-time-budget-x-importtime.md +0 -0
  318. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/stop-re-serializing-entry-meta-on-every-search.md +0 -0
  319. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/structured-json-log-output-mode.md +0 -0
  320. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/supply-chain-posture-openssf-scorecard.md +0 -0
  321. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/surface-every-docs-page-from-the-guide.md +0 -0
  322. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/sync-deletes-unowned-broken-symlinks.md +0 -0
  323. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/sync-relinks-into-every-agent-ignoring-scope.md +0 -0
  324. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/tap-signing-and-provenance-sigstore-minisign.md +0 -0
  325. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/theme-asset-linting-stylelint-eslint.md +0 -0
  326. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/typo-detection-codespell.md +0 -0
  327. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/typosquat-and-name-confusion-detection.md +0 -0
  328. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/unify-tilde-two-copies-have-a-boundary-bug.md +0 -0
  329. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/uninstall-has-no-confirmation-prompt.md +0 -0
  330. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/untrack-generated-build-noise.md +0 -0
  331. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/update-diff-before-apply.md +0 -0
  332. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/update-refreshes-rules-and-workflows.md +0 -0
  333. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/update-reinstall-widens-agent-scope.md +0 -0
  334. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/visual-regression-pass-on-the-guide.md +0 -0
  335. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/widen-the-ruff-rule-surface-b-sim-c4-perf-ruf.md +0 -0
  336. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/windows-in-the-ci-matrix.md +0 -0
  337. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/wire-bdd-suite-into-ci.md +0 -0
  338. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/workflow-install-native-materialization.md +0 -0
  339. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/workflow-linting-actionlint.md +0 -0
  340. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/workflow-sast-zizmor.md +0 -0
  341. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/workspace-scope-install.md +0 -0
  342. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/docs/roadmap/items/zizmor-pin-is-a-yanked-release.md +0 -0
  343. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/eslint.config.mjs +0 -0
  344. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/evals/README.md +0 -0
  345. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/evals/__init__.py +0 -0
  346. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/evals/baseline.json +0 -0
  347. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/evals/faithfulness.py +0 -0
  348. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/evals/golden_set.json +0 -0
  349. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/evals/make_corpus.py +0 -0
  350. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/evals/make_golden.py +0 -0
  351. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/evals/metrics.py +0 -0
  352. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/evals/run_evals.py +0 -0
  353. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/examples/README.md +0 -0
  354. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/examples/adapt-demo.sh +0 -0
  355. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/examples/boost-run-prototype.sh +0 -0
  356. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/index.html +0 -0
  357. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/noxfile.py +0 -0
  358. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/pyproject.toml +0 -0
  359. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/requirements/coverage-tools.in +0 -0
  360. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/requirements/coverage-tools.txt +0 -0
  361. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/requirements/lint-tools.in +0 -0
  362. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/requirements/lint-tools.txt +0 -0
  363. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/requirements/mutation-tools.in +0 -0
  364. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/requirements/mutation-tools.txt +0 -0
  365. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/requirements/platform-pins.lock +0 -0
  366. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/requirements/release-tools.in +0 -0
  367. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/requirements/release-tools.txt +0 -0
  368. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/requirements/test-tools.in +0 -0
  369. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/requirements/test-tools.txt +0 -0
  370. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/scripts/a11y_check.py +0 -0
  371. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/scripts/bench_cli.sh +0 -0
  372. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/scripts/build_command_reference.py +0 -0
  373. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/scripts/build_registries.py +0 -0
  374. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/scripts/build_roadmap.py +0 -0
  375. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/scripts/check_anchors.py +0 -0
  376. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/scripts/check_licenses.py +0 -0
  377. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/scripts/check_required_checks.py +0 -0
  378. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/scripts/ensure_eval_corpus.sh +0 -0
  379. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/scripts/eval_explain.py +0 -0
  380. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/scripts/eval_gate.py +0 -0
  381. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/scripts/eval_recommend.py +0 -0
  382. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/scripts/eval_retrieval.py +0 -0
  383. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/scripts/eval_stats_summary.py +0 -0
  384. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/scripts/import_budget.py +0 -0
  385. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/scripts/lock_toolchain.py +0 -0
  386. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/scripts/mutation_gate.py +0 -0
  387. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/scripts/mutation_shards.py +0 -0
  388. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/scripts/mutation_weights.json +0 -0
  389. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/scripts/perf_gate.py +0 -0
  390. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/scripts/post_deploy_smoke.py +0 -0
  391. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/scripts/release_guard.py +0 -0
  392. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/scripts/release_preflight.py +0 -0
  393. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/setup.cfg +0 -0
  394. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/sonar-project.properties +0 -0
  395. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/style/README.md +0 -0
  396. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/style/boost.css +0 -0
  397. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/style/boost.js +0 -0
  398. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/style/demo.html +0 -0
  399. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/bdd/features/adapt.feature +0 -0
  400. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/bdd/features/browse.feature +0 -0
  401. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/bdd/features/count.feature +0 -0
  402. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/bdd/features/discover.feature +0 -0
  403. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/bdd/features/doctor.feature +0 -0
  404. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/bdd/features/environment.py +0 -0
  405. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/bdd/features/explain.feature +0 -0
  406. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/bdd/features/index.feature +0 -0
  407. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/bdd/features/install.feature +0 -0
  408. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/bdd/features/list.feature +0 -0
  409. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/bdd/features/mcp.feature +0 -0
  410. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/bdd/features/search.feature +0 -0
  411. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/bdd/features/steps/cli_steps.py +0 -0
  412. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/bdd/features/steps/discovery_steps.py +0 -0
  413. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/bdd/features/steps/mcp_steps.py +0 -0
  414. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/bdd/features/steps/quality_steps.py +0 -0
  415. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/conftest.py +0 -0
  416. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/eval/baseline.json +0 -0
  417. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/eval/explain.jsonl +0 -0
  418. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/eval/golden.jsonl +0 -0
  419. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/eval/recommend.jsonl +0 -0
  420. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/eval/taps.txt +0 -0
  421. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/functional/test_capabilities_policy.py +0 -0
  422. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/functional/test_cli_adapt.py +0 -0
  423. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/functional/test_cli_bmad.py +0 -0
  424. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/functional/test_cli_configuration.py +0 -0
  425. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/functional/test_cli_discovery.py +0 -0
  426. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/functional/test_cli_hooks.py +0 -0
  427. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/functional/test_cli_info.py +0 -0
  428. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/functional/test_cli_intelligence.py +0 -0
  429. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/functional/test_cli_pkg.py +0 -0
  430. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/functional/test_cli_quality.py +0 -0
  431. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/functional/test_cli_taps.py +0 -0
  432. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/functional/test_cli_team.py +0 -0
  433. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/functional/test_everyday_loop.py +0 -0
  434. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/functional/test_integrity_enforce.py +0 -0
  435. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/functional/test_property_parsers.py +0 -0
  436. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/functional/test_run.py +0 -0
  437. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/functional/test_tap_signing.py +0 -0
  438. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/fuzz/README.md +0 -0
  439. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/fuzz/corpus/frontmatter/01-typical.md +0 -0
  440. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/fuzz/corpus/frontmatter/02-lossy-version.md +0 -0
  441. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/fuzz/corpus/frontmatter/03-lossy-numbers.md +0 -0
  442. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/fuzz/corpus/frontmatter/04-lists.md +0 -0
  443. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/fuzz/corpus/frontmatter/05-nested.md +0 -0
  444. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/fuzz/corpus/frontmatter/06-empty-block.md +0 -0
  445. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/fuzz/corpus/frontmatter/07-unterminated.md +0 -0
  446. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/fuzz/corpus/frontmatter/08-none.md +0 -0
  447. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/fuzz/corpus/frontmatter/09-unbalanced-quote.md +0 -0
  448. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/fuzz/corpus/frontmatter/10-keywords.md +0 -0
  449. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/fuzz/corpus/frontmatter/11-crlf.md +0 -0
  450. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/fuzz/corpus/frontmatter/12-bom.md +0 -0
  451. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/fuzz/corpus/registry/01-shorthand.txt +0 -0
  452. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/fuzz/corpus/registry/02-https.txt +0 -0
  453. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/fuzz/corpus/registry/03-ssh.txt +0 -0
  454. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/fuzz/corpus/registry/04-traversal.txt +0 -0
  455. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/fuzz/corpus/registry/05-empty.txt +0 -0
  456. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/fuzz/corpus/registry/06-space.txt +0 -0
  457. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/fuzz/corpus/registry/07-slash.txt +0 -0
  458. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/fuzz/corpus/registry/08-bare-host.txt +0 -0
  459. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/fuzz/fuzz_frontmatter.py +0 -0
  460. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/fuzz/fuzz_registry.py +0 -0
  461. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/make_fixture.py +0 -0
  462. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/perf/test_benchmarks.py +0 -0
  463. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/smoke.sh +0 -0
  464. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_a11y_check.py +0 -0
  465. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_adapters.py +0 -0
  466. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_adapters_multi.py +0 -0
  467. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_adapters_runner.py +0 -0
  468. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_agents.py +0 -0
  469. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_ai.py +0 -0
  470. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_capabilities.py +0 -0
  471. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_catalog.py +0 -0
  472. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_check_anchors.py +0 -0
  473. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_check_licenses.py +0 -0
  474. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_claude_settings.py +0 -0
  475. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_cliparse.py +0 -0
  476. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_codeql_analysis_key.py +0 -0
  477. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_command_reference_fresh.py +0 -0
  478. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_community_health_files.py +0 -0
  479. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_config.py +0 -0
  480. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_dense.py +0 -0
  481. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_dense_fallback.py +0 -0
  482. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_dependabot_config.py +0 -0
  483. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_docs_pages_linked.py +0 -0
  484. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_docsite_chrome.py +0 -0
  485. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_ed25519.py +0 -0
  486. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_embed.py +0 -0
  487. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_errors_and_cli_table.py +0 -0
  488. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_eval_faithfulness.py +0 -0
  489. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_eval_gate.py +0 -0
  490. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_eval_metrics.py +0 -0
  491. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_eval_stats_summary.py +0 -0
  492. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_faithfulness.py +0 -0
  493. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_frontmatter.py +0 -0
  494. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_fuzz_targets.py +0 -0
  495. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_gitleaks_config.py +0 -0
  496. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_gitutil.py +0 -0
  497. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_imperative.py +0 -0
  498. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_import_budget.py +0 -0
  499. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_injectscan.py +0 -0
  500. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_installscan.py +0 -0
  501. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_integrity.py +0 -0
  502. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_journal.py +0 -0
  503. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_lockfile.py +0 -0
  504. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_logs.py +0 -0
  505. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_marketing_counts.py +0 -0
  506. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_mcp.py +0 -0
  507. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_mcp_install_scan.py +0 -0
  508. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_mcpdecl.py +0 -0
  509. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_mcphost.py +0 -0
  510. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_minisign.py +0 -0
  511. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_mutation_hardening.py +0 -0
  512. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_mutation_shards.py +0 -0
  513. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_mutation_subfile_shards.py +0 -0
  514. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_mutmut_source_paths.py +0 -0
  515. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_nethttp.py +0 -0
  516. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_output.py +0 -0
  517. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_paths.py +0 -0
  518. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_perf_gate.py +0 -0
  519. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_pkg_confusions.py +0 -0
  520. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_pkg_injection.py +0 -0
  521. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_pkg_secrets.py +0 -0
  522. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_platform_pins.py +0 -0
  523. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_policy.py +0 -0
  524. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_post_deploy_smoke.py +0 -0
  525. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_projectlock.py +0 -0
  526. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_provenance.py +0 -0
  527. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_rag.py +0 -0
  528. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_registries_fresh.py +0 -0
  529. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_registry.py +0 -0
  530. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_registry_categories.py +0 -0
  531. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_release_guard.py +0 -0
  532. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_release_preflight.py +0 -0
  533. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_required_checks.py +0 -0
  534. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_resolve.py +0 -0
  535. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_roadmap_fresh.py +0 -0
  536. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_rules.py +0 -0
  537. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_scopes.py +0 -0
  538. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_secretscan.py +0 -0
  539. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_selfupdate.py +0 -0
  540. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_serve.py +0 -0
  541. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_spin.py +0 -0
  542. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_stackprobe.py +0 -0
  543. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_staleness.py +0 -0
  544. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_store.py +0 -0
  545. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_token_parity.py +0 -0
  546. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_toolchain_lock.py +0 -0
  547. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_trustaudit.py +0 -0
  548. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_typosquat.py +0 -0
  549. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_updatediff.py +0 -0
  550. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_util.py +0 -0
  551. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_version.py +0 -0
  552. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_workflow_concurrency.py +0 -0
  553. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_workflow_timeouts.py +0 -0
  554. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/unit/test_workflows.py +0 -0
  555. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/visual/a11y_check.mjs +0 -0
  556. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/visual/console_check.mjs +0 -0
  557. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/visual/package-lock.json +0 -0
  558. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/visual/package.json +0 -0
  559. {boost_skill_cli-1.0.306 → boost_skill_cli-1.0.307}/tests/visual/visual_check.mjs +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: boost-skill-cli
3
- Version: 1.0.306
3
+ Version: 1.0.307
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.306'
22
- __version_tuple__ = version_tuple = (1, 0, 306)
21
+ __version__ = version = '1.0.307'
22
+ __version_tuple__ = version_tuple = (1, 0, 307)
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -123,7 +123,33 @@ def _offer_mcp(res: store.InstallResult, no_mcp: bool = False) -> None:
123
123
  rows = res.mcp_servers
124
124
  if not rows or no_mcp or os.environ.get("BOOST_NO_MCP_OFFER"):
125
125
  return
126
- from ..core import mcpdecl
126
+ from ..core import mcpdecl, scopes
127
+ # A project-scoped install already recorded these in the repo's .mcp.json
128
+ # (store.register_project_mcp), which is the committable, reviewable
129
+ # registration `--scope project` promises. Offering a `<host> mcp add` on
130
+ # top would register the same servers a second time, machine-wide — which
131
+ # is the bug this path had: the offer never looked at res.scope at all.
132
+ if res.scope == scopes.SCOPE_PROJECT:
133
+ # Report what was RECORDED, not what was declared. The two differ when
134
+ # the sidecar could not be written — a read-only checkout, a root-owned
135
+ # .mcp.json — and claiming success there would be the worse failure,
136
+ # because the skill really is installed and the servers really are not.
137
+ wanted = [r["name"] for r in mcpdecl.registrable(rows)]
138
+ if not wanted:
139
+ return
140
+ out.info("")
141
+ if res.mcp_recorded:
142
+ out.ok("recorded %s in %s"
143
+ % (_plural(len(res.mcp_recorded), "MCP server"),
144
+ mcpdecl.SIDECAR))
145
+ out.dim(" %s — commit it to share with the team"
146
+ % ", ".join(res.mcp_recorded))
147
+ else:
148
+ out.warn("could not write %s — %s not registered"
149
+ % (mcpdecl.SIDECAR, ", ".join(wanted)))
150
+ out.dim(" the skill is installed; fix the file's permissions and "
151
+ "reinstall to record them")
152
+ return
127
153
  out.info("")
128
154
  out.warn("%s needs %s to work:" % (res.name, _plural(len(rows), "MCP server")))
129
155
  for row in rows:
@@ -142,22 +168,32 @@ def _offer_mcp(res: store.InstallResult, no_mcp: bool = False) -> None:
142
168
  targets = [h for h in mcphost.hosts() if shutil.which(mcphost.cli(h))] \
143
169
  or mcphost.hosts()
144
170
  where = " · ".join(mcphost.label(h) for h in targets)
145
- if not out.confirm("register %s with %s now?"
171
+ # Name the scope. The prompt used to say only "register N servers with
172
+ # Claude Code now?", which is the one detail the answer turns on — this
173
+ # writes a registration every project on this machine will then launch.
174
+ if not out.confirm("register %s with %s, for every project on this machine?"
146
175
  % (_plural(len(wirable), "server"), where), default=False):
147
176
  out.dim(" skipped — `%s mcp add …` when you're ready"
148
177
  % mcphost.cli(targets[0]))
149
178
  return
150
179
  for row in wirable:
151
180
  for host in targets:
152
- _register_mcp_server(row["name"], row["spec"], host=host)
181
+ _register_mcp_server(row["name"], row["spec"], host=host,
182
+ scope=res.scope)
153
183
 
154
184
 
155
- def _register_mcp_server(name: str, spec: dict, host: str = "claude") -> None:
156
- """Run one `<host> mcp add` for a skill-declared server. Never raises."""
185
+ def _register_mcp_server(name: str, spec: dict, host: str = "claude",
186
+ scope: str = "user") -> None:
187
+ """Run one `<host> mcp add` for a skill-declared server. Never raises.
188
+
189
+ ``scope`` is threaded from the install rather than defaulted, because
190
+ ``register_argv``'s own default is ``"user"`` and silently taking it is how
191
+ a ``--scope project`` install ended up registering machine-wide.
192
+ """
157
193
  import subprocess
158
194
 
159
195
  from ..core import mcpdecl, mcphost
160
- argv = mcpdecl.register_argv(name, spec, host=host)
196
+ argv = mcpdecl.register_argv(name, spec, host=host, scope=scope)
161
197
  if not shutil.which(mcphost.cli(host)):
162
198
  out.warn("`%s` CLI not found — run this yourself:" % mcphost.cli(host))
163
199
  out.info(" " + " ".join(argv))
@@ -51,6 +51,10 @@ class InstallResult:
51
51
  # but never acted on: core stays non-interactive, so the command layer owns
52
52
  # the offer to register them — same split as `conflicts` and `score`.
53
53
  mcp_servers: List[dict] = field(default_factory=list)
54
+ # Names actually written to the project's .mcp.json — not what was
55
+ # declared. The two differ when the file could not be written, and the
56
+ # install report must show the former.
57
+ mcp_recorded: List[str] = field(default_factory=list)
54
58
 
55
59
 
56
60
  def skill_store_dir(name: str) -> Path:
@@ -266,6 +270,89 @@ def declared_mcp_servers(skill_dir) -> List[dict]:
266
270
  return mcpdecl.servers_for(meta, sidecar)
267
271
 
268
272
 
273
+ def project_mcp_sidecar(base) -> Path:
274
+ """The repo's ``.mcp.json`` — where a project-scoped install records servers.
275
+
276
+ The committable file agents already read, which is the whole point of
277
+ project scope over shelling out to ``<host> mcp add``: a registration that
278
+ lives here is reviewable in a diff and arrives with a teammate's clone,
279
+ where one made through a host CLI exists only on the machine that ran it.
280
+ """
281
+ from . import mcpdecl
282
+ return Path(base) / mcpdecl.SIDECAR
283
+
284
+
285
+ def _load_sidecar(path: Path) -> Optional[dict]:
286
+ """The sidecar document, or None if absent or unreadable.
287
+
288
+ Best-effort by design, exactly like :func:`declared_mcp_servers`: by the
289
+ time this runs the skill is already on disk, so a corrupt ``.mcp.json`` must
290
+ not turn a completed install into a traceback. ``merge_into`` treats a
291
+ non-dict as empty, so a damaged file is rebuilt rather than propagated.
292
+ """
293
+ import json
294
+ try:
295
+ return json.loads(path.read_text(encoding="utf-8"))
296
+ except (OSError, ValueError):
297
+ return None
298
+
299
+
300
+ def _write_sidecar(path: Path, doc: dict) -> bool:
301
+ """Write the sidecar as indented JSON. False if it could not be written.
302
+
303
+ Best-effort on the way OUT as well as in. ``_load_sidecar`` already refuses
304
+ to turn a corrupt file into a traceback, but the write is the half that runs
305
+ *after* the skill is materialized, the lock is written and the journal is
306
+ logged — so an unwritable ``.mcp.json`` (read-only checkout, a root-owned
307
+ file, a full disk) would crash an install that had already succeeded. The
308
+ caller reports what was actually recorded rather than what was declared, so
309
+ a failure here is visible instead of silent.
310
+ """
311
+ import json
312
+ try:
313
+ path.write_text(json.dumps(doc, indent=2, sort_keys=True) + "\n",
314
+ encoding="utf-8")
315
+ return True
316
+ except OSError:
317
+ return False
318
+
319
+
320
+ def register_project_mcp(base, rows, skill: str) -> List[str]:
321
+ """Record ``skill``'s declared MCP servers in the repo. Returns names added.
322
+
323
+ Never overwrites a server already present — one the user configured by hand,
324
+ or one another skill declared first — and never creates the file for a skill
325
+ that declares nothing registrable, so a repo gains an ``.mcp.json`` only
326
+ when there is genuinely something in it.
327
+ """
328
+ from . import mcpdecl as _decl
329
+ if not _decl.registrable(rows):
330
+ return []
331
+ path = project_mcp_sidecar(base)
332
+ doc, added = _decl.merge_into(_load_sidecar(path), rows, skill)
333
+ if added and not _write_sidecar(path, doc):
334
+ return [] # nothing was recorded; do not claim otherwise
335
+ return added
336
+
337
+
338
+ def unregister_project_mcp(base, skill: str) -> List[str]:
339
+ """Remove the servers boost recorded for ``skill``. Returns names removed.
340
+
341
+ Marker-keyed entries only, so a hand-configured server and another skill's
342
+ server both survive. Writes nothing when it owns nothing, which keeps an
343
+ uninstall from rewriting — and reformatting — a file it has no claim on.
344
+ """
345
+ from . import mcpdecl as _decl
346
+ path = project_mcp_sidecar(base)
347
+ existing = _load_sidecar(path)
348
+ if existing is None:
349
+ return []
350
+ doc, removed = _decl.strip_owned(existing, skill)
351
+ if removed and not _write_sidecar(path, doc):
352
+ return []
353
+ return removed
354
+
355
+
269
356
  def _enforce_capability_policy(name: str, skill_md: Path) -> None:
270
357
  """Raise if the skill's declared/detected capabilities are denied by policy.
271
358
 
@@ -501,6 +588,12 @@ def _install_project_skill(entry: dict, force: bool = False,
501
588
  res.upgraded = existing is not None
502
589
  res.scope = scopes.SCOPE_PROJECT
503
590
  res.score, _ = util.score_skill(first)
591
+ res.mcp_servers = declared_mcp_servers(first)
592
+ # Project scope registers into the repo's own .mcp.json rather than leaving
593
+ # it to the command layer's `<host> mcp add` offer, which is user-scoped and
594
+ # would put a machine-wide registration behind a --scope project install.
595
+ # Recorded here so it lands with the skill and reverses with it.
596
+ res.mcp_recorded = register_project_mcp(resolved_base, res.mcp_servers, name)
504
597
  return res
505
598
 
506
599
 
@@ -525,8 +618,14 @@ def uninstall_project(name: str, base=None) -> dict:
525
618
  if m.get("agent"):
526
619
  removed.append(m["agent"])
527
620
  projectlock.remove_skill(resolved_base, name)
621
+ # Reverse exactly what the install recorded. Marker-keyed entries only, so a
622
+ # server the user configured by hand — or one another skill still needs —
623
+ # survives. Without this a skill tried once keeps launching its server for
624
+ # every project that clones the repo.
625
+ unregistered = unregister_project_mcp(resolved_base, name)
528
626
  journal.log("uninstall", name, scope=scopes.SCOPE_PROJECT)
529
627
  return {"name": name, "unlinked": removed, "entry": entry,
628
+ "mcp_unregistered": unregistered,
530
629
  "scope": scopes.SCOPE_PROJECT, "base": str(resolved_base)}
531
630
 
532
631
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: boost-skill-cli
3
- Version: 1.0.306
3
+ Version: 1.0.307
4
4
  Summary: boost — Homebrew for AI coding skills
5
5
  Author: Jonathan Reyes
6
6
  License: GNU GENERAL PUBLIC LICENSE
@@ -520,6 +520,7 @@ tests/unit/test_pkg_secrets.py
520
520
  tests/unit/test_platform_pins.py
521
521
  tests/unit/test_policy.py
522
522
  tests/unit/test_post_deploy_smoke.py
523
+ tests/unit/test_project_mcp_sidecar.py
523
524
  tests/unit/test_projectlock.py
524
525
  tests/unit/test_provenance.py
525
526
  tests/unit/test_rag.py
@@ -2,15 +2,15 @@
2
2
  id: mcp-servers-ignore-install-scope
3
3
  board: code
4
4
  section: dx
5
- status: planned
5
+ status: shipped
6
6
  category: Bug · MCP
7
7
  complexity: M
8
8
  impact: High
9
9
  wow: 4
10
10
  note: --scope project installs the skill into the repo and its MCP server machine-wide
11
11
  order: 14
12
- owner:
13
- pr:
12
+ owner: loop/mcp-scope-fix
13
+ pr: 351
14
14
  title: A project-scoped install registers its MCP servers <em>machine-wide</em>
15
15
  ---
16
16
  <code>boost install &lt;skill&gt; --scope project</code> (or <code>--here</code>) is a promise about
@@ -66,5 +66,31 @@ the scope it was registered at, which is another reason to record it rather than
66
66
  names no scope. It should say which file or scope is about to change, because that is the decision
67
67
  being made.
68
68
 
69
+ <b>Shipped, all four.</b> Scope now flows: <code>_offer_mcp</code> reads <code>res.scope</code> and
70
+ threads it through <code>_register_mcp_server</code> into <code>register_argv</code>, so a
71
+ user-scope install passes its scope explicitly rather than silently inheriting the
72
+ <code>scope="user"</code> default that caused this. A project-scope install does not shell out at
73
+ all &mdash; it records into the repo's <code>.mcp.json</code>, which is the committable, reviewable
74
+ registration <code>--scope project</code> promises, and it arrives with a teammate's clone where a
75
+ host-CLI registration exists only on the machine that ran it. Uninstall reverses exactly those
76
+ entries. And the prompt names the scope: it now asks to register "for every project on this
77
+ machine", which is the detail the answer turns on.
78
+
79
+ Wiring was most of it &mdash; <b>both halves of the document logic already existed and had no
80
+ callers</b>. <code>merge_into</code> and <code>strip_owned</code> were written, tested and unused;
81
+ the new code is the file I/O around them, which lives in <code>core/store.py</code> because
82
+ <code>core/mcpdecl.py</code> is deliberately I/O-free (the same split <code>core/mcphost.py</code>
83
+ keeps).
84
+
85
+ The properties worth stating, because each is a way to destroy someone else's work: a server the
86
+ user configured by hand is never overwritten on install and never removed on uninstall; another
87
+ skill's server survives both; unrelated keys in the document survive both; an uninstall that owns
88
+ nothing does not rewrite &mdash; and so does not reformat &mdash; a file it has no claim on; and a
89
+ corrupt or absent <code>.mcp.json</code> is never fatal, because by then the skill is already on
90
+ disk. A skill declaring nothing registrable creates no file at all.
91
+
92
+ Verified by disabling the wiring and confirming the end-to-end tests fail without it, rather than
93
+ trusting that a passing test proves anything.
94
+
69
95
  Related: [[mcp-aware-skills]] (which added the declaration format),
70
96
  [[mcp-install-skips-the-injection-scan]] and [[mcp-register-names-server-before-env]].
@@ -3284,7 +3284,7 @@ suite only runs if a human remembers to run it locally, so a CLI change that bre
3284
3284
  </article>
3285
3285
 
3286
3286
  <article class="cap rcard" id="mcp-servers-ignore-install-scope">
3287
- <div class="head"><span class="pill planned">Planned</span><span class="cat">Bug · MCP</span></div>
3287
+ <div class="head"><span class="pill shipped">Shipped</span><span class="cat">Bug · MCP</span></div>
3288
3288
  <h3>A project-scoped install registers its MCP servers <em>machine-wide</em></h3>
3289
3289
  <p><code>boost install &lt;skill&gt; --scope project</code> (or <code>--here</code>) is a promise about
3290
3290
  blast radius: the skill lands inside this repo, committable, affecting nobody else's machine. The
@@ -3339,6 +3339,32 @@ the scope it was registered at, which is another reason to record it rather than
3339
3339
  names no scope. It should say which file or scope is about to change, because that is the decision
3340
3340
  being made.
3341
3341
 
3342
+ <b>Shipped, all four.</b> Scope now flows: <code>_offer_mcp</code> reads <code>res.scope</code> and
3343
+ threads it through <code>_register_mcp_server</code> into <code>register_argv</code>, so a
3344
+ user-scope install passes its scope explicitly rather than silently inheriting the
3345
+ <code>scope="user"</code> default that caused this. A project-scope install does not shell out at
3346
+ all &mdash; it records into the repo's <code>.mcp.json</code>, which is the committable, reviewable
3347
+ registration <code>--scope project</code> promises, and it arrives with a teammate's clone where a
3348
+ host-CLI registration exists only on the machine that ran it. Uninstall reverses exactly those
3349
+ entries. And the prompt names the scope: it now asks to register "for every project on this
3350
+ machine", which is the detail the answer turns on.
3351
+
3352
+ Wiring was most of it &mdash; <b>both halves of the document logic already existed and had no
3353
+ callers</b>. <code>merge_into</code> and <code>strip_owned</code> were written, tested and unused;
3354
+ the new code is the file I/O around them, which lives in <code>core/store.py</code> because
3355
+ <code>core/mcpdecl.py</code> is deliberately I/O-free (the same split <code>core/mcphost.py</code>
3356
+ keeps).
3357
+
3358
+ The properties worth stating, because each is a way to destroy someone else's work: a server the
3359
+ user configured by hand is never overwritten on install and never removed on uninstall; another
3360
+ skill's server survives both; unrelated keys in the document survive both; an uninstall that owns
3361
+ nothing does not rewrite &mdash; and so does not reformat &mdash; a file it has no claim on; and a
3362
+ corrupt or absent <code>.mcp.json</code> is never fatal, because by then the skill is already on
3363
+ disk. A skill declaring nothing registrable creates no file at all.
3364
+
3365
+ Verified by disabling the wiring and confirming the end-to-end tests fail without it, rather than
3366
+ trusting that a passing test proves anything.
3367
+
3342
3368
  Related: [[mcp-aware-skills]] (which added the declaration format),
3343
3369
  [[mcp-install-skips-the-injection-scan]] and [[mcp-register-names-server-before-env]].</p>
3344
3370
  <div class="meta">
@@ -265,3 +265,66 @@ def test_doctor_reports_intact_project_skills(boost, tapped, repo):
265
265
  boost("install", "brainstorming", "--local")
266
266
  res = boost("doctor")
267
267
  assert "project skill" in res.out and "intact" in res.out
268
+
269
+
270
+ # ── declared MCP servers stay in the repo ────────────────────────────────
271
+
272
+ def _declare_mcp(tapped, skill: str, server: str = "gh"):
273
+ """Give a skill in the tap clone an .mcp.json sidecar declaring a server."""
274
+ from boost_cli.core import catalog, mcpdecl
275
+ matches = catalog.find(skill)
276
+ assert matches, skill
277
+ src = store.source_dir_for(matches[0])
278
+ (src / mcpdecl.SIDECAR).write_text(json.dumps(
279
+ {mcpdecl.SERVERS_KEY: {server: {"command": "npx", "args": ["-y", server]}}}),
280
+ encoding="utf-8")
281
+
282
+
283
+ def test_a_local_install_records_mcp_servers_in_the_repo(boost, tapped, repo):
284
+ """THE BUG: --local promised repo-scoped and registered machine-wide.
285
+
286
+ A project install must leave its declared servers in the repo's own
287
+ .mcp.json — committable, reviewable, and arriving with a teammate's clone —
288
+ rather than in this machine's user-scope host config.
289
+ """
290
+ from boost_cli.core import mcpdecl
291
+ _declare_mcp(tapped, "brainstorming")
292
+ boost("install", "brainstorming", "--local")
293
+ sidecar = repo / mcpdecl.SIDECAR
294
+ assert sidecar.is_file(), "no .mcp.json written into the repo"
295
+ servers = json.loads(sidecar.read_text())[mcpdecl.SERVERS_KEY]
296
+ assert "gh" in servers
297
+ assert servers["gh"][mcpdecl.MARKER_KEY] == "brainstorming", \
298
+ "the entry must name the skill that asked for it, so uninstall can reverse it"
299
+
300
+
301
+ def test_uninstalling_locally_removes_the_servers_it_added(boost, tapped, repo):
302
+ from boost_cli.core import mcpdecl
303
+ _declare_mcp(tapped, "brainstorming")
304
+ boost("install", "brainstorming", "--local")
305
+ boost("uninstall", "brainstorming", "--local")
306
+ servers = json.loads((repo / mcpdecl.SIDECAR).read_text())[mcpdecl.SERVERS_KEY]
307
+ assert "gh" not in servers, \
308
+ "a skill removed from the repo must stop launching its server"
309
+
310
+
311
+ def test_uninstall_leaves_a_hand_written_server_alone(boost, tapped, repo):
312
+ from boost_cli.core import mcpdecl
313
+ (repo / mcpdecl.SIDECAR).write_text(json.dumps(
314
+ {mcpdecl.SERVERS_KEY: {"mine": {"command": "my-own-thing"}}}),
315
+ encoding="utf-8")
316
+ _declare_mcp(tapped, "brainstorming")
317
+ boost("install", "brainstorming", "--local")
318
+ boost("uninstall", "brainstorming", "--local")
319
+ servers = json.loads((repo / mcpdecl.SIDECAR).read_text())[mcpdecl.SERVERS_KEY]
320
+ assert servers["mine"] == {"command": "my-own-thing"}, \
321
+ "boost must only reverse what boost wrote"
322
+
323
+
324
+ def test_a_user_install_writes_no_sidecar_into_the_repo(boost, tapped, repo):
325
+ # The complement: user scope must not start scattering .mcp.json files into
326
+ # whatever directory the install happened to run from.
327
+ from boost_cli.core import mcpdecl
328
+ _declare_mcp(tapped, "brainstorming")
329
+ boost("install", "brainstorming")
330
+ assert not (repo / mcpdecl.SIDECAR).exists()
@@ -0,0 +1,187 @@
1
+ """Unit tests: a project-scoped install records its MCP servers in the repo.
2
+
3
+ ``boost install <skill> --scope project`` is a promise about blast radius: the
4
+ skill lands inside this repo, committable, affecting nobody else's machine. Its
5
+ declared MCP servers did not keep that promise — they were registered at *user*
6
+ scope, globally, whatever scope the skill was installed at, because
7
+ ``_offer_mcp`` never read ``res.scope`` and ``_register_mcp_server`` took no
8
+ scope at all.
9
+
10
+ The document logic for doing it properly already existed and had no callers:
11
+ ``mcpdecl.merge_into`` merges declared servers into an ``.mcp.json`` — the
12
+ committable file agents already read — stamping each entry with a marker naming
13
+ the skill that asked for it, and ``mcpdecl.strip_owned`` reverses exactly those.
14
+ Both are pure. These tests cover the file I/O that wires them up, which lives in
15
+ ``store`` because ``mcpdecl`` is deliberately I/O-free.
16
+
17
+ The properties that matter are all about *not* destroying someone else's work:
18
+ a hand-configured server, another skill's server, and any unrelated key in the
19
+ document must survive both an install and an uninstall.
20
+ """
21
+ from __future__ import annotations
22
+
23
+ import json
24
+
25
+ import pytest
26
+
27
+ from boost_cli.core import mcpdecl, store
28
+
29
+ pytestmark = pytest.mark.usefixtures("sandbox")
30
+
31
+
32
+ def _rows(*names):
33
+ """Registrable declaration rows, the shape `declared_mcp_servers` returns."""
34
+ return [{"name": n, "spec": {"command": "npx", "args": ["-y", n]}}
35
+ for n in names]
36
+
37
+
38
+ def _read(base):
39
+ return json.loads((base / mcpdecl.SIDECAR).read_text(encoding="utf-8"))
40
+
41
+
42
+ def _servers(base):
43
+ return _read(base).get(mcpdecl.SERVERS_KEY, {})
44
+
45
+
46
+ class TestRegister:
47
+ def test_writes_a_sidecar_naming_the_skill(self, tmp_path):
48
+ added = store.register_project_mcp(tmp_path, _rows("gh"), "my-skill")
49
+ assert added == ["gh"]
50
+ entry = _servers(tmp_path)["gh"]
51
+ assert entry["command"] == "npx"
52
+ assert entry[mcpdecl.MARKER_KEY] == "my-skill"
53
+
54
+ def test_the_file_is_json_a_human_can_review(self, tmp_path):
55
+ # The whole point of project scope over `mcp add` is that it lands in a
56
+ # file you can read in a diff and commit.
57
+ store.register_project_mcp(tmp_path, _rows("gh"), "sk")
58
+ text = (tmp_path / mcpdecl.SIDECAR).read_text(encoding="utf-8")
59
+ assert text.endswith("\n")
60
+ assert "\n " in text, "should be indented, not one line"
61
+
62
+ def test_an_existing_hand_written_server_is_never_overwritten(self, tmp_path):
63
+ (tmp_path / mcpdecl.SIDECAR).write_text(json.dumps(
64
+ {mcpdecl.SERVERS_KEY: {"gh": {"command": "mine"}}}), encoding="utf-8")
65
+ added = store.register_project_mcp(tmp_path, _rows("gh"), "sk")
66
+ assert added == []
67
+ assert _servers(tmp_path)["gh"] == {"command": "mine"}, \
68
+ "a server the user configured by hand must survive untouched"
69
+
70
+ def test_unrelated_keys_survive(self, tmp_path):
71
+ (tmp_path / mcpdecl.SIDECAR).write_text(
72
+ json.dumps({"inputs": [1, 2], mcpdecl.SERVERS_KEY: {}}),
73
+ encoding="utf-8")
74
+ store.register_project_mcp(tmp_path, _rows("gh"), "sk")
75
+ assert _read(tmp_path)["inputs"] == [1, 2]
76
+
77
+ def test_a_corrupt_sidecar_does_not_lose_the_install(self, tmp_path):
78
+ # Best-effort, like declared_mcp_servers: the skill is already on disk
79
+ # by this point, so an unreadable sidecar must not raise.
80
+ (tmp_path / mcpdecl.SIDECAR).write_text("{not json", encoding="utf-8")
81
+ added = store.register_project_mcp(tmp_path, _rows("gh"), "sk")
82
+ assert added == ["gh"]
83
+ assert "gh" in _servers(tmp_path)
84
+
85
+ def test_no_rows_writes_nothing(self, tmp_path):
86
+ assert store.register_project_mcp(tmp_path, [], "sk") == []
87
+ assert not (tmp_path / mcpdecl.SIDECAR).exists(), \
88
+ "a skill with no servers must not create an empty sidecar"
89
+
90
+ def test_a_name_only_declaration_is_not_invented(self, tmp_path):
91
+ # `registrable` filters these out: boost will not invent a command line.
92
+ assert store.register_project_mcp(
93
+ tmp_path, [{"name": "gh", "spec": {}}], "sk") == []
94
+ assert not (tmp_path / mcpdecl.SIDECAR).exists()
95
+
96
+ def test_two_skills_each_keep_their_own_marker(self, tmp_path):
97
+ store.register_project_mcp(tmp_path, _rows("a"), "one")
98
+ store.register_project_mcp(tmp_path, _rows("b"), "two")
99
+ servers = _servers(tmp_path)
100
+ assert servers["a"][mcpdecl.MARKER_KEY] == "one"
101
+ assert servers["b"][mcpdecl.MARKER_KEY] == "two"
102
+
103
+
104
+ class TestUnregister:
105
+ def test_removes_only_this_skills_servers(self, tmp_path):
106
+ store.register_project_mcp(tmp_path, _rows("a"), "one")
107
+ store.register_project_mcp(tmp_path, _rows("b"), "two")
108
+ removed = store.unregister_project_mcp(tmp_path, "one")
109
+ assert removed == ["a"]
110
+ assert list(_servers(tmp_path)) == ["b"], \
111
+ "another skill's server must survive this uninstall"
112
+
113
+ def test_a_hand_written_server_survives_uninstall(self, tmp_path):
114
+ (tmp_path / mcpdecl.SIDECAR).write_text(json.dumps(
115
+ {mcpdecl.SERVERS_KEY: {"mine": {"command": "x"}}}), encoding="utf-8")
116
+ store.register_project_mcp(tmp_path, _rows("gh"), "sk")
117
+ store.unregister_project_mcp(tmp_path, "sk")
118
+ assert list(_servers(tmp_path)) == ["mine"]
119
+
120
+ def test_unrelated_keys_survive_uninstall(self, tmp_path):
121
+ (tmp_path / mcpdecl.SIDECAR).write_text(
122
+ json.dumps({"inputs": [7], mcpdecl.SERVERS_KEY: {}}),
123
+ encoding="utf-8")
124
+ store.register_project_mcp(tmp_path, _rows("gh"), "sk")
125
+ store.unregister_project_mcp(tmp_path, "sk")
126
+ assert _read(tmp_path)["inputs"] == [7]
127
+
128
+ def test_no_sidecar_is_not_an_error(self, tmp_path):
129
+ assert store.unregister_project_mcp(tmp_path, "sk") == []
130
+
131
+ def test_a_corrupt_sidecar_is_not_an_error(self, tmp_path):
132
+ (tmp_path / mcpdecl.SIDECAR).write_text("{not json", encoding="utf-8")
133
+ assert store.unregister_project_mcp(tmp_path, "sk") == []
134
+
135
+ def test_nothing_owned_leaves_the_file_untouched(self, tmp_path):
136
+ original = json.dumps({mcpdecl.SERVERS_KEY: {"mine": {"command": "x"}}})
137
+ (tmp_path / mcpdecl.SIDECAR).write_text(original, encoding="utf-8")
138
+ assert store.unregister_project_mcp(tmp_path, "sk") == []
139
+ assert (tmp_path / mcpdecl.SIDECAR).read_text(encoding="utf-8") == original, \
140
+ "removing nothing must not rewrite the file"
141
+
142
+ def test_register_then_unregister_round_trips(self, tmp_path):
143
+ store.register_project_mcp(tmp_path, _rows("a", "b"), "sk")
144
+ assert sorted(_servers(tmp_path)) == ["a", "b"]
145
+ assert store.unregister_project_mcp(tmp_path, "sk") == ["a", "b"]
146
+ assert _servers(tmp_path) == {}
147
+
148
+
149
+ class TestAnUnwritableSidecarNeverCrashesAnInstall:
150
+ """The write is the half that runs AFTER the install is already committed.
151
+
152
+ By the time `register_project_mcp` is called the skill is materialized, the
153
+ project lock is written and the journal is logged. An unwritable
154
+ `.mcp.json` — read-only checkout, root-owned file, full disk — must not
155
+ turn that completed install into a traceback, which is the same contract
156
+ `_load_sidecar` already keeps for a corrupt file on the way in.
157
+ """
158
+
159
+ @staticmethod
160
+ def _unwritable(monkeypatch):
161
+ def boom(*_a, **_k):
162
+ raise OSError(13, "Permission denied")
163
+ monkeypatch.setattr(store.Path, "write_text", boom)
164
+
165
+ def test_register_reports_nothing_recorded_instead_of_raising(
166
+ self, tmp_path, monkeypatch):
167
+ self._unwritable(monkeypatch)
168
+ assert store.register_project_mcp(tmp_path, _rows("gh"), "sk") == []
169
+
170
+ def test_unregister_reports_nothing_removed_instead_of_raising(
171
+ self, tmp_path, monkeypatch):
172
+ (tmp_path / mcpdecl.SIDECAR).write_text(json.dumps(
173
+ {mcpdecl.SERVERS_KEY: {"gh": {"command": "npx",
174
+ mcpdecl.MARKER_KEY: "sk"}}}),
175
+ encoding="utf-8")
176
+ self._unwritable(monkeypatch)
177
+ assert store.unregister_project_mcp(tmp_path, "sk") == []
178
+
179
+ def test_a_failed_write_is_not_reported_as_success(self, tmp_path,
180
+ monkeypatch):
181
+ # The return value is what the install report prints, so it must not
182
+ # name servers that were never written.
183
+ self._unwritable(monkeypatch)
184
+ recorded = store.register_project_mcp(tmp_path, _rows("a", "b"), "sk")
185
+ assert recorded == [], \
186
+ "claiming a server was recorded when the file could not be " \
187
+ "written is worse than the failure itself"