boost-skill-cli 1.2.30__tar.gz → 1.2.31__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.
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/CLAUDE.md +52 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/PKG-INFO +20 -4
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/README.md +19 -3
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/_version.py +2 -2
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/cli.py +1 -1
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/commands/configuration.py +13 -3
- boost_skill_cli-1.2.31/boost_cli/commands/hooks.py +156 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/commands/quality.py +45 -1
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/claude_settings.py +75 -34
- boost_skill_cli-1.2.31/boost_cli/core/hookhost.py +240 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/mcphost.py +36 -17
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/store.py +108 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_skill_cli.egg-info/PKG-INFO +20 -4
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_skill_cli.egg-info/SOURCES.txt +7 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/carousel.html +6 -4
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/commands.html +10 -7
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/index.html +1 -1
- boost_skill_cli-1.2.31/docs/roadmap/items/gemini-cli-agent-target.md +18 -0
- boost_skill_cli-1.2.31/docs/roadmap/items/gemini-duplicate-skill-discovery.md +67 -0
- boost_skill_cli-1.2.31/docs/roadmap/items/gemini-hooks-host-aware.md +41 -0
- boost_skill_cli-1.2.31/docs/roadmap/items/gemini-mcp-parity.md +40 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap.html +140 -2
- boost_skill_cli-1.2.31/tests/functional/test_cli_hooks_gemini.py +103 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/functional/test_cli_quality.py +90 -0
- boost_skill_cli-1.2.31/tests/unit/test_hook_settings_hosts.py +117 -0
- boost_skill_cli-1.2.31/tests/unit/test_hookhost.py +179 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_mcp.py +52 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_mcphost.py +13 -7
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_store.py +190 -0
- boost_skill_cli-1.2.30/boost_cli/commands/hooks.py +0 -91
- boost_skill_cli-1.2.30/docs/roadmap/items/gemini-cli-agent-target.md +0 -16
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/.gitattributes +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/.gitignore +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/.gitleaks.toml +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/.htmlvalidate.json +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/.lighthouserc.json +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/.lycheeignore +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/.markdownlint-cli2.jsonc +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/.pre-commit-config.yaml +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/.stylelintrc.json +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/.vale/styles/boost/AIWriting.yml +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/.vale/styles/boost/Terminology.yml +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/.vale/styles/config/vocabularies/boost/accept.txt +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/.vale.ini +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/CODE_OF_CONDUCT.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/CONTRIBUTING.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/DCO +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/GOVERNANCE.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/LICENSE +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/MAINTAINERS.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/MANIFEST.in +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/Makefile +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/SECURITY.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/SUPPORT.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/__init__.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/__main__.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/cliparse.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/commands/__init__.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/commands/_common.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/commands/bmad.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/commands/discovery.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/commands/info.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/commands/intelligence.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/commands/pkg.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/commands/run.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/commands/safety.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/commands/taps.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/commands/team.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/__init__.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/adapters.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/agents.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/ai.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/bmad.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/bootstrap.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/browse.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/builtin.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/capabilities.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/catalog.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/catalogbundle.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/chat.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/complete.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/config.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/dense.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/ed25519.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/embed.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/faithfulness.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/frontmatter.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/gitutil.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/imperative.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/injectscan.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/installscan.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/integrity.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/journal.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/localembed.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/lockfile.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/logs.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/mcp.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/mcpdecl.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/minisign.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/nethttp.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/output.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/paths.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/policy.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/projectlock.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/provenance.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/rag.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/registry.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/resolve.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/rules.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/scopes.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/secretscan.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/selfupdate.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/serve.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/stackprobe.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/staleness.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/trustaudit.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/typosquat.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/updatediff.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/util.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/core/workflows.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/data/registries.json +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/data/rules/boost-first.mdc +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/errors.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_cli/spin.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_langchain/__init__.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_langchain/_compat.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_langchain/graph.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_langchain/loader.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_langchain/py.typed +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_langchain/retriever.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_skill_cli.egg-info/dependency_links.txt +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_skill_cli.egg-info/entry_points.txt +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_skill_cli.egg-info/requires.txt +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/boost_skill_cli.egg-info/top_level.txt +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/codecov.yml +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/.claude/settings.local.json +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/DEBUGGING.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/adapters.html +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/architecture/README.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/architecture/c4-components-core.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/architecture/c4-containers.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/architecture/c4-context.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/architecture/c4-dynamic-install.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/carousel/gifs/distill.gif +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/carousel/gifs/doctor.gif +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/carousel/gifs/explain.gif +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/carousel/gifs/hooks.gif +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/carousel/gifs/install.gif +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/carousel/gifs/pulse.gif +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/carousel/gifs/search.gif +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/carousel/gifs/tap.gif +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/carousel/tapes/distill.tape +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/carousel/tapes/doctor.tape +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/carousel/tapes/explain.tape +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/carousel/tapes/hooks.tape +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/carousel/tapes/install.tape +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/carousel/tapes/pulse.tape +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/carousel/tapes/search.tape +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/carousel/tapes/tap.tape +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/chat.html +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/commit-audit.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/demo-index.json +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/demo.gif +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/demo.html +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/demo.tape +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/dependencies.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/design-roadmap.html +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/eval-latest.json +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/eval.html +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/langchain.html +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/mcp-hub.html +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/openssf-badge.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/openssf-playbook.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/rag-architecture.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/BOOST-D01.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/BOOST-D02.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/BOOST-D03.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/BOOST-D04.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/BOOST-D05.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/BOOST-D06.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/BOOST-D07.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/BOOST-D08.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/BOOST-D09.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/BOOST-D10.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/BOOST-D11.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/BOOST-D12.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/BOOST-D13.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/BOOST-D14.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/BOOST-D15.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/BOOST-D16.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/BOOST-D17.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/BOOST-D18.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/BOOST-D19.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/BOOST-D20.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/BOOST-D21.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/BOOST-D22.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/BOOST-D23.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/BOOST-D24.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/BOOST-D25.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/BOOST-D26.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/a11y-sweep-flakes-on-color-contrast.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/accessibility-audit-pa11y-ci-axe-core.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/actionlint-skips-shellcheck-silently.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/adapter-conformance-langgraph-leg-never-ran.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/agents-field-records-the-request-not-the-links.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/ai-bridge-silent-failure-logging.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/ambiguous-tap-short-name-resolution.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/atomic-corruption-safe-lock-file-writes.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/atomic-skill-install-temp-dir-swap.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/autonomous-ship-workflow-and-isolated-worktree.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/bm25-has-no-stemming.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/bm25-index-is-one-json-blob.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/bmad-autopilot-one-command-persona-routing.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/boost-first-carried-the-losing-trigger.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/boost-first-rule.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/boost-langchain-publishing.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/boost-run-live-agents.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/bring-commands-under-mutation-testing.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/broken-link-and-anchor-checking-lychee.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/browse-could-not-search-two-words.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/browse-crashes-selecting-a-rule-or-workflow.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/build-provenance-slsa-attestations.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/cache-the-catalog-entry-set-across-rag-queries.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/capability-manifest-and-least-privilege-policy.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/catalogue-entries-carry-no-content-identity.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/chat-cites-sources-by-a-number-it-never-prints.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/chat-command-grounded-conversational-search.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/ci-job-timeout-minutes.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/ci-summary-step-fails-itself.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/ci-time-is-now-runner-queueing.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/clean-env-install-smoke-pip-and-pipx.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/cli-output-ignored-the-terminal.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/code-scanning-rule-can-be-restored.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/codeql-job-rename-stranded-merge-protection.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/cold-search-reads-the-whole-catalogue.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/command-carousel-page.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/command-reference-docs-site.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/completions-complete-only-command-names.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/completions-install-could-eat-your-rc-file.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/complexity-and-dead-code-radar-xenon-vulture.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/consolidate-skill-staleness-drift-logic-into-cor.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/coverage-dashboard-codecov-free-for-oss.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/coverage-guided-fuzzing-atheris-oss-fuzz.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/crash-listing-branch-untested.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/crash-recorder-error-paths-core-logs-py.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/crash-reports-leak-api-keys.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/demo-cannot-open-its-own-pr.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/demo-gif-workflow-has-never-succeeded.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/demo-workflow-cancels-other-prs.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/dense-search-fallback-and-stale-tap-pruning.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/dense-search-rescans-every-vector.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/dependabot-missing-pip-ecosystem.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/dependabot-regeneration-drops-platform-pins.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/dependabot-root-pip-entry-duplicates-requirements.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/dependabot-splits-multi-path-action-repos.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/dependency-cve-gate-pip-audit.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/discover-searches-github-not-a-stale-sample.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/docsite-chrome-and-content-audit.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/docstring-coverage-interrogate.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/doctor-checks-rules-and-workflows.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/dry-run-promised-a-link-nobody-makes.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/efficiency-registries-ponytail-caveman.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/end-of-options-guard-on-git-commands.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/est-items-counts-agent-mirrors-as-items.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/eval-corpus-cannot-see-real-retrieval.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/eval-corpus-is-96x-smaller-than-a-real-install.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/eval-corpus-is-one-strangers-repo.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/eval-corpus-pins-have-no-refresh-path.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/eval-corpus-was-not-actually-pinned.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/eval-deduped-ranked-lists-by-name.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/eval-stats-could-never-publish.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/expanded-card-bodies-overflow.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/extension-free-tests-core-dense-py.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/extract-mcp-http-servers-out-of-configuration-py.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/finish-mutation-hardening-across-core.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/fix-self-update-version-detection-dead-branch.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/fork-safe-network-proxy-handler.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/framework-adapter-langgraph.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/framework-adapter-multi-agent.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/framework-adapters-boost-adapt.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/frontmatter-scalar-over-coercion.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/gemini-agent-frontmatter-sanitizer.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/github-community-health-files.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/github-pages-deploy-is-broken-every-push.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/golden-set-grades-by-name-not-by-skill.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/golden-set-statistical-power.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/hash-pinned-reproducible-toolchain-uv-lock.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/heal-deleted-links-it-never-made.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/html-validation-html-validate.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/info-rejects-the-qualified-name-it-recommends.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/install-docs-never-mentioned-upgrading.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/install-from-path-bypasses-policy-and-pin-checks.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/install-path-disambiguation.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/install-resolves-skill-dependencies.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/install-scope-user-or-project.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/installed-skill-trust-audit.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/integrity-verification-boost-verify.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/internal-architecture-diagrams.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/invocation-pid-logging-for-crash-correlation.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/journal-rotation-race-and-handle-leak.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/keyless-dense-tier-local-static-embeddings.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/keyless-semantic-search-for-everyone.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/langchain-in-the-wheel.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/langchain-integration-explainer-page.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/langchain-langgraph-langsmith-integration.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/langchain-retriever-metadata-and-k-floor.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/layering-guard-import-linter.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/license-compliance-scanning.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/lighthouse-ci-on-the-pages-site.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/lighthouse-scored-a-page-nobody-is-served.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/lint-tap-misscopes-rule-workflow-entries.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/list-rules-and-workflows.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/localize-the-stored-bm25-snippet.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/lock-invariant-cannot-parse-extras-pins.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/lockfile-enforcement-and-commit-pinning.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/log-timestamps-mislabeled-utc.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/long-hints-overflow-narrow-panes.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/lowest-version-resolution-uv-resolution-lowest-d.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/main-has-no-branch-protection.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/main-ruleset-ref-pattern-has-literal-quotes.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/make-lint-masks-actionlint-failures.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/make-the-roadmaps-discoverable.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/markdown-consistency-markdownlint-cli2.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/markdownlint-lints-the-fuzz-corpus.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/marketing-crm-domain-had-no-category.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/mcp-already-covered-defeater.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/mcp-aware-skills.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/mcp-check-skills-before-starting-a-task.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/mcp-hub-diagram-node-text-overflow.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/mcp-install-skips-the-injection-scan.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/mcp-launch-objc-fork-safety.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/mcp-one-benefit-nameable-task.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/mcp-register-names-server-before-env.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/mcp-search-before-reinventing.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/mcp-search-cost-was-understated.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/mcp-search-hid-which-ranking-ran.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/mcp-servers-ignore-install-scope.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/mcp-startup-self-harden-fork-safety.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/mcp-zero-setup-and-three-kinds.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/memoize-config-load-in-process.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/merge-queue-would-deadlock-most-required-checks.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/merged-loop-branches-are-never-pruned.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/modernization-smells-refurb-pyupgrade.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/mutation-gate-was-the-whole-critical-path.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/mutation-hardening-core-frontmatter-py.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/mutation-hardening-core-gitutil-py.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/mutation-hardening-core-store-py.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/mutation-shard-floor-is-one-file.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/mypy-strict-mode-for-commands.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/near-duplicate-items-eat-the-result-slots.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/negative-limit-inverts-log-pulse-output.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/onboard-overwrites-generated-files-without-confirm.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/one-command-every-env-nox.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/one-commit-can-cut-two-releases.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/one-dead-tap-broke-every-update.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/one-shared-atomic-write-helper.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/openssf-best-practices-badge.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/openssf-playbook.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/openssf-silver.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/osps-baseline-levels.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/package-metadata-validation-twine-check-friends.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/patch-coverage-gate-diff-cover.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/path-traversal-unsanitized-rule-workflow-name.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/pathlib-exists-is-not-total.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/pep585-604-modernization-sweep.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/performance-regression-gate-pytest-benchmark.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/pin-the-lint-toolchain.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/post-deploy-always-defeated-by-skipped-setup.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/post-deploy-smoke-headless-load-check.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/pre-release-python-canary-3-14t-free-threaded.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/prerequisites-and-semantic-search-setup.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/project-scope-across-every-command.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/project-scope-symlink-escape-on-write.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/promote-nav-footer-into-the-shared-style-system.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/prompt-injection-scanning-of-skill-markdown.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/property-based-tests-hypothesis-on-the-parsers.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/prose-and-terminology-linting-vale.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/prune-ignored-dirs-during-scan-dir-walk.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/publish-gate-ignores-pip-audit-and-metadata.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/publish-trigger-was-reachable-from-a-fork.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/pytest-tmpdir-cve-blocked-by-py39-floor.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/python-floor-moves-to-312.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/quality-dashboard-sonarcloud-free-for-oss.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/ragas-unpin-when-upstream-ships.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/ranx-significance-monitor.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/reconcile-the-theme-drift.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/refresh-the-marketing-surface.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/rel-time-tests-race-the-wall-clock.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/release-verifies-the-wrong-commit.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/required-checks-can-declare-a-check-that-deadlocks-prs.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/required-checks-config-drift.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/resolve-vendored-duplicate-copies.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/retrieval-quality-eval-harness.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/reuse-helpers-kill-minor-dead-work.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/roadmap-html-goes-stale-on-every-rebase.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/roadmap-page-weight-grows-without-bound.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/roadmap-perf-budget-has-no-local-guard.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/robust-tag-argument-parsing.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/ruff-016-widens-the-default-rule-set.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/rule-install-native-materialization.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/rules-install-but-cannot-be-governed.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/runner-egress-monitoring-stepsecurity-harden-run.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/runtime-explain-faithfulness-guardrail.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/sbom-aware-scanning-osv-scanner.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/sbom-declares-the-wrong-version.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/sbom-on-every-release-cyclonedx-syft.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/sbom-release-event-never-fires.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/scan-and-sync-rules-and-workflows.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/scheduled-toolchain-lock-regeneration.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/scorecard-findings-triage.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/scripts-under-the-lint-gate.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/search-and-browse-visual-refresh.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/search-never-notices-a-new-tap.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/second-type-checker-pyright.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/secret-and-pii-scanning-of-installed-skills.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/secret-scanning-gitleaks-push-protection.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/security-linting-bandit-via-ruff-s-rules.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/self-update-broken-for-pip-pipx-installs.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/self-update-claims-up-to-date-without-asking.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/serve-404-reflected-the-request.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/serve-is-a-searchable-catalogue.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/serve-py-traversal-guards-untested.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/shards-pipeline-never-produced-a-shard.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/shareable-catalogue-bundle.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/shift-left-gate-pre-commit-pre-commit-ci.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/single-imperative-rule-extractor.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/single-tech-stack-prober.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/smart-rerank-pays-per-novel-query.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/split-oversized-command-modules.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/startup-and-import-time-budget-x-importtime.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/stop-re-serializing-entry-meta-on-every-search.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/structured-json-log-output-mode.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/supply-chain-posture-openssf-scorecard.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/surface-every-docs-page-from-the-guide.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/sweep-died-at-launch-not-at-a-page.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/sync-could-not-repair-a-gutted-skill.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/sync-deletes-unowned-broken-symlinks.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/sync-relinks-into-every-agent-ignoring-scope.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/sync-reported-success-for-a-link-it-refused.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/tap-signing-and-provenance-sigstore-minisign.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/taps-check-out-freight-they-never-index.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/the-catalogue-advertised-repos-that-no-longer-exist.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/the-scale-corpus-refreshed-the-wrong-rows.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/the-shard-job-that-could-not-finish.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/theme-asset-linting-stylelint-eslint.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/tool-call-eval-tier.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/two-ci-controls-that-could-not-act.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/two-crashes-that-should-have-been-messages.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/typo-detection-codespell.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/typosquat-and-name-confusion-detection.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/unify-tilde-two-copies-have-a-boundary-bug.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/uninstall-has-no-confirmation-prompt.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/untrack-generated-build-noise.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/unwatched-crons-hid-a-real-fuzz-crash.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/update-advertises-a-flag-it-rejects.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/update-diff-before-apply.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/update-refreshed-rules-without-a-gate.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/update-refreshes-rules-and-workflows.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/update-reinstall-widens-agent-scope.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/visual-regression-pass-on-the-guide.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/widen-the-ruff-rule-surface-b-sim-c4-perf-ruf.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/windows-in-the-ci-matrix.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/wire-bdd-suite-into-ci.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/workflow-install-native-materialization.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/workflow-linting-actionlint.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/workflow-sast-zizmor.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/workspace-scope-install.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/zip-strict-audit.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/zizmor-ignores-drift-and-make-lint-never-ran-it.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/roadmap/items/zizmor-pin-is-a-yanked-release.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/security-design.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/superpowers/specs/2026-08-16-catalogue-content-identity-design.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/docs/verifying-releases.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/eslint.config.mjs +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/evals/README.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/evals/__init__.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/evals/baseline.json +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/evals/faithfulness.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/evals/golden_set.json +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/evals/make_corpus.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/evals/make_golden.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/evals/metrics.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/evals/publish_golden_dataset.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/evals/run_evals.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/examples/README.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/examples/adapt-demo.sh +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/examples/boost-run-prototype.sh +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/index.html +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/noxfile.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/pyproject.toml +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/requirements/coverage-tools.in +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/requirements/coverage-tools.txt +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/requirements/lint-tools.in +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/requirements/lint-tools.txt +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/requirements/mutation-tools.in +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/requirements/mutation-tools.txt +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/requirements/platform-pins.lock +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/requirements/release-tools.in +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/requirements/release-tools.txt +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/requirements/test-tools.in +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/requirements/test-tools.txt +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/scripts/a11y_check.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/scripts/bench_cli.sh +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/scripts/build_command_reference.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/scripts/build_demo_index.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/scripts/build_registries.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/scripts/build_roadmap.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/scripts/build_scale_corpus.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/scripts/check_anchors.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/scripts/check_dco.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/scripts/check_licenses.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/scripts/check_required_checks.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/scripts/ensure_eval_corpus.sh +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/scripts/eval_corpus.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/scripts/eval_explain.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/scripts/eval_gate.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/scripts/eval_recommend.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/scripts/eval_retrieval.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/scripts/eval_stats_summary.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/scripts/import_budget.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/scripts/lock_toolchain.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/scripts/measure_registry.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/scripts/mutation_gate.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/scripts/mutation_shards.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/scripts/mutation_weights.json +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/scripts/page_budget.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/scripts/perf_gate.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/scripts/post_deploy_smoke.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/scripts/publish_eval_json.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/scripts/release_guard.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/scripts/release_preflight.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/scripts/serve_docs.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/setup.cfg +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/sonar-project.properties +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/style/README.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/style/boost.css +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/style/boost.js +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/style/demo.html +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/bdd/features/adapt.feature +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/bdd/features/browse.feature +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/bdd/features/count.feature +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/bdd/features/discover.feature +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/bdd/features/doctor.feature +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/bdd/features/environment.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/bdd/features/explain.feature +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/bdd/features/index.feature +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/bdd/features/install.feature +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/bdd/features/list.feature +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/bdd/features/mcp.feature +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/bdd/features/search.feature +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/bdd/features/steps/cli_steps.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/bdd/features/steps/discovery_steps.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/bdd/features/steps/mcp_steps.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/bdd/features/steps/quality_steps.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/conftest.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/eval/baseline.json +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/eval/explain.jsonl +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/eval/golden-natural.jsonl +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/eval/golden.jsonl +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/eval/recommend.jsonl +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/eval/taps-scale.txt +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/eval/taps.txt +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/functional/test_capabilities_policy.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/functional/test_cli_adapt.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/functional/test_cli_bmad.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/functional/test_cli_catalog.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/functional/test_cli_chat.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/functional/test_cli_configuration.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/functional/test_cli_discovery.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/functional/test_cli_hooks.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/functional/test_cli_info.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/functional/test_cli_intelligence.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/functional/test_cli_pane_width.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/functional/test_cli_pkg.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/functional/test_cli_taps.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/functional/test_cli_team.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/functional/test_everyday_loop.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/functional/test_integrity_enforce.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/functional/test_kind_conformance.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/functional/test_property_parsers.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/functional/test_run.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/functional/test_tap_signing.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/functional/test_workspace_scope.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/fuzz/README.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/fuzz/corpus/frontmatter/01-typical.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/fuzz/corpus/frontmatter/02-lossy-version.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/fuzz/corpus/frontmatter/03-lossy-numbers.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/fuzz/corpus/frontmatter/04-lists.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/fuzz/corpus/frontmatter/05-nested.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/fuzz/corpus/frontmatter/06-empty-block.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/fuzz/corpus/frontmatter/07-unterminated.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/fuzz/corpus/frontmatter/08-none.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/fuzz/corpus/frontmatter/09-unbalanced-quote.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/fuzz/corpus/frontmatter/10-keywords.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/fuzz/corpus/frontmatter/11-crlf.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/fuzz/corpus/frontmatter/12-bom.md +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/fuzz/corpus/registry/01-shorthand.txt +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/fuzz/corpus/registry/02-https.txt +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/fuzz/corpus/registry/03-ssh.txt +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/fuzz/corpus/registry/04-traversal.txt +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/fuzz/corpus/registry/05-empty.txt +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/fuzz/corpus/registry/06-space.txt +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/fuzz/corpus/registry/07-slash.txt +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/fuzz/corpus/registry/08-bare-host.txt +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/fuzz/corpus/registry/09-nul.txt +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/fuzz/corpus/registry/10-name-too-long.txt +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/fuzz/corpus/registry/11-long-owner-repo.txt +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/fuzz/fuzz_frontmatter.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/fuzz/fuzz_registry.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/langchain/conftest.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/langchain/test_graph.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/langchain/test_loader.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/langchain/test_retriever.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/make_fixture.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/perf/test_benchmarks.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/smoke.sh +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_a11y_check.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_action_pin_lockstep.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_adapters.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_adapters_multi.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_adapters_runner.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_agents.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_ai.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_bmad_core.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_boost_first_offer.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_bootstrap.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_browse.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_builtin.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_capabilities.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_catalog.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_catalogbundle.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_chat.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_check_anchors.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_check_dco.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_check_licenses.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_claude_settings.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_clean_internal_cache.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_cliparse.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_codeql_analysis_key.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_command_reference_fresh.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_community_health_files.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_compact.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_complete.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_complete_rc_block.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_config.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_content_dedupe.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_content_identity.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_crash_redaction.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_dedup_trust.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_demo_index.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_dense.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_dense_embed_dedupe.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_dense_fallback.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_dense_fix_hint.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_dense_quantized.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_dense_ready_order.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_dense_shard_real_schema.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_dense_shard_unreadable_vectors.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_dense_shards.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_dense_status.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_dense_status_cheap.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_dependabot_config.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_docs_pages_linked.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_docsite_chrome.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_ed25519.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_embed.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_embed_local.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_embed_truncated_response.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_entry_key.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_errors_and_cli_table.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_eval_baseline.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_eval_corpus.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_eval_faithfulness.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_eval_gate.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_eval_grading.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_eval_metrics.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_eval_stats_summary.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_failure_alerting_covers_unattended.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_faithfulness.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_frontmatter.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_fuzz_targets.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_gemini_agent_sanitize.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_gitleaks_config.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_gitutil.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_gitutil_lfs.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_gitutil_sparse.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_imperative.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_import_budget.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_injectscan.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_install_permission_error.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_installscan.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_integrity.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_journal.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_langchain_packaging.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_link_ownership.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_localembed.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_localembed_e2e.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_lockfile.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_logs.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_marketing_counts.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_mcp_install_scan.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_mcpdecl.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_measure_registry.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_minisign.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_mutation_hardening.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_mutation_shards.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_mutation_subfile_shards.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_mutmut_source_paths.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_nethttp.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_output.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_page_budget.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_paths.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_perf_gate.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_pkg_confusions.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_pkg_injection.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_pkg_secrets.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_platform_pins.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_policy.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_post_deploy_smoke.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_project_mcp_sidecar.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_projectlock.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_provenance.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_publish_golden_dataset.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_rag.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_rag_fastpath.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_rag_fusion.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_registries_fresh.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_registry.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_registry_categories.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_registry_control_chars.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_release_guard.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_release_preflight.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_required_checks.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_rerank_cache.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_resolve.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_roadmap_fresh.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_rules.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_scale_corpus.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_scopes.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_secretscan.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_selfupdate.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_serve.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_serve_docs.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_shards_matrix.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_smoke_covers_every_command.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_spin.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_stackprobe.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_staleness.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_store_materialize.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_sync_blocked_links.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_sync_repairs_gutted_skill.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_token_parity.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_toolchain_lock.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_trustaudit.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_typosquat.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_updatediff.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_util.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_version.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_visual_harness_flags.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_workflow_concurrency.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_workflow_concurrency_groups.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_workflow_push_has_credentials.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_workflow_timeouts.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_workflows.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/unit/test_zizmor_ignores_still_anchor.py +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/visual/a11y_check.mjs +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/visual/console_check.mjs +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/visual/package-lock.json +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/visual/package.json +0 -0
- {boost_skill_cli-1.2.30 → boost_skill_cli-1.2.31}/tests/visual/visual_check.mjs +0 -0
|
@@ -339,6 +339,25 @@ for code you write:
|
|
|
339
339
|
stale-link sweeps, coverage counts). `agents.enabled_agents()` is still right
|
|
340
340
|
for rules and workflows, which materialize into `~/.gemini/` like any other
|
|
341
341
|
agent's dotdir. `agents.native_store_agents()` is the complement, for reporting.
|
|
342
|
+
- **Boost not linking there does not mean nothing else does**, and the warning
|
|
343
|
+
costs the user the same either way. `store.duplicate_discovery()` walks
|
|
344
|
+
`native_store_agents()` for entries that resolve back into the canonical
|
|
345
|
+
store — one skill in two of that agent's discovery tiers, whoever wrote it.
|
|
346
|
+
On a real machine 24 of the 25 entries in `~/.gemini/skills` led to
|
|
347
|
+
`~/.claude/skills` directories boost does not manage, and one resolved into
|
|
348
|
+
the store, so the test is **topology, not ownership**: a sweep of "boost's
|
|
349
|
+
stale links" would have deleted two dozen files belonging to another tool.
|
|
350
|
+
`boost doctor` counts each hit as an issue; `boost heal` names them and
|
|
351
|
+
removes nothing; `boost heal --prune-duplicates` removes them, re-checking at
|
|
352
|
+
the point of deletion that the entry is still a symlink still resolving into
|
|
353
|
+
the store. A real directory is never touched.
|
|
354
|
+
- **`points_into_store` and `resolves_into_store` answer different questions.**
|
|
355
|
+
The first reads one `readlink()` because it judges *broken* links, where
|
|
356
|
+
there is nothing to resolve. The second follows the whole chain, because the
|
|
357
|
+
live shape is `~/.gemini/skills/x -> ../../.claude/skills/x -> the store` and
|
|
358
|
+
one hop lands in another agent's dir. It resolves **both sides**: on macOS a
|
|
359
|
+
`$HOME` under `/var/folders` resolves to `/private/var/...`, so resolving
|
|
360
|
+
only the target compares a real path against a nominal one and never matches.
|
|
342
361
|
- Per-agent *formats* differ and are pure functions in `core/`: `rules.CONTEXT_FILES`
|
|
343
362
|
maps an agent with no rules dir to its context file (`claude-code` → CLAUDE.md /
|
|
344
363
|
CLAUDE.local.md, `gemini` → GEMINI.md for both scopes), and
|
|
@@ -350,6 +369,39 @@ for code you write:
|
|
|
350
369
|
Gemini disagree on name position, the `--` separator, and whether unregister
|
|
351
370
|
needs an explicit scope — all three verified against the real CLIs and pinned
|
|
352
371
|
by `tests/unit/test_mcphost.py`. Don't "simplify" them into one shape.
|
|
372
|
+
- **`core/hookhost.py` is the same idea for hooks, and two hosts have them.**
|
|
373
|
+
`boost hooks` writes Claude Code's `~/.claude/settings.json` (the default,
|
|
374
|
+
unchanged) or, behind `--host gemini`, the `~/.gemini/settings.json` that
|
|
375
|
+
Gemini CLI reads;
|
|
376
|
+
`core/claude_settings.py` takes `host=` throughout and asks the table for the
|
|
377
|
+
differences. The `hooks` key and the `{matcher, hooks: [{type, command,
|
|
378
|
+
timeout}]}` block shape are *identical* between them, which is exactly what
|
|
379
|
+
makes the three real differences easy to ship wrong:
|
|
380
|
+
- **`timeout` units.** Claude's is **seconds**; Gemini's is **milliseconds**
|
|
381
|
+
(`DEFAULT_HOOK_TIMEOUT = 6e4`, fed straight to `setTimeout`). Callers pass
|
|
382
|
+
seconds and `hookhost.hook_entry` converts, so boost's `--timeout 10` is ten
|
|
383
|
+
seconds on both. Gemini's own `hooks migrate --from-claude` copies the number
|
|
384
|
+
verbatim, which turns a 10-second Claude hook into a 10-**millisecond**
|
|
385
|
+
Gemini one; don't copy that.
|
|
386
|
+
- **Event names.** Only `SessionStart`, `SessionEnd` and `Notification` are
|
|
387
|
+
spelled alike. `CLAUDE_TO_GEMINI` maps all ten Claude events explicitly and
|
|
388
|
+
`tests/unit/test_hookhost.py` fails if one is missing. `SubagentStop` and
|
|
389
|
+
`SubagentStart` map to **`None`** — Gemini has no sub-agents, so boost
|
|
390
|
+
refuses the hook and says why. (The upstream `EVENT_MAPPING` means to fold
|
|
391
|
+
them into `AfterAgent` but keys `SubAgentStop`, a spelling Claude never
|
|
392
|
+
emits, so `migrate` writes an event Gemini can never fire.)
|
|
393
|
+
- **The `name` field.** Gemini's hook config takes one — it is what
|
|
394
|
+
`/hooks panel` shows and `/hooks enable <name>` targets — and Claude's does
|
|
395
|
+
not. The `# boost:<name>` command marker stays the ownership mechanism for
|
|
396
|
+
both; `name` is added on top for Gemini, never instead.
|
|
397
|
+
A `matcher` is **not** translated: `boost hooks add` is not porting a config,
|
|
398
|
+
so it stays host-native — for a Gemini tool event it is a regular expression
|
|
399
|
+
over *Gemini* tool names like `run_shell_command`, and for a lifecycle event
|
|
400
|
+
it is an exact string. All of this was established against Gemini CLI
|
|
401
|
+
0.57.0's own bundle — the `docs/hooks/` it ships, the `HookEventName` list and
|
|
402
|
+
`EVENT_MAPPING` in the bundled JS, and an observed `migrate` run — and those
|
|
403
|
+
sources are named at the top of `hookhost.py` so the next person can re-check
|
|
404
|
+
them against a newer release.
|
|
353
405
|
|
|
354
406
|
`core/catalog.scan_dir` walks a tap's clone and classifies each file into one
|
|
355
407
|
of the three item kinds (see Non-obvious rules above); `core/store.py` owns
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: boost-skill-cli
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.31
|
|
4
4
|
Summary: boost — Homebrew for AI coding skills
|
|
5
5
|
Author: Jonathan Reyes
|
|
6
6
|
License: GNU GENERAL PUBLIC LICENSE
|
|
@@ -1121,10 +1121,10 @@ as **Connected**. (Gemini only connects stdio servers in a trusted folder; run
|
|
|
1121
1121
|
`gemini` once in the directory and accept the trust prompt if it shows
|
|
1122
1122
|
`Disabled`.)
|
|
1123
1123
|
|
|
1124
|
-
##
|
|
1124
|
+
## Agent hooks & the BMAD Method
|
|
1125
1125
|
|
|
1126
|
-
`boost hooks` manages
|
|
1127
|
-
|
|
1126
|
+
`boost hooks` manages hooks in `settings.json` at either scope — `--scope
|
|
1127
|
+
project` (`./.claude/settings.json`) or `--scope global`
|
|
1128
1128
|
(`~/.claude/settings.json`). boost only ever touches hooks it created (tagged
|
|
1129
1129
|
with a `# boost:<name>` marker in the command), never your own, and snapshots
|
|
1130
1130
|
the prior file before each write.
|
|
@@ -1135,6 +1135,22 @@ boost hooks list
|
|
|
1135
1135
|
boost hooks remove -n greet --scope project
|
|
1136
1136
|
```
|
|
1137
1137
|
|
|
1138
|
+
Gemini CLI has hooks too, behind `--host gemini` (`~/.gemini/settings.json`).
|
|
1139
|
+
The file shape is the same but two details are not, so boost handles both for
|
|
1140
|
+
you: its `timeout` is in milliseconds rather than seconds — `--timeout 10` is
|
|
1141
|
+
ten seconds on either host — and most event names differ. Pass whichever
|
|
1142
|
+
vocabulary you know and boost translates, saying which name it used:
|
|
1143
|
+
|
|
1144
|
+
```bash
|
|
1145
|
+
boost hooks add PreToolUse --host gemini -c 'boost check' -n guard
|
|
1146
|
+
# Claude's 'PreToolUse' is Gemini's 'BeforeTool' — using that
|
|
1147
|
+
boost hooks list # both hosts, with a host column
|
|
1148
|
+
```
|
|
1149
|
+
|
|
1150
|
+
`SubagentStop` and `SubagentStart` have no Gemini counterpart at all — it has
|
|
1151
|
+
no sub-agents — so boost refuses those rather than writing a hook that could
|
|
1152
|
+
never fire.
|
|
1153
|
+
|
|
1138
1154
|
### BMAD autopilot
|
|
1139
1155
|
|
|
1140
1156
|
`boost bmad on` is a one-time, global switch that puts the
|
|
@@ -403,10 +403,10 @@ as **Connected**. (Gemini only connects stdio servers in a trusted folder; run
|
|
|
403
403
|
`gemini` once in the directory and accept the trust prompt if it shows
|
|
404
404
|
`Disabled`.)
|
|
405
405
|
|
|
406
|
-
##
|
|
406
|
+
## Agent hooks & the BMAD Method
|
|
407
407
|
|
|
408
|
-
`boost hooks` manages
|
|
409
|
-
|
|
408
|
+
`boost hooks` manages hooks in `settings.json` at either scope — `--scope
|
|
409
|
+
project` (`./.claude/settings.json`) or `--scope global`
|
|
410
410
|
(`~/.claude/settings.json`). boost only ever touches hooks it created (tagged
|
|
411
411
|
with a `# boost:<name>` marker in the command), never your own, and snapshots
|
|
412
412
|
the prior file before each write.
|
|
@@ -417,6 +417,22 @@ boost hooks list
|
|
|
417
417
|
boost hooks remove -n greet --scope project
|
|
418
418
|
```
|
|
419
419
|
|
|
420
|
+
Gemini CLI has hooks too, behind `--host gemini` (`~/.gemini/settings.json`).
|
|
421
|
+
The file shape is the same but two details are not, so boost handles both for
|
|
422
|
+
you: its `timeout` is in milliseconds rather than seconds — `--timeout 10` is
|
|
423
|
+
ten seconds on either host — and most event names differ. Pass whichever
|
|
424
|
+
vocabulary you know and boost translates, saying which name it used:
|
|
425
|
+
|
|
426
|
+
```bash
|
|
427
|
+
boost hooks add PreToolUse --host gemini -c 'boost check' -n guard
|
|
428
|
+
# Claude's 'PreToolUse' is Gemini's 'BeforeTool' — using that
|
|
429
|
+
boost hooks list # both hosts, with a host column
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
`SubagentStop` and `SubagentStart` have no Gemini counterpart at all — it has
|
|
433
|
+
no sub-agents — so boost refuses those rather than writing a hook that could
|
|
434
|
+
never fire.
|
|
435
|
+
|
|
420
436
|
### BMAD autopilot
|
|
421
437
|
|
|
422
438
|
`boost bmad on` is a one-time, global switch that puts the
|
|
@@ -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.2.
|
|
22
|
-
__version_tuple__ = version_tuple = (1, 2,
|
|
21
|
+
__version__ = version = '1.2.31'
|
|
22
|
+
__version_tuple__ = version_tuple = (1, 2, 31)
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -125,7 +125,7 @@ COMMANDS = [
|
|
|
125
125
|
("schedule", "cfg", "configuration", "Manage automatic skill-sync scheduling"),
|
|
126
126
|
("serve", "cfg", "configuration", "Browse the catalogue in a browser: search, facets and a tap graph"),
|
|
127
127
|
("mcp", "cfg", "configuration", "Register boost as an MCP server (Claude Code, Gemini CLI)"),
|
|
128
|
-
("hooks", "cfg", "hooks", "Manage Claude Code
|
|
128
|
+
("hooks", "cfg", "hooks", "Manage agent hooks (Claude Code, Gemini CLI) in settings.json"),
|
|
129
129
|
("bmad", "cfg", "bmad", "BMAD Method autopilot — `bmad on` routes every task to a persona"),
|
|
130
130
|
("self-update", "cfg", "configuration", "Update boost itself to the latest version"),
|
|
131
131
|
# Team & Collaboration (6)
|
|
@@ -1329,9 +1329,19 @@ REGISTRY.register(
|
|
|
1329
1329
|
"what this machine holds, not what exists, and a kind sitting at zero is a "
|
|
1330
1330
|
"kind nothing here could have loaded. boost_search is what reads the "
|
|
1331
1331
|
"registries themselves. "
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
"
|
|
1332
|
+
# The cost clause names its own mechanism. Gemini CLI never delivers
|
|
1333
|
+
# server `instructions` in interactive mode, so INSTRUCTIONS' "boost_list
|
|
1334
|
+
# is free, call it whenever" is absent on that host and this declaration
|
|
1335
|
+
# is the only place left to say it. "Instant" alone is a claim about the
|
|
1336
|
+
# clock that an agent has to take on trust; "a local file read rather
|
|
1337
|
+
# than a search" is the reason for it, checkable against what the tool
|
|
1338
|
+
# obviously does, and it is why no threshold follows. boost_search's
|
|
1339
|
+
# "10-15 seconds" stays out — that is the other tool's price, and this
|
|
1340
|
+
# one does not pay it.
|
|
1341
|
+
"Read-only and it installs nothing: a local file read rather than a "
|
|
1342
|
+
"search, so it is instant and free. Unlike boost_search there is "
|
|
1343
|
+
"therefore no threshold worth applying: call it whenever you are about "
|
|
1344
|
+
"to plan something. Planning from memory while "
|
|
1335
1345
|
"the answer already sits on disk is the one avoidable mistake here.",
|
|
1336
1346
|
{"type": "object", "properties": {}},
|
|
1337
1347
|
_tool_list)
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
"""boost hooks — scope- and host-aware management of agent hooks in settings.json.
|
|
2
|
+
|
|
3
|
+
boost hooks add SessionStart --command 'boost bmad orient' --name bmad \
|
|
4
|
+
--scope global --matcher 'startup|resume|clear'
|
|
5
|
+
boost hooks add PreToolUse --host gemini -c 'boost check' -n guard
|
|
6
|
+
boost hooks list
|
|
7
|
+
boost hooks remove --name bmad
|
|
8
|
+
|
|
9
|
+
Two hosts have hooks: Claude Code (`~/.claude/settings.json`, the default and
|
|
10
|
+
unchanged) and Gemini CLI (`~/.gemini/settings.json`). What differs between
|
|
11
|
+
them is a pure table in core/hookhost.py; this layer only picks a host, spells
|
|
12
|
+
the event the way that host spells it, and reports what it did.
|
|
13
|
+
|
|
14
|
+
Event names mostly differ, so `--host gemini` accepts either vocabulary and
|
|
15
|
+
says which translation it applied. Two Claude events — SubagentStop and
|
|
16
|
+
SubagentStart — have no Gemini counterpart at all, and are refused rather than
|
|
17
|
+
silently dropped: a hook that looks installed and never fires is the failure
|
|
18
|
+
mode worth being loud about.
|
|
19
|
+
|
|
20
|
+
Only hooks boost created (tagged `# boost:<name>`) are ever touched; user hooks
|
|
21
|
+
are left untouched. See core/claude_settings.py.
|
|
22
|
+
"""
|
|
23
|
+
from __future__ import annotations
|
|
24
|
+
|
|
25
|
+
from .. import cliparse
|
|
26
|
+
from ..core import claude_settings as cs
|
|
27
|
+
from ..core import hookhost, journal
|
|
28
|
+
from ..core import output as out
|
|
29
|
+
from ..errors import BoostError
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def cmd_hooks(argv) -> int:
|
|
33
|
+
p = cliparse.parser(
|
|
34
|
+
prog="boost hooks",
|
|
35
|
+
description="Manage agent hooks (scope- and host-aware) in settings.json")
|
|
36
|
+
p.add_argument("action", choices=("add", "remove", "list"),
|
|
37
|
+
help="add | remove | list")
|
|
38
|
+
p.add_argument("event", nargs="?",
|
|
39
|
+
help="hook event, e.g. SessionStart (required for add)")
|
|
40
|
+
p.add_argument("--host", metavar="H", default=None,
|
|
41
|
+
choices=(*hookhost.hosts(), "auto"),
|
|
42
|
+
help="agent CLI whose settings.json to manage: %s "
|
|
43
|
+
"(default: claude for add/remove, all of them for list)"
|
|
44
|
+
% ", ".join(hookhost.hosts()))
|
|
45
|
+
p.add_argument("-c", "--command", help="command the hook runs (add)")
|
|
46
|
+
p.add_argument("-n", "--name", help="stable name used to tag & find the hook")
|
|
47
|
+
p.add_argument("-s", "--scope", choices=cs.SCOPES, default=None,
|
|
48
|
+
help="settings scope (default: project; list shows both)")
|
|
49
|
+
p.add_argument("-m", "--matcher",
|
|
50
|
+
help="Claude matcher, e.g. 'startup|resume|clear'")
|
|
51
|
+
p.add_argument("--timeout", type=int, default=10,
|
|
52
|
+
help="hook timeout in seconds (default: 10)")
|
|
53
|
+
args = p.parse_args(argv)
|
|
54
|
+
|
|
55
|
+
if args.action == "list":
|
|
56
|
+
return _list(args.scope, args.host)
|
|
57
|
+
if args.action == "add":
|
|
58
|
+
return _add(args)
|
|
59
|
+
return _remove(args)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def _list(scope, host) -> int:
|
|
63
|
+
rows = cs.list_all_hooks(scope, host=host)
|
|
64
|
+
if not rows:
|
|
65
|
+
out.info("no boost-managed hooks" + (" in %s scope" % scope if scope else ""))
|
|
66
|
+
return 0
|
|
67
|
+
out.table(
|
|
68
|
+
[(r["host"], r["scope"], r["event"], r["name"], r["matcher"] or "-",
|
|
69
|
+
r["command"]) for r in rows],
|
|
70
|
+
headers=("host", "scope", "event", "name", "matcher", "command"))
|
|
71
|
+
return 0
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def _write_host(requested) -> str:
|
|
75
|
+
"""The single host an `add`/`remove` targets. Claude unless told otherwise.
|
|
76
|
+
|
|
77
|
+
`auto` is a read-only idea — fanning a write across every installed CLI is
|
|
78
|
+
not what someone asking for one hook meant — so it is rejected here rather
|
|
79
|
+
than quietly meaning "claude".
|
|
80
|
+
"""
|
|
81
|
+
if requested in (None, ""):
|
|
82
|
+
return hookhost.CLAUDE
|
|
83
|
+
if requested == "auto":
|
|
84
|
+
raise BoostError("--host auto only makes sense for `hooks list`",
|
|
85
|
+
hint="name one host: %s" % ", ".join(hookhost.hosts()))
|
|
86
|
+
return requested
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def _where(host: str, scope: str) -> str:
|
|
90
|
+
"""How a write is named back to the user: "global", or "gemini/global".
|
|
91
|
+
|
|
92
|
+
Claude Code is the default host, so its scope stays unqualified — the
|
|
93
|
+
wording predates there being a second host and there is nothing to
|
|
94
|
+
disambiguate. A host the user had to ask for by name is worth repeating
|
|
95
|
+
back, because "removed 1 hook" is only reassuring if it says where from.
|
|
96
|
+
"""
|
|
97
|
+
return scope if host == hookhost.CLAUDE else "%s/%s" % (host, scope)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def _native_event(host: str, event: str) -> str:
|
|
101
|
+
"""`event` as `host` spells it, saying so, or refusing if it cannot."""
|
|
102
|
+
native = hookhost.translate(host, event)
|
|
103
|
+
if native is None:
|
|
104
|
+
raise BoostError(
|
|
105
|
+
"'%s' has no %s counterpart" % (event, hookhost.label(host)),
|
|
106
|
+
hint="%s has no sub-agents; its events are: %s"
|
|
107
|
+
% (hookhost.label(host), ", ".join(hookhost.events(host))))
|
|
108
|
+
if native != event:
|
|
109
|
+
out.info("Claude's '%s' is %s's '%s' — using that"
|
|
110
|
+
% (event, hookhost.event_label(host), native))
|
|
111
|
+
return native
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def _add(args) -> int:
|
|
115
|
+
if not args.event:
|
|
116
|
+
raise BoostError("hooks add needs an EVENT",
|
|
117
|
+
hint="e.g. boost hooks add SessionStart -c '<cmd>' -n <name>")
|
|
118
|
+
if not args.command:
|
|
119
|
+
raise BoostError("hooks add needs --command",
|
|
120
|
+
hint="the shell command Claude should run for this hook")
|
|
121
|
+
if not args.name:
|
|
122
|
+
raise BoostError("hooks add needs --name",
|
|
123
|
+
hint="a stable name so the hook can be removed later")
|
|
124
|
+
scope = args.scope or "project"
|
|
125
|
+
host = _write_host(args.host)
|
|
126
|
+
event = _native_event(host, args.event)
|
|
127
|
+
if event not in hookhost.events(host):
|
|
128
|
+
out.warn("'%s' is not a known %s hook event — adding anyway"
|
|
129
|
+
% (event, hookhost.event_label(host)))
|
|
130
|
+
cs.add_hook(scope, event, args.name, args.command,
|
|
131
|
+
matcher=args.matcher, timeout=args.timeout, host=host)
|
|
132
|
+
journal.log("hook-add", args.name, scope=scope, event=event, host=host)
|
|
133
|
+
out.ok("added %s hook '%s' (%s) → %s"
|
|
134
|
+
% (event, args.name, _where(host, scope), args.command))
|
|
135
|
+
out.dim(" settings: %s" % cs.settings_path(scope, host=host))
|
|
136
|
+
return 0
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def _remove(args) -> int:
|
|
140
|
+
if not args.name:
|
|
141
|
+
raise BoostError("hooks remove needs --name",
|
|
142
|
+
hint="the name you gave the hook when adding it")
|
|
143
|
+
scope = args.scope or "project"
|
|
144
|
+
host = _write_host(args.host)
|
|
145
|
+
events = ((_native_event(host, args.event),) if args.event
|
|
146
|
+
else hookhost.events(host))
|
|
147
|
+
removed = sum(cs.remove_hook(scope, ev, args.name, host=host)
|
|
148
|
+
for ev in events)
|
|
149
|
+
journal.log("hook-remove", args.name, scope=scope, host=host)
|
|
150
|
+
if removed:
|
|
151
|
+
out.ok("removed %d hook(s) named '%s' (%s)"
|
|
152
|
+
% (removed, args.name, _where(host, scope)))
|
|
153
|
+
else:
|
|
154
|
+
out.warn("no boost hook named '%s' in %s scope"
|
|
155
|
+
% (args.name, _where(host, scope)))
|
|
156
|
+
return 0
|
|
@@ -535,6 +535,19 @@ def cmd_doctor(argv):
|
|
|
535
535
|
"left alone; yours to remove or repair"
|
|
536
536
|
% (len(foreign), _s(len(foreign))))
|
|
537
537
|
|
|
538
|
+
for dup in store.duplicate_discovery():
|
|
539
|
+
# An agent that reads the canonical store natively, holding its own
|
|
540
|
+
# entry for a skill that store already carries. Boost did not put it
|
|
541
|
+
# there — it never links into a native-store agent — but the agent
|
|
542
|
+
# loads the same skill from two discovery tiers and says so on every
|
|
543
|
+
# session, so a health check that stayed quiet about it would be
|
|
544
|
+
# describing a machine the user is not looking at.
|
|
545
|
+
bad("skill %s is discoverable twice by %s — %s leads to %s, which it "
|
|
546
|
+
"already reads natively; remove the duplicate with "
|
|
547
|
+
"`boost heal --prune-duplicates`"
|
|
548
|
+
% (dup.name, agents.display_name(dup.agent), _tilde(dup.path),
|
|
549
|
+
_tilde(dup.target)), wrap=True)
|
|
550
|
+
|
|
538
551
|
for adir in enabled.values():
|
|
539
552
|
if adir.is_dir() and not os.access(str(adir), os.W_OK):
|
|
540
553
|
bad("agent dir %s is not writable" % _tilde(adir))
|
|
@@ -854,6 +867,9 @@ def cmd_heal(argv):
|
|
|
854
867
|
description="Self-diagnose & repair the boost environment")
|
|
855
868
|
ap.add_argument("--dry-run", action="store_true",
|
|
856
869
|
help="show repairs without applying them")
|
|
870
|
+
ap.add_argument("--prune-duplicates", action="store_true",
|
|
871
|
+
help="remove symlinks in a native-store agent's skills dir "
|
|
872
|
+
"that lead back into the canonical store")
|
|
857
873
|
args = ap.parse_args(argv)
|
|
858
874
|
dry = args.dry_run
|
|
859
875
|
actions: list[str] = []
|
|
@@ -903,6 +919,30 @@ def cmd_heal(argv):
|
|
|
903
919
|
out.ok(msg.replace(str(paths.home()), "~"))
|
|
904
920
|
actions.append(msg)
|
|
905
921
|
|
|
922
|
+
# Opt-in, unlike everything above it. The rest of `heal` repairs what boost
|
|
923
|
+
# itself created; these entries boost did not create, so deleting one on a
|
|
924
|
+
# plain `boost heal` would be silently removing another tool's file. Named
|
|
925
|
+
# every run so the flag is discoverable from the command that would use it.
|
|
926
|
+
duplicates = store.duplicate_discovery()
|
|
927
|
+
declined_duplicates = bool(duplicates) and not args.prune_duplicates
|
|
928
|
+
for dup in duplicates:
|
|
929
|
+
label = "%s → %s (%s)" % (_tilde(dup.path), _tilde(dup.target), dup.agent)
|
|
930
|
+
if not args.prune_duplicates:
|
|
931
|
+
out.info("duplicate skill discovery %s — %s reads the store "
|
|
932
|
+
"natively; remove it with `boost heal --prune-duplicates`"
|
|
933
|
+
% (label, agents.display_name(dup.agent)), wrap=True)
|
|
934
|
+
elif dry:
|
|
935
|
+
out.info("would remove duplicate skill discovery %s" % label)
|
|
936
|
+
actions.append("duplicate %s" % dup.path)
|
|
937
|
+
elif store.remove_duplicate_discovery(dup):
|
|
938
|
+
out.ok("removed duplicate skill discovery %s" % label)
|
|
939
|
+
actions.append("duplicate %s" % dup.path)
|
|
940
|
+
else:
|
|
941
|
+
# Re-gated at the point of deletion, so a real directory or a link
|
|
942
|
+
# repointed since the scan lands here rather than being removed.
|
|
943
|
+
out.warn("%s is no longer a symlink into the store — left alone"
|
|
944
|
+
% _tilde(dup.path))
|
|
945
|
+
|
|
906
946
|
for tap in registry.list_taps():
|
|
907
947
|
if not tap.is_cloned:
|
|
908
948
|
out.warn("tap %s not cloned — skipped (run `boost update`)" % tap.name)
|
|
@@ -929,7 +969,11 @@ def cmd_heal(argv):
|
|
|
929
969
|
actions.append("rotate")
|
|
930
970
|
|
|
931
971
|
if not actions:
|
|
932
|
-
|
|
972
|
+
# A duplicate this run declined to prune is something `heal` saw, can
|
|
973
|
+
# fix, and deliberately left. A bare "nothing to heal" printed under
|
|
974
|
+
# the line offering the flag contradicts it.
|
|
975
|
+
out.ok("nothing to heal automatically"
|
|
976
|
+
if declined_duplicates else "nothing to heal")
|
|
933
977
|
elif not dry:
|
|
934
978
|
journal.log("heal", "%d actions" % len(actions))
|
|
935
979
|
return 0
|
|
@@ -1,9 +1,17 @@
|
|
|
1
|
-
"""Scope-aware read/merge/write of
|
|
1
|
+
"""Scope- and host-aware read/merge/write of a settings.json + hook management.
|
|
2
2
|
|
|
3
3
|
Claude Code reads hooks from a JSON `settings.json` at two scopes:
|
|
4
4
|
global -> ~/.claude/settings.json
|
|
5
5
|
project -> <project>/.claude/settings.json
|
|
6
6
|
|
|
7
|
+
Gemini CLI reads the same shape from `~/.gemini/settings.json` and
|
|
8
|
+
`<project>/.gemini/settings.json`. Every function here takes `host=` (default
|
|
9
|
+
`"claude"`, so nothing that predates the second host changed) and gets the
|
|
10
|
+
per-host facts — the dotdir, the event vocabulary, the timeout units — from
|
|
11
|
+
`core/hookhost.py`, which is a pure table. The units are the trap worth naming
|
|
12
|
+
twice: Claude's `timeout` is seconds and Gemini's is milliseconds, so callers
|
|
13
|
+
pass **seconds** and `hookhost.hook_entry` converts.
|
|
14
|
+
|
|
7
15
|
boost only ever touches hooks it created. Each managed hook's command carries a
|
|
8
16
|
trailing shell comment marker `# boost:<name>` so we can find and remove exactly
|
|
9
17
|
our own entries and never clobber the user's hooks. Every write first snapshots
|
|
@@ -25,26 +33,27 @@ import json
|
|
|
25
33
|
from pathlib import Path
|
|
26
34
|
|
|
27
35
|
from ..errors import BoostError
|
|
28
|
-
from . import paths, util
|
|
36
|
+
from . import hookhost, paths, util
|
|
29
37
|
|
|
30
38
|
SCOPES = ("global", "project")
|
|
31
39
|
MARKER = "# boost:"
|
|
32
40
|
HISTORY_KEEP = 50
|
|
33
41
|
|
|
34
42
|
# Known Claude Code hook events (permissive — validated by callers that care).
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
)
|
|
43
|
+
# Kept as an alias so importers that predate the host table still work; the
|
|
44
|
+
# list itself lives in hookhost alongside Gemini's.
|
|
45
|
+
KNOWN_EVENTS = hookhost.CLAUDE_EVENTS
|
|
39
46
|
|
|
40
47
|
|
|
41
|
-
def settings_path(scope: str, project_dir: Path | None = None
|
|
42
|
-
|
|
48
|
+
def settings_path(scope: str, project_dir: Path | None = None,
|
|
49
|
+
host: str = hookhost.CLAUDE) -> Path:
|
|
50
|
+
"""Absolute path to the settings.json for a scope, on a host."""
|
|
51
|
+
dotdir = hookhost.settings_dir(host)
|
|
43
52
|
if scope == "global":
|
|
44
|
-
return paths.home() /
|
|
53
|
+
return paths.home() / dotdir / "settings.json"
|
|
45
54
|
if scope == "project":
|
|
46
55
|
base = Path(project_dir) if project_dir else Path.cwd()
|
|
47
|
-
return base /
|
|
56
|
+
return base / dotdir / "settings.json"
|
|
48
57
|
raise BoostError("unknown scope %r" % scope,
|
|
49
58
|
hint="use 'global' or 'project'")
|
|
50
59
|
|
|
@@ -53,9 +62,10 @@ def _history_dir() -> Path:
|
|
|
53
62
|
return paths.state_dir() / "claude-settings-history"
|
|
54
63
|
|
|
55
64
|
|
|
56
|
-
def load(scope: str, project_dir: Path | None = None
|
|
65
|
+
def load(scope: str, project_dir: Path | None = None,
|
|
66
|
+
host: str = hookhost.CLAUDE) -> dict:
|
|
57
67
|
"""Parse a scope's settings.json ({} if missing or corrupt)."""
|
|
58
|
-
p = settings_path(scope, project_dir)
|
|
68
|
+
p = settings_path(scope, project_dir, host)
|
|
59
69
|
if not p.exists():
|
|
60
70
|
return {}
|
|
61
71
|
try:
|
|
@@ -65,18 +75,25 @@ def load(scope: str, project_dir: Path | None = None) -> dict:
|
|
|
65
75
|
return data if isinstance(data, dict) else {}
|
|
66
76
|
|
|
67
77
|
|
|
68
|
-
def save(scope: str, data: dict, project_dir: Path | None = None
|
|
69
|
-
|
|
70
|
-
|
|
78
|
+
def save(scope: str, data: dict, project_dir: Path | None = None,
|
|
79
|
+
host: str = hookhost.CLAUDE) -> None:
|
|
80
|
+
"""Write a scope's settings.json, snapshotting the prior version first.
|
|
81
|
+
|
|
82
|
+
Snapshots are named ``<host prefix><scope>-<stamp>.json``. Claude's prefix
|
|
83
|
+
is empty, so its history filenames are exactly what they always were and a
|
|
84
|
+
Gemini write cannot land on top of one.
|
|
85
|
+
"""
|
|
86
|
+
p = settings_path(scope, project_dir, host)
|
|
71
87
|
p.parent.mkdir(parents=True, exist_ok=True)
|
|
72
88
|
if p.exists():
|
|
73
89
|
hist = _history_dir()
|
|
74
90
|
hist.mkdir(parents=True, exist_ok=True)
|
|
75
91
|
stamp = util.now_iso().replace(":", "").replace("-", "")
|
|
76
|
-
|
|
92
|
+
pre = hookhost.history_prefix(host)
|
|
93
|
+
dest = hist / ("%s%s-%s.json" % (pre, scope, stamp))
|
|
77
94
|
n = 2
|
|
78
95
|
while dest.exists():
|
|
79
|
-
dest = hist / ("%s-%s-%d.json" % (scope, stamp, n))
|
|
96
|
+
dest = hist / ("%s%s-%s-%d.json" % (pre, scope, stamp, n))
|
|
80
97
|
n += 1
|
|
81
98
|
dest.write_text(p.read_text(encoding="utf-8"), encoding="utf-8")
|
|
82
99
|
_prune_history()
|
|
@@ -108,28 +125,34 @@ def _hook_name(command: str) -> str | None:
|
|
|
108
125
|
|
|
109
126
|
def add_hook(scope: str, event: str, name: str, command: str,
|
|
110
127
|
matcher: str | None = None, timeout: int = 10,
|
|
111
|
-
project_dir: Path | None = None
|
|
112
|
-
|
|
113
|
-
|
|
128
|
+
project_dir: Path | None = None,
|
|
129
|
+
host: str = hookhost.CLAUDE) -> None:
|
|
130
|
+
"""Idempotently install a boost-managed hook (replaces same-named entry).
|
|
131
|
+
|
|
132
|
+
``timeout`` is in **seconds** whatever the host; ``hookhost.hook_entry``
|
|
133
|
+
converts it to the units that host's settings.json is read in. ``event``
|
|
134
|
+
must already be spelled the way ``host`` spells it — translating is the
|
|
135
|
+
command layer's job, because a Claude event with no Gemini counterpart has
|
|
136
|
+
to be refused out loud rather than silently dropped here.
|
|
137
|
+
"""
|
|
138
|
+
data = load(scope, project_dir, host)
|
|
114
139
|
event_list = data.setdefault("hooks", {}).setdefault(event, [])
|
|
115
140
|
# Drop any prior entry we own with this name so re-adding is idempotent.
|
|
116
141
|
_strip(event_list, name)
|
|
117
142
|
block: dict = {}
|
|
118
143
|
if matcher:
|
|
119
144
|
block["matcher"] = matcher
|
|
120
|
-
block["hooks"] = [
|
|
121
|
-
|
|
122
|
-
"command": _tag(command, name),
|
|
123
|
-
"timeout": timeout,
|
|
124
|
-
}]
|
|
145
|
+
block["hooks"] = [hookhost.hook_entry(host, _tag(command, name), timeout,
|
|
146
|
+
name=name)]
|
|
125
147
|
event_list.append(block)
|
|
126
|
-
save(scope, data, project_dir)
|
|
148
|
+
save(scope, data, project_dir, host)
|
|
127
149
|
|
|
128
150
|
|
|
129
151
|
def remove_hook(scope: str, event: str, name: str,
|
|
130
|
-
project_dir: Path | None = None
|
|
152
|
+
project_dir: Path | None = None,
|
|
153
|
+
host: str = hookhost.CLAUDE) -> int:
|
|
131
154
|
"""Remove boost-managed hooks matching name; return how many were removed."""
|
|
132
|
-
data = load(scope, project_dir)
|
|
155
|
+
data = load(scope, project_dir, host)
|
|
133
156
|
hooks = data.get("hooks")
|
|
134
157
|
if not isinstance(hooks, dict) or event not in hooks:
|
|
135
158
|
return 0
|
|
@@ -140,7 +163,7 @@ def remove_hook(scope: str, event: str, name: str,
|
|
|
140
163
|
del hooks[event]
|
|
141
164
|
if not hooks:
|
|
142
165
|
del data["hooks"]
|
|
143
|
-
save(scope, data, project_dir)
|
|
166
|
+
save(scope, data, project_dir, host)
|
|
144
167
|
return removed
|
|
145
168
|
|
|
146
169
|
|
|
@@ -165,8 +188,9 @@ def _strip(event_list: list, name: str) -> int:
|
|
|
165
188
|
|
|
166
189
|
|
|
167
190
|
def has_hook(scope: str, event: str, name: str,
|
|
168
|
-
project_dir: Path | None = None
|
|
169
|
-
|
|
191
|
+
project_dir: Path | None = None,
|
|
192
|
+
host: str = hookhost.CLAUDE) -> bool:
|
|
193
|
+
data = load(scope, project_dir, host)
|
|
170
194
|
for block in data.get("hooks", {}).get(event, []) or []:
|
|
171
195
|
for h in (block.get("hooks") or []) if isinstance(block, dict) else []:
|
|
172
196
|
if _hook_name(str(h.get("command", ""))) == name:
|
|
@@ -175,12 +199,13 @@ def has_hook(scope: str, event: str, name: str,
|
|
|
175
199
|
|
|
176
200
|
|
|
177
201
|
def list_hooks(scope: str | None = None,
|
|
178
|
-
project_dir: Path | None = None
|
|
179
|
-
|
|
202
|
+
project_dir: Path | None = None,
|
|
203
|
+
host: str = hookhost.CLAUDE) -> list[dict]:
|
|
204
|
+
"""One host's boost-managed hooks: [{scope, event, name, command, matcher}]."""
|
|
180
205
|
scopes = (scope,) if scope else SCOPES
|
|
181
206
|
rows: list[dict] = []
|
|
182
207
|
for sc in scopes:
|
|
183
|
-
data = load(sc, project_dir)
|
|
208
|
+
data = load(sc, project_dir, host)
|
|
184
209
|
for event, blocks in (data.get("hooks") or {}).items():
|
|
185
210
|
for block in blocks or []:
|
|
186
211
|
if not isinstance(block, dict):
|
|
@@ -198,3 +223,19 @@ def list_hooks(scope: str | None = None,
|
|
|
198
223
|
"matcher": block.get("matcher", ""),
|
|
199
224
|
})
|
|
200
225
|
return rows
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
def list_all_hooks(scope: str | None = None,
|
|
229
|
+
project_dir: Path | None = None,
|
|
230
|
+
host: str | None = None) -> list[dict]:
|
|
231
|
+
""":func:`list_hooks` across hosts, each row tagged with the host it is in.
|
|
232
|
+
|
|
233
|
+
``host=None`` means every known host, which is what ``boost hooks list``
|
|
234
|
+
wants: a hook boost installed into a CLI the user has since stopped naming
|
|
235
|
+
is exactly the one they need shown. Kept separate from :func:`list_hooks`
|
|
236
|
+
rather than folded into it because that function's row shape is what
|
|
237
|
+
callers already destructure.
|
|
238
|
+
"""
|
|
239
|
+
return [{"host": hs} | row
|
|
240
|
+
for hs in hookhost.resolve(host)
|
|
241
|
+
for row in list_hooks(scope, project_dir, hs)]
|