boost-skill-cli 1.0.181__tar.gz → 1.0.183__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.183/.vale/styles/boost/Terminology.yml +17 -0
- boost_skill_cli-1.0.183/.vale/styles/config/vocabularies/boost/accept.txt +72 -0
- boost_skill_cli-1.0.183/.vale.ini +24 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/Makefile +2 -1
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/PKG-INFO +1 -1
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/_version.py +2 -2
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/core/agents.py +3 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/core/ai.py +7 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/core/catalog.py +16 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/core/config.py +8 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/core/dense.py +2 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/core/embed.py +8 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/core/gitutil.py +13 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/core/injectscan.py +9 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/core/journal.py +5 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/core/lockfile.py +26 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/core/logs.py +2 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/core/output.py +18 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/core/paths.py +14 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/core/policy.py +8 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/core/registry.py +21 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/core/secretscan.py +10 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/core/store.py +18 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/core/util.py +12 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_skill_cli.egg-info/PKG-INFO +1 -1
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_skill_cli.egg-info/SOURCES.txt +3 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/docstring-coverage-interrogate.md +3 -3
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/prose-and-terminology-linting-vale.md +3 -3
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap.html +2 -2
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/pyproject.toml +16 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/.gitattributes +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/.gitignore +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/.gitleaks.toml +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/.htmlvalidate.json +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/.markdownlint-cli2.jsonc +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/.pre-commit-config.yaml +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/.stylelintrc.json +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/CLAUDE.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/CONTRIBUTING.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/LICENSE +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/MANIFEST.in +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/README.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/SECURITY.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/__init__.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/__main__.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/cli.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/cliparse.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/commands/__init__.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/commands/bmad.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/commands/configuration.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/commands/discovery.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/commands/hooks.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/commands/info.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/commands/intelligence.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/commands/pkg.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/commands/quality.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/commands/taps.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/commands/team.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/core/__init__.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/core/adapters.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/core/claude_settings.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/core/frontmatter.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/core/imperative.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/core/mcp.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/core/nethttp.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/core/rag.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/core/rules.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/core/serve.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/core/stackprobe.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/core/staleness.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/core/typosquat.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/core/updatediff.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/core/workflows.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/data/registries.json +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/errors.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_cli/spin.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_skill_cli.egg-info/dependency_links.txt +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_skill_cli.egg-info/entry_points.txt +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_skill_cli.egg-info/requires.txt +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/boost_skill_cli.egg-info/top_level.txt +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/.claude/settings.local.json +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/DEBUGGING.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/adapters.html +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/commands.html +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/demo.gif +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/demo.tape +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/design-roadmap.html +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/eval.html +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/index.html +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/mcp-hub.html +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/rag-architecture.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/BOOST-D01.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/BOOST-D02.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/BOOST-D03.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/BOOST-D04.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/BOOST-D05.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/BOOST-D06.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/BOOST-D07.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/BOOST-D08.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/BOOST-D09.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/BOOST-D10.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/BOOST-D11.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/BOOST-D12.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/BOOST-D13.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/BOOST-D14.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/BOOST-D15.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/BOOST-D16.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/BOOST-D17.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/BOOST-D18.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/BOOST-D19.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/BOOST-D20.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/BOOST-D21.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/BOOST-D22.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/BOOST-D23.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/BOOST-D24.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/BOOST-D25.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/BOOST-D26.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/accessibility-audit-pa11y-ci-axe-core.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/atomic-corruption-safe-lock-file-writes.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/atomic-skill-install-temp-dir-swap.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/autonomous-ship-workflow-and-isolated-worktree.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/boost-run-live-agents.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/bring-commands-under-mutation-testing.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/broken-link-and-anchor-checking-lychee.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/browse-crashes-selecting-a-rule-or-workflow.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/build-provenance-slsa-attestations.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/cache-the-catalog-entry-set-across-rag-queries.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/capability-manifest-and-least-privilege-policy.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/clean-env-install-smoke-pip-and-pipx.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/command-reference-docs-site.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/complexity-and-dead-code-radar-xenon-vulture.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/consolidate-skill-staleness-drift-logic-into-cor.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/coverage-dashboard-codecov-free-for-oss.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/coverage-guided-fuzzing-atheris-oss-fuzz.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/crash-recorder-error-paths-core-logs-py.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/dependency-cve-gate-pip-audit.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/doctor-checks-rules-and-workflows.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/end-of-options-guard-on-git-commands.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/extension-free-tests-core-dense-py.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/extract-mcp-http-servers-out-of-configuration-py.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/finish-mutation-hardening-across-core.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/fix-self-update-version-detection-dead-branch.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/fork-safe-network-proxy-handler.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/framework-adapter-langgraph.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/framework-adapter-multi-agent.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/framework-adapters-boost-adapt.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/frontmatter-scalar-over-coercion.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/github-pages-deploy-is-broken-every-push.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/golden-set-statistical-power.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/hash-pinned-reproducible-toolchain-uv-lock.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/html-validation-html-validate.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/install-scope-user-or-project.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/integrity-verification-boost-verify.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/invocation-pid-logging-for-crash-correlation.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/layering-guard-import-linter.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/lighthouse-ci-on-the-pages-site.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/list-rules-and-workflows.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/localize-the-stored-bm25-snippet.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/lockfile-enforcement-and-commit-pinning.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/log-timestamps-mislabeled-utc.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/lowest-version-resolution-uv-resolution-lowest-d.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/make-the-roadmaps-discoverable.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/markdown-consistency-markdownlint-cli2.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/mcp-hub-diagram-node-text-overflow.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/mcp-launch-objc-fork-safety.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/mcp-register-names-server-before-env.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/mcp-startup-self-harden-fork-safety.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/memoize-config-load-in-process.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/modernization-smells-refurb-pyupgrade.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/mutation-hardening-core-frontmatter-py.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/mutation-hardening-core-gitutil-py.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/mutation-hardening-core-store-py.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/one-command-every-env-nox.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/one-shared-atomic-write-helper.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/package-metadata-validation-twine-check-friends.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/patch-coverage-gate-diff-cover.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/performance-regression-gate-pytest-benchmark.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/post-deploy-smoke-headless-load-check.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/pre-release-python-canary-3-14t-free-threaded.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/promote-nav-footer-into-the-shared-style-system.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/prompt-injection-scanning-of-skill-markdown.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/property-based-tests-hypothesis-on-the-parsers.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/prune-ignored-dirs-during-scan-dir-walk.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/quality-dashboard-sonarcloud-free-for-oss.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/ranx-significance-monitor.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/reconcile-the-theme-drift.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/refresh-the-marketing-surface.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/retrieval-quality-eval-harness.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/reuse-helpers-kill-minor-dead-work.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/robust-tag-argument-parsing.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/rule-install-native-materialization.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/runner-egress-monitoring-stepsecurity-harden-run.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/runtime-explain-faithfulness-guardrail.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/sbom-aware-scanning-osv-scanner.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/sbom-on-every-release-cyclonedx-syft.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/scan-and-sync-rules-and-workflows.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/second-type-checker-pyright.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/secret-and-pii-scanning-of-installed-skills.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/secret-scanning-gitleaks-push-protection.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/security-linting-bandit-via-ruff-s-rules.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/shift-left-gate-pre-commit-pre-commit-ci.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/single-imperative-rule-extractor.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/single-tech-stack-prober.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/split-oversized-command-modules.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/startup-and-import-time-budget-x-importtime.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/stop-re-serializing-entry-meta-on-every-search.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/supply-chain-posture-openssf-scorecard.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/surface-every-docs-page-from-the-guide.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/tap-signing-and-provenance-sigstore-minisign.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/theme-asset-linting-stylelint-eslint.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/typo-detection-codespell.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/typosquat-and-name-confusion-detection.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/unify-tilde-two-copies-have-a-boundary-bug.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/untrack-generated-build-noise.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/update-diff-before-apply.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/update-refreshes-rules-and-workflows.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/visual-regression-pass-on-the-guide.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/widen-the-ruff-rule-surface-b-sim-c4-perf-ruf.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/windows-in-the-ci-matrix.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/workflow-install-native-materialization.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/workflow-linting-actionlint.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/workflow-sast-zizmor.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/docs/roadmap/items/workspace-scope-install.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/eslint.config.mjs +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/examples/README.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/examples/adapt-demo.sh +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/examples/boost-run-prototype.sh +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/index.html +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/noxfile.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/scripts/bench_cli.sh +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/scripts/build_command_reference.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/scripts/build_registries.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/scripts/build_roadmap.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/scripts/ensure_eval_corpus.sh +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/scripts/eval_explain.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/scripts/eval_recommend.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/scripts/eval_retrieval.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/scripts/eval_stats_summary.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/scripts/import_budget.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/scripts/mutation_gate.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/setup.cfg +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/style/README.md +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/style/boost.css +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/style/boost.js +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/style/demo.html +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/bdd/features/adapt.feature +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/bdd/features/browse.feature +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/bdd/features/count.feature +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/bdd/features/discover.feature +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/bdd/features/doctor.feature +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/bdd/features/environment.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/bdd/features/explain.feature +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/bdd/features/index.feature +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/bdd/features/install.feature +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/bdd/features/list.feature +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/bdd/features/mcp.feature +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/bdd/features/search.feature +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/bdd/features/steps/cli_steps.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/bdd/features/steps/discovery_steps.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/bdd/features/steps/mcp_steps.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/bdd/features/steps/quality_steps.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/conftest.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/eval/baseline.json +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/eval/explain.jsonl +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/eval/golden.jsonl +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/eval/recommend.jsonl +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/eval/taps.txt +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/functional/test_cli_adapt.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/functional/test_cli_bmad.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/functional/test_cli_configuration.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/functional/test_cli_discovery.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/functional/test_cli_hooks.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/functional/test_cli_info.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/functional/test_cli_intelligence.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/functional/test_cli_pkg.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/functional/test_cli_quality.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/functional/test_cli_taps.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/functional/test_cli_team.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/functional/test_everyday_loop.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/functional/test_property_parsers.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/make_fixture.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/perf/test_benchmarks.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/smoke.sh +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/unit/test_adapters.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/unit/test_agents.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/unit/test_ai.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/unit/test_catalog.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/unit/test_claude_settings.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/unit/test_cliparse.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/unit/test_command_reference_fresh.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/unit/test_config.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/unit/test_dense.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/unit/test_dense_fallback.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/unit/test_docs_pages_linked.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/unit/test_embed.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/unit/test_errors_and_cli_table.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/unit/test_eval_stats_summary.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/unit/test_frontmatter.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/unit/test_gitleaks_config.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/unit/test_gitutil.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/unit/test_imperative.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/unit/test_import_budget.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/unit/test_injectscan.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/unit/test_journal.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/unit/test_lockfile.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/unit/test_logs.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/unit/test_mcp.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/unit/test_mutation_hardening.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/unit/test_nethttp.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/unit/test_output.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/unit/test_paths.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/unit/test_pkg_confusions.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/unit/test_pkg_injection.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/unit/test_pkg_secrets.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/unit/test_policy.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/unit/test_rag.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/unit/test_registries_fresh.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/unit/test_registry.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/unit/test_roadmap_fresh.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/unit/test_rules.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/unit/test_secretscan.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/unit/test_serve.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/unit/test_spin.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/unit/test_stackprobe.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/unit/test_staleness.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/unit/test_store.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/unit/test_token_parity.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/unit/test_typosquat.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/unit/test_updatediff.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/unit/test_util.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/unit/test_version.py +0 -0
- {boost_skill_cli-1.0.181 → boost_skill_cli-1.0.183}/tests/unit/test_workflows.py +0 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
extends: substitution
|
|
2
|
+
message: "Use '%s' instead of '%s'."
|
|
3
|
+
level: error
|
|
4
|
+
ignorecase: false
|
|
5
|
+
# Canonical casing for names that appear in boost's prose. Scope is text only —
|
|
6
|
+
# Vale never looks inside code spans or fences, so `github.com/...` URLs and
|
|
7
|
+
# shell examples are unaffected.
|
|
8
|
+
swap:
|
|
9
|
+
'\bGithub\b': GitHub
|
|
10
|
+
'\bgithub\b(?!\.com)': GitHub
|
|
11
|
+
'\bPypi\b': PyPI
|
|
12
|
+
'\bpypi\b(?!\.org)': PyPI
|
|
13
|
+
'\bMacos\b': macOS
|
|
14
|
+
'\bMacOS\b': macOS
|
|
15
|
+
'\bCrewai\b': CrewAI
|
|
16
|
+
'\bLanggraph\b': LangGraph
|
|
17
|
+
'\bjavascript\b': JavaScript
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
agentic
|
|
2
|
+
allowlisted
|
|
3
|
+
argparse
|
|
4
|
+
bmad
|
|
5
|
+
bookended
|
|
6
|
+
CI's
|
|
7
|
+
codespell
|
|
8
|
+
config
|
|
9
|
+
configs
|
|
10
|
+
cyclomatic
|
|
11
|
+
Dependabot
|
|
12
|
+
deps
|
|
13
|
+
Dev
|
|
14
|
+
docsite
|
|
15
|
+
DSPy
|
|
16
|
+
else's
|
|
17
|
+
env
|
|
18
|
+
evals
|
|
19
|
+
freemium
|
|
20
|
+
frontmatter
|
|
21
|
+
gitignored
|
|
22
|
+
glassmorphic
|
|
23
|
+
hardcode
|
|
24
|
+
jonnyeclectic
|
|
25
|
+
jonnyeclectic's
|
|
26
|
+
langchain
|
|
27
|
+
lowercasing
|
|
28
|
+
mcp
|
|
29
|
+
mergeable
|
|
30
|
+
mutmut
|
|
31
|
+
mypy
|
|
32
|
+
npm
|
|
33
|
+
Pinecone
|
|
34
|
+
pytest
|
|
35
|
+
rebased
|
|
36
|
+
reindex
|
|
37
|
+
repo
|
|
38
|
+
repo's
|
|
39
|
+
repos
|
|
40
|
+
rerank
|
|
41
|
+
Rerank
|
|
42
|
+
reranking
|
|
43
|
+
ruleset
|
|
44
|
+
rulesets
|
|
45
|
+
Rulesets
|
|
46
|
+
sandboxed
|
|
47
|
+
sandboxing
|
|
48
|
+
stderr
|
|
49
|
+
Stdlib
|
|
50
|
+
stdlib
|
|
51
|
+
stdout
|
|
52
|
+
subagents
|
|
53
|
+
subcommand
|
|
54
|
+
teardown
|
|
55
|
+
tempdir
|
|
56
|
+
toggleable
|
|
57
|
+
Tokenization
|
|
58
|
+
tokenization
|
|
59
|
+
toolkits
|
|
60
|
+
traceback
|
|
61
|
+
tracebacks
|
|
62
|
+
unkilled
|
|
63
|
+
unstaged
|
|
64
|
+
untap
|
|
65
|
+
venv
|
|
66
|
+
venvs
|
|
67
|
+
Weaviate
|
|
68
|
+
webfont
|
|
69
|
+
wordmark
|
|
70
|
+
worktree
|
|
71
|
+
worktrees
|
|
72
|
+
zsh
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
; Vale — prose & terminology linting for the contributor-facing Markdown
|
|
2
|
+
; surfaces (the same set markdownlint covers). Two things are enforced:
|
|
3
|
+
; 1. Vale.Spelling with the boost vocabulary (.vale/styles/config/
|
|
4
|
+
; vocabularies/boost/accept.txt) — catches future typos codespell's
|
|
5
|
+
; dictionary misses, without nagging on the project's technical terms.
|
|
6
|
+
; 2. boost.Terminology — canonical casing for product names (GitHub, PyPI,
|
|
7
|
+
; macOS, ...) in prose. Code spans and fences are never checked.
|
|
8
|
+
; Run locally: vale README.md CONTRIBUTING.md docs/*.md
|
|
9
|
+
StylesPath = .vale/styles
|
|
10
|
+
MinAlertLevel = warning
|
|
11
|
+
Vocab = boost
|
|
12
|
+
|
|
13
|
+
[*.md]
|
|
14
|
+
BasedOnStyles = Vale, boost
|
|
15
|
+
; accept.txt is a spelling allowlist, not canonical casing — MCP vs mcp both fine.
|
|
16
|
+
Vale.Terms = NO
|
|
17
|
+
|
|
18
|
+
; Roadmap card bodies are HTML-in-Markdown copy rendered by build_roadmap.py,
|
|
19
|
+
; and .claude/ is agent-harness config — neither is standalone prose.
|
|
20
|
+
[docs/roadmap/items/*.md]
|
|
21
|
+
BasedOnStyles =
|
|
22
|
+
|
|
23
|
+
[.claude/**/*.md]
|
|
24
|
+
BasedOnStyles =
|
|
@@ -14,7 +14,7 @@ EVAL_HOME := $(CURDIR)/.eval-home
|
|
|
14
14
|
|
|
15
15
|
venv:
|
|
16
16
|
python3 -m venv $(VENV)
|
|
17
|
-
$(VENV)/bin/pip -q install pytest pytest-cov coverage mutmut ruff mypy codespell hypothesis import-linter diff-cover vulture xenon pyright
|
|
17
|
+
$(VENV)/bin/pip -q install pytest pytest-cov coverage mutmut ruff mypy codespell hypothesis import-linter diff-cover vulture xenon pyright interrogate
|
|
18
18
|
|
|
19
19
|
unit:
|
|
20
20
|
$(PYTEST) tests/unit -q
|
|
@@ -49,6 +49,7 @@ lint:
|
|
|
49
49
|
$(VENV)/bin/lint-imports
|
|
50
50
|
$(VENV)/bin/vulture boost_cli --min-confidence 80
|
|
51
51
|
$(VENV)/bin/xenon --max-absolute F --max-modules E --max-average B boost_cli
|
|
52
|
+
$(VENV)/bin/interrogate boost_cli/core
|
|
52
53
|
$(VENV)/bin/codespell boost_cli docs README.md
|
|
53
54
|
@command -v actionlint >/dev/null 2>&1 && actionlint || echo "actionlint not on PATH — skipping (CI enforces it)"
|
|
54
55
|
$(PY) scripts/build_registries.py --check
|
|
@@ -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.183'
|
|
22
|
+
__version_tuple__ = version_tuple = (1, 0, 183)
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -21,13 +21,16 @@ def known_agents() -> Dict[str, dict]:
|
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
def enabled_agents() -> Dict[str, Path]:
|
|
24
|
+
"""{name: dir Path} for just the agents whose "enabled" flag is true."""
|
|
24
25
|
return {n: s["dir"] for n, s in known_agents().items() if s["enabled"]}
|
|
25
26
|
|
|
26
27
|
|
|
27
28
|
def display_name(agent: str) -> str:
|
|
29
|
+
"""`claude-code` -> "Claude Code"; unknown names pass through unchanged."""
|
|
28
30
|
return DISPLAY.get(agent, agent)
|
|
29
31
|
|
|
30
32
|
|
|
31
33
|
def ensure_agent_dirs() -> None:
|
|
34
|
+
"""Create every enabled agent's skills dir (`mkdir -p`, idempotent)."""
|
|
32
35
|
for d in enabled_agents().values():
|
|
33
36
|
d.mkdir(parents=True, exist_ok=True)
|
|
@@ -20,18 +20,25 @@ API_URL = "https://api.anthropic.com/v1/messages"
|
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
def enabled() -> bool:
|
|
23
|
+
"""Return True when `ai.enabled` is on and BOOST_NO_AI is unset."""
|
|
23
24
|
return bool(config.get("ai.enabled", True)) and not os.environ.get("BOOST_NO_AI")
|
|
24
25
|
|
|
25
26
|
|
|
26
27
|
def available() -> bool:
|
|
28
|
+
"""Return True when AI is enabled and a backend exists: the `claude`
|
|
29
|
+
|
|
30
|
+
CLI on PATH or ANTHROPIC_API_KEY set.
|
|
31
|
+
"""
|
|
27
32
|
return enabled() and (has_cli() or bool(os.environ.get("ANTHROPIC_API_KEY")))
|
|
28
33
|
|
|
29
34
|
|
|
30
35
|
def has_cli() -> bool:
|
|
36
|
+
"""Return True when the `claude` CLI is on PATH."""
|
|
31
37
|
return shutil.which("claude") is not None
|
|
32
38
|
|
|
33
39
|
|
|
34
40
|
def fallback_note() -> str:
|
|
41
|
+
"""Return the one-line hint shown when a command degrades to heuristics."""
|
|
35
42
|
return ("AI features need the `claude` CLI on PATH or ANTHROPIC_API_KEY set "
|
|
36
43
|
"— using the heuristic fallback")
|
|
37
44
|
|
|
@@ -102,6 +102,11 @@ def _classify_workflow(path: Path, meta: dict) -> bool:
|
|
|
102
102
|
|
|
103
103
|
|
|
104
104
|
def scan_dir(root: Path, tap_name: str = "local", curated: bool = False) -> List[dict]:
|
|
105
|
+
"""Walk `root` and index every skill/rule/workflow into entry dicts.
|
|
106
|
+
|
|
107
|
+
Files inside a SKILL.md dir belong to that skill, never re-indexed;
|
|
108
|
+
output is sorted by (skill_md, name) regardless of walk order.
|
|
109
|
+
"""
|
|
105
110
|
root = Path(root)
|
|
106
111
|
entries: List[dict] = []
|
|
107
112
|
skill_dirs: Set[Path] = set()
|
|
@@ -155,6 +160,11 @@ def scan_dir(root: Path, tap_name: str = "local", curated: bool = False) -> List
|
|
|
155
160
|
|
|
156
161
|
|
|
157
162
|
def rebuild_tap(tap: "registry.Tap") -> List[dict]:
|
|
163
|
+
"""Rescan a cloned tap and rewrite its JSON cache file -> entries.
|
|
164
|
+
|
|
165
|
+
Raises BoostError when the tap is not cloned; also drops the
|
|
166
|
+
in-process entry cache so an immediate load sees the rebuild.
|
|
167
|
+
"""
|
|
158
168
|
if not tap.is_cloned:
|
|
159
169
|
raise BoostError("tap %s is not cloned" % tap.name,
|
|
160
170
|
hint="run `boost update %s`" % tap.name)
|
|
@@ -206,6 +216,11 @@ def _cached_tap(tap: "registry.Tap") -> Optional[List[dict]]:
|
|
|
206
216
|
|
|
207
217
|
|
|
208
218
|
def load_tap(tap: "registry.Tap", rebuild: bool = False) -> List[dict]:
|
|
219
|
+
"""Return a tap's entries, from the mtime-keyed cache when fresh.
|
|
220
|
+
|
|
221
|
+
`rebuild=True` or a missing/corrupt cache forces a rescan; an
|
|
222
|
+
uncloned tap yields `[]`.
|
|
223
|
+
"""
|
|
209
224
|
if not rebuild:
|
|
210
225
|
cached = _cached_tap(tap)
|
|
211
226
|
if cached is not None:
|
|
@@ -216,6 +231,7 @@ def load_tap(tap: "registry.Tap", rebuild: bool = False) -> List[dict]:
|
|
|
216
231
|
|
|
217
232
|
|
|
218
233
|
def all_entries() -> List[dict]:
|
|
234
|
+
"""Return the entries of every configured tap, concatenated."""
|
|
219
235
|
out: List[dict] = []
|
|
220
236
|
for tap in registry.list_taps():
|
|
221
237
|
out.extend(load_tap(tap))
|
|
@@ -124,18 +124,25 @@ def _cached() -> dict:
|
|
|
124
124
|
|
|
125
125
|
|
|
126
126
|
def load() -> dict:
|
|
127
|
+
"""Return a deep copy of the merged config, safe for callers to mutate."""
|
|
127
128
|
# A defensive copy so callers can mutate the result (set_value/unset do)
|
|
128
129
|
# without corrupting the shared cache.
|
|
129
130
|
return deepcopy(_cached())
|
|
130
131
|
|
|
131
132
|
|
|
132
133
|
def save(cfg: dict) -> None:
|
|
134
|
+
"""Atomically write `cfg` to `~/.boost/config.json`, creating dirs first."""
|
|
133
135
|
paths.ensure_dirs()
|
|
134
136
|
util.atomic_write_text(
|
|
135
137
|
paths.config_path(), json.dumps(cfg, indent=2, sort_keys=False) + "\n")
|
|
136
138
|
|
|
137
139
|
|
|
138
140
|
def get(dotted: str, default=None):
|
|
141
|
+
"""Look up a dotted key (`ai.model`) in the merged config.
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
Returns a deep copy of the value, or `default` if any part is missing.
|
|
145
|
+
"""
|
|
139
146
|
node = _cached()
|
|
140
147
|
for part in dotted.split("."):
|
|
141
148
|
if not isinstance(node, dict) or part not in node:
|
|
@@ -162,6 +169,7 @@ def set_value(dotted: str, raw: str) -> None:
|
|
|
162
169
|
|
|
163
170
|
|
|
164
171
|
def unset(dotted: str) -> bool:
|
|
172
|
+
"""Delete a dotted key and save; True if removed, False (no write) if absent."""
|
|
165
173
|
cfg = load()
|
|
166
174
|
node: Any = cfg
|
|
167
175
|
parts = dotted.split(".")
|
|
@@ -35,10 +35,12 @@ def _load():
|
|
|
35
35
|
|
|
36
36
|
|
|
37
37
|
def have_backend() -> bool:
|
|
38
|
+
"""True when the ``sqlite-vec`` backend (the ``[rag]`` extra) imports."""
|
|
38
39
|
return _load() is not None
|
|
39
40
|
|
|
40
41
|
|
|
41
42
|
def db_path() -> Path:
|
|
43
|
+
"""Path of the vector store: ``rag_vectors.sqlite`` in the cache dir."""
|
|
42
44
|
return paths.cache_dir() / "rag_vectors.sqlite"
|
|
43
45
|
|
|
44
46
|
|
|
@@ -29,6 +29,7 @@ _DIMS = {VOYAGE_MODEL: 1024, OPENAI_MODEL: 1536}
|
|
|
29
29
|
|
|
30
30
|
|
|
31
31
|
def enabled() -> bool:
|
|
32
|
+
"""True unless the ``BOOST_NO_EMBED`` kill-switch is set."""
|
|
32
33
|
return not os.environ.get("BOOST_NO_EMBED")
|
|
33
34
|
|
|
34
35
|
|
|
@@ -44,10 +45,12 @@ def provider() -> Optional[str]:
|
|
|
44
45
|
|
|
45
46
|
|
|
46
47
|
def available() -> bool:
|
|
48
|
+
"""True when embeddings are enabled and a provider key is present."""
|
|
47
49
|
return provider() is not None
|
|
48
50
|
|
|
49
51
|
|
|
50
52
|
def model() -> Optional[str]:
|
|
53
|
+
"""The active provider's model name, or None when unconfigured."""
|
|
51
54
|
p = provider()
|
|
52
55
|
if p == "voyage":
|
|
53
56
|
return VOYAGE_MODEL
|
|
@@ -57,11 +60,16 @@ def model() -> Optional[str]:
|
|
|
57
60
|
|
|
58
61
|
|
|
59
62
|
def dimension() -> Optional[int]:
|
|
63
|
+
"""Output vector dimension of the active model, or None when
|
|
64
|
+
|
|
65
|
+
unconfigured. Stored in the index so a model switch forces a rebuild.
|
|
66
|
+
"""
|
|
60
67
|
m = model()
|
|
61
68
|
return _DIMS.get(m) if m is not None else None
|
|
62
69
|
|
|
63
70
|
|
|
64
71
|
def fallback_note() -> str:
|
|
72
|
+
"""The one-line hint shown when dense search degrades to BM25."""
|
|
65
73
|
return ("dense search needs the `rag` extra and VOYAGE_API_KEY or "
|
|
66
74
|
"OPENAI_API_KEY — using the BM25 full-content engine")
|
|
67
75
|
|
|
@@ -10,11 +10,17 @@ from ..errors import BoostError
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
def has_git() -> bool:
|
|
13
|
+
"""Return True when a `git` executable is on PATH."""
|
|
13
14
|
return shutil.which("git") is not None
|
|
14
15
|
|
|
15
16
|
|
|
16
17
|
def run(args: List[str], cwd: Optional[Path] = None, check: bool = True,
|
|
17
18
|
timeout: int = 300) -> subprocess.CompletedProcess:
|
|
19
|
+
"""Run `git *args` with captured text output; return the CompletedProcess.
|
|
20
|
+
|
|
21
|
+
Raises BoostError if git is missing, on timeout, or (when `check`)
|
|
22
|
+
on nonzero exit.
|
|
23
|
+
"""
|
|
18
24
|
if not has_git():
|
|
19
25
|
raise BoostError("git is required but was not found on PATH",
|
|
20
26
|
hint="install git, e.g. `xcode-select --install` or `brew install git`")
|
|
@@ -38,6 +44,10 @@ _UNSAFE_TRANSPORTS = ("ext::", "file::", "fd::")
|
|
|
38
44
|
|
|
39
45
|
|
|
40
46
|
def clone_shallow(url: str, dest: Path) -> None:
|
|
47
|
+
"""Shallow-clone (`--depth 1`) `url` into `dest`, creating parent dirs.
|
|
48
|
+
|
|
49
|
+
Raises BoostError for unsafe remote-helper transports like `ext::`.
|
|
50
|
+
"""
|
|
41
51
|
if url.lstrip().lower().startswith(_UNSAFE_TRANSPORTS):
|
|
42
52
|
raise BoostError(
|
|
43
53
|
"refusing to clone via unsafe git transport: %s" % url,
|
|
@@ -61,11 +71,13 @@ def pull(repo: Path) -> str:
|
|
|
61
71
|
|
|
62
72
|
|
|
63
73
|
def head_commit(repo: Path) -> str:
|
|
74
|
+
"""Return the full HEAD commit hash of `repo`, or "" if unresolvable."""
|
|
64
75
|
proc = run(["-C", str(repo), "rev-parse", "HEAD"], check=False)
|
|
65
76
|
return proc.stdout.strip() if proc.returncode == 0 else ""
|
|
66
77
|
|
|
67
78
|
|
|
68
79
|
def remote_url(repo: Path) -> str:
|
|
80
|
+
"""Return the URL of `repo`'s `origin` remote, or "" if it has none."""
|
|
69
81
|
proc = run(["-C", str(repo), "remote", "get-url", "origin"], check=False)
|
|
70
82
|
return proc.stdout.strip() if proc.returncode == 0 else ""
|
|
71
83
|
|
|
@@ -78,4 +90,5 @@ def log_for_path(repo: Path, rel_path: str = ".", n: int = 20) -> List[str]:
|
|
|
78
90
|
|
|
79
91
|
|
|
80
92
|
def is_repo(path: Path) -> bool:
|
|
93
|
+
"""Return True when `path` contains a `.git` entry."""
|
|
81
94
|
return (Path(path) / ".git").exists()
|
|
@@ -23,6 +23,11 @@ _SEVERITY_RANK = {"high": 3, "medium": 2, "low": 1}
|
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
class Rule(NamedTuple):
|
|
26
|
+
"""One curated detection pattern applied per line of scanned text.
|
|
27
|
+
|
|
28
|
+
``id`` is stable for callers/tests to key on; ``severity`` is one
|
|
29
|
+
of "high", "medium", or "low".
|
|
30
|
+
"""
|
|
26
31
|
id: str
|
|
27
32
|
severity: str
|
|
28
33
|
pattern: "re.Pattern[str]"
|
|
@@ -30,6 +35,10 @@ class Rule(NamedTuple):
|
|
|
30
35
|
|
|
31
36
|
|
|
32
37
|
class Finding(NamedTuple):
|
|
38
|
+
"""One rule match on one line of scanned text.
|
|
39
|
+
|
|
40
|
+
``line`` is 1-based; ``snippet`` is the offending line, trimmed.
|
|
41
|
+
"""
|
|
33
42
|
rule_id: str
|
|
34
43
|
severity: str
|
|
35
44
|
line: int # 1-based line number the pattern matched on
|
|
@@ -14,6 +14,10 @@ ROTATE_KEEP = 2500
|
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
def log(action: str, subject: str = "", **fields) -> None:
|
|
17
|
+
"""Append one event line to the pulse feed, rotating when oversized.
|
|
18
|
+
|
|
19
|
+
None-valued keyword fields are dropped from the record.
|
|
20
|
+
"""
|
|
17
21
|
paths.ensure_dirs()
|
|
18
22
|
event = {"ts": util.now_iso(), "user": util.user(), "action": action,
|
|
19
23
|
"subject": subject}
|
|
@@ -46,6 +50,7 @@ def events(n: Optional[int] = None, action: Optional[str] = None,
|
|
|
46
50
|
|
|
47
51
|
|
|
48
52
|
def rotation_healthy() -> bool:
|
|
53
|
+
"""True when the pulse feed is absent or at most ROTATE_AT lines long."""
|
|
49
54
|
p = paths.pulse_path()
|
|
50
55
|
if not p.exists():
|
|
51
56
|
return True
|
|
@@ -25,6 +25,11 @@ def _skeleton() -> dict:
|
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
def read() -> dict:
|
|
28
|
+
"""Load the lock file, guaranteeing skills/rules/workflows keys.
|
|
29
|
+
|
|
30
|
+
Missing file -> empty skeleton; a corrupt file is preserved as
|
|
31
|
+
``<lock>.corrupt`` before falling back to the skeleton.
|
|
32
|
+
"""
|
|
28
33
|
p = paths.lockfile_path()
|
|
29
34
|
if not p.exists():
|
|
30
35
|
return _skeleton() # empty: never installed anything yet
|
|
@@ -65,6 +70,11 @@ def _preserve_corrupt(p) -> None:
|
|
|
65
70
|
|
|
66
71
|
|
|
67
72
|
def write(lock: dict) -> None:
|
|
73
|
+
"""Snapshot the existing lock to history, then write ``lock`` atomically.
|
|
74
|
+
|
|
75
|
+
Stamps ``version``/``updated`` on ``lock`` in place and prunes
|
|
76
|
+
history to the newest HISTORY_KEEP snapshots.
|
|
77
|
+
"""
|
|
68
78
|
paths.ensure_dirs()
|
|
69
79
|
p = paths.lockfile_path()
|
|
70
80
|
if p.exists():
|
|
@@ -96,16 +106,19 @@ def _prune_history() -> None:
|
|
|
96
106
|
|
|
97
107
|
|
|
98
108
|
def get_skill(name: str) -> Optional[dict]:
|
|
109
|
+
"""Return the lock entry for skill ``name``, or None if not installed."""
|
|
99
110
|
return read()["skills"].get(name)
|
|
100
111
|
|
|
101
112
|
|
|
102
113
|
def set_skill(name: str, entry: dict) -> None:
|
|
114
|
+
"""Insert or replace the lock entry for skill ``name`` and persist."""
|
|
103
115
|
lock = read()
|
|
104
116
|
lock["skills"][name] = entry
|
|
105
117
|
write(lock)
|
|
106
118
|
|
|
107
119
|
|
|
108
120
|
def remove_skill(name: str) -> bool:
|
|
121
|
+
"""Drop skill ``name`` from the lock; return True if it was present."""
|
|
109
122
|
lock = read()
|
|
110
123
|
if name in lock["skills"]:
|
|
111
124
|
del lock["skills"][name]
|
|
@@ -115,20 +128,24 @@ def remove_skill(name: str) -> bool:
|
|
|
115
128
|
|
|
116
129
|
|
|
117
130
|
def installed() -> dict:
|
|
131
|
+
"""Return the name -> entry mapping of installed skills."""
|
|
118
132
|
return read()["skills"]
|
|
119
133
|
|
|
120
134
|
|
|
121
135
|
def get_rule(name: str) -> Optional[dict]:
|
|
136
|
+
"""Return the lock entry for rule ``name``, or None if not installed."""
|
|
122
137
|
return read()["rules"].get(name)
|
|
123
138
|
|
|
124
139
|
|
|
125
140
|
def set_rule(name: str, entry: dict) -> None:
|
|
141
|
+
"""Insert or replace the lock entry for rule ``name`` and persist."""
|
|
126
142
|
lock = read()
|
|
127
143
|
lock["rules"][name] = entry
|
|
128
144
|
write(lock)
|
|
129
145
|
|
|
130
146
|
|
|
131
147
|
def remove_rule(name: str) -> bool:
|
|
148
|
+
"""Drop rule ``name`` from the lock; return True if it was present."""
|
|
132
149
|
lock = read()
|
|
133
150
|
if name in lock["rules"]:
|
|
134
151
|
del lock["rules"][name]
|
|
@@ -138,20 +155,24 @@ def remove_rule(name: str) -> bool:
|
|
|
138
155
|
|
|
139
156
|
|
|
140
157
|
def installed_rules() -> dict:
|
|
158
|
+
"""Return the name -> entry mapping of installed rules."""
|
|
141
159
|
return read()["rules"]
|
|
142
160
|
|
|
143
161
|
|
|
144
162
|
def get_workflow(name: str) -> Optional[dict]:
|
|
163
|
+
"""Return the lock entry for workflow ``name``, or None if not installed."""
|
|
145
164
|
return read()["workflows"].get(name)
|
|
146
165
|
|
|
147
166
|
|
|
148
167
|
def set_workflow(name: str, entry: dict) -> None:
|
|
168
|
+
"""Insert or replace the lock entry for workflow ``name`` and persist."""
|
|
149
169
|
lock = read()
|
|
150
170
|
lock["workflows"][name] = entry
|
|
151
171
|
write(lock)
|
|
152
172
|
|
|
153
173
|
|
|
154
174
|
def remove_workflow(name: str) -> bool:
|
|
175
|
+
"""Drop workflow ``name`` from the lock; return True if it was present."""
|
|
155
176
|
lock = read()
|
|
156
177
|
if name in lock["workflows"]:
|
|
157
178
|
del lock["workflows"][name]
|
|
@@ -161,6 +182,7 @@ def remove_workflow(name: str) -> bool:
|
|
|
161
182
|
|
|
162
183
|
|
|
163
184
|
def installed_workflows() -> dict:
|
|
185
|
+
"""Return the name -> entry mapping of installed workflows."""
|
|
164
186
|
return read()["workflows"]
|
|
165
187
|
|
|
166
188
|
|
|
@@ -182,6 +204,10 @@ def history_list() -> List[dict]:
|
|
|
182
204
|
|
|
183
205
|
|
|
184
206
|
def history_read(hist_id: str) -> dict:
|
|
207
|
+
"""Return the parsed lock snapshot for history entry ``hist_id``.
|
|
208
|
+
|
|
209
|
+
Raises BoostError (with a `boost replay` hint) if no such entry.
|
|
210
|
+
"""
|
|
185
211
|
p = paths.lock_history_dir() / ("lock-%s.json" % hist_id)
|
|
186
212
|
if not p.exists():
|
|
187
213
|
from ..errors import BoostError
|
|
@@ -67,6 +67,7 @@ def _file_stamp() -> str:
|
|
|
67
67
|
|
|
68
68
|
|
|
69
69
|
def log_path() -> Path:
|
|
70
|
+
"""Return the rotating diagnostic log's path (``~/.boost/logs/boost.log``)."""
|
|
70
71
|
return paths.logs_dir() / "boost.log"
|
|
71
72
|
|
|
72
73
|
|
|
@@ -105,6 +106,7 @@ def _file_enabled() -> bool:
|
|
|
105
106
|
|
|
106
107
|
|
|
107
108
|
def get_logger() -> logging.Logger:
|
|
109
|
+
"""Return the shared ``boost`` logger; :func:`configure` attaches handlers."""
|
|
108
110
|
return logging.getLogger(LOGGER_NAME)
|
|
109
111
|
|
|
110
112
|
|
|
@@ -45,6 +45,11 @@ def harden_console_encoding() -> None:
|
|
|
45
45
|
|
|
46
46
|
|
|
47
47
|
def use_color(stream=None) -> bool:
|
|
48
|
+
"""True when ANSI color should be emitted on `stream` (default stdout).
|
|
49
|
+
|
|
50
|
+
BOOST_COLOR=always/never is boost's explicit override and beats
|
|
51
|
+
NO_COLOR, CLICOLOR_FORCE and the TTY check.
|
|
52
|
+
"""
|
|
48
53
|
# BOOST_COLOR is boost's own explicit override and wins over everything
|
|
49
54
|
# else (most-specific-wins): always/never force it on/off regardless of
|
|
50
55
|
# NO_COLOR, CLICOLOR_FORCE or the TTY check. Anything else (incl. "auto")
|
|
@@ -63,6 +68,7 @@ def use_color(stream=None) -> bool:
|
|
|
63
68
|
|
|
64
69
|
|
|
65
70
|
def c(text: str, *styles: str) -> str:
|
|
71
|
+
"""Wrap text in the given SGR styles + RESET; plain when color is off."""
|
|
66
72
|
if not styles or not use_color():
|
|
67
73
|
return text
|
|
68
74
|
return "".join(styles) + text + RESET
|
|
@@ -193,28 +199,34 @@ def gradient(text: str, stream=None) -> str:
|
|
|
193
199
|
|
|
194
200
|
|
|
195
201
|
def ok(msg: str) -> None:
|
|
202
|
+
"""Print msg as an indented success line with a green check mark."""
|
|
196
203
|
print(" " + role("✓", "success") + " " + msg)
|
|
197
204
|
|
|
198
205
|
|
|
199
206
|
def warn(msg: str) -> None:
|
|
207
|
+
"""Print msg as an indented `!` warning line, all in the warn role."""
|
|
200
208
|
print(" " + role("!", "warn") + " " + role(msg, "warn"))
|
|
201
209
|
|
|
202
210
|
|
|
203
211
|
def err(msg: str, hint: str | None = None) -> None:
|
|
212
|
+
"""Print `Error: msg` to stderr, plus a dim hint line when given."""
|
|
204
213
|
print(c("Error: ", RED, BOLD) + msg, file=sys.stderr)
|
|
205
214
|
if hint:
|
|
206
215
|
print(c(" hint: " + hint, DIM), file=sys.stderr)
|
|
207
216
|
|
|
208
217
|
|
|
209
218
|
def info(msg: str = "") -> None:
|
|
219
|
+
"""Print msg indented two spaces; a blank line when msg is empty."""
|
|
210
220
|
print(" " + msg if msg else "")
|
|
211
221
|
|
|
212
222
|
|
|
213
223
|
def dim(msg: str) -> None:
|
|
224
|
+
"""Print msg in the muted role (dim when color is on)."""
|
|
214
225
|
print(role(msg, "muted"))
|
|
215
226
|
|
|
216
227
|
|
|
217
228
|
def heading(msg: str) -> None:
|
|
229
|
+
"""Print a bold section header led by the accent `==>` marker."""
|
|
218
230
|
# Brand the section marker in the accent role (Aurora cyan — truecolor,
|
|
219
231
|
# 16-color fallback, plain under NO_COLOR) so every command's headers read
|
|
220
232
|
# as one system.
|
|
@@ -333,6 +345,7 @@ def meter(fraction: float, width: int = 4) -> str:
|
|
|
333
345
|
|
|
334
346
|
|
|
335
347
|
def kv(key: str, value: str, width: int = 14) -> None:
|
|
348
|
+
"""Print an indented key/value line: dim key padded to width, then value."""
|
|
336
349
|
print(" " + c(key.ljust(width), DIM) + str(value))
|
|
337
350
|
|
|
338
351
|
|
|
@@ -454,6 +467,11 @@ def table(rows, headers=None) -> None:
|
|
|
454
467
|
|
|
455
468
|
|
|
456
469
|
def confirm(prompt: str, default: bool = False) -> bool:
|
|
470
|
+
"""Ask a yes/no question and return the answer as a bool.
|
|
471
|
+
|
|
472
|
+
BOOST_ASSUME_YES or --yes/-y force True; non-TTY stdin and an empty
|
|
473
|
+
answer return `default`; EOF or Ctrl-C returns False.
|
|
474
|
+
"""
|
|
457
475
|
if os.environ.get("BOOST_ASSUME_YES") or "--yes" in sys.argv or "-y" in sys.argv:
|
|
458
476
|
return True
|
|
459
477
|
if not sys.stdin.isatty():
|