boost-skill-cli 1.0.154__tar.gz → 1.0.156__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 (319) hide show
  1. boost_skill_cli-1.0.156/.gitleaks.toml +17 -0
  2. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/Makefile +1 -0
  3. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/PKG-INFO +1 -1
  4. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/_version.py +2 -2
  5. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/commands/discovery.py +9 -1
  6. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_skill_cli.egg-info/PKG-INFO +1 -1
  7. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_skill_cli.egg-info/SOURCES.txt +4 -0
  8. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/secret-scanning-gitleaks-push-protection.md +3 -3
  9. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/startup-and-import-time-budget-x-importtime.md +3 -3
  10. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap.html +2 -2
  11. boost_skill_cli-1.0.156/scripts/import_budget.py +156 -0
  12. boost_skill_cli-1.0.156/tests/unit/test_gitleaks_config.py +59 -0
  13. boost_skill_cli-1.0.156/tests/unit/test_import_budget.py +135 -0
  14. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/.gitattributes +0 -0
  15. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/.gitignore +0 -0
  16. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/CLAUDE.md +0 -0
  17. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/CONTRIBUTING.md +0 -0
  18. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/LICENSE +0 -0
  19. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/MANIFEST.in +0 -0
  20. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/README.md +0 -0
  21. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/SECURITY.md +0 -0
  22. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost +0 -0
  23. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/__init__.py +0 -0
  24. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/__main__.py +0 -0
  25. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/cli.py +0 -0
  26. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/cliparse.py +0 -0
  27. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/commands/__init__.py +0 -0
  28. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/commands/bmad.py +0 -0
  29. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/commands/configuration.py +0 -0
  30. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/commands/hooks.py +0 -0
  31. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/commands/info.py +0 -0
  32. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/commands/intelligence.py +0 -0
  33. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/commands/pkg.py +0 -0
  34. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/commands/quality.py +0 -0
  35. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/commands/taps.py +0 -0
  36. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/commands/team.py +0 -0
  37. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/core/__init__.py +0 -0
  38. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/core/adapters.py +0 -0
  39. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/core/agents.py +0 -0
  40. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/core/ai.py +0 -0
  41. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/core/catalog.py +0 -0
  42. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/core/claude_settings.py +0 -0
  43. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/core/config.py +0 -0
  44. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/core/dense.py +0 -0
  45. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/core/embed.py +0 -0
  46. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/core/frontmatter.py +0 -0
  47. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/core/gitutil.py +0 -0
  48. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/core/imperative.py +0 -0
  49. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/core/injectscan.py +0 -0
  50. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/core/journal.py +0 -0
  51. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/core/lockfile.py +0 -0
  52. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/core/logs.py +0 -0
  53. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/core/mcp.py +0 -0
  54. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/core/nethttp.py +0 -0
  55. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/core/output.py +0 -0
  56. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/core/paths.py +0 -0
  57. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/core/policy.py +0 -0
  58. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/core/rag.py +0 -0
  59. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/core/registry.py +0 -0
  60. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/core/rules.py +0 -0
  61. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/core/secretscan.py +0 -0
  62. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/core/serve.py +0 -0
  63. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/core/stackprobe.py +0 -0
  64. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/core/staleness.py +0 -0
  65. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/core/store.py +0 -0
  66. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/core/typosquat.py +0 -0
  67. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/core/updatediff.py +0 -0
  68. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/core/util.py +0 -0
  69. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/core/workflows.py +0 -0
  70. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/data/registries.json +0 -0
  71. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/errors.py +0 -0
  72. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_cli/spin.py +0 -0
  73. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_skill_cli.egg-info/dependency_links.txt +0 -0
  74. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_skill_cli.egg-info/entry_points.txt +0 -0
  75. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_skill_cli.egg-info/requires.txt +0 -0
  76. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/boost_skill_cli.egg-info/top_level.txt +0 -0
  77. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/.claude/settings.local.json +0 -0
  78. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/DEBUGGING.md +0 -0
  79. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/adapters.html +0 -0
  80. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/demo.gif +0 -0
  81. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/demo.tape +0 -0
  82. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/design-roadmap.html +0 -0
  83. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/eval.html +0 -0
  84. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/index.html +0 -0
  85. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/mcp-hub.html +0 -0
  86. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/rag-architecture.md +0 -0
  87. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/BOOST-D01.md +0 -0
  88. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/BOOST-D02.md +0 -0
  89. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/BOOST-D03.md +0 -0
  90. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/BOOST-D04.md +0 -0
  91. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/BOOST-D05.md +0 -0
  92. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/BOOST-D06.md +0 -0
  93. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/BOOST-D07.md +0 -0
  94. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/BOOST-D08.md +0 -0
  95. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/BOOST-D09.md +0 -0
  96. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/BOOST-D10.md +0 -0
  97. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/BOOST-D11.md +0 -0
  98. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/BOOST-D12.md +0 -0
  99. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/BOOST-D13.md +0 -0
  100. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/BOOST-D14.md +0 -0
  101. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/BOOST-D15.md +0 -0
  102. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/BOOST-D16.md +0 -0
  103. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/BOOST-D17.md +0 -0
  104. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/BOOST-D18.md +0 -0
  105. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/BOOST-D19.md +0 -0
  106. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/BOOST-D20.md +0 -0
  107. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/BOOST-D21.md +0 -0
  108. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/BOOST-D22.md +0 -0
  109. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/BOOST-D23.md +0 -0
  110. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/BOOST-D24.md +0 -0
  111. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/BOOST-D25.md +0 -0
  112. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/BOOST-D26.md +0 -0
  113. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/accessibility-audit-pa11y-ci-axe-core.md +0 -0
  114. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/atomic-corruption-safe-lock-file-writes.md +0 -0
  115. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/atomic-skill-install-temp-dir-swap.md +0 -0
  116. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/autonomous-ship-workflow-and-isolated-worktree.md +0 -0
  117. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/boost-run-live-agents.md +0 -0
  118. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/bring-commands-under-mutation-testing.md +0 -0
  119. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/broken-link-and-anchor-checking-lychee.md +0 -0
  120. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/browse-crashes-selecting-a-rule-or-workflow.md +0 -0
  121. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/build-provenance-slsa-attestations.md +0 -0
  122. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/cache-the-catalog-entry-set-across-rag-queries.md +0 -0
  123. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/capability-manifest-and-least-privilege-policy.md +0 -0
  124. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/clean-env-install-smoke-pip-and-pipx.md +0 -0
  125. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/command-reference-docs-site.md +0 -0
  126. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/complexity-and-dead-code-radar-xenon-vulture.md +0 -0
  127. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/consolidate-skill-staleness-drift-logic-into-cor.md +0 -0
  128. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/coverage-dashboard-codecov-free-for-oss.md +0 -0
  129. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/coverage-guided-fuzzing-atheris-oss-fuzz.md +0 -0
  130. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/crash-recorder-error-paths-core-logs-py.md +0 -0
  131. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/dependency-cve-gate-pip-audit.md +0 -0
  132. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/docstring-coverage-interrogate.md +0 -0
  133. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/doctor-checks-rules-and-workflows.md +0 -0
  134. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/end-of-options-guard-on-git-commands.md +0 -0
  135. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/extension-free-tests-core-dense-py.md +0 -0
  136. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/extract-mcp-http-servers-out-of-configuration-py.md +0 -0
  137. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/finish-mutation-hardening-across-core.md +0 -0
  138. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/fix-self-update-version-detection-dead-branch.md +0 -0
  139. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/fork-safe-network-proxy-handler.md +0 -0
  140. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/framework-adapter-langgraph.md +0 -0
  141. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/framework-adapter-multi-agent.md +0 -0
  142. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/framework-adapters-boost-adapt.md +0 -0
  143. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/frontmatter-scalar-over-coercion.md +0 -0
  144. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/github-pages-deploy-is-broken-every-push.md +0 -0
  145. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/golden-set-statistical-power.md +0 -0
  146. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/hash-pinned-reproducible-toolchain-uv-lock.md +0 -0
  147. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/html-validation-html-validate.md +0 -0
  148. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/install-scope-user-or-project.md +0 -0
  149. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/integrity-verification-boost-verify.md +0 -0
  150. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/invocation-pid-logging-for-crash-correlation.md +0 -0
  151. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/layering-guard-import-linter.md +0 -0
  152. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/lighthouse-ci-on-the-pages-site.md +0 -0
  153. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/list-rules-and-workflows.md +0 -0
  154. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/localize-the-stored-bm25-snippet.md +0 -0
  155. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/lockfile-enforcement-and-commit-pinning.md +0 -0
  156. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/log-timestamps-mislabeled-utc.md +0 -0
  157. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/lowest-version-resolution-uv-resolution-lowest-d.md +0 -0
  158. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/make-the-roadmaps-discoverable.md +0 -0
  159. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/markdown-consistency-markdownlint-cli2.md +0 -0
  160. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/mcp-hub-diagram-node-text-overflow.md +0 -0
  161. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/mcp-launch-objc-fork-safety.md +0 -0
  162. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/mcp-register-names-server-before-env.md +0 -0
  163. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/mcp-startup-self-harden-fork-safety.md +0 -0
  164. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/memoize-config-load-in-process.md +0 -0
  165. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/modernization-smells-refurb-pyupgrade.md +0 -0
  166. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/mutation-hardening-core-frontmatter-py.md +0 -0
  167. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/mutation-hardening-core-gitutil-py.md +0 -0
  168. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/mutation-hardening-core-store-py.md +0 -0
  169. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/one-command-every-env-nox.md +0 -0
  170. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/one-shared-atomic-write-helper.md +0 -0
  171. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/package-metadata-validation-twine-check-friends.md +0 -0
  172. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/patch-coverage-gate-diff-cover.md +0 -0
  173. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/performance-regression-gate-pytest-benchmark.md +0 -0
  174. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/post-deploy-smoke-headless-load-check.md +0 -0
  175. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/pre-release-python-canary-3-14t-free-threaded.md +0 -0
  176. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/promote-nav-footer-into-the-shared-style-system.md +0 -0
  177. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/prompt-injection-scanning-of-skill-markdown.md +0 -0
  178. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/property-based-tests-hypothesis-on-the-parsers.md +0 -0
  179. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/prose-and-terminology-linting-vale.md +0 -0
  180. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/prune-ignored-dirs-during-scan-dir-walk.md +0 -0
  181. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/quality-dashboard-sonarcloud-free-for-oss.md +0 -0
  182. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/ranx-significance-monitor.md +0 -0
  183. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/reconcile-the-theme-drift.md +0 -0
  184. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/refresh-the-marketing-surface.md +0 -0
  185. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/retrieval-quality-eval-harness.md +0 -0
  186. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/reuse-helpers-kill-minor-dead-work.md +0 -0
  187. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/robust-tag-argument-parsing.md +0 -0
  188. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/rule-install-native-materialization.md +0 -0
  189. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/runner-egress-monitoring-stepsecurity-harden-run.md +0 -0
  190. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/runtime-explain-faithfulness-guardrail.md +0 -0
  191. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/sbom-aware-scanning-osv-scanner.md +0 -0
  192. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/sbom-on-every-release-cyclonedx-syft.md +0 -0
  193. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/scan-and-sync-rules-and-workflows.md +0 -0
  194. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/second-type-checker-pyright.md +0 -0
  195. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/secret-and-pii-scanning-of-installed-skills.md +0 -0
  196. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/security-linting-bandit-via-ruff-s-rules.md +0 -0
  197. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/shift-left-gate-pre-commit-pre-commit-ci.md +0 -0
  198. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/single-imperative-rule-extractor.md +0 -0
  199. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/single-tech-stack-prober.md +0 -0
  200. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/split-oversized-command-modules.md +0 -0
  201. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/stop-re-serializing-entry-meta-on-every-search.md +0 -0
  202. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/supply-chain-posture-openssf-scorecard.md +0 -0
  203. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/surface-every-docs-page-from-the-guide.md +0 -0
  204. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/tap-signing-and-provenance-sigstore-minisign.md +0 -0
  205. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/theme-asset-linting-stylelint-eslint.md +0 -0
  206. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/typo-detection-codespell.md +0 -0
  207. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/typosquat-and-name-confusion-detection.md +0 -0
  208. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/unify-tilde-two-copies-have-a-boundary-bug.md +0 -0
  209. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/untrack-generated-build-noise.md +0 -0
  210. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/update-diff-before-apply.md +0 -0
  211. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/update-refreshes-rules-and-workflows.md +0 -0
  212. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/visual-regression-pass-on-the-guide.md +0 -0
  213. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/widen-the-ruff-rule-surface-b-sim-c4-perf-ruf.md +0 -0
  214. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/windows-in-the-ci-matrix.md +0 -0
  215. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/workflow-install-native-materialization.md +0 -0
  216. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/workflow-linting-actionlint.md +0 -0
  217. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/workflow-sast-zizmor.md +0 -0
  218. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/docs/roadmap/items/workspace-scope-install.md +0 -0
  219. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/examples/README.md +0 -0
  220. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/examples/adapt-demo.sh +0 -0
  221. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/examples/boost-run-prototype.sh +0 -0
  222. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/index.html +0 -0
  223. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/pyproject.toml +0 -0
  224. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/scripts/bench_cli.sh +0 -0
  225. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/scripts/build_registries.py +0 -0
  226. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/scripts/build_roadmap.py +0 -0
  227. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/scripts/ensure_eval_corpus.sh +0 -0
  228. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/scripts/eval_explain.py +0 -0
  229. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/scripts/eval_recommend.py +0 -0
  230. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/scripts/eval_retrieval.py +0 -0
  231. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/scripts/mutation_gate.py +0 -0
  232. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/setup.cfg +0 -0
  233. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/style/README.md +0 -0
  234. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/style/boost.css +0 -0
  235. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/style/boost.js +0 -0
  236. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/style/demo.html +0 -0
  237. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/bdd/features/adapt.feature +0 -0
  238. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/bdd/features/browse.feature +0 -0
  239. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/bdd/features/count.feature +0 -0
  240. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/bdd/features/discover.feature +0 -0
  241. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/bdd/features/doctor.feature +0 -0
  242. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/bdd/features/environment.py +0 -0
  243. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/bdd/features/explain.feature +0 -0
  244. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/bdd/features/index.feature +0 -0
  245. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/bdd/features/install.feature +0 -0
  246. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/bdd/features/list.feature +0 -0
  247. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/bdd/features/mcp.feature +0 -0
  248. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/bdd/features/search.feature +0 -0
  249. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/bdd/features/steps/cli_steps.py +0 -0
  250. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/bdd/features/steps/discovery_steps.py +0 -0
  251. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/bdd/features/steps/mcp_steps.py +0 -0
  252. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/bdd/features/steps/quality_steps.py +0 -0
  253. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/conftest.py +0 -0
  254. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/eval/baseline.json +0 -0
  255. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/eval/explain.jsonl +0 -0
  256. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/eval/golden.jsonl +0 -0
  257. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/eval/recommend.jsonl +0 -0
  258. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/eval/taps.txt +0 -0
  259. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/functional/test_cli_adapt.py +0 -0
  260. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/functional/test_cli_bmad.py +0 -0
  261. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/functional/test_cli_configuration.py +0 -0
  262. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/functional/test_cli_discovery.py +0 -0
  263. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/functional/test_cli_hooks.py +0 -0
  264. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/functional/test_cli_info.py +0 -0
  265. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/functional/test_cli_intelligence.py +0 -0
  266. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/functional/test_cli_pkg.py +0 -0
  267. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/functional/test_cli_quality.py +0 -0
  268. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/functional/test_cli_taps.py +0 -0
  269. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/functional/test_cli_team.py +0 -0
  270. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/functional/test_everyday_loop.py +0 -0
  271. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/functional/test_property_parsers.py +0 -0
  272. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/make_fixture.py +0 -0
  273. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/perf/test_benchmarks.py +0 -0
  274. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/smoke.sh +0 -0
  275. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/unit/test_adapters.py +0 -0
  276. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/unit/test_agents.py +0 -0
  277. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/unit/test_ai.py +0 -0
  278. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/unit/test_catalog.py +0 -0
  279. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/unit/test_claude_settings.py +0 -0
  280. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/unit/test_cliparse.py +0 -0
  281. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/unit/test_config.py +0 -0
  282. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/unit/test_dense.py +0 -0
  283. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/unit/test_dense_fallback.py +0 -0
  284. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/unit/test_docs_pages_linked.py +0 -0
  285. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/unit/test_embed.py +0 -0
  286. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/unit/test_errors_and_cli_table.py +0 -0
  287. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/unit/test_frontmatter.py +0 -0
  288. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/unit/test_gitutil.py +0 -0
  289. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/unit/test_imperative.py +0 -0
  290. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/unit/test_injectscan.py +0 -0
  291. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/unit/test_journal.py +0 -0
  292. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/unit/test_lockfile.py +0 -0
  293. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/unit/test_logs.py +0 -0
  294. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/unit/test_mcp.py +0 -0
  295. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/unit/test_mutation_hardening.py +0 -0
  296. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/unit/test_nethttp.py +0 -0
  297. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/unit/test_output.py +0 -0
  298. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/unit/test_paths.py +0 -0
  299. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/unit/test_pkg_confusions.py +0 -0
  300. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/unit/test_pkg_injection.py +0 -0
  301. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/unit/test_pkg_secrets.py +0 -0
  302. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/unit/test_policy.py +0 -0
  303. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/unit/test_rag.py +0 -0
  304. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/unit/test_registries_fresh.py +0 -0
  305. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/unit/test_registry.py +0 -0
  306. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/unit/test_roadmap_fresh.py +0 -0
  307. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/unit/test_rules.py +0 -0
  308. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/unit/test_secretscan.py +0 -0
  309. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/unit/test_serve.py +0 -0
  310. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/unit/test_spin.py +0 -0
  311. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/unit/test_stackprobe.py +0 -0
  312. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/unit/test_staleness.py +0 -0
  313. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/unit/test_store.py +0 -0
  314. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/unit/test_token_parity.py +0 -0
  315. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/unit/test_typosquat.py +0 -0
  316. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/unit/test_updatediff.py +0 -0
  317. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/unit/test_util.py +0 -0
  318. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/unit/test_version.py +0 -0
  319. {boost_skill_cli-1.0.154 → boost_skill_cli-1.0.156}/tests/unit/test_workflows.py +0 -0
@@ -0,0 +1,17 @@
1
+ # gitleaks configuration — secret-scanning gate (see .github/workflows/ci.yml).
2
+ #
3
+ # Extends gitleaks' upstream default ruleset (which covers cloud keys, tokens,
4
+ # private keys, high-entropy strings, …) and allowlists the one place boost
5
+ # ships *synthetic* secrets on purpose: its own secret-scanner test fixtures.
6
+ # Everything else — source, docs, real history — is scanned unmodified.
7
+
8
+ title = "boost gitleaks config"
9
+
10
+ [extend]
11
+ useDefault = true
12
+
13
+ [[allowlists]]
14
+ description = "boost's own secret-scanner tests ship synthetic private keys / tokens by design (they exist to prove core/secretscan.py flags them)"
15
+ paths = [
16
+ '''tests/unit/test_secretscan\.py''',
17
+ ]
@@ -43,6 +43,7 @@ lint:
43
43
  @command -v actionlint >/dev/null 2>&1 && actionlint || echo "actionlint not on PATH — skipping (CI enforces it)"
44
44
  $(PY) scripts/build_registries.py --check
45
45
  $(PY) scripts/build_roadmap.py --check
46
+ $(PY) scripts/import_budget.py
46
47
 
47
48
  # Supply-chain CVE gate: fail on a known OSV/PyPI advisory in the project's
48
49
  # dependency closure. Mirrors the pip-audit CI workflow; run before releasing.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: boost-skill-cli
3
- Version: 1.0.154
3
+ Version: 1.0.156
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.154'
22
- __version_tuple__ = version_tuple = (1, 0, 154)
21
+ __version__ = version = '1.0.156'
22
+ __version_tuple__ = version_tuple = (1, 0, 156)
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -17,7 +17,7 @@ import urllib.parse
17
17
  from pathlib import Path
18
18
 
19
19
  from .. import cliparse, spin
20
- from ..core import (agents, ai, catalog, config, dense, embed, gitutil,
20
+ from ..core import (agents, ai, catalog, config, gitutil,
21
21
  journal, lockfile, paths, rag, registry, store, util)
22
22
  from ..core import output as out
23
23
  from ..core.stackprobe import detect_stack # re-exported: shared with Quality
@@ -165,6 +165,11 @@ def cmd_reindex(argv):
165
165
  stats = rag.build(force=args.force)
166
166
  dense_stats = None
167
167
  if args.dense:
168
+ # Imported lazily (only on `--dense`) so the optional dense/embedding
169
+ # stack never loads for the common offline commands this module also
170
+ # holds — count, stats, trending, plain search. See the import-budget
171
+ # gate (scripts/import_budget.py).
172
+ from ..core import embed
168
173
  with spin.Spinner("embedding chunks into the dense store"):
169
174
  dense_stats = _reindex_dense(args.force)
170
175
  if args.as_json:
@@ -192,6 +197,9 @@ def cmd_reindex(argv):
192
197
 
193
198
  def _reindex_dense(force):
194
199
  """Build the dense vector store; returns stats or None when unavailable."""
200
+ # Local import: the dense/embedding engines are opt-in (`search --dense`),
201
+ # so they stay out of startup for every other command in this module.
202
+ from ..core import dense, embed
195
203
  if not dense.have_backend() or not embed.available():
196
204
  return None
197
205
  return dense.build(force=force)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: boost-skill-cli
3
- Version: 1.0.154
3
+ Version: 1.0.156
4
4
  Summary: boost — Homebrew for AI coding skills
5
5
  Author: Jonathan Reyes
6
6
  License: GNU GENERAL PUBLIC LICENSE
@@ -1,5 +1,6 @@
1
1
  .gitattributes
2
2
  .gitignore
3
+ .gitleaks.toml
3
4
  CLAUDE.md
4
5
  CONTRIBUTING.md
5
6
  LICENSE
@@ -224,6 +225,7 @@ scripts/ensure_eval_corpus.sh
224
225
  scripts/eval_explain.py
225
226
  scripts/eval_recommend.py
226
227
  scripts/eval_retrieval.py
228
+ scripts/import_budget.py
227
229
  scripts/mutation_gate.py
228
230
  style/README.md
229
231
  style/boost.css
@@ -280,8 +282,10 @@ tests/unit/test_docs_pages_linked.py
280
282
  tests/unit/test_embed.py
281
283
  tests/unit/test_errors_and_cli_table.py
282
284
  tests/unit/test_frontmatter.py
285
+ tests/unit/test_gitleaks_config.py
283
286
  tests/unit/test_gitutil.py
284
287
  tests/unit/test_imperative.py
288
+ tests/unit/test_import_budget.py
285
289
  tests/unit/test_injectscan.py
286
290
  tests/unit/test_journal.py
287
291
  tests/unit/test_lockfile.py
@@ -2,15 +2,15 @@
2
2
  id: secret-scanning-gitleaks-push-protection
3
3
  board: code
4
4
  section: health
5
- status: planned
5
+ status: shipped
6
6
  category: Security · Secrets
7
7
  complexity: S
8
8
  impact: Med
9
9
  wow: 3
10
10
  note: pre-commit-able
11
11
  order: 4
12
- owner:
13
- pr:
12
+ owner: loop/gitleaks
13
+ pr: 180
14
14
  title: Secret scanning — <code>gitleaks</code> + push protection
15
15
  ---
16
16
  Scan the full history and every PR diff for leaked tokens, keys and
@@ -2,15 +2,15 @@
2
2
  id: startup-and-import-time-budget-x-importtime
3
3
  board: code
4
4
  section: compat
5
- status: planned
5
+ status: shipped
6
6
  category: Perf · Startup
7
7
  complexity: M
8
8
  impact: High
9
9
  wow: 4
10
10
  note: lazy-import guard
11
11
  order: 5
12
- owner:
13
- pr:
12
+ owner: loop/import-budget
13
+ pr: 179
14
14
  title: Startup &amp; import-time budget — <code>-X importtime</code>
15
15
  ---
16
16
  For a CLI, cold-start latency <em>is</em> the UX — every command pays it.
@@ -987,7 +987,7 @@ harness.</p>
987
987
  </article>
988
988
 
989
989
  <article class="cap rcard">
990
- <div class="head"><span class="pill planned">Planned</span><span class="cat">Security · Secrets</span></div>
990
+ <div class="head"><span class="pill shipped">Shipped</span><span class="cat">Security · Secrets</span></div>
991
991
  <h3>Secret scanning — <code>gitleaks</code> + push protection</h3>
992
992
  <p>Scan the full history and every PR diff for leaked tokens, keys and
993
993
  PyPI credentials with the free <code>gitleaks</code> action, paired
@@ -1787,7 +1787,7 @@ and the work stays visible.</p>
1787
1787
  </article>
1788
1788
 
1789
1789
  <article class="cap rcard">
1790
- <div class="head"><span class="pill planned">Planned</span><span class="cat">Perf · Startup</span></div>
1790
+ <div class="head"><span class="pill shipped">Shipped</span><span class="cat">Perf · Startup</span></div>
1791
1791
  <h3>Startup &amp; import-time budget — <code>-X importtime</code></h3>
1792
1792
  <p>For a CLI, cold-start latency <em>is</em> the UX — every command pays it.
1793
1793
  A gate on <code>python -X importtime boost</code> catches the accidental
@@ -0,0 +1,156 @@
1
+ #!/usr/bin/env python3
2
+ """Startup import-time budget — the lazy-import guard.
3
+
4
+ For a CLI, cold-start latency *is* the UX: every command pays it before it does
5
+ anything. This gate runs ``python -X importtime`` for a set of common, fully
6
+ offline commands and asserts that a denylist of heavy or optional-only modules
7
+ never gets imported at startup.
8
+
9
+ The classic regression it catches is the accidental *top-level* import of an
10
+ optional dependency — the ``[rag]`` stack (``sqlite_vec``), an embedding/AI SDK,
11
+ or a scientific-python tree — that a hot path only ever needs lazily. boost is
12
+ architected so those load inside the one function that needs them (e.g.
13
+ ``search --dense``); this gate keeps it that way.
14
+
15
+ Deliberately name-based, not timing-based: a denylisted module is either
16
+ imported or it isn't, identically on a fast laptop and a slow, differently
17
+ CPU-throttled CI runner across every Python version — so the gate is
18
+ deterministic and never flakes. A coarse module-count ceiling is reported as an
19
+ advisory only (stdlib import graphs differ across Python versions), never a hard
20
+ failure.
21
+
22
+ Usage:
23
+ python scripts/import_budget.py # exit 1 if anything leaked
24
+ python scripts/import_budget.py --list # also print each command's count
25
+ """
26
+ from __future__ import annotations
27
+
28
+ import os
29
+ import subprocess
30
+ import sys
31
+ import tempfile
32
+ from pathlib import Path
33
+ from typing import Dict, List, Set
34
+
35
+ ROOT = Path(__file__).resolve().parent.parent
36
+
37
+ # Common commands that must stay lean. All are fully offline and touch the core
38
+ # dispatch + store/catalog paths, so a leak anywhere in that surface is caught.
39
+ COMMANDS: List[List[str]] = [["--help"], ["--version"], ["list"], ["count"]]
40
+
41
+ # Modules that must NEVER load for the commands above. Heavy C extensions,
42
+ # scientific-python, and the embedding/AI SDKs — plus boost's own optional-only
43
+ # engines, which stay lazy behind `search --dense`. A leak means a hot path grew
44
+ # a top-level import of an optional dependency.
45
+ DENYLIST: Set[str] = {
46
+ # the [rag] extra's native dependency
47
+ "sqlite_vec",
48
+ # scientific-python / vector libs an embedding backend might drag in
49
+ "numpy", "scipy", "pandas", "torch", "transformers",
50
+ "sentence_transformers", "faiss",
51
+ # embedding / LLM provider SDKs (boost talks to them over stdlib urllib,
52
+ # so none of these should ever import at startup)
53
+ "openai", "voyageai", "anthropic", "cohere",
54
+ "langchain", "langchain_core", "langchain_community",
55
+ "ragas", "ranx",
56
+ # boost's own optional-only engines
57
+ "boost_cli.core.dense", "boost_cli.core.embed",
58
+ }
59
+
60
+ # Advisory ceiling on total modules imported by a single command — reported, not
61
+ # enforced (import graphs legitimately differ across Python versions/platforms).
62
+ SOFT_MODULE_CEILING = 260
63
+
64
+
65
+ def parse_modules(importtime_stderr: str) -> Set[str]:
66
+ """Module names from ``python -X importtime`` stderr.
67
+
68
+ Each line is ``import time: <self> | <cumulative> | <indent><module>``; the
69
+ module name is the third ``|``-delimited field with its nesting indent
70
+ stripped. The header line (``self [us] | cumulative | imported package``)
71
+ has no numeric first field and is skipped.
72
+ """
73
+ modules: Set[str] = set()
74
+ for line in importtime_stderr.splitlines():
75
+ if "import time:" not in line:
76
+ continue
77
+ _, _, rest = line.partition("import time:")
78
+ parts = rest.split("|")
79
+ if len(parts) != 3:
80
+ continue
81
+ if not parts[0].strip().isdigit(): # the header row
82
+ continue
83
+ name = parts[2].strip()
84
+ if name:
85
+ modules.add(name)
86
+ return modules
87
+
88
+
89
+ def imported_modules(command: List[str]) -> Set[str]:
90
+ """The set of modules imported when running ``boost <command>``.
91
+
92
+ Runs in a subprocess with a throwaway ``$HOME`` so a real ``~/.boost`` can
93
+ never influence which modules load (or leave state behind), and with
94
+ ``PYTHONPATH`` pointed at the repo so no editable install is required.
95
+ """
96
+ env = dict(os.environ)
97
+ with tempfile.TemporaryDirectory(prefix="boost-import-budget-") as home:
98
+ env["HOME"] = home
99
+ env["PYTHONPATH"] = str(ROOT)
100
+ env["BOOST_NO_AI"] = "1"
101
+ env.pop("BOOST_HOME", None)
102
+ proc = subprocess.run(
103
+ [sys.executable, "-X", "importtime", "-c",
104
+ "from boost_cli.cli import main; main(%r)" % (command,)],
105
+ cwd=str(ROOT), env=env, capture_output=True, text=True,
106
+ )
107
+ return parse_modules(proc.stderr)
108
+
109
+
110
+ def leaks_for(modules: Set[str]) -> List[str]:
111
+ """Sorted denylisted modules present in ``modules`` (empty = clean)."""
112
+ return sorted(DENYLIST & modules)
113
+
114
+
115
+ def check() -> Dict[str, dict]:
116
+ """Run every command; return ``{label: {"leaks": [...], "count": int}}``."""
117
+ report: Dict[str, dict] = {}
118
+ for command in COMMANDS:
119
+ mods = imported_modules(command)
120
+ report["boost " + " ".join(command)] = {
121
+ "leaks": leaks_for(mods),
122
+ "count": len(mods),
123
+ }
124
+ return report
125
+
126
+
127
+ def main(argv: List[str] | None = None) -> int:
128
+ argv = list(sys.argv[1:] if argv is None else argv)
129
+ show_counts = "--list" in argv
130
+ report = check()
131
+
132
+ failed = False
133
+ for label, data in report.items():
134
+ if data["leaks"]:
135
+ failed = True
136
+ print("import-budget: FAIL %s imported %s"
137
+ % (label, ", ".join(data["leaks"])))
138
+ if show_counts:
139
+ print(" %-16s %d modules" % (label, data["count"]))
140
+ if data["count"] > SOFT_MODULE_CEILING:
141
+ print("import-budget: note — %s imported %d modules (advisory "
142
+ "ceiling %d); check for a new heavy dependency"
143
+ % (label, data["count"], SOFT_MODULE_CEILING))
144
+
145
+ if failed:
146
+ print("\nimport-budget: heavy/optional modules must stay lazy — move "
147
+ "the import inside the function that needs it (see "
148
+ "scripts/import_budget.py DENYLIST).")
149
+ return 1
150
+ print("import-budget: OK — no heavy/optional module imported by %d common "
151
+ "commands" % len(COMMANDS))
152
+ return 0
153
+
154
+
155
+ if __name__ == "__main__":
156
+ sys.exit(main())
@@ -0,0 +1,59 @@
1
+ """Unit test: .gitleaks.toml — the secret-scanning gate's configuration.
2
+
3
+ Validates the config is well-formed and does what the CI gate relies on:
4
+ extend the upstream default ruleset and allowlist boost's own synthetic
5
+ secret-scanner fixtures (so the gate stays green on deliberate test data while
6
+ still catching a real leak anywhere else).
7
+ """
8
+ from __future__ import annotations
9
+
10
+ import sys
11
+ from pathlib import Path
12
+
13
+ import pytest
14
+
15
+ _CONFIG = Path(__file__).resolve().parents[2] / ".gitleaks.toml"
16
+
17
+ pytestmark = [
18
+ pytest.mark.skipif(not _CONFIG.exists(),
19
+ reason="repo-root .gitleaks.toml not reachable (e.g. mutation sandbox)"),
20
+ pytest.mark.skipif(sys.version_info < (3, 11),
21
+ reason="tomllib is stdlib only on Python 3.11+"),
22
+ ]
23
+
24
+
25
+ def _load():
26
+ import tomllib
27
+ with open(_CONFIG, "rb") as f:
28
+ return tomllib.load(f)
29
+
30
+
31
+ def test_is_valid_toml():
32
+ assert isinstance(_load(), dict)
33
+
34
+
35
+ def test_extends_the_default_ruleset():
36
+ # Without useDefault the config would replace, not extend, gitleaks' rules —
37
+ # silently disabling every built-in detector.
38
+ cfg = _load()
39
+ assert cfg.get("extend", {}).get("useDefault") is True
40
+
41
+
42
+ def test_allowlists_the_secretscan_fixtures():
43
+ cfg = _load()
44
+ allowlists = cfg.get("allowlists") or ([cfg["allowlist"]] if "allowlist" in cfg else [])
45
+ paths = [p for al in allowlists for p in al.get("paths", [])]
46
+ assert any("test_secretscan" in p for p in paths), (
47
+ "the synthetic-secret fixture file must be allowlisted or the gate "
48
+ "reports boost's own test data as a leak")
49
+
50
+
51
+ def test_allowlist_does_not_blanket_ignore_tests():
52
+ # A too-broad `tests/` allowlist would blind the scanner to a real secret
53
+ # committed in any other test file. Keep it scoped to the fixture file.
54
+ cfg = _load()
55
+ allowlists = cfg.get("allowlists") or ([cfg["allowlist"]] if "allowlist" in cfg else [])
56
+ paths = [p for al in allowlists for p in al.get("paths", [])]
57
+ for p in paths:
58
+ assert p.rstrip("$").rstrip("/") not in ("tests", "tests/", r"tests/.*", "tests"), \
59
+ "allowlist path %r is too broad — scope it to the fixture file" % p
@@ -0,0 +1,135 @@
1
+ """Unit tests: scripts/import_budget.py — the startup lazy-import guard.
2
+
3
+ The pure parsing/denylist logic is tested directly; a single integration test
4
+ runs the real gate over the live interpreter so a genuine leak (a heavy module
5
+ newly imported at startup) fails here too, not just in CI.
6
+ """
7
+ from __future__ import annotations
8
+
9
+ import importlib.util
10
+ from pathlib import Path
11
+
12
+ import pytest
13
+
14
+ _SCRIPT = Path(__file__).resolve().parents[2] / "scripts" / "import_budget.py"
15
+
16
+
17
+ def _load():
18
+ spec = importlib.util.spec_from_file_location("import_budget", _SCRIPT)
19
+ mod = importlib.util.module_from_spec(spec)
20
+ spec.loader.exec_module(mod)
21
+ return mod
22
+
23
+
24
+ pytestmark = pytest.mark.skipif(
25
+ not _SCRIPT.exists(), reason="repo-root scripts/ not reachable (e.g. mutation sandbox)")
26
+
27
+
28
+ # A realistic slice of `python -X importtime` stderr (the real header + rows).
29
+ _SAMPLE = """\
30
+ import time: self [us] | cumulative | imported package
31
+ import time: 120 | 120 | _io
32
+ import time: 200 | 900 | urllib.request
33
+ import time: 90 | 90 | http.client
34
+ import time: 300 | 1200 | boost_cli.cli
35
+ import time: 150 | 150 | sqlite_vec
36
+ """
37
+
38
+
39
+ class TestParseModules:
40
+ def test_extracts_names_and_skips_header(self):
41
+ mod = _load()
42
+ names = mod.parse_modules(_SAMPLE)
43
+ assert "urllib.request" in names
44
+ assert "boost_cli.cli" in names
45
+ assert "sqlite_vec" in names
46
+ # the header row ("self [us] | cumulative | imported package") is not a
47
+ # module and must not be captured
48
+ assert "imported package" not in names
49
+ assert "cumulative" not in names
50
+
51
+ def test_strips_nesting_indent(self):
52
+ mod = _load()
53
+ # deeply nested rows keep only the dotted module name, no leading spaces
54
+ names = mod.parse_modules("import time: 90 | 90 | a.b.c\n")
55
+ assert names == {"a.b.c"}
56
+
57
+ def test_ignores_non_importtime_lines(self):
58
+ mod = _load()
59
+ noise = "some other stderr line\nWARNING: whatever\n"
60
+ assert mod.parse_modules(noise) == set()
61
+
62
+ def test_ignores_malformed_rows(self):
63
+ mod = _load()
64
+ # a row missing the third field yields nothing rather than a bad name
65
+ assert mod.parse_modules("import time: 10 | 10\n") == set()
66
+
67
+
68
+ class TestLeaksFor:
69
+ def test_flags_denylisted_modules_only(self):
70
+ mod = _load()
71
+ present = {"json", "os", "sqlite_vec", "boost_cli.core.dense", "urllib.request"}
72
+ assert mod.leaks_for(present) == ["boost_cli.core.dense", "sqlite_vec"]
73
+
74
+ def test_clean_set_has_no_leaks(self):
75
+ mod = _load()
76
+ assert mod.leaks_for({"json", "os", "boost_cli.cli", "urllib.request"}) == []
77
+
78
+ def test_result_is_sorted(self):
79
+ mod = _load()
80
+ present = {"ranx", "anticipation", "numpy", "torch"}
81
+ assert mod.leaks_for(present) == sorted(mod.DENYLIST & present)
82
+
83
+
84
+ class TestMain:
85
+ def test_returns_1_and_reports_on_leak(self, monkeypatch, capsys):
86
+ mod = _load()
87
+ monkeypatch.setattr(mod, "check", lambda: {
88
+ "boost count": {"leaks": ["sqlite_vec"], "count": 210},
89
+ })
90
+ rc = mod.main([])
91
+ out = capsys.readouterr().out
92
+ assert rc == 1
93
+ assert "FAIL" in out and "sqlite_vec" in out and "boost count" in out
94
+
95
+ def test_returns_0_when_clean(self, monkeypatch, capsys):
96
+ mod = _load()
97
+ monkeypatch.setattr(mod, "check", lambda: {
98
+ "boost --help": {"leaks": [], "count": 177},
99
+ })
100
+ rc = mod.main([])
101
+ assert rc == 0
102
+ assert "OK" in capsys.readouterr().out
103
+
104
+ def test_list_flag_prints_counts(self, monkeypatch, capsys):
105
+ mod = _load()
106
+ monkeypatch.setattr(mod, "check", lambda: {
107
+ "boost list": {"leaks": [], "count": 201},
108
+ })
109
+ mod.main(["--list"])
110
+ assert "201 modules" in capsys.readouterr().out
111
+
112
+ def test_soft_ceiling_is_advisory_not_fatal(self, monkeypatch, capsys):
113
+ mod = _load()
114
+ over = mod.SOFT_MODULE_CEILING + 50
115
+ monkeypatch.setattr(mod, "check", lambda: {
116
+ "boost --help": {"leaks": [], "count": over},
117
+ })
118
+ rc = mod.main([])
119
+ # a high module count is a note, not a failure (import graphs differ
120
+ # across Python versions/platforms)
121
+ assert rc == 0
122
+ assert "advisory ceiling" in capsys.readouterr().out
123
+
124
+
125
+ class TestIntegration:
126
+ def test_live_startup_has_no_heavy_imports(self):
127
+ """The real gate over this interpreter must be clean — a genuine
128
+ regression (a heavy module imported at startup) fails the suite here."""
129
+ mod = _load()
130
+ report = mod.check()
131
+ offenders = {label: data["leaks"]
132
+ for label, data in report.items() if data["leaks"]}
133
+ assert not offenders, (
134
+ "heavy/optional modules leaked into startup: %s — keep the import "
135
+ "lazy (see scripts/import_budget.py)" % offenders)