boost-skill-cli 1.2.54__tar.gz → 1.2.56__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.54 → boost_skill_cli-1.2.56}/CLAUDE.md +20 -0
- {boost_skill_cli-1.2.54/boost_skill_cli.egg-info → boost_skill_cli-1.2.56}/PKG-INFO +5 -3
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/README.md +4 -2
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/_version.py +2 -2
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/commands/configuration.py +83 -7
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/commands/discovery.py +23 -2
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/commands/info.py +15 -1
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/commands/quality.py +24 -5
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/commands/quickstart.py +20 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/dense.py +171 -19
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/mcp.py +56 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56/boost_skill_cli.egg-info}/PKG-INFO +5 -3
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_skill_cli.egg-info/SOURCES.txt +2 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/mcp-hub.html +9 -7
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/dense-reindex-reuses-whole-taps.md +33 -2
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/mcp-cannot-read-a-skill-before-installing.md +25 -3
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap.html +60 -5
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/bdd/features/doctor.feature +4 -2
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_cli_configuration.py +2 -2
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_cli_info.py +40 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_cli_quality.py +40 -1
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_cli_quickstart.py +74 -0
- boost_skill_cli-1.2.56/tests/unit/test_dense_entry_reuse.py +512 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_dense_fallback.py +8 -1
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_dense_shard_unreadable_vectors.py +1 -1
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_dense_shards.py +1 -1
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_mcp.py +1 -1
- boost_skill_cli-1.2.56/tests/unit/test_mcp_read.py +341 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/.gitattributes +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/.gitignore +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/.gitleaks.toml +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/.htmlvalidate.json +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/.lighthouserc.json +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/.lycheeignore +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/.markdownlint-cli2.jsonc +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/.pre-commit-config.yaml +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/.stylelintrc.json +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/.vale/styles/boost/AIWriting.yml +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/.vale/styles/boost/Terminology.yml +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/.vale/styles/config/vocabularies/boost/accept.txt +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/.vale.ini +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/CODE_OF_CONDUCT.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/CONTRIBUTING.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/DCO +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/GOVERNANCE.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/LICENSE +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/MAINTAINERS.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/MANIFEST.in +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/Makefile +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/SECURITY.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/SUPPORT.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/__init__.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/__main__.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/cli.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/cliparse.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/commands/__init__.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/commands/_common.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/commands/bmad.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/commands/hooks.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/commands/intelligence.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/commands/pkg.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/commands/run.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/commands/safety.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/commands/taps.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/commands/team.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/__init__.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/adapters.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/agents.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/ai.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/aihost.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/bmad.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/bootstrap.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/browse.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/builtin.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/capabilities.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/catalog.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/catalogbundle.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/chat.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/claude_settings.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/complete.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/config.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/ed25519.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/embed.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/faithfulness.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/frontmatter.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/gitutil.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/hookhost.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/imperative.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/injectscan.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/installscan.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/integrity.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/journal.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/localembed.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/lockfile.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/logs.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/mcpdecl.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/mcphost.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/minisign.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/nethttp.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/output.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/paths.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/policy.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/projectlock.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/provenance.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/rag.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/registry.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/resolve.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/rules.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/scopes.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/secretscan.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/selfupdate.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/serve.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/shards.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/stackprobe.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/staleness.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/store.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/trustaudit.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/typosquat.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/updatediff.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/util.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/workflows.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/data/registries.json +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/data/rules/boost-first.mdc +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/errors.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/spin.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_langchain/__init__.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_langchain/_compat.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_langchain/graph.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_langchain/loader.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_langchain/py.typed +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_langchain/retriever.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_skill_cli.egg-info/dependency_links.txt +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_skill_cli.egg-info/entry_points.txt +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_skill_cli.egg-info/requires.txt +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_skill_cli.egg-info/top_level.txt +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/codecov.yml +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/.claude/settings.local.json +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/DEBUGGING.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/adapters.html +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/architecture/README.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/architecture/c4-components-core.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/architecture/c4-containers.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/architecture/c4-context.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/architecture/c4-dynamic-install.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/bmad.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/carousel/gifs/distill.gif +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/carousel/gifs/doctor.gif +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/carousel/gifs/explain.gif +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/carousel/gifs/hooks.gif +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/carousel/gifs/install.gif +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/carousel/gifs/pulse.gif +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/carousel/gifs/search.gif +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/carousel/gifs/tap.gif +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/carousel/tapes/distill.tape +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/carousel/tapes/doctor.tape +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/carousel/tapes/explain.tape +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/carousel/tapes/hooks.tape +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/carousel/tapes/install.tape +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/carousel/tapes/pulse.tape +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/carousel/tapes/search.tape +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/carousel/tapes/tap.tape +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/carousel.html +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/chat.html +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/code-review.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/commands.html +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/commit-audit.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/demo-index.json +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/demo.gif +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/demo.html +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/demo.tape +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/dependencies.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/design-roadmap.html +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/eval-latest.json +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/eval.html +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/index.html +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/langchain.html +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/openssf-badge.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/openssf-playbook.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/rag-architecture.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D01.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D02.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D03.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D04.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D05.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D06.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D07.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D08.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D09.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D10.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D11.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D12.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D13.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D14.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D15.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D16.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D17.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D18.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D19.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D20.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D21.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D22.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D23.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D24.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D25.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D26.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D27.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/a11y-sweep-flakes-on-color-contrast.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/accessibility-audit-pa11y-ci-axe-core.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/actionlint-skips-shellcheck-silently.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/adapter-conformance-langgraph-leg-never-ran.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/agents-field-records-the-request-not-the-links.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/ai-backend-fanout.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/ai-bridge-silent-failure-logging.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/ambiguous-tap-short-name-resolution.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/atomic-corruption-safe-lock-file-writes.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/atomic-skill-install-temp-dir-swap.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/autonomous-ship-workflow-and-isolated-worktree.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/bm25-has-no-stemming.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/bm25-index-is-one-json-blob.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/bmad-autopilot-one-command-persona-routing.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/bmad-hooks-all-hosts.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/boost-first-carried-the-losing-trigger.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/boost-first-rule.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/boost-langchain-publishing.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/boost-run-live-agents.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/branch-current-gate.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/bring-commands-under-mutation-testing.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/broken-link-and-anchor-checking-lychee.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/browse-could-not-search-two-words.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/browse-crashes-selecting-a-rule-or-workflow.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/build-provenance-slsa-attestations.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/cache-the-catalog-entry-set-across-rag-queries.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/capability-manifest-and-least-privilege-policy.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/catalogue-entries-carry-no-content-identity.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/chat-cites-sources-by-a-number-it-never-prints.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/chat-command-grounded-conversational-search.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/ci-job-timeout-minutes.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/ci-summary-step-fails-itself.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/ci-time-is-now-runner-queueing.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/clean-env-install-smoke-pip-and-pipx.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/cli-command-audit.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/cli-output-ignored-the-terminal.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/code-scanning-rule-can-be-restored.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/codeql-job-rename-stranded-merge-protection.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/cold-search-reads-the-whole-catalogue.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/command-carousel-page.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/command-reference-docs-site.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/completions-complete-only-command-names.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/completions-install-could-eat-your-rc-file.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/complexity-and-dead-code-radar-xenon-vulture.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/consolidate-skill-staleness-drift-logic-into-cor.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/coverage-dashboard-codecov-free-for-oss.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/coverage-guided-fuzzing-atheris-oss-fuzz.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/crash-listing-branch-untested.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/crash-recorder-error-paths-core-logs-py.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/crash-reports-leak-api-keys.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/demo-cannot-open-its-own-pr.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/demo-gif-workflow-has-never-succeeded.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/demo-workflow-cancels-other-prs.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/dense-reindex-has-no-progress-or-durability.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/dense-search-fallback-and-stale-tap-pruning.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/dense-search-rescans-every-vector.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/dependabot-missing-pip-ecosystem.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/dependabot-regeneration-drops-platform-pins.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/dependabot-root-pip-entry-duplicates-requirements.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/dependabot-splits-multi-path-action-repos.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/dependency-cve-gate-pip-audit.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/discover-searches-github-not-a-stale-sample.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/docsite-chrome-and-content-audit.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/docstring-coverage-interrogate.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/doctor-checks-rules-and-workflows.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/dry-run-promised-a-link-nobody-makes.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/efficiency-registries-ponytail-caveman.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/end-of-options-guard-on-git-commands.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/est-items-counts-agent-mirrors-as-items.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/eval-corpus-cannot-see-real-retrieval.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/eval-corpus-is-96x-smaller-than-a-real-install.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/eval-corpus-is-one-strangers-repo.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/eval-corpus-pins-have-no-refresh-path.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/eval-corpus-was-not-actually-pinned.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/eval-deduped-ranked-lists-by-name.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/eval-stats-could-never-publish.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/expanded-card-bodies-overflow.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/extension-free-tests-core-dense-py.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/extract-mcp-http-servers-out-of-configuration-py.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/finish-mutation-hardening-across-core.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/fix-self-update-version-detection-dead-branch.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/fork-safe-network-proxy-handler.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/framework-adapter-langgraph.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/framework-adapter-multi-agent.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/framework-adapters-boost-adapt.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/frontmatter-scalar-over-coercion.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/gemini-agent-frontmatter-sanitizer.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/gemini-cli-agent-target.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/gemini-duplicate-skill-discovery.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/gemini-hooks-host-aware.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/gemini-mcp-parity.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/github-community-health-files.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/github-pages-deploy-is-broken-every-push.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/golden-set-grades-by-name-not-by-skill.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/golden-set-statistical-power.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/gstack-tap-first-then-coexistence.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/hash-pinned-reproducible-toolchain-uv-lock.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/heal-deleted-links-it-never-made.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/html-validation-html-validate.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/info-rejects-the-qualified-name-it-recommends.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/install-docs-never-mentioned-upgrading.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/install-from-path-bypasses-policy-and-pin-checks.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/install-path-disambiguation.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/install-resolves-skill-dependencies.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/install-scope-user-or-project.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/installed-skill-trust-audit.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/integrity-verification-boost-verify.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/internal-architecture-diagrams.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/invocation-pid-logging-for-crash-correlation.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/journal-rotation-race-and-handle-leak.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/keyless-dense-tier-local-static-embeddings.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/keyless-semantic-search-for-everyone.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/langchain-in-the-wheel.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/langchain-integration-explainer-page.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/langchain-langgraph-langsmith-integration.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/langchain-retriever-metadata-and-k-floor.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/layering-guard-import-linter.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/license-compliance-scanning.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/lighthouse-ci-on-the-pages-site.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/lighthouse-scored-a-page-nobody-is-served.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/lint-tap-misscopes-rule-workflow-entries.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/list-rules-and-workflows.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/localize-the-stored-bm25-snippet.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/lock-invariant-cannot-parse-extras-pins.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/lockfile-enforcement-and-commit-pinning.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/log-timestamps-mislabeled-utc.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/long-hints-overflow-narrow-panes.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/lowest-version-resolution-uv-resolution-lowest-d.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/main-has-no-branch-protection.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/main-ruleset-ref-pattern-has-literal-quotes.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/make-lint-masks-actionlint-failures.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/make-the-roadmaps-discoverable.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/markdown-consistency-markdownlint-cli2.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/markdownlint-lints-the-fuzz-corpus.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/marketing-crm-domain-had-no-category.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/mcp-already-covered-defeater.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/mcp-aware-skills.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/mcp-check-skills-before-starting-a-task.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/mcp-hub-diagram-node-text-overflow.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/mcp-install-skips-the-injection-scan.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/mcp-launch-objc-fork-safety.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/mcp-one-benefit-nameable-task.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/mcp-register-names-server-before-env.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/mcp-search-before-reinventing.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/mcp-search-cost-was-understated.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/mcp-search-hid-which-ranking-ran.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/mcp-servers-ignore-install-scope.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/mcp-startup-self-harden-fork-safety.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/mcp-zero-setup-and-three-kinds.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/memoize-config-load-in-process.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/merge-queue-would-deadlock-most-required-checks.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/merged-loop-branches-are-never-pruned.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/modernization-smells-refurb-pyupgrade.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/mutation-gate-was-the-whole-critical-path.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/mutation-hardening-core-frontmatter-py.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/mutation-hardening-core-gitutil-py.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/mutation-hardening-core-store-py.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/mutation-shard-floor-is-one-file.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/mypy-strict-mode-for-commands.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/near-duplicate-items-eat-the-result-slots.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/negative-limit-inverts-log-pulse-output.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/onboard-overwrites-generated-files-without-confirm.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/one-command-every-env-nox.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/one-commit-can-cut-two-releases.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/one-dead-tap-broke-every-update.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/one-shared-atomic-write-helper.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/openssf-best-practices-badge.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/openssf-gold-ceiling.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/openssf-playbook.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/openssf-silver.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/osps-baseline-levels.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/package-metadata-validation-twine-check-friends.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/patch-coverage-gate-diff-cover.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/path-traversal-unsanitized-rule-workflow-name.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/pathlib-exists-is-not-total.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/pep585-604-modernization-sweep.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/performance-regression-gate-pytest-benchmark.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/pin-the-lint-toolchain.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/post-deploy-always-defeated-by-skipped-setup.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/post-deploy-smoke-headless-load-check.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/pre-release-python-canary-3-14t-free-threaded.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/prerequisites-and-semantic-search-setup.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/project-scope-across-every-command.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/project-scope-symlink-escape-on-write.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/promote-nav-footer-into-the-shared-style-system.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/prompt-injection-scanning-of-skill-markdown.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/property-based-tests-hypothesis-on-the-parsers.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/prose-and-terminology-linting-vale.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/prune-ignored-dirs-during-scan-dir-walk.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/publish-gate-ignores-pip-audit-and-metadata.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/publish-trigger-was-reachable-from-a-fork.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/published-shards-have-no-consumer.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/pytest-tmpdir-cve-blocked-by-py39-floor.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/python-floor-moves-to-312.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/quality-dashboard-sonarcloud-free-for-oss.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/ragas-unpin-when-upstream-ships.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/ranx-significance-monitor.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/readme-prune-and-search-guide.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/reconcile-the-theme-drift.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/refresh-the-marketing-surface.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/rel-time-tests-race-the-wall-clock.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/release-verifies-the-wrong-commit.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/relicence-apache-2.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/reproducible-release-artifacts.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/required-checks-can-declare-a-check-that-deadlocks-prs.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/required-checks-config-drift.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/resolve-vendored-duplicate-copies.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/retrieval-quality-eval-harness.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/reuse-helpers-kill-minor-dead-work.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/roadmap-html-goes-stale-on-every-rebase.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/roadmap-page-weight-grows-without-bound.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/roadmap-perf-budget-has-no-local-guard.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/robust-tag-argument-parsing.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/ruff-016-widens-the-default-rule-set.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/rule-install-native-materialization.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/rules-install-but-cannot-be-governed.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/runner-egress-monitoring-stepsecurity-harden-run.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/runtime-explain-faithfulness-guardrail.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/sbom-aware-scanning-osv-scanner.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/sbom-declares-the-wrong-version.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/sbom-on-every-release-cyclonedx-syft.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/sbom-release-event-never-fires.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/scan-and-sync-rules-and-workflows.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/scheduled-toolchain-lock-regeneration.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/scorecard-findings-triage.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/scripts-under-the-lint-gate.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/search-and-browse-visual-refresh.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/search-never-notices-a-new-tap.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/second-type-checker-pyright.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/secret-and-pii-scanning-of-installed-skills.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/secret-scanning-gitleaks-push-protection.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/security-linting-bandit-via-ruff-s-rules.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/self-update-broken-for-pip-pipx-installs.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/self-update-claims-up-to-date-without-asking.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/serve-404-reflected-the-request.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/serve-is-a-searchable-catalogue.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/serve-py-traversal-guards-untested.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/shard-runs-reembed-everything-weekly.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/shards-pipeline-never-produced-a-shard.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/shareable-catalogue-bundle.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/shift-left-gate-pre-commit-pre-commit-ci.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/single-imperative-rule-extractor.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/single-tech-stack-prober.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/smart-rerank-pays-per-novel-query.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/split-oversized-command-modules.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/startup-and-import-time-budget-x-importtime.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/stop-re-serializing-entry-meta-on-every-search.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/structured-json-log-output-mode.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/supply-chain-posture-openssf-scorecard.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/surface-every-docs-page-from-the-guide.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/sweep-died-at-launch-not-at-a-page.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/sync-could-not-repair-a-gutted-skill.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/sync-deletes-unowned-broken-symlinks.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/sync-relinks-into-every-agent-ignoring-scope.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/sync-reported-success-for-a-link-it-refused.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/tap-signing-and-provenance-sigstore-minisign.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/taps-check-out-freight-they-never-index.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/the-catalogue-advertised-repos-that-no-longer-exist.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/the-scale-corpus-refreshed-the-wrong-rows.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/the-shard-job-that-could-not-finish.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/theme-asset-linting-stylelint-eslint.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/tool-call-eval-tier.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/two-ci-controls-that-could-not-act.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/two-crashes-that-should-have-been-messages.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/typo-detection-codespell.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/typosquat-and-name-confusion-detection.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/unify-tilde-two-copies-have-a-boundary-bug.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/uninstall-has-no-confirmation-prompt.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/untrack-generated-build-noise.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/unwatched-crons-hid-a-real-fuzz-crash.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/update-advertises-a-flag-it-rejects.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/update-diff-before-apply.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/update-refreshed-rules-without-a-gate.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/update-refreshes-rules-and-workflows.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/update-reinstall-widens-agent-scope.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/vex-openvex-feed.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/visual-regression-pass-on-the-guide.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/widen-the-ruff-rule-surface-b-sim-c4-perf-ruf.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/windows-in-the-ci-matrix.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/wire-bdd-suite-into-ci.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/workflow-install-native-materialization.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/workflow-linting-actionlint.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/workflow-sast-zizmor.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/workspace-scope-install.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/zip-strict-audit.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/zizmor-ignores-drift-and-make-lint-never-ran-it.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/zizmor-pin-is-a-yanked-release.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/security-design.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/semantic-search.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/superpowers/specs/2026-08-16-catalogue-content-identity-design.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/verifying-releases.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/vex/meta.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/vex/openvex.json +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/vex/statements/gitleaks-secretscan-test-fixtures.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/vex/statements/quality-trust-fingerprint-not-sensitive.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/vex/statements/zizmor-adhoc-packages-lint-runners.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/vex/statements/zizmor-dangerous-triggers-workflow-run.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/eslint.config.mjs +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/evals/README.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/evals/__init__.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/evals/baseline.json +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/evals/faithfulness.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/evals/golden_set.json +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/evals/make_corpus.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/evals/make_golden.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/evals/metrics.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/evals/publish_golden_dataset.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/evals/run_evals.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/examples/README.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/examples/adapt-demo.sh +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/examples/boost-run-prototype.sh +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/index.html +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/noxfile.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/pyproject.toml +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/requirements/coverage-tools.in +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/requirements/coverage-tools.txt +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/requirements/lint-tools.in +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/requirements/lint-tools.txt +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/requirements/mutation-tools.in +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/requirements/mutation-tools.txt +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/requirements/platform-pins.lock +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/requirements/release-tools.in +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/requirements/release-tools.txt +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/requirements/test-tools.in +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/requirements/test-tools.txt +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/a11y_check.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/add_spdx_headers.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/bench_cli.sh +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/build_command_reference.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/build_demo_index.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/build_registries.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/build_roadmap.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/build_scale_corpus.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/build_vex.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/check_anchors.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/check_branch_current.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/check_dco.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/check_licenses.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/check_reproducible.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/check_required_checks.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/ensure_eval_corpus.sh +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/eval_corpus.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/eval_explain.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/eval_gate.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/eval_recommend.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/eval_retrieval.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/eval_stats_summary.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/import_budget.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/lock_toolchain.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/measure_registry.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/mutation_gate.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/mutation_shards.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/mutation_weights.json +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/normalize_sdist.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/page_budget.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/perf_gate.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/post_deploy_smoke.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/publish_eval_json.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/publish_shards.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/release_guard.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/release_preflight.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/serve_docs.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/shard_plan.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/setup.cfg +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/sonar-project.properties +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/style/README.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/style/boost.css +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/style/boost.js +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/style/demo.html +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/bdd/features/adapt.feature +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/bdd/features/browse.feature +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/bdd/features/count.feature +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/bdd/features/discover.feature +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/bdd/features/environment.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/bdd/features/explain.feature +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/bdd/features/index.feature +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/bdd/features/install.feature +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/bdd/features/list.feature +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/bdd/features/mcp.feature +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/bdd/features/search.feature +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/bdd/features/steps/cli_steps.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/bdd/features/steps/discovery_steps.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/bdd/features/steps/mcp_steps.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/bdd/features/steps/quality_steps.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/conftest.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/eval/baseline.json +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/eval/explain.jsonl +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/eval/golden-natural.jsonl +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/eval/golden.jsonl +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/eval/recommend.jsonl +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/eval/taps-scale.txt +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/eval/taps.txt +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_bmad_all_hosts.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_capabilities_policy.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_cli_adapt.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_cli_bmad.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_cli_catalog.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_cli_chat.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_cli_discovery.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_cli_hooks.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_cli_hooks_gemini.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_cli_intelligence.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_cli_pane_width.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_cli_pkg.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_cli_tap_pins.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_cli_taps.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_cli_team.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_everyday_loop.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_integrity_enforce.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_kind_conformance.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_property_parsers.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_run.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_tap_signing.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_workspace_scope.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/README.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/corpus/frontmatter/01-typical.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/corpus/frontmatter/02-lossy-version.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/corpus/frontmatter/03-lossy-numbers.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/corpus/frontmatter/04-lists.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/corpus/frontmatter/05-nested.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/corpus/frontmatter/06-empty-block.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/corpus/frontmatter/07-unterminated.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/corpus/frontmatter/08-none.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/corpus/frontmatter/09-unbalanced-quote.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/corpus/frontmatter/10-keywords.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/corpus/frontmatter/11-crlf.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/corpus/frontmatter/12-bom.md +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/corpus/registry/01-shorthand.txt +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/corpus/registry/02-https.txt +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/corpus/registry/03-ssh.txt +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/corpus/registry/04-traversal.txt +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/corpus/registry/05-empty.txt +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/corpus/registry/06-space.txt +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/corpus/registry/07-slash.txt +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/corpus/registry/08-bare-host.txt +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/corpus/registry/09-nul.txt +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/corpus/registry/10-name-too-long.txt +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/corpus/registry/11-long-owner-repo.txt +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/fuzz_frontmatter.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/fuzz_registry.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/langchain/conftest.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/langchain/test_graph.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/langchain/test_loader.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/langchain/test_retriever.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/make_fixture.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/perf/test_benchmarks.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/smoke.sh +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_a11y_check.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_action_pin_lockstep.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_adapters.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_adapters_multi.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_adapters_runner.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_agents.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_ai.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_aihost.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_bmad_core.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_boost_first_offer.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_bootstrap.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_branch_current.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_browse.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_builtin.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_capabilities.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_catalog.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_catalogbundle.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_chat.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_check_anchors.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_check_dco.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_check_licenses.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_check_reproducible.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_claude_settings.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_clean_internal_cache.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_cliparse.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_codeql_analysis_key.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_command_reference_fresh.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_community_health_files.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_compact.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_complete.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_complete_rc_block.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_config.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_content_dedupe.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_content_identity.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_crash_redaction.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_dedup_trust.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_demo_index.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_dense.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_dense_embed_dedupe.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_dense_fix_hint.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_dense_progress.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_dense_quantized.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_dense_ready_order.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_dense_shard_real_schema.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_dense_status.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_dense_status_cheap.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_dependabot_config.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_docs_pages_linked.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_docsite_chrome.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_ed25519.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_embed.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_embed_local.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_embed_truncated_response.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_entry_key.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_errors_and_cli_table.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_eval_baseline.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_eval_corpus.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_eval_faithfulness.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_eval_gate.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_eval_grading.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_eval_metrics.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_eval_stats_summary.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_failure_alerting_covers_unattended.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_faithfulness.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_frontmatter.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_fuzz_targets.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_gemini_agent_sanitize.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_gitleaks_config.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_gitutil.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_gitutil_lfs.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_gitutil_sparse.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_hook_settings_hosts.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_hookhost.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_imperative.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_import_budget.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_injectscan.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_install_permission_error.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_installscan.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_integrity.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_journal.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_langchain_packaging.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_link_ownership.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_localembed.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_localembed_e2e.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_lockfile.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_logs.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_marketing_counts.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_mcp_install_scan.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_mcpdecl.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_mcphost.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_measure_registry.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_minisign.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_mutation_hardening.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_mutation_shards.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_mutation_subfile_shards.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_mutmut_source_paths.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_nethttp.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_normalize_sdist.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_output.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_page_budget.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_paths.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_perf_gate.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_pkg_confusions.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_pkg_injection.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_pkg_secrets.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_platform_pins.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_policy.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_post_deploy_smoke.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_project_mcp_sidecar.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_projectlock.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_provenance.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_publish_golden_dataset.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_rag.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_rag_fastpath.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_rag_fusion.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_registries_fresh.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_registry.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_registry_categories.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_registry_control_chars.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_registry_parallel.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_release_guard.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_release_preflight.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_required_checks.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_rerank_cache.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_resolve.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_roadmap_fresh.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_rules.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_scale_corpus.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_scopes.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_secretscan.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_selfupdate.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_serve.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_serve_docs.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_shard_plan.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_shards.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_shards_incremental.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_shards_matrix.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_smoke_covers_every_command.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_spdx_headers.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_spin.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_stackprobe.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_staleness.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_store.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_store_materialize.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_sync_blocked_links.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_sync_repairs_gutted_skill.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_tap_pins.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_token_parity.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_toolchain_lock.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_trustaudit.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_typosquat.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_updatediff.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_util.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_version.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_version_tags.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_vex.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_visual_harness_flags.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_workflow_concurrency.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_workflow_concurrency_groups.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_workflow_push_has_credentials.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_workflow_timeouts.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_workflows.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_zizmor_ignores_still_anchor.py +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/visual/a11y_check.mjs +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/visual/console_check.mjs +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/visual/package-lock.json +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/visual/package.json +0 -0
- {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/visual/visual_check.mjs +0 -0
|
@@ -584,6 +584,26 @@ Consequences for code you write here:
|
|
|
584
584
|
real install are repeats and are embedded once — so a progress total taken
|
|
585
585
|
from row count would over-report the work.
|
|
586
586
|
|
|
587
|
+
- **Dense reuse is decided at TWO levels, and the second one is why `chunks`
|
|
588
|
+
carries a `digest`.** A tap whose git commit is unchanged is skipped whole.
|
|
589
|
+
A tap whose commit *moved* is not therefore changed: `_split_by_digest`
|
|
590
|
+
compares each entry's `content` digest against the one stored beside its
|
|
591
|
+
chunks, and only the entries that really differ are deleted and re-embedded.
|
|
592
|
+
Measured on a real 464-tap install: 19 taps drifted in 6.85 h and re-embedded
|
|
593
|
+
112,081 chunks for 659 chunks of actual change (**170x**), and **10 of the
|
|
594
|
+
19 changed nothing boost indexes at all** — badge `.json`, star-history
|
|
595
|
+
`.svg`, CI `.yml` — for 40.0% of the bill. Three rules make it safe, and
|
|
596
|
+
each was a real bug waiting: an entry is reused only when **every** stored
|
|
597
|
+
chunk carries the current digest, because a half-written entry must not be
|
|
598
|
+
served as a mixture of two versions' vectors; `_prune_stale_entries` drops
|
|
599
|
+
rows for entries the catalog dropped, which whole-tap deletion used to sweep
|
|
600
|
+
for free; and a **missing digest is never a match**, because two absences
|
|
601
|
+
are two unknowns. The digest travels in a shard too — without it an imported
|
|
602
|
+
shard re-embeds on the next build, spending the CPU the download existed to
|
|
603
|
+
save. The lookup is scoped by tap through the `chunks_tap` index: reading
|
|
604
|
+
the whole table instead measured 3.75 s cold on a 657,587-chunk store, and
|
|
605
|
+
ran even on the build where nothing had changed.
|
|
606
|
+
|
|
587
607
|
- **Nothing on the search path may count `chunks`.** `SELECT COUNT(*)` scans the
|
|
588
608
|
`chunks_tap` covering index — 8,419 pages / 34.5 MB, measured 1.94 s — and
|
|
589
609
|
both `ready()` and `status()` did it on every search, the latter only to word
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: boost-skill-cli
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.56
|
|
4
4
|
Summary: boost — Homebrew for AI coding skills
|
|
5
5
|
Author: Jonathan Reyes
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -448,8 +448,10 @@ purely local operation, for CI images and air-gapped machines.
|
|
|
448
448
|
| Claude Code | `claude` | `claude mcp add` → its user-scope MCP config |
|
|
449
449
|
| Gemini CLI | `gemini` | `gemini mcp add -s user` → `~/.gemini/settings.json` |
|
|
450
450
|
|
|
451
|
-
|
|
452
|
-
`boost_install`, `boost_doctor` and
|
|
451
|
+
Seven tools are exposed: `boost_search`, `boost_list`, `boost_info`,
|
|
452
|
+
`boost_read`, `boost_install`, `boost_doctor` and
|
|
453
|
+
`boost_discover_github`. `boost_read` is the one that returns an item's
|
|
454
|
+
actual text — without it, installing was the only way to read a skill.
|
|
453
455
|
|
|
454
456
|
The server also returns MCP `instructions`, telling the agent when boost is
|
|
455
457
|
relevant. The two hosts place those differently, and it matters. Claude Code
|
|
@@ -406,8 +406,10 @@ purely local operation, for CI images and air-gapped machines.
|
|
|
406
406
|
| Claude Code | `claude` | `claude mcp add` → its user-scope MCP config |
|
|
407
407
|
| Gemini CLI | `gemini` | `gemini mcp add -s user` → `~/.gemini/settings.json` |
|
|
408
408
|
|
|
409
|
-
|
|
410
|
-
`boost_install`, `boost_doctor` and
|
|
409
|
+
Seven tools are exposed: `boost_search`, `boost_list`, `boost_info`,
|
|
410
|
+
`boost_read`, `boost_install`, `boost_doctor` and
|
|
411
|
+
`boost_discover_github`. `boost_read` is the one that returns an item's
|
|
412
|
+
actual text — without it, installing was the only way to read a skill.
|
|
411
413
|
|
|
412
414
|
The server also returns MCP `instructions`, telling the agent when boost is
|
|
413
415
|
relevant. The two hosts place those differently, and it matters. Claude Code
|
|
@@ -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.56'
|
|
22
|
+
__version_tuple__ = version_tuple = (1, 2, 56)
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -1169,6 +1169,47 @@ def _tool_info(args: dict):
|
|
|
1169
1169
|
return "\n".join(lines), False
|
|
1170
1170
|
|
|
1171
1171
|
|
|
1172
|
+
def _tool_read(args: dict):
|
|
1173
|
+
"""`boost_read` — the item's own text, so an agent can look before it acts.
|
|
1174
|
+
|
|
1175
|
+
The gap this closes: ``boost_info`` returns the same one-line description
|
|
1176
|
+
``boost_search`` already returned, so an agent deciding whether a procedure
|
|
1177
|
+
is worth adopting had one sentence written by whoever published it, and its
|
|
1178
|
+
only route to the actual steps was to install into the user's real
|
|
1179
|
+
``~/.agents/skills`` and read it off disk. That inverts the surface's own
|
|
1180
|
+
pitch — ``boost_search`` spends 10-15 s of rerank so the top result is worth
|
|
1181
|
+
acting on, and then nothing let the agent look at it.
|
|
1182
|
+
|
|
1183
|
+
The body is also the only thing separating a written skill from a generated
|
|
1184
|
+
stub, and the catalogue holds both: two ranked hits share the description
|
|
1185
|
+
"To optimize **Skill**, we enforce the following foundational rules:" — an
|
|
1186
|
+
unfilled template — and ``superpowers-lab`` is an 868-byte SKILL.md whose
|
|
1187
|
+
Instructions section is its own name echoed back. Both index, rank and
|
|
1188
|
+
render exactly like real results. The eval gate cannot catch it either:
|
|
1189
|
+
``golden.jsonl`` grades by *name*, and a stub matches its own name
|
|
1190
|
+
perfectly.
|
|
1191
|
+
|
|
1192
|
+
Read-only, and that is the whole point rather than a side note — this is
|
|
1193
|
+
the tool that exists so an agent does *not* have to install to look, so it
|
|
1194
|
+
must never become a second install path. It reuses ``boost cat``'s
|
|
1195
|
+
resolution (``info._resolve_text``): the installed copy when there is one,
|
|
1196
|
+
the tap source otherwise, with the same integrity and quarantine rules. A
|
|
1197
|
+
second resolver would be a second opinion about what "this item" means,
|
|
1198
|
+
disagreeing with the tool it is advising about.
|
|
1199
|
+
|
|
1200
|
+
``cat`` rather than ``explain``: cat is offline, deterministic and free,
|
|
1201
|
+
while ``explain`` goes through ``core/ai.py`` and costs seconds plus a key.
|
|
1202
|
+
The cheap answer must not sit behind the expensive one's latency — the same
|
|
1203
|
+
reason ``boost_list`` never reads the catalog.
|
|
1204
|
+
"""
|
|
1205
|
+
from . import info
|
|
1206
|
+
name = str(args.get("name", ""))
|
|
1207
|
+
if not name.strip():
|
|
1208
|
+
return "boost_read needs a name — pass one as boost_search returned it", True
|
|
1209
|
+
text, kind, lock, _cat = info._resolve_text(name)
|
|
1210
|
+
return mcp.read_reply(name, text, kind=kind, installed=lock is not None), False
|
|
1211
|
+
|
|
1212
|
+
|
|
1172
1213
|
def _tool_install(args: dict):
|
|
1173
1214
|
entry = catalog.resolve_one(str(args.get("name", "")))
|
|
1174
1215
|
res = store.install(entry)
|
|
@@ -1369,19 +1410,54 @@ REGISTRY.register(
|
|
|
1369
1410
|
_tool_list)
|
|
1370
1411
|
REGISTRY.register(
|
|
1371
1412
|
"boost_info",
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1413
|
+
# This used to promise "the whole picture" and return five fields, one of
|
|
1414
|
+
# which — description — is byte-identical to the one-liner boost_search
|
|
1415
|
+
# already returned. So the tool added `installed: no`, which the search
|
|
1416
|
+
# reply already marks, to an agent that had been told to expect what the
|
|
1417
|
+
# item does. An overstated description costs a wasted call and teaches an
|
|
1418
|
+
# agent to discount the rest of the surface, which is the expensive half.
|
|
1419
|
+
# It now says what it returns (status and provenance) and names the tool
|
|
1420
|
+
# that returns the body.
|
|
1421
|
+
"Where one skill, rule or workflow came from, by name, and whether it is "
|
|
1422
|
+
"already here — its kind, tap, version, install state, and which agents "
|
|
1423
|
+
"it reached. It is the STATUS of an item, not its contents: the description "
|
|
1424
|
+
"it echoes is the same one-liner boost_search returned, so to read what "
|
|
1425
|
+
"the item actually says, call boost_read. Reach for boost_info when a "
|
|
1426
|
+
"name arrives from somewhere else — a teammate, a README, a repo you are "
|
|
1427
|
+
"reading — and you need to know whether this machine already has it. You "
|
|
1428
|
+
"do not need this between a search and an install: boost_search already "
|
|
1429
|
+
"returns each match's kind, description and installed marker.",
|
|
1379
1430
|
{"type": "object",
|
|
1380
1431
|
"properties": {"name": {"type": "string",
|
|
1381
1432
|
"description": "the item's name, as boost_search "
|
|
1382
1433
|
"or boost_list returned it"}},
|
|
1383
1434
|
"required": ["name"]},
|
|
1384
1435
|
_tool_info)
|
|
1436
|
+
REGISTRY.register(
|
|
1437
|
+
"boost_read",
|
|
1438
|
+
"Read the actual procedure before you commit to it — the item's own text, "
|
|
1439
|
+
"not its one-line description. This is the tool that makes looking cheaper "
|
|
1440
|
+
"than installing: without it the only way to see what a skill actually "
|
|
1441
|
+
"says is to install it into the user's machine and read it off disk, which "
|
|
1442
|
+
"is a change to their setup made in order to answer a question. Reach for "
|
|
1443
|
+
"it on the top hit from boost_search before boost_install, and whenever a "
|
|
1444
|
+
"one-liner is doing more selling than describing. What you are checking "
|
|
1445
|
+
"for is specific: the catalogue is indexed rather than reviewed, so it "
|
|
1446
|
+
"holds unfilled templates and stubs that echo their own name back, and "
|
|
1447
|
+
"those rank and render exactly like a procedure someone debugged. The body "
|
|
1448
|
+
"is the only thing that tells them apart. Read-only and offline — it "
|
|
1449
|
+
"installs nothing, changes nothing, and unlike boost_search costs no "
|
|
1450
|
+
"rerank, so it is fast. Long items are truncated at a stated character "
|
|
1451
|
+
"count and the reply says so and names the command that returns the rest; "
|
|
1452
|
+
"a body that arrives whole is whole.",
|
|
1453
|
+
{"type": "object",
|
|
1454
|
+
"properties": {"name": {"type": "string",
|
|
1455
|
+
"description": "the item's name, as boost_search "
|
|
1456
|
+
"or boost_list returned it; qualify with the tap "
|
|
1457
|
+
"(\"owner/repo:name\") when the same name exists "
|
|
1458
|
+
"in more than one"}},
|
|
1459
|
+
"required": ["name"]},
|
|
1460
|
+
_tool_read)
|
|
1385
1461
|
REGISTRY.register(
|
|
1386
1462
|
"boost_install",
|
|
1387
1463
|
"Turn a skill you found with boost_search into permanent capability: copied "
|
|
@@ -423,8 +423,29 @@ def cmd_reindex(argv):
|
|
|
423
423
|
"`boost reindex --dense --force`."
|
|
424
424
|
% len(dense_stats["reused"]))
|
|
425
425
|
else:
|
|
426
|
-
|
|
427
|
-
|
|
426
|
+
# `chunks` is the store TOTAL, not this run's work, so on an
|
|
427
|
+
# incremental run "embedded 657,587 passages" described an
|
|
428
|
+
# afternoon of CPU that did not happen. `added` is what this
|
|
429
|
+
# run actually paid for.
|
|
430
|
+
added = dense_stats.get("added", dense_stats["chunks"])
|
|
431
|
+
out.ok("embedded %d passage%s (%s) — the dense store holds %d"
|
|
432
|
+
% (added, "" if added == 1 else "s",
|
|
433
|
+
dense_stats["provider"], dense_stats["chunks"]))
|
|
434
|
+
# The saving the tap-level line cannot show: a tap appears in
|
|
435
|
+
# `reindexed` the moment its commit moves, so a run that reused
|
|
436
|
+
# every entry inside three moved taps otherwise reads as three
|
|
437
|
+
# taps fully re-embedded.
|
|
438
|
+
kept = dense_stats.get("reused_entries") or 0
|
|
439
|
+
if kept:
|
|
440
|
+
out.info(out.role(
|
|
441
|
+
"reused %d unchanged item%s inside %d moved tap%s — "
|
|
442
|
+
"only %d item%s changed"
|
|
443
|
+
% (kept, "" if kept == 1 else "s",
|
|
444
|
+
len(dense_stats["reindexed"]),
|
|
445
|
+
"" if len(dense_stats["reindexed"]) == 1 else "s",
|
|
446
|
+
dense_stats.get("embedded_entries") or 0,
|
|
447
|
+
"" if dense_stats.get("embedded_entries") == 1
|
|
448
|
+
else "s"), "muted"))
|
|
428
449
|
if dense_stats.get("quantized"):
|
|
429
450
|
out.ok("quantized %d existing vectors — dense search no longer "
|
|
430
451
|
"scans the whole store on every query"
|
|
@@ -149,7 +149,21 @@ def _resolve_text(name: str):
|
|
|
149
149
|
found = lockfile.find_any(bare)
|
|
150
150
|
if found is None or found[0] == "skill":
|
|
151
151
|
path, lock, cat = _resolve_skill_md(name)
|
|
152
|
-
|
|
152
|
+
# The lock file is the authority for an INSTALLED item, and for one
|
|
153
|
+
# that is not installed it has no opinion at all — so a rule or
|
|
154
|
+
# workflow that is only in a tap arrived here and was reported as a
|
|
155
|
+
# skill, contradicting this function's own "any kind" contract. The
|
|
156
|
+
# catalog entry knows, and `_resolve_skill_md` has already resolved it:
|
|
157
|
+
# it returns a catalog entry on exactly the branch where `lock` is
|
|
158
|
+
# None, so no second lookup is needed (and a fallback for `cat is None`
|
|
159
|
+
# here would guard a state that function cannot produce).
|
|
160
|
+
#
|
|
161
|
+
# Every caller before `boost_read` discarded this value (`_kind`), so
|
|
162
|
+
# the wrong answer was invisible: the resolution and the text were
|
|
163
|
+
# always right, only the label was not.
|
|
164
|
+
kind = ((cat.get("kind") or "skill")
|
|
165
|
+
if lock is None and cat else "skill")
|
|
166
|
+
return _read(path), kind, lock, cat
|
|
153
167
|
kind, entry = found
|
|
154
168
|
lock = _for_tap(entry, qualifier)
|
|
155
169
|
if lock is not None:
|
|
@@ -395,7 +395,14 @@ def cmd_doctor(argv):
|
|
|
395
395
|
if taps and tap_ok == len(taps):
|
|
396
396
|
out.ok("%d tap%s cloned & cached" % (len(taps), _s(len(taps))))
|
|
397
397
|
elif not taps:
|
|
398
|
-
|
|
398
|
+
# `boost tap --defaults` leads, and it is the same command in the same
|
|
399
|
+
# order that `boost search`'s error, `mcp.no_results` and the MCP
|
|
400
|
+
# `boost_doctor` tool all name. A user who hits two of these surfaces
|
|
401
|
+
# in one session must not see the recommendation flip and read it as
|
|
402
|
+
# two different fixes — which is exactly what happened here: search
|
|
403
|
+
# said `--defaults`, doctor said `owner/repo`.
|
|
404
|
+
out.info("no registries tapped — nothing is searchable yet; add the "
|
|
405
|
+
"recommended ones with `boost tap --defaults`", wrap=True)
|
|
399
406
|
|
|
400
407
|
lock_ok = True
|
|
401
408
|
lp = paths.lockfile_path()
|
|
@@ -598,10 +605,22 @@ def cmd_doctor(argv):
|
|
|
598
605
|
else:
|
|
599
606
|
out.warn("lock file integrity or log rotation needs attention")
|
|
600
607
|
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
608
|
+
# A machine with no taps has nothing to disagree about, so every check
|
|
609
|
+
# above passes and the verdict read "healthy" — directly under the line
|
|
610
|
+
# saying no registries are tapped. That is the one state where a clean bill
|
|
611
|
+
# of health actively misleads: boost cannot answer anything yet, which is a
|
|
612
|
+
# setup step rather than a fault. Reported, never fatal — the exit code
|
|
613
|
+
# still turns only on real issues, so scripts and CI are unaffected. The
|
|
614
|
+
# MCP `boost_doctor` tool already refused to say "healthy" here; this is
|
|
615
|
+
# the CLI half of the same rule.
|
|
616
|
+
if issues == 0 and not taps:
|
|
617
|
+
out.verdict(True, "ready to set up — tap a registry to make boost "
|
|
618
|
+
"searchable")
|
|
619
|
+
else:
|
|
620
|
+
out.verdict(issues == 0,
|
|
621
|
+
"healthy" if not issues else
|
|
622
|
+
"%d issue%s need attention — see the suggestions above"
|
|
623
|
+
% (issues, _s(issues)))
|
|
605
624
|
return 1 if issues else 0
|
|
606
625
|
|
|
607
626
|
|
|
@@ -162,6 +162,26 @@ def cmd_quickstart(argv) -> int:
|
|
|
162
162
|
planned = [n for n in names if n in pins] if manifest else []
|
|
163
163
|
out.info("would build the keyword index, then import %d shard(s)"
|
|
164
164
|
% len(planned))
|
|
165
|
+
# "0 shard(s)" reads as "none are published" when the real cause is
|
|
166
|
+
# local, and --dry-run is exactly what a cautious new user runs first.
|
|
167
|
+
# The live path already explains both cases; without this the preview
|
|
168
|
+
# is the one surface that reports the symptom and withholds the reason.
|
|
169
|
+
if not planned:
|
|
170
|
+
if args.no_vectors:
|
|
171
|
+
out.info(out.role("(0 because --no-vectors was asked for)",
|
|
172
|
+
"muted"))
|
|
173
|
+
elif not dense.have_backend():
|
|
174
|
+
out.info("0 because semantic search needs the extra: "
|
|
175
|
+
"`pipx inject boost-skill-cli "
|
|
176
|
+
"\"boost-skill-cli[rag]\"` — keyword search works "
|
|
177
|
+
"without it", wrap=True)
|
|
178
|
+
elif manifest is None:
|
|
179
|
+
out.info(out.role("(0 because the shard manifest could not be "
|
|
180
|
+
"read — keyword search is unaffected)",
|
|
181
|
+
"muted"), wrap=True)
|
|
182
|
+
else:
|
|
183
|
+
out.info(out.role("(0 because none of these registries have a "
|
|
184
|
+
"published shard yet)", "muted"), wrap=True)
|
|
165
185
|
return 0
|
|
166
186
|
|
|
167
187
|
with spin.Spinner("building the keyword index"):
|
|
@@ -23,7 +23,13 @@ from ..errors import BoostError
|
|
|
23
23
|
from . import catalog, embed, paths
|
|
24
24
|
from .rag import Hit, chunk, entry_key, read_body
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
# 3 -- `chunks.digest` carries each row's entry content digest, which is what
|
|
27
|
+
# lets reuse be decided per ENTRY rather than per tap. Bumping this is the
|
|
28
|
+
# migration: a v2 store has no such column, `_ensure_schema` cannot add one
|
|
29
|
+
# to an existing table (CREATE TABLE IF NOT EXISTS), and `build` already
|
|
30
|
+
# wipes on a version change. That costs one full re-embed, once — the same
|
|
31
|
+
# price v2 charged when it landed, and the last one this mechanism needs.
|
|
32
|
+
INDEX_VERSION = 3
|
|
27
33
|
_BATCH = 128 # texts per embedding request
|
|
28
34
|
|
|
29
35
|
#: Rows between commits while storing vectors. Small enough that an interrupted
|
|
@@ -112,8 +118,14 @@ def quantized(con: sqlite3.Connection) -> bool:
|
|
|
112
118
|
def _ensure_schema(con: sqlite3.Connection, dim: int) -> None:
|
|
113
119
|
con.execute(
|
|
114
120
|
"CREATE TABLE IF NOT EXISTS chunks (id INTEGER PRIMARY KEY AUTOINCREMENT,"
|
|
115
|
-
" name TEXT, tap TEXT, path TEXT, kind TEXT, cix INTEGER, snip TEXT
|
|
121
|
+
" name TEXT, tap TEXT, path TEXT, kind TEXT, cix INTEGER, snip TEXT,"
|
|
122
|
+
" digest TEXT)")
|
|
116
123
|
con.execute("CREATE INDEX IF NOT EXISTS chunks_tap ON chunks(tap)")
|
|
124
|
+
# Keyed by (tap, path) because that is `rag.entry_key` — row identity, the
|
|
125
|
+
# thing an entry's chunks belong to. Keying it on `digest` alone would be
|
|
126
|
+
# the content question, which is a different one: two taps shipping the
|
|
127
|
+
# same file share a digest and must still be deleted independently.
|
|
128
|
+
con.execute("CREATE INDEX IF NOT EXISTS chunks_entry ON chunks(tap, path)")
|
|
117
129
|
con.execute("CREATE TABLE IF NOT EXISTS meta (k TEXT PRIMARY KEY, v TEXT)")
|
|
118
130
|
if _quantizable(dim):
|
|
119
131
|
# Two relations, because one cannot do both jobs. `vec0` is the only
|
|
@@ -518,17 +530,38 @@ def build(entries: list[dict] | None = None, force: bool = False,
|
|
|
518
530
|
if commit and old_commits.get(safe) == commit:
|
|
519
531
|
reused.add(safe)
|
|
520
532
|
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
changed_taps = sorted({e["tap"] for e in
|
|
533
|
+
candidates = [e for e in entries
|
|
534
|
+
if e["tap"].replace("/", "__") not in reused]
|
|
535
|
+
changed_taps = sorted({e["tap"] for e in candidates})
|
|
524
536
|
# Prune taps that are gone entirely, not only the ones that changed.
|
|
525
537
|
# `boost untap` removes a tap's entries, so it can never appear in
|
|
526
|
-
# `
|
|
538
|
+
# `candidates` and its vectors survived every later incremental build —
|
|
527
539
|
# crowding the KNN pool on every query with rows `retrieve` then
|
|
528
540
|
# discards for not being live, which is how a dense search quietly
|
|
529
541
|
# returns fewer hits the longer an index has been in use.
|
|
530
542
|
removed_taps = sorted(_indexed_taps(con) - {e["tap"] for e in entries})
|
|
531
|
-
_delete_taps(con,
|
|
543
|
+
_delete_taps(con, removed_taps)
|
|
544
|
+
|
|
545
|
+
# Second-level reuse, and the reason it is worth the column. A tap's
|
|
546
|
+
# commit moving says *something* in that clone changed — not that
|
|
547
|
+
# anything boost indexes did. Measured on a real 464-tap install: 19
|
|
548
|
+
# taps drifted in 6.85 h, and 10 of them changed nothing indexed at all
|
|
549
|
+
# (badge JSON, star-history SVGs, CI YAML, e2e TypeScript), yet cost
|
|
550
|
+
# 44,866 chunks — 40.0% of the incremental bill. Across all 19, 967
|
|
551
|
+
# changed files mapped to 39 indexed entries owning 659 chunks, against
|
|
552
|
+
# 112,081 re-embedded: 170x the actual change.
|
|
553
|
+
#
|
|
554
|
+
# The digest is not new identity machinery. `catalog._content_digest`
|
|
555
|
+
# already stamps every entry with a hash of exactly what `read_body`
|
|
556
|
+
# assembles, and `tests/unit/test_content_identity.py` pins that parity
|
|
557
|
+
# — so an entry whose digest matches the one stored beside its chunks
|
|
558
|
+
# is one whose embedded text is byte-identical.
|
|
559
|
+
fresh, kept = _split_by_digest(con, candidates)
|
|
560
|
+
_delete_entries(con, [entry_key(e) for e in fresh])
|
|
561
|
+
# An entry deleted upstream keeps answering queries otherwise: whole-tap
|
|
562
|
+
# deletion used to sweep it for free, and reuse is exactly what stops
|
|
563
|
+
# that happening.
|
|
564
|
+
_prune_stale_entries(con, changed_taps, {entry_key(e) for e in entries})
|
|
532
565
|
|
|
533
566
|
added, failed_taps = _embed_and_store(con, fresh, tap_paths,
|
|
534
567
|
on_progress=on_progress)
|
|
@@ -555,6 +588,12 @@ def build(entries: list[dict] | None = None, force: bool = False,
|
|
|
555
588
|
"reindexed": changed_taps,
|
|
556
589
|
"pruned": removed_taps,
|
|
557
590
|
"reused": sorted(reused),
|
|
591
|
+
# Entries inside a moved tap whose content had not changed. This is
|
|
592
|
+
# the number the tap-level `reused` cannot show — a tap appears in
|
|
593
|
+
# `reindexed` the moment its commit moves, and on real data most of
|
|
594
|
+
# its entries are still untouched.
|
|
595
|
+
"reused_entries": len(kept),
|
|
596
|
+
"embedded_entries": len(fresh),
|
|
558
597
|
"failed": sorted(failed_taps),
|
|
559
598
|
"provider": prov,
|
|
560
599
|
"model": mdl,
|
|
@@ -614,7 +653,8 @@ def export_shard(tap: str) -> dict:
|
|
|
614
653
|
vt = "vec_raw v ON v.id = c.id" if quantized(con) \
|
|
615
654
|
else "vec_chunks v ON v.rowid = c.id"
|
|
616
655
|
rows = con.execute(
|
|
617
|
-
"SELECT c.name, c.tap, c.path, c.kind, c.cix, c.snip,
|
|
656
|
+
"SELECT c.name, c.tap, c.path, c.kind, c.cix, c.snip, " # noqa: S608 relation name from a literal pair
|
|
657
|
+
"c.digest, v.embedding "
|
|
618
658
|
"FROM chunks c JOIN %s WHERE c.tap = ? ORDER BY c.id" % vt,
|
|
619
659
|
(tap,)).fetchall()
|
|
620
660
|
except sqlite3.Error as exc:
|
|
@@ -630,10 +670,16 @@ def export_shard(tap: str) -> dict:
|
|
|
630
670
|
# the vector rows are gone or unlinked. Still not "never built".
|
|
631
671
|
raise _unreadable_vectors(tap, expected, None)
|
|
632
672
|
for row in rows:
|
|
633
|
-
name, ctap, path, kind, cix, snip, emb = row
|
|
673
|
+
name, ctap, path, kind, cix, snip, digest, emb = row
|
|
634
674
|
chunks.append({
|
|
635
675
|
"name": name, "tap": ctap, "path": path, "kind": kind,
|
|
636
676
|
"cix": cix, "snip": snip,
|
|
677
|
+
# The digest travels with the vector or the shard defeats its
|
|
678
|
+
# own purpose: `_split_by_digest` reuses an entry only when the
|
|
679
|
+
# stored digest matches the catalog's, so an imported chunk
|
|
680
|
+
# without one is re-embedded on the very next build — paying
|
|
681
|
+
# in CPU exactly what downloading the shard was meant to save.
|
|
682
|
+
"digest": digest,
|
|
637
683
|
# base64 so the shard is plain JSON and can be published as a
|
|
638
684
|
# release artifact without a binary format of its own.
|
|
639
685
|
"embedding": base64.b64encode(bytes(emb)).decode("ascii"),
|
|
@@ -714,10 +760,15 @@ def import_shard(shard: dict, commit: str) -> tuple[bool, str]:
|
|
|
714
760
|
mod = _load()
|
|
715
761
|
for c in shard.get("chunks") or []:
|
|
716
762
|
cur = con.execute(
|
|
717
|
-
"INSERT INTO chunks (name, tap, path, kind, cix, snip) "
|
|
718
|
-
"VALUES (?, ?, ?, ?, ?, ?)",
|
|
763
|
+
"INSERT INTO chunks (name, tap, path, kind, cix, snip, digest) "
|
|
764
|
+
"VALUES (?, ?, ?, ?, ?, ?, ?)",
|
|
719
765
|
(c.get("name"), c.get("tap"), c.get("path"), c.get("kind"),
|
|
720
|
-
c.get("cix"), c.get("snip")
|
|
766
|
+
c.get("cix"), c.get("snip"),
|
|
767
|
+
# A shard published before the digest travelled has none, and
|
|
768
|
+
# None is the honest value: that tap re-embeds once, which is
|
|
769
|
+
# what it did before this existed. Never a placeholder — a
|
|
770
|
+
# wrong digest would suppress a real re-embed forever.
|
|
771
|
+
c.get("digest")))
|
|
721
772
|
blob = base64.b64decode(c["embedding"])
|
|
722
773
|
_store_vector(con, cur.lastrowid, blob)
|
|
723
774
|
commits = meta.get("commits")
|
|
@@ -748,12 +799,109 @@ def _indexed_taps(con: sqlite3.Connection) -> set:
|
|
|
748
799
|
return set() # no chunks table yet — nothing indexed, nothing stale
|
|
749
800
|
|
|
750
801
|
|
|
802
|
+
def _delete_matching(con: sqlite3.Connection, where: str,
|
|
803
|
+
params: tuple) -> int:
|
|
804
|
+
"""Drop the chunk rows matching ``where``, and their vectors. Rows hit.
|
|
805
|
+
|
|
806
|
+
Deleting a chunk is two statements that must not drift apart: the vectors
|
|
807
|
+
go through :func:`_drop_vectors` (which knows both store layouts) and only
|
|
808
|
+
then does the row go. Tap-level and entry-level deletion had that pair
|
|
809
|
+
written out twice, which is one copy too many for a rule this easy to half-
|
|
810
|
+
apply — an orphan vector outlives every later deletion, because those are
|
|
811
|
+
all scoped through ``chunks``.
|
|
812
|
+
|
|
813
|
+
``where`` is a literal from this module, never caller data; the parameters
|
|
814
|
+
are bound.
|
|
815
|
+
"""
|
|
816
|
+
# `%` rather than `+`, to match every other interpolated statement in this
|
|
817
|
+
# module: those are the shapes ruff's S608 is known to flag here, so the
|
|
818
|
+
# suppression is one ruff actually consumes rather than an unused `noqa`
|
|
819
|
+
# that RUF100 would then reject.
|
|
820
|
+
ids = [r[0] for r in con.execute(
|
|
821
|
+
"SELECT id FROM chunks WHERE %s" % where, params)] # noqa: S608 literal clause
|
|
822
|
+
if not ids:
|
|
823
|
+
return 0
|
|
824
|
+
_drop_vectors(con, ids)
|
|
825
|
+
con.execute("DELETE FROM chunks WHERE %s" % where, params) # noqa: S608 same literal
|
|
826
|
+
return len(ids)
|
|
827
|
+
|
|
828
|
+
|
|
829
|
+
def _delete_entries(con: sqlite3.Connection,
|
|
830
|
+
keys: list[tuple[str, str]]) -> int:
|
|
831
|
+
"""Drop every chunk row for these ``(tap, path)`` entries. Returns rows hit.
|
|
832
|
+
|
|
833
|
+
The entry-level counterpart to :func:`_delete_taps`, and it must stay
|
|
834
|
+
row-scoped rather than content-scoped: two taps can ship a byte-identical
|
|
835
|
+
file, so deleting by digest would take another tap's rows with it.
|
|
836
|
+
"""
|
|
837
|
+
return sum(_delete_matching(con, "tap = ? AND path = ?", (tap, path))
|
|
838
|
+
for tap, path in keys)
|
|
839
|
+
|
|
840
|
+
|
|
841
|
+
def _prune_stale_entries(con: sqlite3.Connection, taps: list[str],
|
|
842
|
+
live: set[tuple[str, str]]) -> int:
|
|
843
|
+
"""Drop rows in ``taps`` for entries the catalog no longer has.
|
|
844
|
+
|
|
845
|
+
Whole-tap deletion used to do this for free: a changed tap was emptied and
|
|
846
|
+
rebuilt, so an entry deleted upstream simply never came back. Reuse keeps
|
|
847
|
+
the rows instead, which means a file removed from a registry would answer
|
|
848
|
+
queries forever — the same silent-stale-row failure `_delete_taps`'s
|
|
849
|
+
`removed_taps` sweep exists to prevent, one level down.
|
|
850
|
+
"""
|
|
851
|
+
stale = [(tap, path) for tap in taps
|
|
852
|
+
for (path,) in con.execute(
|
|
853
|
+
"SELECT DISTINCT path FROM chunks WHERE tap = ?", (tap,))
|
|
854
|
+
if (tap, path) not in live]
|
|
855
|
+
return _delete_entries(con, stale)
|
|
856
|
+
|
|
857
|
+
|
|
858
|
+
def _split_by_digest(con: sqlite3.Connection,
|
|
859
|
+
entries: list[dict]) -> tuple[list[dict], list[dict]]:
|
|
860
|
+
"""Partition ``entries`` into ``(to_embed, already_stored)``.
|
|
861
|
+
|
|
862
|
+
An entry is already stored when the store holds chunks for its
|
|
863
|
+
``(tap, path)`` **and every one of them** carries its current content
|
|
864
|
+
digest. Every one, not any: a partially-written entry — an interrupted
|
|
865
|
+
build, or one whose digest changed mid-run — would otherwise be reused
|
|
866
|
+
with a mixture of two versions' vectors, which is worse than re-embedding
|
|
867
|
+
because nothing later notices.
|
|
868
|
+
|
|
869
|
+
An entry with no digest is never reused. `catalog._content_digest` stamps
|
|
870
|
+
them at scan time, but a cache written before ``CACHE_FORMAT`` has none,
|
|
871
|
+
and CLAUDE.md's rule is explicit: consumers degrade cleanly when ``content``
|
|
872
|
+
is absent and **must never treat two absences as a match**. Two entries
|
|
873
|
+
with no digest are not the same entry; they are two unknowns.
|
|
874
|
+
"""
|
|
875
|
+
# Nothing to decide, and the early return is the common case rather than a
|
|
876
|
+
# guard: on a build where no tap moved, `candidates` is empty, and without
|
|
877
|
+
# this the store gets scanned end to end to answer a question nobody asked.
|
|
878
|
+
if not entries:
|
|
879
|
+
return [], []
|
|
880
|
+
# Scoped to the taps actually in play, via the `chunks_tap` index. Reading
|
|
881
|
+
# the whole table instead measured 3.75 s cold (0.17 s warm) against 0.08 s
|
|
882
|
+
# for the nineteen largest taps and under 0.01 s for nineteen typical ones,
|
|
883
|
+
# on a real 657,587-chunk store. The full read was also the wrong shape: it
|
|
884
|
+
# grows with the store while the work grows with the drift.
|
|
885
|
+
stored: dict[tuple[str, str], set] = {}
|
|
886
|
+
for tap in sorted({e["tap"] for e in entries}):
|
|
887
|
+
for path, digest in con.execute(
|
|
888
|
+
"SELECT path, digest FROM chunks WHERE tap = ?", (tap,)):
|
|
889
|
+
stored.setdefault((tap, path), set()).add(digest)
|
|
890
|
+
to_embed, kept = [], []
|
|
891
|
+
for e in entries:
|
|
892
|
+
digest = e.get("content")
|
|
893
|
+
have = stored.get(entry_key(e))
|
|
894
|
+
if digest and have == {digest}:
|
|
895
|
+
kept.append(e)
|
|
896
|
+
else:
|
|
897
|
+
to_embed.append(e)
|
|
898
|
+
return to_embed, kept
|
|
899
|
+
|
|
900
|
+
|
|
751
901
|
def _delete_taps(con: sqlite3.Connection, taps: list[str]) -> None:
|
|
902
|
+
"""Drop every chunk row belonging to these taps, and their vectors."""
|
|
752
903
|
for tap in taps:
|
|
753
|
-
|
|
754
|
-
con.execute("SELECT id FROM chunks WHERE tap = ?", (tap,))]
|
|
755
|
-
_drop_vectors(con, ids)
|
|
756
|
-
con.execute("DELETE FROM chunks WHERE tap = ?", (tap,))
|
|
904
|
+
_delete_matching(con, "tap = ?", (tap,))
|
|
757
905
|
|
|
758
906
|
|
|
759
907
|
def _embed_and_store(con: sqlite3.Connection, entries: list[dict],
|
|
@@ -825,10 +973,14 @@ def _embed_and_store(con: sqlite3.Connection, entries: list[dict],
|
|
|
825
973
|
failed_taps.add(e["tap"])
|
|
826
974
|
continue
|
|
827
975
|
cur = con.execute(
|
|
828
|
-
"INSERT INTO chunks (name, tap, path, kind, cix, snip) "
|
|
829
|
-
"VALUES (?, ?, ?, ?, ?, ?)",
|
|
976
|
+
"INSERT INTO chunks (name, tap, path, kind, cix, snip, digest) "
|
|
977
|
+
"VALUES (?, ?, ?, ?, ?, ?, ?)",
|
|
830
978
|
(e["name"], e["tap"], e["skill_md"],
|
|
831
|
-
e.get("kind", "skill"), ci, text[:200].strip()
|
|
979
|
+
e.get("kind", "skill"), ci, text[:200].strip(),
|
|
980
|
+
# None where the catalog has no digest, which `_split_by_digest`
|
|
981
|
+
# then refuses to reuse — the honest answer for a cache written
|
|
982
|
+
# before CACHE_FORMAT stamped one.
|
|
983
|
+
e.get("content")))
|
|
832
984
|
_store_vector(con, cur.lastrowid, mod.serialize_float32(vec))
|
|
833
985
|
added += 1
|
|
834
986
|
since_commit += 1
|
|
@@ -266,6 +266,62 @@ def hit_line(entry: dict, *, installed: bool = False) -> str:
|
|
|
266
266
|
entry.get("tap", "?"))
|
|
267
267
|
|
|
268
268
|
|
|
269
|
+
# `boost_read`'s budget, and it is a measured number rather than a round one.
|
|
270
|
+
# An MCP reply lands directly in an agent's context and a SKILL.md is not
|
|
271
|
+
# bounded above, so a tool that returns one whole is how a single lookup costs
|
|
272
|
+
# a session. Measured over the 63,053 items in a real 467-tap install: median
|
|
273
|
+
# 6,063 bytes, p90 16,225, p99 35,275, **max 567,484** — three orders of
|
|
274
|
+
# magnitude between the middle and the tail, which is the shape that makes an
|
|
275
|
+
# unbounded read a real hazard rather than a theoretical one.
|
|
276
|
+
#
|
|
277
|
+
# 12,000 is the knee. It delivers 80.3% of the catalogue whole against 62.8%
|
|
278
|
+
# at 8,000 — two thirds of the remaining truncations bought for 50% more bytes
|
|
279
|
+
# — and caps the worst case near 3,000 tokens. Raising it to 16,000 buys 9.3
|
|
280
|
+
# points for another third again, which is the wrong side of the trade for a
|
|
281
|
+
# tool an agent may call several times in one turn.
|
|
282
|
+
#
|
|
283
|
+
# The cap counts CHARACTERS, deliberately: boost cannot know the caller's
|
|
284
|
+
# tokenizer, and a character count is one an agent can check against the reply
|
|
285
|
+
# it is already holding. Truncation is never the failure mode this guards
|
|
286
|
+
# against, because it is announced — see :func:`read_reply`.
|
|
287
|
+
READ_LIMIT = 12000
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
def read_reply(name: str, text: str, *, kind: str = "skill",
|
|
291
|
+
installed: bool = False, limit: int = READ_LIMIT) -> str:
|
|
292
|
+
"""`boost_read`'s reply: a header, then the item's own content.
|
|
293
|
+
|
|
294
|
+
The header exists because the body alone does not say what the agent is
|
|
295
|
+
holding. A tap-qualified name resolves to one item out of several that
|
|
296
|
+
share a bare name, and whether it is already installed decides whether the
|
|
297
|
+
next call is `boost_install` or nothing at all — both are one line here and
|
|
298
|
+
neither is recoverable from Markdown.
|
|
299
|
+
|
|
300
|
+
**Truncation is announced, in the reply, at the point it happens.** A body
|
|
301
|
+
cut silently reads as a complete document that simply ends — which for a
|
|
302
|
+
procedure is worse than no body at all, because the agent acts on the half
|
|
303
|
+
it can see and never learns there was a second half. The notice names the
|
|
304
|
+
command that returns the rest, so the reply carries its own recovery path
|
|
305
|
+
the way ``tool-design`` asks agent-facing errors to.
|
|
306
|
+
|
|
307
|
+
Truncation cuts at a LINE boundary within the budget rather than mid-line.
|
|
308
|
+
A Markdown body cut mid-fence or mid-sentence is text an agent has to
|
|
309
|
+
guess about; a whole-line cut is unambiguously "the document continues".
|
|
310
|
+
A body whose first line already exceeds the budget has no such boundary,
|
|
311
|
+
so it falls back to a hard character cut — announced the same way.
|
|
312
|
+
"""
|
|
313
|
+
head = ["name: %s" % name]
|
|
314
|
+
if kind != "skill":
|
|
315
|
+
head.append("kind: %s" % kind)
|
|
316
|
+
head.append("installed: %s" % ("yes" if installed else "no"))
|
|
317
|
+
body = text.strip("\n")
|
|
318
|
+
if len(body) > limit:
|
|
319
|
+
cut = body[:limit].rpartition("\n")[0] or body[:limit]
|
|
320
|
+
body = ("%s\n\n[truncated at %d of %d characters — read the rest with "
|
|
321
|
+
"`boost cat %s`]" % (cut, len(cut), len(text), name))
|
|
322
|
+
return "\n".join(head) + "\n\n" + body
|
|
323
|
+
|
|
324
|
+
|
|
269
325
|
# The lock sections, in the order every boost surface names them. Fixed here
|
|
270
326
|
# rather than read off the caller's dict, so the footer's column order cannot
|
|
271
327
|
# drift between a machine that has rules and one that does not.
|