boost-skill-cli 1.0.204__tar.gz → 1.0.206__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.0.204 → boost_skill_cli-1.0.206}/Makefile +1 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/PKG-INFO +1 -1
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/__init__.py +4 -9
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/_version.py +2 -2
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/commands/bmad.py +4 -5
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/commands/configuration.py +2 -2
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/commands/discovery.py +7 -8
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/commands/info.py +1 -1
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/commands/intelligence.py +1 -1
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/commands/pkg.py +4 -4
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/commands/quality.py +6 -6
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/commands/run.py +2 -1
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/commands/safety.py +1 -1
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/commands/taps.py +3 -4
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/core/adapters.py +9 -14
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/core/ai.py +3 -1
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/core/capabilities.py +4 -3
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/core/catalog.py +10 -7
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/core/claude_settings.py +1 -2
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/core/config.py +4 -1
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/core/dense.py +4 -4
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/core/embed.py +2 -2
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/core/faithfulness.py +2 -4
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/core/frontmatter.py +3 -6
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/core/imperative.py +2 -1
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/core/injectscan.py +2 -2
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/core/lockfile.py +2 -3
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/core/logs.py +3 -5
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/core/mcp.py +3 -3
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/core/output.py +3 -1
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/core/policy.py +1 -1
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/core/projectlock.py +2 -3
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/core/provenance.py +1 -1
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/core/rag.py +12 -13
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/core/registry.py +1 -1
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/core/resolve.py +3 -2
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/core/rules.py +1 -1
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/core/scopes.py +6 -4
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/core/secretscan.py +2 -2
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/core/store.py +3 -3
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/core/typosquat.py +2 -1
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/core/updatediff.py +2 -1
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/core/util.py +4 -3
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/spin.py +1 -1
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_skill_cli.egg-info/PKG-INFO +1 -1
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/install-resolves-skill-dependencies.md +1 -1
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/modernization-smells-refurb-pyupgrade.md +3 -3
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap.html +2 -2
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/pyproject.toml +27 -2
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/requirements/lint-tools.txt +7 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_docsite_chrome.py +2 -2
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_util.py +1 -1
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/.gitattributes +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/.gitignore +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/.gitleaks.toml +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/.htmlvalidate.json +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/.lighthouserc.json +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/.lycheeignore +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/.markdownlint-cli2.jsonc +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/.pre-commit-config.yaml +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/.stylelintrc.json +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/.vale/styles/boost/Terminology.yml +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/.vale/styles/config/vocabularies/boost/accept.txt +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/.vale.ini +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/CLAUDE.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/CONTRIBUTING.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/LICENSE +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/MANIFEST.in +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/README.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/SECURITY.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/__main__.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/cli.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/cliparse.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/commands/__init__.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/commands/_common.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/commands/hooks.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/commands/team.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/core/__init__.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/core/agents.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/core/ed25519.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/core/gitutil.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/core/integrity.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/core/journal.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/core/minisign.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/core/nethttp.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/core/paths.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/core/serve.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/core/stackprobe.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/core/staleness.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/core/workflows.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/data/registries.json +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_cli/errors.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_skill_cli.egg-info/SOURCES.txt +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_skill_cli.egg-info/dependency_links.txt +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_skill_cli.egg-info/entry_points.txt +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_skill_cli.egg-info/requires.txt +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/boost_skill_cli.egg-info/top_level.txt +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/.claude/settings.local.json +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/DEBUGGING.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/adapters.html +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/commands.html +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/demo.gif +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/demo.tape +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/design-roadmap.html +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/eval.html +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/index.html +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/mcp-hub.html +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/rag-architecture.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/BOOST-D01.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/BOOST-D02.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/BOOST-D03.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/BOOST-D04.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/BOOST-D05.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/BOOST-D06.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/BOOST-D07.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/BOOST-D08.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/BOOST-D09.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/BOOST-D10.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/BOOST-D11.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/BOOST-D12.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/BOOST-D13.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/BOOST-D14.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/BOOST-D15.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/BOOST-D16.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/BOOST-D17.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/BOOST-D18.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/BOOST-D19.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/BOOST-D20.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/BOOST-D21.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/BOOST-D22.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/BOOST-D23.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/BOOST-D24.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/BOOST-D25.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/BOOST-D26.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/accessibility-audit-pa11y-ci-axe-core.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/atomic-corruption-safe-lock-file-writes.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/atomic-skill-install-temp-dir-swap.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/autonomous-ship-workflow-and-isolated-worktree.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/boost-run-live-agents.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/bring-commands-under-mutation-testing.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/broken-link-and-anchor-checking-lychee.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/browse-crashes-selecting-a-rule-or-workflow.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/build-provenance-slsa-attestations.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/cache-the-catalog-entry-set-across-rag-queries.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/capability-manifest-and-least-privilege-policy.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/clean-env-install-smoke-pip-and-pipx.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/command-reference-docs-site.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/complexity-and-dead-code-radar-xenon-vulture.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/consolidate-skill-staleness-drift-logic-into-cor.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/coverage-dashboard-codecov-free-for-oss.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/coverage-guided-fuzzing-atheris-oss-fuzz.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/crash-recorder-error-paths-core-logs-py.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/dependency-cve-gate-pip-audit.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/docsite-chrome-and-content-audit.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/docstring-coverage-interrogate.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/doctor-checks-rules-and-workflows.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/end-of-options-guard-on-git-commands.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/extension-free-tests-core-dense-py.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/extract-mcp-http-servers-out-of-configuration-py.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/finish-mutation-hardening-across-core.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/fix-self-update-version-detection-dead-branch.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/fork-safe-network-proxy-handler.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/framework-adapter-langgraph.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/framework-adapter-multi-agent.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/framework-adapters-boost-adapt.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/frontmatter-scalar-over-coercion.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/github-pages-deploy-is-broken-every-push.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/golden-set-statistical-power.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/hash-pinned-reproducible-toolchain-uv-lock.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/html-validation-html-validate.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/install-scope-user-or-project.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/installed-skill-trust-audit.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/integrity-verification-boost-verify.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/invocation-pid-logging-for-crash-correlation.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/layering-guard-import-linter.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/lighthouse-ci-on-the-pages-site.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/list-rules-and-workflows.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/localize-the-stored-bm25-snippet.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/lockfile-enforcement-and-commit-pinning.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/log-timestamps-mislabeled-utc.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/lowest-version-resolution-uv-resolution-lowest-d.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/make-the-roadmaps-discoverable.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/markdown-consistency-markdownlint-cli2.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/mcp-aware-skills.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/mcp-hub-diagram-node-text-overflow.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/mcp-launch-objc-fork-safety.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/mcp-register-names-server-before-env.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/mcp-search-before-reinventing.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/mcp-startup-self-harden-fork-safety.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/memoize-config-load-in-process.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/mutation-hardening-core-frontmatter-py.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/mutation-hardening-core-gitutil-py.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/mutation-hardening-core-store-py.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/one-command-every-env-nox.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/one-shared-atomic-write-helper.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/package-metadata-validation-twine-check-friends.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/patch-coverage-gate-diff-cover.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/performance-regression-gate-pytest-benchmark.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/pin-the-lint-toolchain.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/post-deploy-smoke-headless-load-check.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/pre-release-python-canary-3-14t-free-threaded.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/project-scope-across-every-command.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/project-scope-symlink-escape-on-write.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/promote-nav-footer-into-the-shared-style-system.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/prompt-injection-scanning-of-skill-markdown.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/property-based-tests-hypothesis-on-the-parsers.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/prose-and-terminology-linting-vale.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/prune-ignored-dirs-during-scan-dir-walk.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/quality-dashboard-sonarcloud-free-for-oss.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/ranx-significance-monitor.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/reconcile-the-theme-drift.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/refresh-the-marketing-surface.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/retrieval-quality-eval-harness.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/reuse-helpers-kill-minor-dead-work.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/robust-tag-argument-parsing.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/rule-install-native-materialization.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/runner-egress-monitoring-stepsecurity-harden-run.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/runtime-explain-faithfulness-guardrail.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/sbom-aware-scanning-osv-scanner.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/sbom-on-every-release-cyclonedx-syft.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/scan-and-sync-rules-and-workflows.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/second-type-checker-pyright.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/secret-and-pii-scanning-of-installed-skills.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/secret-scanning-gitleaks-push-protection.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/security-linting-bandit-via-ruff-s-rules.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/shift-left-gate-pre-commit-pre-commit-ci.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/single-imperative-rule-extractor.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/single-tech-stack-prober.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/split-oversized-command-modules.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/startup-and-import-time-budget-x-importtime.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/stop-re-serializing-entry-meta-on-every-search.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/supply-chain-posture-openssf-scorecard.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/surface-every-docs-page-from-the-guide.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/tap-signing-and-provenance-sigstore-minisign.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/theme-asset-linting-stylelint-eslint.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/typo-detection-codespell.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/typosquat-and-name-confusion-detection.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/unify-tilde-two-copies-have-a-boundary-bug.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/untrack-generated-build-noise.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/update-diff-before-apply.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/update-refreshes-rules-and-workflows.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/visual-regression-pass-on-the-guide.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/widen-the-ruff-rule-surface-b-sim-c4-perf-ruf.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/windows-in-the-ci-matrix.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/workflow-install-native-materialization.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/workflow-linting-actionlint.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/workflow-sast-zizmor.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/docs/roadmap/items/workspace-scope-install.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/eslint.config.mjs +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/examples/README.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/examples/adapt-demo.sh +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/examples/boost-run-prototype.sh +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/index.html +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/noxfile.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/scripts/bench_cli.sh +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/scripts/build_command_reference.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/scripts/build_registries.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/scripts/build_roadmap.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/scripts/check_anchors.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/scripts/ensure_eval_corpus.sh +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/scripts/eval_explain.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/scripts/eval_recommend.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/scripts/eval_retrieval.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/scripts/eval_stats_summary.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/scripts/import_budget.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/scripts/mutation_gate.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/scripts/perf_gate.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/setup.cfg +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/style/README.md +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/style/boost.css +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/style/boost.js +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/style/demo.html +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/bdd/features/adapt.feature +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/bdd/features/browse.feature +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/bdd/features/count.feature +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/bdd/features/discover.feature +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/bdd/features/doctor.feature +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/bdd/features/environment.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/bdd/features/explain.feature +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/bdd/features/index.feature +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/bdd/features/install.feature +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/bdd/features/list.feature +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/bdd/features/mcp.feature +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/bdd/features/search.feature +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/bdd/features/steps/cli_steps.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/bdd/features/steps/discovery_steps.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/bdd/features/steps/mcp_steps.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/bdd/features/steps/quality_steps.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/conftest.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/eval/baseline.json +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/eval/explain.jsonl +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/eval/golden.jsonl +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/eval/recommend.jsonl +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/eval/taps.txt +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/functional/test_capabilities_policy.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/functional/test_cli_adapt.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/functional/test_cli_bmad.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/functional/test_cli_configuration.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/functional/test_cli_discovery.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/functional/test_cli_hooks.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/functional/test_cli_info.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/functional/test_cli_intelligence.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/functional/test_cli_pkg.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/functional/test_cli_quality.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/functional/test_cli_taps.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/functional/test_cli_team.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/functional/test_everyday_loop.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/functional/test_integrity_enforce.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/functional/test_property_parsers.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/functional/test_run.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/functional/test_tap_signing.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/functional/test_workspace_scope.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/make_fixture.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/perf/test_benchmarks.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/smoke.sh +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_adapters.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_adapters_multi.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_adapters_runner.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_agents.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_ai.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_capabilities.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_catalog.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_check_anchors.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_claude_settings.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_cliparse.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_command_reference_fresh.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_config.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_dense.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_dense_fallback.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_docs_pages_linked.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_ed25519.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_embed.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_errors_and_cli_table.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_eval_stats_summary.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_faithfulness.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_frontmatter.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_gitleaks_config.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_gitutil.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_imperative.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_import_budget.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_injectscan.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_integrity.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_journal.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_lockfile.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_logs.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_mcp.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_minisign.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_mutation_hardening.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_nethttp.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_output.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_paths.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_perf_gate.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_pkg_confusions.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_pkg_injection.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_pkg_secrets.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_policy.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_projectlock.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_provenance.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_rag.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_registries_fresh.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_registry.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_resolve.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_roadmap_fresh.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_rules.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_scopes.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_secretscan.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_serve.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_spin.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_stackprobe.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_staleness.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_store.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_token_parity.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_typosquat.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_updatediff.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_version.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/unit/test_workflows.py +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/visual/package.json +0 -0
- {boost_skill_cli-1.0.204 → boost_skill_cli-1.0.206}/tests/visual/visual_check.mjs +0 -0
|
@@ -51,6 +51,7 @@ lint:
|
|
|
51
51
|
$(VENV)/bin/vulture boost_cli --min-confidence 80
|
|
52
52
|
$(VENV)/bin/xenon --max-absolute F --max-modules E --max-average B boost_cli
|
|
53
53
|
$(VENV)/bin/interrogate boost_cli/core
|
|
54
|
+
$(VENV)/bin/refurb boost_cli
|
|
54
55
|
$(VENV)/bin/codespell boost_cli docs README.md
|
|
55
56
|
@command -v actionlint >/dev/null 2>&1 && actionlint || echo "actionlint not on PATH — skipping (CI enforces it)"
|
|
56
57
|
$(PY) scripts/build_registries.py --check
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"""boost — Homebrew for AI coding skills."""
|
|
2
|
+
from contextlib import suppress
|
|
2
3
|
|
|
3
4
|
|
|
4
5
|
def _detect_version() -> str:
|
|
@@ -8,17 +9,13 @@ def _detect_version() -> str:
|
|
|
8
9
|
package metadata, then a git-checkout fallback (stdlib only, so the
|
|
9
10
|
dependency-free runtime stays intact), then a sentinel.
|
|
10
11
|
"""
|
|
11
|
-
|
|
12
|
+
with suppress(Exception):
|
|
12
13
|
from ._version import version as scm_version
|
|
13
14
|
return scm_version
|
|
14
|
-
|
|
15
|
-
pass
|
|
16
|
-
try:
|
|
15
|
+
with suppress(Exception):
|
|
17
16
|
from importlib.metadata import version as dist_version
|
|
18
17
|
return dist_version("boost-skill-cli")
|
|
19
|
-
|
|
20
|
-
pass
|
|
21
|
-
try:
|
|
18
|
+
with suppress(Exception):
|
|
22
19
|
import subprocess
|
|
23
20
|
from pathlib import Path
|
|
24
21
|
root = Path(__file__).resolve().parent.parent
|
|
@@ -28,8 +25,6 @@ def _detect_version() -> str:
|
|
|
28
25
|
described = proc.stdout.strip()
|
|
29
26
|
if proc.returncode == 0 and described:
|
|
30
27
|
return described.lstrip("v")
|
|
31
|
-
except Exception:
|
|
32
|
-
pass
|
|
33
28
|
return "0.0.0+unknown"
|
|
34
29
|
|
|
35
30
|
|
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '1.0.
|
|
22
|
-
__version_tuple__ = version_tuple = (1, 0,
|
|
21
|
+
__version__ = version = '1.0.206'
|
|
22
|
+
__version_tuple__ = version_tuple = (1, 0, 206)
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -27,6 +27,7 @@ import shlex
|
|
|
27
27
|
import shutil
|
|
28
28
|
import subprocess
|
|
29
29
|
import tempfile
|
|
30
|
+
from contextlib import suppress
|
|
30
31
|
from pathlib import Path
|
|
31
32
|
|
|
32
33
|
from .. import cliparse
|
|
@@ -110,7 +111,7 @@ def _require_npx() -> None:
|
|
|
110
111
|
hint="install Node.js 20.12+ (e.g. `brew install node`), then retry")
|
|
111
112
|
|
|
112
113
|
|
|
113
|
-
def _run_installer(directory: Path, modules: str) ->
|
|
114
|
+
def _run_installer(directory: Path, modules: str) -> subprocess.CompletedProcess:
|
|
114
115
|
cmd = ["npx", "--yes", "bmad-method@latest", "install",
|
|
115
116
|
"--yes", "--directory", str(directory),
|
|
116
117
|
"--tools", "claude-code", "--modules", modules,
|
|
@@ -136,7 +137,7 @@ def _whoami() -> str:
|
|
|
136
137
|
|
|
137
138
|
|
|
138
139
|
def _parse_version(text: str) -> str:
|
|
139
|
-
m = re.search(r"v(\d+\.\d+\.\d+)", text
|
|
140
|
+
m = re.search(r"v(\d+\.\d+\.\d+)", text)
|
|
140
141
|
return m.group(1) if m else "unknown"
|
|
141
142
|
|
|
142
143
|
|
|
@@ -225,11 +226,9 @@ def _startup(value, scope) -> int:
|
|
|
225
226
|
def _orient(scope) -> int:
|
|
226
227
|
"""SessionStart hook target: print orientation iff enabled (else silent)."""
|
|
227
228
|
scope = scope or "project"
|
|
228
|
-
|
|
229
|
+
with suppress(Exception): # a hook must never break the session
|
|
229
230
|
if _get_scope_state(scope).get("startup"):
|
|
230
231
|
print(ORIENT)
|
|
231
|
-
except Exception:
|
|
232
|
-
pass # a hook must never break the session
|
|
233
232
|
return 0
|
|
234
233
|
|
|
235
234
|
|
|
@@ -793,8 +793,8 @@ def _tool_info(args: dict):
|
|
|
793
793
|
if src.get("description"):
|
|
794
794
|
lines.append("description: %s" % src["description"])
|
|
795
795
|
if entry:
|
|
796
|
-
lines.
|
|
797
|
-
|
|
796
|
+
lines.extend(("installed: yes (%s)" % entry.get("installed_at", "?"),
|
|
797
|
+
"agents: %s" % (", ".join(entry.get("agents") or []) or "none")))
|
|
798
798
|
if entry.get("pinned"):
|
|
799
799
|
lines.append("pinned: yes")
|
|
800
800
|
else:
|
|
@@ -7,6 +7,7 @@ from __future__ import annotations
|
|
|
7
7
|
|
|
8
8
|
import argparse
|
|
9
9
|
import json
|
|
10
|
+
import operator
|
|
10
11
|
import re
|
|
11
12
|
import shutil
|
|
12
13
|
import subprocess
|
|
@@ -43,7 +44,7 @@ _tilde = paths.tilde
|
|
|
43
44
|
|
|
44
45
|
def _json_array(text):
|
|
45
46
|
"""Best-effort extraction of the first JSON array in an AI reply."""
|
|
46
|
-
m = re.search(r"\[.*\]", text or "", re.
|
|
47
|
+
m = re.search(r"\[.*\]", text or "", re.DOTALL)
|
|
47
48
|
if not m:
|
|
48
49
|
return None
|
|
49
50
|
try:
|
|
@@ -108,7 +109,7 @@ def cmd_search(argv):
|
|
|
108
109
|
else:
|
|
109
110
|
scored = catalog.search(query)
|
|
110
111
|
if args.as_json:
|
|
111
|
-
print(json.dumps([
|
|
112
|
+
print(json.dumps([e | {"score": s} for e, s in scored[:args.limit]]))
|
|
112
113
|
return 0
|
|
113
114
|
if not scored:
|
|
114
115
|
out.info("no matches for %r" % query)
|
|
@@ -412,7 +413,7 @@ def cmd_recommend(argv):
|
|
|
412
413
|
key=lambda r: (-r["score"], r["entry"]["name"]))
|
|
413
414
|
if args.as_json:
|
|
414
415
|
print(json.dumps({"stack": stack, "recommendations": [
|
|
415
|
-
|
|
416
|
+
r["entry"] | {"score": r["score"], "because": sorted(r["because"])}
|
|
416
417
|
for r in ranked[:args.limit]]}))
|
|
417
418
|
return 0
|
|
418
419
|
line = "stack: " + (", ".join(stack["languages"]) or "unknown")
|
|
@@ -833,7 +834,7 @@ def cmd_browse(argv):
|
|
|
833
834
|
prog="boost browse",
|
|
834
835
|
description="Interactive full-screen TUI with fuzzy search")
|
|
835
836
|
p.parse_args(argv)
|
|
836
|
-
entries = sorted(catalog.all_entries(), key=
|
|
837
|
+
entries = sorted(catalog.all_entries(), key=operator.itemgetter("name"))
|
|
837
838
|
if not entries:
|
|
838
839
|
raise BoostError("no skills available to browse",
|
|
839
840
|
hint="add registries with `boost tap --defaults`")
|
|
@@ -886,7 +887,7 @@ def cmd_trending(argv):
|
|
|
886
887
|
descw = max(out.term_width() - 24, 24) # reserve name + version columns
|
|
887
888
|
out.table([(e["name"], "v" + e["version"],
|
|
888
889
|
out.truncate(e["description"], descw))
|
|
889
|
-
for e in sorted(curated, key=
|
|
890
|
+
for e in sorted(curated, key=operator.itemgetter("name"))[:args.limit]])
|
|
890
891
|
return 0
|
|
891
892
|
agg = {}
|
|
892
893
|
for ev in evs: # most-recent-first, so first ts per subject is the latest
|
|
@@ -924,13 +925,11 @@ def cmd_stats(argv):
|
|
|
924
925
|
latest = cat["version"] if cat else None
|
|
925
926
|
upstream = None
|
|
926
927
|
if cat:
|
|
927
|
-
|
|
928
|
+
with contextlib.suppress(BoostError):
|
|
928
929
|
tap = registry.get(cat["tap"])
|
|
929
930
|
if tap.is_cloned:
|
|
930
931
|
lines = gitutil.log_for_path(tap.path, cat["rel_dir"], n=1)
|
|
931
932
|
upstream = lines[0] if lines else None
|
|
932
|
-
except BoostError:
|
|
933
|
-
pass
|
|
934
933
|
sdir = store.skill_store_dir(name)
|
|
935
934
|
size = util.dir_size(sdir) if lock and sdir.is_dir() else None
|
|
936
935
|
if args.as_json:
|
|
@@ -495,7 +495,7 @@ def cmd_explain(argv):
|
|
|
495
495
|
desc = str(meta.get("description") or "").strip()
|
|
496
496
|
if desc:
|
|
497
497
|
_print_wrapped(desc)
|
|
498
|
-
headings = re.findall(r"^(#{1,6})\s+(.*)$", body, re.
|
|
498
|
+
headings = re.findall(r"^(#{1,6})\s+(.*)$", body, re.MULTILINE)
|
|
499
499
|
if headings:
|
|
500
500
|
print()
|
|
501
501
|
out.info(out.c("Outline:", out.BOLD))
|
|
@@ -418,7 +418,7 @@ def _commit_rule(style: Tuple[int, int]) -> str:
|
|
|
418
418
|
def _infer_ai(name: str, root: Path, facts: dict) -> Optional[str]:
|
|
419
419
|
listing = ", ".join(sorted(p.name for p in root.iterdir()
|
|
420
420
|
if not p.name.startswith("."))[:30])
|
|
421
|
-
detected =
|
|
421
|
+
detected = facts.copy()
|
|
422
422
|
if detected.get("commit_style"):
|
|
423
423
|
detected["commit_style"] = _commit_rule(detected["commit_style"])
|
|
424
424
|
reply = ai.ask_author(
|
|
@@ -165,7 +165,7 @@ def _boostfile_text(skills: Dict[str, dict], via: str = "boost bundle dump") ->
|
|
|
165
165
|
|
|
166
166
|
def _rel_list(meta: dict, key: str) -> List[str]:
|
|
167
167
|
"""A skill's `requires:`/`conflicts:` frontmatter as a clean name list."""
|
|
168
|
-
val =
|
|
168
|
+
val = meta.get(key)
|
|
169
169
|
if val in (None, "", False):
|
|
170
170
|
return []
|
|
171
171
|
if isinstance(val, list):
|
|
@@ -181,7 +181,7 @@ def _skill_relations(name: str, key: str) -> List[str]:
|
|
|
181
181
|
return _rel_list(matches[0].get("meta") or {}, key)
|
|
182
182
|
|
|
183
183
|
|
|
184
|
-
def _expand_dependencies(entries: List[dict]) ->
|
|
184
|
+
def _expand_dependencies(entries: List[dict]) -> tuple[List[dict], resolve.Resolution]:
|
|
185
185
|
"""Grow the requested entries into their full `requires:` closure.
|
|
186
186
|
|
|
187
187
|
Returns ``(ordered_entries, resolution)`` — the entries to install in
|
|
@@ -391,7 +391,7 @@ def cmd_uninstall(argv: List[str]) -> int:
|
|
|
391
391
|
removed += 1
|
|
392
392
|
if removed:
|
|
393
393
|
lines = ["Uninstalled %s" % _plural(removed, "skill")]
|
|
394
|
-
if removed == 1
|
|
394
|
+
if removed == 1 == len(args.names):
|
|
395
395
|
lines.append(out.role("next: boost list", "muted"))
|
|
396
396
|
print(out.panel(lines, title="removed", hue="pink"))
|
|
397
397
|
return 1 if failed else 0
|
|
@@ -425,7 +425,7 @@ def cmd_sync(argv: List[str]) -> int:
|
|
|
425
425
|
|
|
426
426
|
if args.diff:
|
|
427
427
|
if args.json:
|
|
428
|
-
print(json.dumps(
|
|
428
|
+
print(json.dumps(plan | {"project": pplan}, indent=2))
|
|
429
429
|
return 0
|
|
430
430
|
if not any(plan.values()) and not any(pplan.values()):
|
|
431
431
|
out.ok("everything in sync")
|
|
@@ -11,7 +11,9 @@ import hashlib
|
|
|
11
11
|
import json
|
|
12
12
|
import os
|
|
13
13
|
import re
|
|
14
|
+
from contextlib import suppress
|
|
14
15
|
from datetime import datetime, timedelta, timezone
|
|
16
|
+
from itertools import starmap
|
|
15
17
|
from pathlib import Path
|
|
16
18
|
from typing import List, Optional, Tuple
|
|
17
19
|
|
|
@@ -150,13 +152,11 @@ def _stack_keywords(cwd: Path) -> set:
|
|
|
150
152
|
detect_stack keywords, enriched with coarse filesystem markers (so tags
|
|
151
153
|
like `testing` or `git` can match even when detect_stack is language-only)."""
|
|
152
154
|
kws: List[str] = []
|
|
153
|
-
|
|
155
|
+
with suppress(Exception):
|
|
154
156
|
from ..core.stackprobe import detect_stack
|
|
155
157
|
stack = detect_stack(cwd)
|
|
156
158
|
if isinstance(stack, dict):
|
|
157
159
|
kws.extend(str(k) for k in (stack.get("keywords") or []))
|
|
158
|
-
except Exception:
|
|
159
|
-
pass
|
|
160
160
|
for marker, words in _STACK_MARKERS:
|
|
161
161
|
if (Path(cwd) / marker).exists():
|
|
162
162
|
kws.extend(words)
|
|
@@ -906,7 +906,7 @@ def cmd_trust(argv) -> int:
|
|
|
906
906
|
else:
|
|
907
907
|
results = _tap_provenance_rows()
|
|
908
908
|
if args.json:
|
|
909
|
-
print(json.dumps(
|
|
909
|
+
print(json.dumps(list(starmap(_result_json, results)), indent=2))
|
|
910
910
|
else:
|
|
911
911
|
_print_provenance(results)
|
|
912
912
|
# A specific tap must verify; a full sweep only alarms on tampering.
|
|
@@ -922,7 +922,7 @@ def cmd_trust(argv) -> int:
|
|
|
922
922
|
"trusted_keys": [{"name": k["name"],
|
|
923
923
|
"fingerprint": k.get("fingerprint", "")}
|
|
924
924
|
for k in keys],
|
|
925
|
-
"taps":
|
|
925
|
+
"taps": list(starmap(_result_json, taps)),
|
|
926
926
|
}, indent=2))
|
|
927
927
|
return 0
|
|
928
928
|
out.heading("trusted keys")
|
|
@@ -936,7 +936,7 @@ def cmd_trust(argv) -> int:
|
|
|
936
936
|
return 0
|
|
937
937
|
|
|
938
938
|
|
|
939
|
-
def _result_json(tap_name: str, r:
|
|
939
|
+
def _result_json(tap_name: str, r: provenance.Result) -> dict:
|
|
940
940
|
return {"tap": tap_name, "status": r.status, "key_name": r.key_name,
|
|
941
941
|
"fingerprint": r.fingerprint, "trusted_comment": r.trusted_comment}
|
|
942
942
|
|
|
@@ -18,6 +18,7 @@ import os
|
|
|
18
18
|
import subprocess
|
|
19
19
|
import sys
|
|
20
20
|
import tempfile
|
|
21
|
+
from pathlib import Path
|
|
21
22
|
from typing import List
|
|
22
23
|
|
|
23
24
|
from .. import cliparse
|
|
@@ -111,6 +112,6 @@ def _execute(runner: str, display: str, model, target) -> int: # pragma: no cov
|
|
|
111
112
|
proc = subprocess.run([sys.executable, runner_path])
|
|
112
113
|
finally:
|
|
113
114
|
with contextlib.suppress(OSError):
|
|
114
|
-
|
|
115
|
+
Path(runner_path).unlink()
|
|
115
116
|
journal.log("run", display)
|
|
116
117
|
return proc.returncode
|
|
@@ -23,7 +23,7 @@ from ._common import _iter_installed, _s
|
|
|
23
23
|
_AUDIT_PATTERNS = [
|
|
24
24
|
(re.compile(r"(?:curl|wget)[^|\n]*\|\s*(?:sudo\s+)?(?:ba|z|da)?sh\b"),
|
|
25
25
|
"HIGH", "remote-exec"),
|
|
26
|
-
(re.compile(r"rm\s+-(?:rf|fr)\s+(?:/|~)(?=[\s'\";`)]|$)", re.
|
|
26
|
+
(re.compile(r"rm\s+-(?:rf|fr)\s+(?:/|~)(?=[\s'\";`)]|$)", re.MULTILINE),
|
|
27
27
|
"HIGH", "destructive"),
|
|
28
28
|
(re.compile(r"base64\s+(?:-d|-D|--decode)\b[^\n]*\|\s*(?:ba|z)?sh\b"),
|
|
29
29
|
"HIGH", "obfuscated-exec"),
|
|
@@ -3,6 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
|
|
4
4
|
import argparse
|
|
5
5
|
import json
|
|
6
|
+
from contextlib import suppress
|
|
6
7
|
|
|
7
8
|
from .. import cliparse, spin
|
|
8
9
|
from ..core import catalog, config, gitutil, journal, lockfile, paths, registry, staleness, store, util
|
|
@@ -145,17 +146,15 @@ def cmd_untap(argv) -> int:
|
|
|
145
146
|
return 0
|
|
146
147
|
|
|
147
148
|
|
|
148
|
-
def _tap_updated(tap:
|
|
149
|
+
def _tap_updated(tap: registry.Tap) -> str:
|
|
149
150
|
"""Last-commit date of a tap clone, else the cache's generated age."""
|
|
150
151
|
if tap.is_cloned:
|
|
151
|
-
|
|
152
|
+
with suppress(BoostError):
|
|
152
153
|
# --date=short --format=%cd == %cs, but works on git < 2.21 too
|
|
153
154
|
proc = gitutil.run(["-C", str(tap.path), "log", "-1",
|
|
154
155
|
"--date=short", "--format=%cd"], check=False)
|
|
155
156
|
if proc.returncode == 0 and proc.stdout.strip():
|
|
156
157
|
return proc.stdout.strip()
|
|
157
|
-
except BoostError:
|
|
158
|
-
pass
|
|
159
158
|
try:
|
|
160
159
|
data = json.loads(tap.cache_file.read_text(encoding="utf-8"))
|
|
161
160
|
return util.rel_time(data.get("generated", ""))
|
|
@@ -26,7 +26,7 @@ from . import frontmatter
|
|
|
26
26
|
|
|
27
27
|
# Public: the format id shown in `--to`/errors -> its renderer.
|
|
28
28
|
# Populated at the bottom once the render_* functions are defined.
|
|
29
|
-
FORMATS: Dict[str,
|
|
29
|
+
FORMATS: Dict[str, Callable[..., str]] = {}
|
|
30
30
|
|
|
31
31
|
# Subagent (crew member) directories: a Markdown file under one of these, at any
|
|
32
32
|
# depth beneath a skill, is one of the skill's subagents — so both a flat
|
|
@@ -401,10 +401,8 @@ def render_crew(workflow: str, description: str, specs: List[AgentSpec],
|
|
|
401
401
|
|
|
402
402
|
parts = [_crew_header("crewai", workflow, description), "\n".join(imports) + "\n", "\n"]
|
|
403
403
|
if tools:
|
|
404
|
-
parts.
|
|
405
|
-
|
|
406
|
-
parts.append("\n".join(blocks))
|
|
407
|
-
parts.append("\n" + crew)
|
|
404
|
+
parts.extend(("\n".join(_tool_stub(t, "@tool(%s)" % _py_str(t)) for t in tools), "\n"))
|
|
405
|
+
parts.extend(("\n".join(blocks), "\n" + crew))
|
|
408
406
|
return "".join(parts)
|
|
409
407
|
|
|
410
408
|
|
|
@@ -439,25 +437,22 @@ def render_graph(workflow: str, description: str, specs: List[AgentSpec],
|
|
|
439
437
|
for ident, spec in zip(idents, specs))
|
|
440
438
|
lines.append("")
|
|
441
439
|
for ident in idents:
|
|
442
|
-
lines.
|
|
443
|
-
|
|
444
|
-
lines.
|
|
445
|
-
lines.append(" builder = StateGraph(MessagesState)")
|
|
440
|
+
lines.extend((" def %s_node(state):" % ident,
|
|
441
|
+
" return {\"messages\": %s.invoke(state)[\"messages\"]}" % ident))
|
|
442
|
+
lines.extend(("", " builder = StateGraph(MessagesState)"))
|
|
446
443
|
lines.extend(" builder.add_node(%s, %s_node)" % (_py_str(ident), ident)
|
|
447
444
|
for ident in idents)
|
|
448
445
|
prev = "START"
|
|
449
446
|
for ident in idents:
|
|
450
447
|
lines.append(" builder.add_edge(%s, %s)" % (prev, _py_str(ident)))
|
|
451
448
|
prev = _py_str(ident)
|
|
452
|
-
lines.
|
|
453
|
-
lines.append(" return builder.compile()")
|
|
449
|
+
lines.extend((" builder.add_edge(%s, END)" % prev, " return builder.compile()"))
|
|
454
450
|
factory = "def build_%s(%s):\n%s\n" % (_ident(workflow), sig, "\n".join(lines))
|
|
455
451
|
|
|
456
452
|
parts = [_crew_header("langgraph", workflow, description),
|
|
457
453
|
"\n".join(imports) + "\n", "\n", prompts, "\n"]
|
|
458
454
|
if tools:
|
|
459
|
-
parts.
|
|
460
|
-
parts.append("\n\n")
|
|
455
|
+
parts.extend(("\n".join(_tool_stub(t, "@tool") for t in tools), "\n\n"))
|
|
461
456
|
parts.append(factory)
|
|
462
457
|
return "".join(parts)
|
|
463
458
|
|
|
@@ -465,7 +460,7 @@ def render_graph(workflow: str, description: str, specs: List[AgentSpec],
|
|
|
465
460
|
# Multi-agent (crew/graph) renderers, keyed by the same format id as FORMATS.
|
|
466
461
|
# A format absent here has no multi-agent path; the command layer falls back to
|
|
467
462
|
# the single-agent renderer (flattening the skill to its primary agent).
|
|
468
|
-
MULTI_FORMATS: Dict[str,
|
|
463
|
+
MULTI_FORMATS: Dict[str, Callable[..., str]] = {
|
|
469
464
|
"crewai": render_crew,
|
|
470
465
|
"langgraph": render_graph,
|
|
471
466
|
}
|
|
@@ -111,7 +111,9 @@ def _ask_api(prompt: str, system: Optional[str], model: str,
|
|
|
111
111
|
|
|
112
112
|
def extract_markdown(text: str) -> str:
|
|
113
113
|
"""Strip a ```markdown fence if the model wrapped its answer in one."""
|
|
114
|
-
|
|
114
|
+
# `or ""`: callers hand this a model reply, which is None when the call
|
|
115
|
+
# failed — tolerating None here is tested behavior, not dead defense.
|
|
116
|
+
t = (text or "").strip() # noqa: FURB143
|
|
115
117
|
if t.startswith("```"):
|
|
116
118
|
lines = t.splitlines()
|
|
117
119
|
if lines[0].startswith("```"):
|
|
@@ -30,7 +30,7 @@ from typing import List, Set
|
|
|
30
30
|
NETWORK = "network"
|
|
31
31
|
SHELL = "shell"
|
|
32
32
|
FILESYSTEM = "filesystem"
|
|
33
|
-
KNOWN:
|
|
33
|
+
KNOWN: tuple[str, ...] = (NETWORK, SHELL, FILESYSTEM)
|
|
34
34
|
|
|
35
35
|
# Aliases an author might write for a bucket, folded to the canonical name.
|
|
36
36
|
_ALIASES = {
|
|
@@ -60,7 +60,8 @@ _TELLS = {
|
|
|
60
60
|
r"\bwrite_text\b", r"\bopen\([^)]*['\"][wa]", r"\brmdir\b",
|
|
61
61
|
],
|
|
62
62
|
}
|
|
63
|
-
_COMPILED = {cap: [re.compile(p, re.
|
|
63
|
+
_COMPILED = {cap: [re.compile(p, re.IGNORECASE) for p in pats]
|
|
64
|
+
for cap, pats in _TELLS.items()}
|
|
64
65
|
|
|
65
66
|
|
|
66
67
|
def declared(meta: dict) -> Set[str]:
|
|
@@ -79,7 +80,7 @@ def unknown(meta: dict) -> Set[str]:
|
|
|
79
80
|
|
|
80
81
|
|
|
81
82
|
def _raw(meta: dict):
|
|
82
|
-
val =
|
|
83
|
+
val = meta.get("capabilities")
|
|
83
84
|
if val in (None, "", False):
|
|
84
85
|
return []
|
|
85
86
|
if isinstance(val, list):
|
|
@@ -18,6 +18,7 @@ that ship in the same GitHub registries:
|
|
|
18
18
|
from __future__ import annotations
|
|
19
19
|
|
|
20
20
|
import json
|
|
21
|
+
import operator
|
|
21
22
|
import os
|
|
22
23
|
import re
|
|
23
24
|
from pathlib import Path
|
|
@@ -155,11 +156,11 @@ def scan_dir(root: Path, tap_name: str = "local", curated: bool = False) -> List
|
|
|
155
156
|
entries.append(_make_entry(root, path, kind, default,
|
|
156
157
|
tap_name, curated, meta, body))
|
|
157
158
|
|
|
158
|
-
entries.sort(key=
|
|
159
|
+
entries.sort(key=operator.itemgetter("skill_md", "name"))
|
|
159
160
|
return entries
|
|
160
161
|
|
|
161
162
|
|
|
162
|
-
def rebuild_tap(tap:
|
|
163
|
+
def rebuild_tap(tap: registry.Tap) -> List[dict]:
|
|
163
164
|
"""Rescan a cloned tap and rewrite its JSON cache file -> entries.
|
|
164
165
|
|
|
165
166
|
Raises BoostError when the tap is not cloned; also drops the
|
|
@@ -192,7 +193,7 @@ def rebuild_tap(tap: "registry.Tap") -> List[dict]:
|
|
|
192
193
|
_ENTRY_CACHE: Dict[str, Tuple[Tuple[int, int], List[dict]]] = {}
|
|
193
194
|
|
|
194
195
|
|
|
195
|
-
def _cached_tap(tap:
|
|
196
|
+
def _cached_tap(tap: registry.Tap) -> Optional[List[dict]]:
|
|
196
197
|
"""Memoized ``skills`` for a tap's cache file, or ``None`` to force a
|
|
197
198
|
rebuild (file missing, unreadable, or corrupt JSON)."""
|
|
198
199
|
p = tap.cache_file
|
|
@@ -215,7 +216,7 @@ def _cached_tap(tap: "registry.Tap") -> Optional[List[dict]]:
|
|
|
215
216
|
return skills
|
|
216
217
|
|
|
217
218
|
|
|
218
|
-
def load_tap(tap:
|
|
219
|
+
def load_tap(tap: registry.Tap, rebuild: bool = False) -> List[dict]:
|
|
219
220
|
"""Return a tap's entries, from the mtime-keyed cache when fresh.
|
|
220
221
|
|
|
221
222
|
`rebuild=True` or a missing/corrupt cache forces a rescan; an
|
|
@@ -244,8 +245,8 @@ def find(name: str, tap: Optional[str] = None) -> List[dict]:
|
|
|
244
245
|
tap, name = name.rsplit(":", 1)
|
|
245
246
|
matches = [e for e in all_entries() if e["name"] == name]
|
|
246
247
|
if tap:
|
|
247
|
-
matches = [e for e in matches
|
|
248
|
-
e["tap"].split("/")[-1]
|
|
248
|
+
matches = [e for e in matches
|
|
249
|
+
if tap in (e["tap"], e["tap"].split("/")[-1])]
|
|
249
250
|
return matches
|
|
250
251
|
|
|
251
252
|
|
|
@@ -293,7 +294,9 @@ def _search_blob(name: str, description: str, meta) -> str:
|
|
|
293
294
|
"""The full lowercased substring-search text for an entry: its name,
|
|
294
295
|
description and flattened frontmatter. Built once at index time and cached
|
|
295
296
|
on the entry as ``search_blob`` so search() never rebuilds it per query."""
|
|
296
|
-
|
|
297
|
+
# `or ""` is load-bearing despite the `str` annotation: search() calls this
|
|
298
|
+
# with e.get("description", ""), which yields None when the key holds None.
|
|
299
|
+
return " ".join([name.lower(), (description or "").lower(), _meta_text(meta)]) # noqa: FURB143
|
|
297
300
|
|
|
298
301
|
|
|
299
302
|
def search(query: str, entries: Optional[List[dict]] = None):
|
|
@@ -112,8 +112,7 @@ def add_hook(scope: str, event: str, name: str, command: str,
|
|
|
112
112
|
project_dir: Optional[Path] = None) -> None:
|
|
113
113
|
"""Idempotently install a boost-managed hook (replaces same-named entry)."""
|
|
114
114
|
data = load(scope, project_dir)
|
|
115
|
-
|
|
116
|
-
event_list = hooks.setdefault(event, [])
|
|
115
|
+
event_list = data.setdefault("hooks", {}).setdefault(event, [])
|
|
117
116
|
# Drop any prior entry we own with this name so re-adding is idempotent.
|
|
118
117
|
_strip(event_list, name)
|
|
119
118
|
block: dict = {}
|
|
@@ -69,7 +69,10 @@ def load_registry_catalog() -> list:
|
|
|
69
69
|
|
|
70
70
|
def _merge(base: dict, override: dict) -> dict:
|
|
71
71
|
out = deepcopy(base)
|
|
72
|
-
|
|
72
|
+
# `or {}`: the only caller feeds this json.loads() of config.json, so a file
|
|
73
|
+
# holding `null` (or `[]`, or any falsy scalar) arrives here as a non-dict —
|
|
74
|
+
# a malformed config must read as "no overrides", never crash the CLI.
|
|
75
|
+
for k, v in (override or {}).items(): # noqa: FURB143
|
|
73
76
|
if isinstance(v, dict) and isinstance(out.get(k), dict):
|
|
74
77
|
out[k] = _merge(out[k], v)
|
|
75
78
|
else:
|
|
@@ -272,8 +272,8 @@ def retrieve(query: str, k: int = 60, kind: Optional[str] = None,
|
|
|
272
272
|
if prev is None or score > prev[0]:
|
|
273
273
|
best[key] = (score, snip)
|
|
274
274
|
ranked = sorted(best.items(), key=lambda kv: (-kv[1][0], kv[0][0]))
|
|
275
|
-
hits: List[Hit] = [
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
275
|
+
hits: List[Hit] = [
|
|
276
|
+
{"entry": live[(name, tap)], "score": score,
|
|
277
|
+
"snippet": snip} # type: ignore[typeddict-item]
|
|
278
|
+
for (name, tap), (score, snip) in ranked[:k]]
|
|
279
279
|
return hits
|
|
@@ -89,12 +89,12 @@ def embed(texts: List[str], input_type: Optional[str] = None,
|
|
|
89
89
|
if not texts:
|
|
90
90
|
return []
|
|
91
91
|
if p == "voyage":
|
|
92
|
-
body = {"input":
|
|
92
|
+
body = {"input": texts.copy(), "model": VOYAGE_MODEL}
|
|
93
93
|
if input_type:
|
|
94
94
|
body["input_type"] = input_type
|
|
95
95
|
return _vectors(_post(VOYAGE_URL, os.environ["VOYAGE_API_KEY"],
|
|
96
96
|
body, timeout), len(texts))
|
|
97
|
-
body = {"input":
|
|
97
|
+
body = {"input": texts.copy(), "model": OPENAI_MODEL}
|
|
98
98
|
return _vectors(_post(OPENAI_URL, os.environ["OPENAI_API_KEY"],
|
|
99
99
|
body, timeout), len(texts))
|
|
100
100
|
|
|
@@ -58,10 +58,8 @@ def salient_terms(s: str) -> Set[str]:
|
|
|
58
58
|
tok = tok.strip("`.,:;()[]{}\"'")
|
|
59
59
|
if tok:
|
|
60
60
|
out.add(tok.lower())
|
|
61
|
-
for m in _CODEISH.findall(s)
|
|
62
|
-
|
|
63
|
-
for m in _FLAG.findall(s):
|
|
64
|
-
out.add(m.lower())
|
|
61
|
+
out.update(m.lower() for m in _CODEISH.findall(s))
|
|
62
|
+
out.update(m.lower() for m in _FLAG.findall(s))
|
|
65
63
|
for m in _ACRONYM.findall(s):
|
|
66
64
|
if m not in _STOP_ACRONYMS:
|
|
67
65
|
out.add(m.lower())
|
|
@@ -13,6 +13,7 @@ Supports the subset actually used by skill files:
|
|
|
13
13
|
"""
|
|
14
14
|
from __future__ import annotations
|
|
15
15
|
|
|
16
|
+
from contextlib import suppress
|
|
16
17
|
from typing import Tuple
|
|
17
18
|
|
|
18
19
|
|
|
@@ -47,14 +48,10 @@ def _scalar(raw: str):
|
|
|
47
48
|
return False
|
|
48
49
|
if low == "null" or s == "~":
|
|
49
50
|
return None
|
|
50
|
-
|
|
51
|
+
with suppress(ValueError):
|
|
51
52
|
return int(s)
|
|
52
|
-
|
|
53
|
-
pass
|
|
54
|
-
try:
|
|
53
|
+
with suppress(ValueError):
|
|
55
54
|
return float(s)
|
|
56
|
-
except ValueError:
|
|
57
|
-
pass
|
|
58
55
|
return s
|
|
59
56
|
|
|
60
57
|
|
|
@@ -15,7 +15,8 @@ rule.
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
17
|
import re
|
|
18
|
-
from typing import List,
|
|
18
|
+
from typing import List, Optional
|
|
19
|
+
from re import Match
|
|
19
20
|
|
|
20
21
|
# An "always / never / must (not) / do not / don't" line, optionally preceded by
|
|
21
22
|
# a list marker. Group 1 = the modal, group 2 = everything after it.
|
|
@@ -30,7 +30,7 @@ class Rule(NamedTuple):
|
|
|
30
30
|
"""
|
|
31
31
|
id: str
|
|
32
32
|
severity: str
|
|
33
|
-
pattern:
|
|
33
|
+
pattern: re.Pattern[str]
|
|
34
34
|
description: str
|
|
35
35
|
|
|
36
36
|
|
|
@@ -46,7 +46,7 @@ class Finding(NamedTuple):
|
|
|
46
46
|
description: str
|
|
47
47
|
|
|
48
48
|
|
|
49
|
-
def _rx(pattern: str) ->
|
|
49
|
+
def _rx(pattern: str) -> re.Pattern[str]:
|
|
50
50
|
return re.compile(pattern, re.IGNORECASE)
|
|
51
51
|
|
|
52
52
|
|