boost-skill-cli 1.0.188__tar.gz → 1.0.190__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 (349) hide show
  1. boost_skill_cli-1.0.190/.lighthouserc.json +29 -0
  2. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/PKG-INFO +1 -1
  3. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/_version.py +2 -2
  4. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/core/scopes.py +24 -0
  5. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/core/store.py +19 -0
  6. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_skill_cli.egg-info/PKG-INFO +1 -1
  7. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_skill_cli.egg-info/SOURCES.txt +2 -0
  8. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/index.html +11 -10
  9. boost_skill_cli-1.0.190/docs/roadmap/items/lighthouse-ci-on-the-pages-site.md +27 -0
  10. boost_skill_cli-1.0.190/docs/roadmap/items/project-scope-symlink-escape-on-write.md +33 -0
  11. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap.html +42 -6
  12. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/style/boost.css +5 -2
  13. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_scopes.py +38 -0
  14. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_store.py +25 -0
  15. boost_skill_cli-1.0.188/docs/roadmap/items/lighthouse-ci-on-the-pages-site.md +0 -20
  16. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/.gitattributes +0 -0
  17. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/.gitignore +0 -0
  18. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/.gitleaks.toml +0 -0
  19. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/.htmlvalidate.json +0 -0
  20. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/.lycheeignore +0 -0
  21. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/.markdownlint-cli2.jsonc +0 -0
  22. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/.pre-commit-config.yaml +0 -0
  23. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/.stylelintrc.json +0 -0
  24. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/.vale/styles/boost/Terminology.yml +0 -0
  25. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/.vale/styles/config/vocabularies/boost/accept.txt +0 -0
  26. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/.vale.ini +0 -0
  27. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/CLAUDE.md +0 -0
  28. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/CONTRIBUTING.md +0 -0
  29. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/LICENSE +0 -0
  30. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/MANIFEST.in +0 -0
  31. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/Makefile +0 -0
  32. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/README.md +0 -0
  33. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/SECURITY.md +0 -0
  34. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost +0 -0
  35. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/__init__.py +0 -0
  36. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/__main__.py +0 -0
  37. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/cli.py +0 -0
  38. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/cliparse.py +0 -0
  39. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/commands/__init__.py +0 -0
  40. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/commands/bmad.py +0 -0
  41. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/commands/configuration.py +0 -0
  42. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/commands/discovery.py +0 -0
  43. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/commands/hooks.py +0 -0
  44. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/commands/info.py +0 -0
  45. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/commands/intelligence.py +0 -0
  46. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/commands/pkg.py +0 -0
  47. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/commands/quality.py +0 -0
  48. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/commands/taps.py +0 -0
  49. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/commands/team.py +0 -0
  50. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/core/__init__.py +0 -0
  51. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/core/adapters.py +0 -0
  52. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/core/agents.py +0 -0
  53. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/core/ai.py +0 -0
  54. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/core/catalog.py +0 -0
  55. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/core/claude_settings.py +0 -0
  56. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/core/config.py +0 -0
  57. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/core/dense.py +0 -0
  58. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/core/embed.py +0 -0
  59. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/core/frontmatter.py +0 -0
  60. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/core/gitutil.py +0 -0
  61. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/core/imperative.py +0 -0
  62. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/core/injectscan.py +0 -0
  63. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/core/journal.py +0 -0
  64. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/core/lockfile.py +0 -0
  65. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/core/logs.py +0 -0
  66. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/core/mcp.py +0 -0
  67. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/core/nethttp.py +0 -0
  68. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/core/output.py +0 -0
  69. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/core/paths.py +0 -0
  70. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/core/policy.py +0 -0
  71. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/core/projectlock.py +0 -0
  72. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/core/rag.py +0 -0
  73. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/core/registry.py +0 -0
  74. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/core/rules.py +0 -0
  75. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/core/secretscan.py +0 -0
  76. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/core/serve.py +0 -0
  77. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/core/stackprobe.py +0 -0
  78. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/core/staleness.py +0 -0
  79. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/core/typosquat.py +0 -0
  80. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/core/updatediff.py +0 -0
  81. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/core/util.py +0 -0
  82. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/core/workflows.py +0 -0
  83. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/data/registries.json +0 -0
  84. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/errors.py +0 -0
  85. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_cli/spin.py +0 -0
  86. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_skill_cli.egg-info/dependency_links.txt +0 -0
  87. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_skill_cli.egg-info/entry_points.txt +0 -0
  88. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_skill_cli.egg-info/requires.txt +0 -0
  89. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/boost_skill_cli.egg-info/top_level.txt +0 -0
  90. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/.claude/settings.local.json +0 -0
  91. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/DEBUGGING.md +0 -0
  92. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/adapters.html +0 -0
  93. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/commands.html +0 -0
  94. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/demo.gif +0 -0
  95. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/demo.tape +0 -0
  96. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/design-roadmap.html +0 -0
  97. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/eval.html +0 -0
  98. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/mcp-hub.html +0 -0
  99. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/rag-architecture.md +0 -0
  100. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/BOOST-D01.md +0 -0
  101. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/BOOST-D02.md +0 -0
  102. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/BOOST-D03.md +0 -0
  103. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/BOOST-D04.md +0 -0
  104. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/BOOST-D05.md +0 -0
  105. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/BOOST-D06.md +0 -0
  106. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/BOOST-D07.md +0 -0
  107. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/BOOST-D08.md +0 -0
  108. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/BOOST-D09.md +0 -0
  109. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/BOOST-D10.md +0 -0
  110. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/BOOST-D11.md +0 -0
  111. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/BOOST-D12.md +0 -0
  112. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/BOOST-D13.md +0 -0
  113. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/BOOST-D14.md +0 -0
  114. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/BOOST-D15.md +0 -0
  115. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/BOOST-D16.md +0 -0
  116. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/BOOST-D17.md +0 -0
  117. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/BOOST-D18.md +0 -0
  118. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/BOOST-D19.md +0 -0
  119. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/BOOST-D20.md +0 -0
  120. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/BOOST-D21.md +0 -0
  121. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/BOOST-D22.md +0 -0
  122. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/BOOST-D23.md +0 -0
  123. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/BOOST-D24.md +0 -0
  124. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/BOOST-D25.md +0 -0
  125. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/BOOST-D26.md +0 -0
  126. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/accessibility-audit-pa11y-ci-axe-core.md +0 -0
  127. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/atomic-corruption-safe-lock-file-writes.md +0 -0
  128. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/atomic-skill-install-temp-dir-swap.md +0 -0
  129. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/autonomous-ship-workflow-and-isolated-worktree.md +0 -0
  130. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/boost-run-live-agents.md +0 -0
  131. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/bring-commands-under-mutation-testing.md +0 -0
  132. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/broken-link-and-anchor-checking-lychee.md +0 -0
  133. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/browse-crashes-selecting-a-rule-or-workflow.md +0 -0
  134. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/build-provenance-slsa-attestations.md +0 -0
  135. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/cache-the-catalog-entry-set-across-rag-queries.md +0 -0
  136. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/capability-manifest-and-least-privilege-policy.md +0 -0
  137. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/clean-env-install-smoke-pip-and-pipx.md +0 -0
  138. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/command-reference-docs-site.md +0 -0
  139. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/complexity-and-dead-code-radar-xenon-vulture.md +0 -0
  140. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/consolidate-skill-staleness-drift-logic-into-cor.md +0 -0
  141. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/coverage-dashboard-codecov-free-for-oss.md +0 -0
  142. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/coverage-guided-fuzzing-atheris-oss-fuzz.md +0 -0
  143. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/crash-recorder-error-paths-core-logs-py.md +0 -0
  144. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/dependency-cve-gate-pip-audit.md +0 -0
  145. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/docstring-coverage-interrogate.md +0 -0
  146. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/doctor-checks-rules-and-workflows.md +0 -0
  147. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/end-of-options-guard-on-git-commands.md +0 -0
  148. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/extension-free-tests-core-dense-py.md +0 -0
  149. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/extract-mcp-http-servers-out-of-configuration-py.md +0 -0
  150. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/finish-mutation-hardening-across-core.md +0 -0
  151. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/fix-self-update-version-detection-dead-branch.md +0 -0
  152. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/fork-safe-network-proxy-handler.md +0 -0
  153. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/framework-adapter-langgraph.md +0 -0
  154. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/framework-adapter-multi-agent.md +0 -0
  155. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/framework-adapters-boost-adapt.md +0 -0
  156. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/frontmatter-scalar-over-coercion.md +0 -0
  157. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/github-pages-deploy-is-broken-every-push.md +0 -0
  158. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/golden-set-statistical-power.md +0 -0
  159. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/hash-pinned-reproducible-toolchain-uv-lock.md +0 -0
  160. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/html-validation-html-validate.md +0 -0
  161. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/install-scope-user-or-project.md +0 -0
  162. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/integrity-verification-boost-verify.md +0 -0
  163. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/invocation-pid-logging-for-crash-correlation.md +0 -0
  164. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/layering-guard-import-linter.md +0 -0
  165. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/list-rules-and-workflows.md +0 -0
  166. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/localize-the-stored-bm25-snippet.md +0 -0
  167. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/lockfile-enforcement-and-commit-pinning.md +0 -0
  168. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/log-timestamps-mislabeled-utc.md +0 -0
  169. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/lowest-version-resolution-uv-resolution-lowest-d.md +0 -0
  170. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/make-the-roadmaps-discoverable.md +0 -0
  171. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/markdown-consistency-markdownlint-cli2.md +0 -0
  172. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/mcp-hub-diagram-node-text-overflow.md +0 -0
  173. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/mcp-launch-objc-fork-safety.md +0 -0
  174. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/mcp-register-names-server-before-env.md +0 -0
  175. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/mcp-startup-self-harden-fork-safety.md +0 -0
  176. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/memoize-config-load-in-process.md +0 -0
  177. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/modernization-smells-refurb-pyupgrade.md +0 -0
  178. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/mutation-hardening-core-frontmatter-py.md +0 -0
  179. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/mutation-hardening-core-gitutil-py.md +0 -0
  180. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/mutation-hardening-core-store-py.md +0 -0
  181. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/one-command-every-env-nox.md +0 -0
  182. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/one-shared-atomic-write-helper.md +0 -0
  183. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/package-metadata-validation-twine-check-friends.md +0 -0
  184. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/patch-coverage-gate-diff-cover.md +0 -0
  185. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/performance-regression-gate-pytest-benchmark.md +0 -0
  186. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/post-deploy-smoke-headless-load-check.md +0 -0
  187. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/pre-release-python-canary-3-14t-free-threaded.md +0 -0
  188. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/project-scope-across-every-command.md +0 -0
  189. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/promote-nav-footer-into-the-shared-style-system.md +0 -0
  190. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/prompt-injection-scanning-of-skill-markdown.md +0 -0
  191. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/property-based-tests-hypothesis-on-the-parsers.md +0 -0
  192. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/prose-and-terminology-linting-vale.md +0 -0
  193. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/prune-ignored-dirs-during-scan-dir-walk.md +0 -0
  194. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/quality-dashboard-sonarcloud-free-for-oss.md +0 -0
  195. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/ranx-significance-monitor.md +0 -0
  196. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/reconcile-the-theme-drift.md +0 -0
  197. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/refresh-the-marketing-surface.md +0 -0
  198. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/retrieval-quality-eval-harness.md +0 -0
  199. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/reuse-helpers-kill-minor-dead-work.md +0 -0
  200. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/robust-tag-argument-parsing.md +0 -0
  201. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/rule-install-native-materialization.md +0 -0
  202. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/runner-egress-monitoring-stepsecurity-harden-run.md +0 -0
  203. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/runtime-explain-faithfulness-guardrail.md +0 -0
  204. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/sbom-aware-scanning-osv-scanner.md +0 -0
  205. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/sbom-on-every-release-cyclonedx-syft.md +0 -0
  206. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/scan-and-sync-rules-and-workflows.md +0 -0
  207. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/second-type-checker-pyright.md +0 -0
  208. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/secret-and-pii-scanning-of-installed-skills.md +0 -0
  209. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/secret-scanning-gitleaks-push-protection.md +0 -0
  210. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/security-linting-bandit-via-ruff-s-rules.md +0 -0
  211. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/shift-left-gate-pre-commit-pre-commit-ci.md +0 -0
  212. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/single-imperative-rule-extractor.md +0 -0
  213. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/single-tech-stack-prober.md +0 -0
  214. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/split-oversized-command-modules.md +0 -0
  215. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/startup-and-import-time-budget-x-importtime.md +0 -0
  216. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/stop-re-serializing-entry-meta-on-every-search.md +0 -0
  217. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/supply-chain-posture-openssf-scorecard.md +0 -0
  218. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/surface-every-docs-page-from-the-guide.md +0 -0
  219. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/tap-signing-and-provenance-sigstore-minisign.md +0 -0
  220. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/theme-asset-linting-stylelint-eslint.md +0 -0
  221. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/typo-detection-codespell.md +0 -0
  222. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/typosquat-and-name-confusion-detection.md +0 -0
  223. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/unify-tilde-two-copies-have-a-boundary-bug.md +0 -0
  224. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/untrack-generated-build-noise.md +0 -0
  225. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/update-diff-before-apply.md +0 -0
  226. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/update-refreshes-rules-and-workflows.md +0 -0
  227. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/visual-regression-pass-on-the-guide.md +0 -0
  228. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/widen-the-ruff-rule-surface-b-sim-c4-perf-ruf.md +0 -0
  229. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/windows-in-the-ci-matrix.md +0 -0
  230. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/workflow-install-native-materialization.md +0 -0
  231. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/workflow-linting-actionlint.md +0 -0
  232. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/workflow-sast-zizmor.md +0 -0
  233. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/docs/roadmap/items/workspace-scope-install.md +0 -0
  234. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/eslint.config.mjs +0 -0
  235. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/examples/README.md +0 -0
  236. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/examples/adapt-demo.sh +0 -0
  237. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/examples/boost-run-prototype.sh +0 -0
  238. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/index.html +0 -0
  239. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/noxfile.py +0 -0
  240. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/pyproject.toml +0 -0
  241. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/scripts/bench_cli.sh +0 -0
  242. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/scripts/build_command_reference.py +0 -0
  243. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/scripts/build_registries.py +0 -0
  244. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/scripts/build_roadmap.py +0 -0
  245. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/scripts/check_anchors.py +0 -0
  246. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/scripts/ensure_eval_corpus.sh +0 -0
  247. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/scripts/eval_explain.py +0 -0
  248. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/scripts/eval_recommend.py +0 -0
  249. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/scripts/eval_retrieval.py +0 -0
  250. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/scripts/eval_stats_summary.py +0 -0
  251. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/scripts/import_budget.py +0 -0
  252. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/scripts/mutation_gate.py +0 -0
  253. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/scripts/perf_gate.py +0 -0
  254. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/setup.cfg +0 -0
  255. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/style/README.md +0 -0
  256. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/style/boost.js +0 -0
  257. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/style/demo.html +0 -0
  258. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/bdd/features/adapt.feature +0 -0
  259. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/bdd/features/browse.feature +0 -0
  260. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/bdd/features/count.feature +0 -0
  261. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/bdd/features/discover.feature +0 -0
  262. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/bdd/features/doctor.feature +0 -0
  263. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/bdd/features/environment.py +0 -0
  264. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/bdd/features/explain.feature +0 -0
  265. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/bdd/features/index.feature +0 -0
  266. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/bdd/features/install.feature +0 -0
  267. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/bdd/features/list.feature +0 -0
  268. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/bdd/features/mcp.feature +0 -0
  269. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/bdd/features/search.feature +0 -0
  270. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/bdd/features/steps/cli_steps.py +0 -0
  271. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/bdd/features/steps/discovery_steps.py +0 -0
  272. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/bdd/features/steps/mcp_steps.py +0 -0
  273. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/bdd/features/steps/quality_steps.py +0 -0
  274. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/conftest.py +0 -0
  275. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/eval/baseline.json +0 -0
  276. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/eval/explain.jsonl +0 -0
  277. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/eval/golden.jsonl +0 -0
  278. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/eval/recommend.jsonl +0 -0
  279. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/eval/taps.txt +0 -0
  280. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/functional/test_cli_adapt.py +0 -0
  281. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/functional/test_cli_bmad.py +0 -0
  282. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/functional/test_cli_configuration.py +0 -0
  283. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/functional/test_cli_discovery.py +0 -0
  284. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/functional/test_cli_hooks.py +0 -0
  285. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/functional/test_cli_info.py +0 -0
  286. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/functional/test_cli_intelligence.py +0 -0
  287. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/functional/test_cli_pkg.py +0 -0
  288. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/functional/test_cli_quality.py +0 -0
  289. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/functional/test_cli_taps.py +0 -0
  290. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/functional/test_cli_team.py +0 -0
  291. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/functional/test_everyday_loop.py +0 -0
  292. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/functional/test_property_parsers.py +0 -0
  293. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/functional/test_workspace_scope.py +0 -0
  294. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/make_fixture.py +0 -0
  295. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/perf/test_benchmarks.py +0 -0
  296. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/smoke.sh +0 -0
  297. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_adapters.py +0 -0
  298. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_agents.py +0 -0
  299. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_ai.py +0 -0
  300. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_catalog.py +0 -0
  301. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_check_anchors.py +0 -0
  302. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_claude_settings.py +0 -0
  303. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_cliparse.py +0 -0
  304. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_command_reference_fresh.py +0 -0
  305. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_config.py +0 -0
  306. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_dense.py +0 -0
  307. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_dense_fallback.py +0 -0
  308. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_docs_pages_linked.py +0 -0
  309. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_embed.py +0 -0
  310. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_errors_and_cli_table.py +0 -0
  311. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_eval_stats_summary.py +0 -0
  312. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_frontmatter.py +0 -0
  313. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_gitleaks_config.py +0 -0
  314. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_gitutil.py +0 -0
  315. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_imperative.py +0 -0
  316. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_import_budget.py +0 -0
  317. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_injectscan.py +0 -0
  318. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_journal.py +0 -0
  319. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_lockfile.py +0 -0
  320. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_logs.py +0 -0
  321. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_mcp.py +0 -0
  322. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_mutation_hardening.py +0 -0
  323. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_nethttp.py +0 -0
  324. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_output.py +0 -0
  325. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_paths.py +0 -0
  326. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_perf_gate.py +0 -0
  327. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_pkg_confusions.py +0 -0
  328. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_pkg_injection.py +0 -0
  329. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_pkg_secrets.py +0 -0
  330. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_policy.py +0 -0
  331. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_projectlock.py +0 -0
  332. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_rag.py +0 -0
  333. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_registries_fresh.py +0 -0
  334. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_registry.py +0 -0
  335. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_roadmap_fresh.py +0 -0
  336. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_rules.py +0 -0
  337. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_secretscan.py +0 -0
  338. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_serve.py +0 -0
  339. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_spin.py +0 -0
  340. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_stackprobe.py +0 -0
  341. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_staleness.py +0 -0
  342. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_token_parity.py +0 -0
  343. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_typosquat.py +0 -0
  344. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_updatediff.py +0 -0
  345. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_util.py +0 -0
  346. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_version.py +0 -0
  347. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/unit/test_workflows.py +0 -0
  348. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/visual/package.json +0 -0
  349. {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.190}/tests/visual/visual_check.mjs +0 -0
@@ -0,0 +1,29 @@
1
+ {
2
+ "ci": {
3
+ "collect": {
4
+ "startServerCommand": "python3 -m http.server 8099 --bind 127.0.0.1",
5
+ "startServerReadyPattern": "Serving HTTP",
6
+ "url": [
7
+ "http://127.0.0.1:8099/docs/index.html",
8
+ "http://127.0.0.1:8099/docs/roadmap.html"
9
+ ],
10
+ "numberOfRuns": 3,
11
+ "settings": {
12
+ "chromeFlags": "--no-sandbox --headless=new"
13
+ }
14
+ },
15
+ "assert": {
16
+ "aggregationMethod": "median-run",
17
+ "assertions": {
18
+ "categories:performance": ["error", { "minScore": 0.85 }],
19
+ "categories:accessibility": ["error", { "minScore": 0.95 }],
20
+ "categories:best-practices": ["error", { "minScore": 0.9 }],
21
+ "categories:seo": ["error", { "minScore": 0.95 }]
22
+ }
23
+ },
24
+ "upload": {
25
+ "target": "filesystem",
26
+ "outputDir": ".lighthouseci"
27
+ }
28
+ }
29
+ }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: boost-skill-cli
3
- Version: 1.0.188
3
+ Version: 1.0.190
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.188'
22
- __version_tuple__ = version_tuple = (1, 0, 188)
21
+ __version__ = version = '1.0.190'
22
+ __version_tuple__ = version_tuple = (1, 0, 190)
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -203,3 +203,27 @@ def contains(base, path) -> bool:
203
203
  return os.path.commonpath([str(base_r), str(path_r)]) == str(base_r)
204
204
  except (OSError, ValueError):
205
205
  return False
206
+
207
+
208
+ def ensure_in_base(base, path):
209
+ """Raise if ``path`` would resolve outside ``base`` — the guard before any
210
+ project-scope WRITE, the mirror of :func:`contains` before every delete.
211
+
212
+ A project destination is built from directory names committed in the repo
213
+ (``.claude/skills`` and its per-agent siblings). A hostile repo can ship one
214
+ of those as a symlink pointing outside the tree — at ``~/.ssh``, say — and
215
+ the ``mkdir(parents=True)`` + ``os.replace`` that materializes a skill would
216
+ then run on the far side, escaping the project entirely. The squatter check
217
+ (refuse to overwrite a path boost did not create) does not stop this:
218
+ dropping a *new* name like ``authorized_keys`` collides with nothing, and
219
+ ``--force`` waives it regardless. ``contains`` resolves symlinks on both
220
+ ends, so re-deriving containment here — before the write, independent of
221
+ existence or force — is the boundary that actually holds. Returns ``path``
222
+ so a caller can wrap the target inline.
223
+ """
224
+ if not contains(base, path):
225
+ raise BoostError(
226
+ "refusing to install %s: it resolves outside this project" % path,
227
+ hint="a directory such as .claude/skills in this repo is a symlink "
228
+ "pointing outside it — remove or replace it, then reinstall")
229
+ return Path(path)
@@ -281,6 +281,15 @@ def _install_project_skill(entry: dict, force: bool = False,
281
281
  for agent, skills_dir in agents.enabled_agents().items()
282
282
  if not only_agents or agent in only_agents]
283
283
 
284
+ # Refuse to write through a symlink that leaves the repo. An agent dir like
285
+ # ``.claude/skills`` is committed, so a hostile clone can ship it as a
286
+ # symlink to ``~/.ssh`` and the copy below would land on the far side.
287
+ # Checked for every target up front — before existence, force, or any write
288
+ # — so a single escaping dir aborts the whole install rather than writing
289
+ # part of it outside the project first.
290
+ for _agent, dest in targets:
291
+ scopes.ensure_in_base(resolved_base, dest)
292
+
284
293
  # Refuse to clobber a directory boost did not put there. In user scope the
285
294
  # store is boost's alone, but here the destination is inside someone's repo
286
295
  # — a same-named hand-written skill is a real possibility, and overwriting
@@ -492,6 +501,11 @@ def _install_rule(entry: dict, force: bool = False,
492
501
  if only_agents and agent not in only_agents:
493
502
  continue
494
503
  mode, path = rules.rule_target(agent, skills_dir, name, base=resolved_base)
504
+ # Project scope writes into the repo, so a committed agent dir could be
505
+ # a symlink escaping it (see scopes.ensure_in_base). User scope writes
506
+ # into the user's own ~/.claude, which they control — nothing to guard.
507
+ if resolved_base is not None:
508
+ scopes.ensure_in_base(resolved_base, path)
495
509
  path.parent.mkdir(parents=True, exist_ok=True)
496
510
  if mode == rules.MODE_CLAUDE:
497
511
  current = path.read_text(encoding="utf-8") if path.exists() else ""
@@ -591,6 +605,11 @@ def _install_workflow(entry: dict, force: bool = False,
591
605
  if only_agents and agent not in only_agents:
592
606
  continue
593
607
  path = workflows.workflow_target(skills_dir, slot, name, base=resolved_base)
608
+ # Project scope writes into the repo; a committed agent dir could be a
609
+ # symlink escaping it (see scopes.ensure_in_base). User scope writes into
610
+ # the user's own ~/.claude, which they control — nothing to guard.
611
+ if resolved_base is not None:
612
+ scopes.ensure_in_base(resolved_base, path)
594
613
  path.parent.mkdir(parents=True, exist_ok=True)
595
614
  util.atomic_write_text(path, raw)
596
615
  materializations.append({"agent": agent, "slot": slot, "path": str(path)})
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: boost-skill-cli
3
- Version: 1.0.188
3
+ Version: 1.0.190
4
4
  Summary: boost — Homebrew for AI coding skills
5
5
  Author: Jonathan Reyes
6
6
  License: GNU GENERAL PUBLIC LICENSE
@@ -2,6 +2,7 @@
2
2
  .gitignore
3
3
  .gitleaks.toml
4
4
  .htmlvalidate.json
5
+ .lighthouserc.json
5
6
  .lycheeignore
6
7
  .markdownlint-cli2.jsonc
7
8
  .pre-commit-config.yaml
@@ -184,6 +185,7 @@ docs/roadmap/items/performance-regression-gate-pytest-benchmark.md
184
185
  docs/roadmap/items/post-deploy-smoke-headless-load-check.md
185
186
  docs/roadmap/items/pre-release-python-canary-3-14t-free-threaded.md
186
187
  docs/roadmap/items/project-scope-across-every-command.md
188
+ docs/roadmap/items/project-scope-symlink-escape-on-write.md
187
189
  docs/roadmap/items/promote-nav-footer-into-the-shared-style-system.md
188
190
  docs/roadmap/items/prompt-injection-scanning-of-skill-markdown.md
189
191
  docs/roadmap/items/property-based-tests-hypothesis-on-the-parsers.md
@@ -3,6 +3,7 @@
3
3
  <head>
4
4
  <meta charset="utf-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <meta name="description" content="boost is a package manager for AI coding skills — find, install, and govern the SKILL.md, rule, and workflow files that Claude Code, Cursor, and Windsurf run on, wired into every agent in one pass.">
6
7
  <title>boost — Homebrew for AI coding skills</title>
7
8
  <!-- Canonical Aurora tokens + primitives (single source of truth). The
8
9
  inline block below carries ONLY page-specific layout, and wins ties
@@ -184,8 +185,8 @@
184
185
  font-family: var(--mono); font-size: 10.5px; font-weight: 700;
185
186
  letter-spacing: .2em; text-transform: uppercase; color: var(--text-2);
186
187
  }
187
- .node h4 { font-size: 18px; font-weight: 750; margin-top: 8px; letter-spacing: -.01em; }
188
- .node h4 code { font-size: 15.5px; color: var(--cyan); }
188
+ .node h3 { font-size: 18px; font-weight: 750; margin-top: 8px; letter-spacing: -.01em; }
189
+ .node h3 code { font-size: 15.5px; color: var(--cyan); }
189
190
  .node p { font-size: 13.5px; color: var(--text-2); margin-top: 6px; }
190
191
  .node.src { border-color: rgba(96,165,250,.5); box-shadow: 0 0 32px rgba(96,165,250,.07); }
191
192
  .node.mid { border-color: rgba(255,255,255,.14); }
@@ -473,7 +474,7 @@ facilitate structured divergent thinking:
473
474
  <div class="flow-row one reveal">
474
475
  <div class="node src">
475
476
  <span class="tag">Source</span>
476
- <h4>GitHub registries</h4>
477
+ <h3>GitHub registries</h3>
477
478
  <p>5 pre-tapped registries + a 10,000-skill discovery index</p>
478
479
  </div>
479
480
  </div>
@@ -484,12 +485,12 @@ facilitate structured divergent thinking:
484
485
  <div class="flow-row two reveal">
485
486
  <div class="node mid">
486
487
  <span class="tag">Local Mirror</span>
487
- <h4><code>~/.boost/repos/</code></h4>
488
+ <h3><code>~/.boost/repos/</code></h3>
488
489
  <p>Shallow git clones</p>
489
490
  </div>
490
491
  <div class="node mid">
491
492
  <span class="tag">Search Cache</span>
492
- <h4><code>~/.boost/cache/</code></h4>
493
+ <h3><code>~/.boost/cache/</code></h3>
493
494
  <p>JSON catalogs from SKILL.md frontmatter</p>
494
495
  </div>
495
496
  </div>
@@ -500,12 +501,12 @@ facilitate structured divergent thinking:
500
501
  <div class="flow-row two reveal">
501
502
  <div class="node store">
502
503
  <span class="tag">Canonical Store</span>
503
- <h4><code>~/.agents/skills/</code></h4>
504
+ <h3><code>~/.agents/skills/</code></h3>
504
505
  <p>Single source of truth for installed skills</p>
505
506
  </div>
506
507
  <div class="node lock">
507
508
  <span class="tag">Lock File</span>
508
- <h4><code>.skill-lock.json</code></h4>
509
+ <h3><code>.skill-lock.json</code></h3>
509
510
  <p>v3 schema — pins version, commit &amp; content hash</p>
510
511
  </div>
511
512
  </div>
@@ -516,17 +517,17 @@ facilitate structured divergent thinking:
516
517
  <div class="flow-row three reveal">
517
518
  <div class="node agent">
518
519
  <span class="tag">Agent</span>
519
- <h4>Claude Code</h4>
520
+ <h3>Claude Code</h3>
520
521
  <p><code>~/.claude/skills/</code></p>
521
522
  </div>
522
523
  <div class="node agent">
523
524
  <span class="tag">Agent</span>
524
- <h4>Windsurf</h4>
525
+ <h3>Windsurf</h3>
525
526
  <p><code>~/.windsurf/skills/</code></p>
526
527
  </div>
527
528
  <div class="node agent">
528
529
  <span class="tag">Agent</span>
529
- <h4>Cursor</h4>
530
+ <h3>Cursor</h3>
530
531
  <p><code>~/.cursor/skills/</code></p>
531
532
  </div>
532
533
  </div>
@@ -0,0 +1,27 @@
1
+ ---
2
+ id: lighthouse-ci-on-the-pages-site
3
+ board: code
4
+ section: docsite
5
+ status: shipped
6
+ category: Docs · Perf
7
+ complexity: M
8
+ impact: High
9
+ wow: 5
10
+ note: 4 budgets + 3 real a11y fixes
11
+ order: 2
12
+ owner: loop/lighthouse
13
+ pr: 214
14
+ title: Lighthouse CI on the Pages site
15
+ ---
16
+ <code>treosh/lighthouse-ci-action</code> scores <code>index.html</code>
17
+ and <code>roadmap.html</code> on performance, accessibility,
18
+ best-practices and SEO on every deploy, and fails the build against
19
+ budgets. Turns the marketing surface's quality into four numbers that can't
20
+ silently regress as the Aurora theme evolves — four floors (a11y and
21
+ SEO 0.95, best-practices 0.90, the noisier performance 0.85) asserted
22
+ on the median of three runs, calibrated below the real scores with
23
+ margin the same way <code>perf_gate</code> sets its thresholds. And,
24
+ as every checker on this repo has, it found real defects on the
25
+ storefront: muted text at <code>3.9:1</code> contrast (below WCAG AA),
26
+ an <code>h2 → h4</code> heading skip, and colour-only footer links —
27
+ all fixed, so both pages now score <code>100</code> on accessibility.
@@ -0,0 +1,33 @@
1
+ ---
2
+ id: project-scope-symlink-escape-on-write
3
+ board: code
4
+ section: trust
5
+ status: shipped
6
+ category: Security · Integrity
7
+ complexity: S
8
+ impact: High
9
+ wow: 4
10
+ note: hostile repo could write outside itself
11
+ order: 6
12
+ owner: loop/writeguard
13
+ pr: 213
14
+ title: Project scope — refuse to write through an escaping symlink
15
+ ---
16
+ Workspace scope (<a href="https://github.com/jonnyeclectic/boost/pull/212">#212</a>)
17
+ guarded the delete side — <code>uninstall --local</code> re-derives every
18
+ recorded path and refuses one that resolves outside the repo — but not
19
+ the <em>write</em> side. A project install builds its destination from
20
+ agent-dir names committed in the repo
21
+ (<code>.claude/skills</code> and its per-agent siblings), and a hostile
22
+ clone can ship one of those as a <strong>symlink pointing outside the
23
+ tree</strong> — at <code>~/.ssh</code>, say. Cloning that repo and
24
+ running <code>boost install &lt;skill&gt; --local</code> then writes on the
25
+ far side: confirmed by reproduction, a skill directory landed in a
26
+ sibling of the repo instead of inside it. The squatter check does not
27
+ stop it (a brand-new leaf name like <code>authorized_keys</code>
28
+ collides with nothing, and <code>--force</code> waives it anyway).
29
+ <code>scopes.ensure_in_base</code> is the write-side mirror of the
30
+ delete guard: it re-derives containment through symlinks for every
31
+ target up front, so one escaping directory aborts the whole install
32
+ before anything is written. Covers all three project-scope kinds —
33
+ skill, rule and workflow.
@@ -73,7 +73,7 @@
73
73
  .legend .k { display: inline-flex; align-items: center; gap: 8px; }
74
74
 
75
75
  footer { text-align: center; padding: 60px 0 48px; color: var(--text-3); font-size: 13px; }
76
- footer a { color: var(--cyan); text-decoration: none; }
76
+ footer a { color: var(--cyan); text-decoration: underline; }
77
77
 
78
78
  @media (max-width: 560px) { .topbar nav { display: none; } }
79
79
  </style>
@@ -118,7 +118,7 @@
118
118
  <div class="stat"><b>16</b><span>Shipped</span></div>
119
119
  <div class="stat"><b>1</b><span>Next up</span></div>
120
120
  <div class="stat"><b>4</b><span>Planned</span></div>
121
- <div class="stat"><b>109</b><span>Loop finds</span></div>
121
+ <div class="stat"><b>110</b><span>Loop finds</span></div>
122
122
  <!-- /ROADMAP:stats -->
123
123
  </div>
124
124
  </section>
@@ -1560,18 +1560,25 @@ and the work stays visible.</p>
1560
1560
  </article>
1561
1561
 
1562
1562
  <article class="cap rcard">
1563
- <div class="head"><span class="pill planned">Planned</span><span class="cat">Docs · Perf</span></div>
1563
+ <div class="head"><span class="pill shipped">Shipped</span><span class="cat">Docs · Perf</span></div>
1564
1564
  <h3>Lighthouse CI on the Pages site</h3>
1565
1565
  <p><code>treosh/lighthouse-ci-action</code> scores <code>index.html</code>
1566
1566
  and <code>roadmap.html</code> on performance, accessibility,
1567
1567
  best-practices and SEO on every deploy, and fails the build against
1568
- budgets. Turns the marketing surface's quality into a number that can't
1569
- silently regress as the Aurora theme evolves.</p>
1568
+ budgets. Turns the marketing surface's quality into four numbers that can't
1569
+ silently regress as the Aurora theme evolves — four floors (a11y and
1570
+ SEO 0.95, best-practices 0.90, the noisier performance 0.85) asserted
1571
+ on the median of three runs, calibrated below the real scores with
1572
+ margin the same way <code>perf_gate</code> sets its thresholds. And,
1573
+ as every checker on this repo has, it found real defects on the
1574
+ storefront: muted text at <code>3.9:1</code> contrast (below WCAG AA),
1575
+ an <code>h2 → h4</code> heading skip, and colour-only footer links —
1576
+ all fixed, so both pages now score <code>100</code> on accessibility.</p>
1570
1577
  <div class="meta">
1571
1578
  <span class="m">Complexity <b>M</b></span>
1572
1579
  <span class="m hi">Impact <b>High</b></span>
1573
1580
  <span class="m">Wow <b class="wow">★★★★★</b></span>
1574
- <span class="m">4 score budgets</span>
1581
+ <span class="m">4 budgets + 3 real a11y fixes</span>
1575
1582
  </div>
1576
1583
  </article>
1577
1584
 
@@ -2082,6 +2089,35 @@ paths.</p>
2082
2089
  </div>
2083
2090
  </article>
2084
2091
 
2092
+ <article class="cap rcard">
2093
+ <div class="head"><span class="pill shipped">Shipped</span><span class="cat">Security · Integrity</span></div>
2094
+ <h3>Project scope — refuse to write through an escaping symlink</h3>
2095
+ <p>Workspace scope (<a href="https://github.com/jonnyeclectic/boost/pull/212">#212</a>)
2096
+ guarded the delete side — <code>uninstall --local</code> re-derives every
2097
+ recorded path and refuses one that resolves outside the repo — but not
2098
+ the <em>write</em> side. A project install builds its destination from
2099
+ agent-dir names committed in the repo
2100
+ (<code>.claude/skills</code> and its per-agent siblings), and a hostile
2101
+ clone can ship one of those as a <strong>symlink pointing outside the
2102
+ tree</strong> — at <code>~/.ssh</code>, say. Cloning that repo and
2103
+ running <code>boost install &lt;skill&gt; --local</code> then writes on the
2104
+ far side: confirmed by reproduction, a skill directory landed in a
2105
+ sibling of the repo instead of inside it. The squatter check does not
2106
+ stop it (a brand-new leaf name like <code>authorized_keys</code>
2107
+ collides with nothing, and <code>--force</code> waives it anyway).
2108
+ <code>scopes.ensure_in_base</code> is the write-side mirror of the
2109
+ delete guard: it re-derives containment through symlinks for every
2110
+ target up front, so one escaping directory aborts the whole install
2111
+ before anything is written. Covers all three project-scope kinds —
2112
+ skill, rule and workflow.</p>
2113
+ <div class="meta">
2114
+ <span class="m">Complexity <b>S</b></span>
2115
+ <span class="m hi">Impact <b>High</b></span>
2116
+ <span class="m">Wow <b class="wow">★★★★</b></span>
2117
+ <span class="m">hostile repo could write outside itself</span>
2118
+ </div>
2119
+ </article>
2120
+
2085
2121
  <article class="cap rcard">
2086
2122
  <div class="head"><span class="pill shipped">Shipped</span><span class="cat">Security · Secrets</span></div>
2087
2123
  <h3>Secret &amp; PII scanning of installed skills</h3>
@@ -26,7 +26,7 @@
26
26
  --line-hi: rgb(255 255 255 / 22%);
27
27
  --text: #e9ebf5;
28
28
  --text-2: #9298b0;
29
- --text-3: #676d86;
29
+ --text-3: #767c96; /* muted; ≥4.5:1 on --bg (WCAG AA) — was #676d86 (3.9:1) */
30
30
 
31
31
  /* --- the triad: the whole identity lives in these three --- */
32
32
  --cyan: #22d3ee; /* primary accent */
@@ -385,7 +385,10 @@ footer {
385
385
  border-top: 1px solid var(--line);
386
386
  color: var(--text-3); font-size: 13px;
387
387
  }
388
- footer a { color: var(--text-2); text-decoration: none; }
388
+ /* Underlined, not colour-only: a link inside footer prose must be
389
+ distinguishable without relying on colour (WCAG 1.4.1 / Lighthouse
390
+ link-in-text-block). */
391
+ footer a { color: var(--text-2); text-decoration: underline; }
389
392
  footer a:hover { color: var(--text); }
390
393
 
391
394
  @media (max-width: 720px) {
@@ -284,3 +284,41 @@ def test_contains_fails_closed_when_resolution_errors(tmp_path, monkeypatch):
284
284
 
285
285
  monkeypatch.setattr(scopes, "Path", ExplodingPath)
286
286
  assert scopes.contains(tmp_path, tmp_path / "x") is False
287
+
288
+
289
+ # ── ensure_in_base: the write guard ──────────────────────────────────────
290
+
291
+ def test_ensure_in_base_returns_the_path_when_inside(tmp_path):
292
+ dest = tmp_path / ".claude" / "skills" / "x"
293
+ assert scopes.ensure_in_base(tmp_path, dest) == Path(dest)
294
+
295
+
296
+ def test_ensure_in_base_raises_on_a_plain_escape(tmp_path):
297
+ (tmp_path / "repo").mkdir()
298
+ with pytest.raises(BoostError) as err:
299
+ scopes.ensure_in_base(tmp_path / "repo", tmp_path / "elsewhere" / "x")
300
+ assert "outside this project" in err.value.message
301
+
302
+
303
+ def test_ensure_in_base_raises_when_a_symlinked_dir_escapes(tmp_path):
304
+ """The write-side attack contains() is reused for: an agent dir committed as
305
+ a symlink pointing outside the repo, targeting a NEW leaf that does not yet
306
+ exist — so nothing but the containment check can catch it."""
307
+ repo = tmp_path / "repo"
308
+ (repo / ".git").mkdir(parents=True)
309
+ (repo / ".claude").mkdir()
310
+ outside = tmp_path / "outside"
311
+ outside.mkdir()
312
+ (repo / ".claude" / "skills").symlink_to(outside, target_is_directory=True)
313
+ # repo/.claude/skills/authorized_keys resolves to outside/authorized_keys.
314
+ dest = repo / ".claude" / "skills" / "authorized_keys"
315
+ with pytest.raises(BoostError):
316
+ scopes.ensure_in_base(repo, dest)
317
+
318
+
319
+ def test_ensure_in_base_allows_a_real_nested_dir(tmp_path):
320
+ # A legitimate project dir, even several levels deep, must pass untouched.
321
+ repo = tmp_path / "repo"
322
+ (repo / ".claude" / "skills").mkdir(parents=True)
323
+ dest = repo / ".claude" / "skills" / "ok"
324
+ assert scopes.ensure_in_base(repo, dest) == Path(dest)
@@ -860,6 +860,31 @@ class TestProjectSkills:
860
860
  store.install(entry, scope="project", base=str(repo), force=True)
861
861
  assert projectlock.get_skill(repo, "brainstorming")["installed_at"] == first
862
862
 
863
+ def test_symlinked_agent_dir_cannot_escape_the_repo(self, entry, tmp_path):
864
+ """A committed ``.claude/skills`` symlink pointing outside the repo must
865
+ not let the install write on the far side.
866
+
867
+ The attack: a hostile clone ships an agent dir as a symlink to, say,
868
+ ``~/.ssh``; ``_copy_skill`` would then ``mkdir``/``os.replace`` through
869
+ it and land outside the project. Guarded by ``scopes.ensure_in_base``
870
+ before any write. Uses a fresh skill name so the squatter check (which
871
+ only fires on an existing path) is not what does the blocking.
872
+ """
873
+ repo = self._repo(tmp_path)
874
+ outside = tmp_path / "outside" # stands in for ~/.ssh
875
+ outside.mkdir()
876
+ (repo / ".claude").mkdir()
877
+ (repo / ".claude" / "skills").symlink_to(outside, target_is_directory=True)
878
+
879
+ with pytest.raises(BoostError) as err:
880
+ store.install(entry, scope="project", base=str(repo))
881
+ assert "outside this project" in err.value.message
882
+ # Nothing written through the symlink, and the all-or-nothing pre-check
883
+ # means the other agents' in-repo dirs stay untouched too.
884
+ assert list(outside.iterdir()) == []
885
+ assert not (repo / ".windsurf" / "skills" / "brainstorming").exists()
886
+ assert not (repo / ".cursor" / "skills" / "brainstorming").exists()
887
+
863
888
  def test_policy_blocks_a_project_install_too(self, entry, tmp_path):
864
889
  # Vendoring into a repo is not an escape hatch around policy.
865
890
  policy.save({"blocked_skills": ["brainstorming"]})
@@ -1,20 +0,0 @@
1
- ---
2
- id: lighthouse-ci-on-the-pages-site
3
- board: code
4
- section: docsite
5
- status: planned
6
- category: Docs · Perf
7
- complexity: M
8
- impact: High
9
- wow: 5
10
- note: 4 score budgets
11
- order: 2
12
- owner:
13
- pr:
14
- title: Lighthouse CI on the Pages site
15
- ---
16
- <code>treosh/lighthouse-ci-action</code> scores <code>index.html</code>
17
- and <code>roadmap.html</code> on performance, accessibility,
18
- best-practices and SEO on every deploy, and fails the build against
19
- budgets. Turns the marketing surface's quality into a number that can't
20
- silently regress as the Aurora theme evolves.