boost-skill-cli 1.0.251__tar.gz → 1.0.253__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.251 → boost_skill_cli-1.0.253}/PKG-INFO +1 -1
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/_version.py +2 -2
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/commands/configuration.py +52 -8
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/commands/discovery.py +5 -17
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/commands/info.py +1 -1
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/commands/team.py +2 -1
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/core/journal.py +8 -2
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/core/util.py +22 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_skill_cli.egg-info/PKG-INFO +1 -1
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/commands.html +4 -3
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/functional/test_cli_configuration.py +148 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/functional/test_cli_info.py +5 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/functional/test_cli_team.py +6 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_journal.py +23 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_util.py +24 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/.gitattributes +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/.gitignore +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/.gitleaks.toml +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/.htmlvalidate.json +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/.lighthouserc.json +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/.lycheeignore +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/.markdownlint-cli2.jsonc +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/.pre-commit-config.yaml +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/.stylelintrc.json +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/.vale/styles/boost/Terminology.yml +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/.vale/styles/config/vocabularies/boost/accept.txt +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/.vale.ini +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/CLAUDE.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/CONTRIBUTING.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/LICENSE +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/MANIFEST.in +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/Makefile +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/README.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/SECURITY.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/__init__.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/__main__.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/cli.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/cliparse.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/commands/__init__.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/commands/_common.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/commands/bmad.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/commands/hooks.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/commands/intelligence.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/commands/pkg.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/commands/quality.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/commands/run.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/commands/safety.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/commands/taps.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/core/__init__.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/core/adapters.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/core/agents.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/core/ai.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/core/capabilities.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/core/catalog.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/core/claude_settings.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/core/config.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/core/dense.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/core/ed25519.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/core/embed.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/core/faithfulness.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/core/frontmatter.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/core/gitutil.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/core/imperative.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/core/injectscan.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/core/integrity.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/core/lockfile.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/core/logs.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/core/mcp.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/core/mcpdecl.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/core/minisign.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/core/nethttp.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/core/output.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/core/paths.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/core/policy.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/core/projectlock.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/core/provenance.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/core/rag.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/core/registry.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/core/resolve.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/core/rules.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/core/scopes.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/core/secretscan.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/core/selfupdate.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/core/serve.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/core/stackprobe.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/core/staleness.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/core/store.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/core/trustaudit.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/core/typosquat.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/core/updatediff.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/core/workflows.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/data/registries.json +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/errors.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_cli/spin.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_skill_cli.egg-info/SOURCES.txt +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_skill_cli.egg-info/dependency_links.txt +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_skill_cli.egg-info/entry_points.txt +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_skill_cli.egg-info/requires.txt +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/boost_skill_cli.egg-info/top_level.txt +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/codecov.yml +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/.claude/settings.local.json +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/DEBUGGING.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/adapters.html +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/carousel/gifs/distill.gif +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/carousel/gifs/doctor.gif +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/carousel/gifs/explain.gif +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/carousel/gifs/hooks.gif +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/carousel/gifs/install.gif +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/carousel/gifs/pulse.gif +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/carousel/gifs/search.gif +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/carousel/gifs/tap.gif +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/carousel/tapes/distill.tape +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/carousel/tapes/doctor.tape +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/carousel/tapes/explain.tape +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/carousel/tapes/hooks.tape +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/carousel/tapes/install.tape +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/carousel/tapes/pulse.tape +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/carousel/tapes/search.tape +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/carousel/tapes/tap.tape +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/carousel.html +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/demo.gif +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/demo.tape +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/design-roadmap.html +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/eval.html +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/index.html +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/mcp-hub.html +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/rag-architecture.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/BOOST-D01.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/BOOST-D02.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/BOOST-D03.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/BOOST-D04.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/BOOST-D05.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/BOOST-D06.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/BOOST-D07.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/BOOST-D08.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/BOOST-D09.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/BOOST-D10.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/BOOST-D11.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/BOOST-D12.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/BOOST-D13.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/BOOST-D14.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/BOOST-D15.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/BOOST-D16.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/BOOST-D17.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/BOOST-D18.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/BOOST-D19.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/BOOST-D20.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/BOOST-D21.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/BOOST-D22.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/BOOST-D23.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/BOOST-D24.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/BOOST-D25.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/BOOST-D26.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/accessibility-audit-pa11y-ci-axe-core.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/adapter-conformance-langgraph-leg-never-ran.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/ai-bridge-silent-failure-logging.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/ambiguous-tap-short-name-resolution.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/atomic-corruption-safe-lock-file-writes.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/atomic-skill-install-temp-dir-swap.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/autonomous-ship-workflow-and-isolated-worktree.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/boost-run-live-agents.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/bring-commands-under-mutation-testing.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/broken-link-and-anchor-checking-lychee.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/browse-crashes-selecting-a-rule-or-workflow.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/build-provenance-slsa-attestations.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/cache-the-catalog-entry-set-across-rag-queries.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/capability-manifest-and-least-privilege-policy.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/ci-job-timeout-minutes.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/ci-summary-step-fails-itself.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/clean-env-install-smoke-pip-and-pipx.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/command-carousel-page.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/command-reference-docs-site.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/complexity-and-dead-code-radar-xenon-vulture.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/consolidate-skill-staleness-drift-logic-into-cor.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/coverage-dashboard-codecov-free-for-oss.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/coverage-guided-fuzzing-atheris-oss-fuzz.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/crash-listing-branch-untested.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/crash-recorder-error-paths-core-logs-py.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/demo-gif-workflow-has-never-succeeded.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/dense-search-fallback-and-stale-tap-pruning.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/dependabot-missing-pip-ecosystem.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/dependency-cve-gate-pip-audit.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/docsite-chrome-and-content-audit.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/docstring-coverage-interrogate.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/doctor-checks-rules-and-workflows.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/end-of-options-guard-on-git-commands.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/extension-free-tests-core-dense-py.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/extract-mcp-http-servers-out-of-configuration-py.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/finish-mutation-hardening-across-core.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/fix-self-update-version-detection-dead-branch.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/fork-safe-network-proxy-handler.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/framework-adapter-langgraph.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/framework-adapter-multi-agent.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/framework-adapters-boost-adapt.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/frontmatter-scalar-over-coercion.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/github-community-health-files.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/github-pages-deploy-is-broken-every-push.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/golden-set-statistical-power.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/hash-pinned-reproducible-toolchain-uv-lock.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/html-validation-html-validate.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/install-docs-never-mentioned-upgrading.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/install-from-path-bypasses-policy-and-pin-checks.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/install-resolves-skill-dependencies.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/install-scope-user-or-project.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/installed-skill-trust-audit.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/integrity-verification-boost-verify.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/invocation-pid-logging-for-crash-correlation.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/journal-rotation-race-and-handle-leak.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/layering-guard-import-linter.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/license-compliance-scanning.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/lighthouse-ci-on-the-pages-site.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/lint-tap-misscopes-rule-workflow-entries.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/list-rules-and-workflows.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/localize-the-stored-bm25-snippet.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/lock-invariant-cannot-parse-extras-pins.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/lockfile-enforcement-and-commit-pinning.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/log-timestamps-mislabeled-utc.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/lowest-version-resolution-uv-resolution-lowest-d.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/main-has-no-branch-protection.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/main-ruleset-ref-pattern-has-literal-quotes.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/make-the-roadmaps-discoverable.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/markdown-consistency-markdownlint-cli2.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/markdownlint-lints-the-fuzz-corpus.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/mcp-aware-skills.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/mcp-hub-diagram-node-text-overflow.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/mcp-launch-objc-fork-safety.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/mcp-register-names-server-before-env.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/mcp-search-before-reinventing.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/mcp-startup-self-harden-fork-safety.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/memoize-config-load-in-process.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/merge-queue-would-deadlock-most-required-checks.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/modernization-smells-refurb-pyupgrade.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/mutation-gate-was-the-whole-critical-path.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/mutation-hardening-core-frontmatter-py.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/mutation-hardening-core-gitutil-py.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/mutation-hardening-core-store-py.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/mypy-strict-mode-for-commands.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/negative-limit-inverts-log-pulse-output.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/onboard-overwrites-generated-files-without-confirm.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/one-command-every-env-nox.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/one-shared-atomic-write-helper.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/package-metadata-validation-twine-check-friends.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/patch-coverage-gate-diff-cover.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/path-traversal-unsanitized-rule-workflow-name.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/performance-regression-gate-pytest-benchmark.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/pin-the-lint-toolchain.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/post-deploy-always-defeated-by-skipped-setup.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/post-deploy-smoke-headless-load-check.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/pre-release-python-canary-3-14t-free-threaded.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/project-scope-across-every-command.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/project-scope-symlink-escape-on-write.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/promote-nav-footer-into-the-shared-style-system.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/prompt-injection-scanning-of-skill-markdown.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/property-based-tests-hypothesis-on-the-parsers.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/prose-and-terminology-linting-vale.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/prune-ignored-dirs-during-scan-dir-walk.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/publish-gate-ignores-pip-audit-and-metadata.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/publish-trigger-was-reachable-from-a-fork.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/pytest-tmpdir-cve-blocked-by-py39-floor.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/quality-dashboard-sonarcloud-free-for-oss.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/ranx-significance-monitor.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/reconcile-the-theme-drift.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/refresh-the-marketing-surface.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/rel-time-tests-race-the-wall-clock.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/required-checks-can-declare-a-check-that-deadlocks-prs.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/required-checks-config-drift.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/retrieval-quality-eval-harness.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/reuse-helpers-kill-minor-dead-work.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/roadmap-html-goes-stale-on-every-rebase.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/robust-tag-argument-parsing.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/ruff-016-widens-the-default-rule-set.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/rule-install-native-materialization.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/runner-egress-monitoring-stepsecurity-harden-run.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/runtime-explain-faithfulness-guardrail.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/sbom-aware-scanning-osv-scanner.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/sbom-on-every-release-cyclonedx-syft.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/sbom-release-event-never-fires.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/scan-and-sync-rules-and-workflows.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/scorecard-findings-triage.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/second-type-checker-pyright.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/secret-and-pii-scanning-of-installed-skills.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/secret-scanning-gitleaks-push-protection.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/security-linting-bandit-via-ruff-s-rules.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/self-update-broken-for-pip-pipx-installs.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/serve-py-traversal-guards-untested.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/shift-left-gate-pre-commit-pre-commit-ci.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/single-imperative-rule-extractor.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/single-tech-stack-prober.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/split-oversized-command-modules.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/startup-and-import-time-budget-x-importtime.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/stop-re-serializing-entry-meta-on-every-search.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/structured-json-log-output-mode.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/supply-chain-posture-openssf-scorecard.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/surface-every-docs-page-from-the-guide.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/sync-deletes-unowned-broken-symlinks.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/tap-signing-and-provenance-sigstore-minisign.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/theme-asset-linting-stylelint-eslint.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/typo-detection-codespell.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/typosquat-and-name-confusion-detection.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/unify-tilde-two-copies-have-a-boundary-bug.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/uninstall-has-no-confirmation-prompt.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/untrack-generated-build-noise.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/update-diff-before-apply.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/update-refreshes-rules-and-workflows.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/update-reinstall-widens-agent-scope.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/visual-regression-pass-on-the-guide.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/widen-the-ruff-rule-surface-b-sim-c4-perf-ruf.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/windows-in-the-ci-matrix.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/wire-bdd-suite-into-ci.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/workflow-install-native-materialization.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/workflow-linting-actionlint.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/workflow-sast-zizmor.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap/items/workspace-scope-install.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/docs/roadmap.html +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/eslint.config.mjs +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/examples/README.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/examples/adapt-demo.sh +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/examples/boost-run-prototype.sh +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/index.html +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/noxfile.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/pyproject.toml +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/requirements/coverage-tools.in +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/requirements/coverage-tools.txt +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/requirements/lint-tools.in +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/requirements/lint-tools.txt +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/requirements/mutation-tools.in +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/requirements/mutation-tools.txt +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/requirements/release-tools.in +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/requirements/release-tools.txt +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/requirements/test-tools.in +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/requirements/test-tools.txt +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/scripts/a11y_check.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/scripts/bench_cli.sh +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/scripts/build_command_reference.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/scripts/build_registries.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/scripts/build_roadmap.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/scripts/check_anchors.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/scripts/check_required_checks.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/scripts/ensure_eval_corpus.sh +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/scripts/eval_explain.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/scripts/eval_recommend.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/scripts/eval_retrieval.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/scripts/eval_stats_summary.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/scripts/import_budget.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/scripts/lock_toolchain.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/scripts/mutation_gate.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/scripts/mutation_shards.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/scripts/mutation_weights.json +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/scripts/perf_gate.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/scripts/post_deploy_smoke.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/scripts/release_preflight.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/setup.cfg +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/sonar-project.properties +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/style/README.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/style/boost.css +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/style/boost.js +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/style/demo.html +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/bdd/features/adapt.feature +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/bdd/features/browse.feature +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/bdd/features/count.feature +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/bdd/features/discover.feature +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/bdd/features/doctor.feature +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/bdd/features/environment.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/bdd/features/explain.feature +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/bdd/features/index.feature +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/bdd/features/install.feature +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/bdd/features/list.feature +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/bdd/features/mcp.feature +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/bdd/features/search.feature +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/bdd/features/steps/cli_steps.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/bdd/features/steps/discovery_steps.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/bdd/features/steps/mcp_steps.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/bdd/features/steps/quality_steps.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/conftest.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/eval/baseline.json +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/eval/explain.jsonl +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/eval/golden.jsonl +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/eval/recommend.jsonl +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/eval/taps.txt +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/functional/test_capabilities_policy.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/functional/test_cli_adapt.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/functional/test_cli_bmad.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/functional/test_cli_discovery.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/functional/test_cli_hooks.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/functional/test_cli_intelligence.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/functional/test_cli_pkg.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/functional/test_cli_quality.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/functional/test_cli_taps.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/functional/test_everyday_loop.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/functional/test_integrity_enforce.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/functional/test_property_parsers.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/functional/test_run.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/functional/test_tap_signing.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/functional/test_workspace_scope.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/fuzz/README.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/fuzz/corpus/frontmatter/01-typical.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/fuzz/corpus/frontmatter/02-lossy-version.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/fuzz/corpus/frontmatter/03-lossy-numbers.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/fuzz/corpus/frontmatter/04-lists.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/fuzz/corpus/frontmatter/05-nested.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/fuzz/corpus/frontmatter/06-empty-block.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/fuzz/corpus/frontmatter/07-unterminated.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/fuzz/corpus/frontmatter/08-none.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/fuzz/corpus/frontmatter/09-unbalanced-quote.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/fuzz/corpus/frontmatter/10-keywords.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/fuzz/corpus/frontmatter/11-crlf.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/fuzz/corpus/frontmatter/12-bom.md +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/fuzz/corpus/registry/01-shorthand.txt +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/fuzz/corpus/registry/02-https.txt +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/fuzz/corpus/registry/03-ssh.txt +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/fuzz/corpus/registry/04-traversal.txt +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/fuzz/corpus/registry/05-empty.txt +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/fuzz/corpus/registry/06-space.txt +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/fuzz/corpus/registry/07-slash.txt +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/fuzz/corpus/registry/08-bare-host.txt +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/fuzz/fuzz_frontmatter.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/fuzz/fuzz_registry.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/make_fixture.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/perf/test_benchmarks.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/smoke.sh +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_a11y_check.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_adapters.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_adapters_multi.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_adapters_runner.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_agents.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_ai.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_capabilities.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_catalog.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_check_anchors.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_claude_settings.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_cliparse.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_command_reference_fresh.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_config.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_dense.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_dense_fallback.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_docs_pages_linked.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_docsite_chrome.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_ed25519.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_embed.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_errors_and_cli_table.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_eval_stats_summary.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_faithfulness.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_frontmatter.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_fuzz_targets.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_gitleaks_config.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_gitutil.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_imperative.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_import_budget.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_injectscan.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_integrity.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_lockfile.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_logs.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_marketing_counts.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_mcp.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_mcpdecl.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_minisign.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_mutation_hardening.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_mutation_shards.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_mutmut_source_paths.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_nethttp.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_output.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_paths.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_perf_gate.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_pkg_confusions.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_pkg_injection.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_pkg_secrets.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_policy.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_post_deploy_smoke.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_projectlock.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_provenance.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_rag.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_registries_fresh.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_registry.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_release_preflight.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_required_checks.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_resolve.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_roadmap_fresh.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_rules.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_scopes.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_secretscan.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_selfupdate.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_serve.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_spin.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_stackprobe.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_staleness.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_store.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_token_parity.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_toolchain_lock.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_trustaudit.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_typosquat.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_updatediff.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_version.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_workflow_timeouts.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/unit/test_workflows.py +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/visual/a11y_check.mjs +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/visual/console_check.mjs +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/visual/package.json +0 -0
- {boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/visual/visual_check.mjs +0 -0
|
@@ -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.253'
|
|
22
|
+
__version_tuple__ = version_tuple = (1, 0, 253)
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
completions, schedule, serve, mcp, self-update."""
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
import argparse
|
|
5
6
|
import json
|
|
6
7
|
import os
|
|
7
8
|
import re
|
|
@@ -401,8 +402,41 @@ jobs:
|
|
|
401
402
|
"""
|
|
402
403
|
|
|
403
404
|
|
|
405
|
+
def _write_onboard_file(dest: Path, content: str, force: bool) -> bool:
|
|
406
|
+
"""Write one generated onboard file; confirm first if it already exists.
|
|
407
|
+
|
|
408
|
+
``boost onboard`` is routinely re-run on a repo that already has its own
|
|
409
|
+
tracked ``.skill-lock.json``, and a bare ``write_text`` there replaces the
|
|
410
|
+
repo's lock with whatever this machine happens to have installed — while
|
|
411
|
+
still reporting "created". Existence has to be checked *before* the write,
|
|
412
|
+
the same way :func:`intelligence._write_generated` already does.
|
|
413
|
+
|
|
414
|
+
Returns True when the file was written.
|
|
415
|
+
"""
|
|
416
|
+
if not dest.exists():
|
|
417
|
+
dest.parent.mkdir(parents=True, exist_ok=True)
|
|
418
|
+
dest.write_text(content, encoding="utf-8")
|
|
419
|
+
out.ok("created %s" % _tilde(dest))
|
|
420
|
+
return True
|
|
421
|
+
try:
|
|
422
|
+
unchanged = dest.read_text(encoding="utf-8") == content
|
|
423
|
+
except (OSError, UnicodeDecodeError):
|
|
424
|
+
unchanged = False # unreadable: treat as different and ask
|
|
425
|
+
if unchanged:
|
|
426
|
+
# Re-running onboard regenerates the workflow byte-for-byte. Prompting
|
|
427
|
+
# to overwrite a file with its own contents is noise, not safety.
|
|
428
|
+
out.info("unchanged %s" % _tilde(dest))
|
|
429
|
+
return False
|
|
430
|
+
if not force and not out.confirm("overwrite %s?" % _tilde(dest)):
|
|
431
|
+
out.info("skipped %s" % _tilde(dest))
|
|
432
|
+
return False
|
|
433
|
+
dest.write_text(content, encoding="utf-8")
|
|
434
|
+
out.ok("updated %s" % _tilde(dest))
|
|
435
|
+
return True
|
|
436
|
+
|
|
437
|
+
|
|
404
438
|
def cmd_onboard(argv) -> int:
|
|
405
|
-
"""boost onboard [--repo DIR] [--pr] [--dry-run]"""
|
|
439
|
+
"""boost onboard [--repo DIR] [--pr] [--dry-run] [--force]"""
|
|
406
440
|
p = cliparse.parser(
|
|
407
441
|
prog="boost onboard",
|
|
408
442
|
description="Add skill-tracker telemetry to a repo & open a PR")
|
|
@@ -411,6 +445,9 @@ def cmd_onboard(argv) -> int:
|
|
|
411
445
|
help="commit on a branch and open a PR with `gh`")
|
|
412
446
|
p.add_argument("--dry-run", action="store_true",
|
|
413
447
|
help="preview the files without writing anything")
|
|
448
|
+
p.add_argument("-f", "--force", action="store_true",
|
|
449
|
+
help="overwrite existing files without confirming")
|
|
450
|
+
p.add_argument("-y", "--yes", action="store_true", help=argparse.SUPPRESS)
|
|
414
451
|
args = p.parse_args(argv)
|
|
415
452
|
|
|
416
453
|
repo = paths.expand(args.repo).resolve()
|
|
@@ -431,7 +468,10 @@ def cmd_onboard(argv) -> int:
|
|
|
431
468
|
|
|
432
469
|
if args.dry_run:
|
|
433
470
|
for rel, content in files:
|
|
434
|
-
|
|
471
|
+
dest = repo / rel
|
|
472
|
+
out.heading("would %s %s"
|
|
473
|
+
% ("overwrite" if dest.exists() else "write",
|
|
474
|
+
_tilde(dest)))
|
|
435
475
|
for line in content.splitlines()[:24]:
|
|
436
476
|
out.dim(" " + line)
|
|
437
477
|
return 0
|
|
@@ -447,17 +487,21 @@ def cmd_onboard(argv) -> int:
|
|
|
447
487
|
raise BoostError("the `gh` CLI is required for --pr",
|
|
448
488
|
hint="brew install gh, or rerun without --pr")
|
|
449
489
|
|
|
450
|
-
for rel, content in files
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
490
|
+
written = [rel for rel, content in files
|
|
491
|
+
if _write_onboard_file(repo / rel, content,
|
|
492
|
+
args.force or args.yes)]
|
|
493
|
+
if not written:
|
|
494
|
+
# Nothing changed, so there is nothing to journal — and nothing for
|
|
495
|
+
# --pr to commit. Branching here would leave an empty branch behind
|
|
496
|
+
# and then fail on `git commit` with no staged changes.
|
|
497
|
+
out.info("nothing to do — %s already onboarded" % _tilde(repo))
|
|
498
|
+
return 0
|
|
455
499
|
journal.log("onboard", _tilde(repo), pr=args.pr or None)
|
|
456
500
|
|
|
457
501
|
if args.pr:
|
|
458
502
|
branch = "boost/onboard-skill-tracker"
|
|
459
503
|
gitutil.run(["-C", str(repo), "checkout", "-b", branch])
|
|
460
|
-
gitutil.run(["-C", str(repo), "add"
|
|
504
|
+
gitutil.run(["-C", str(repo), "add", *written])
|
|
461
505
|
gitutil.run(["-C", str(repo), "commit", "-m",
|
|
462
506
|
"chore: add boost skill tracking (boost onboard)"])
|
|
463
507
|
try:
|
|
@@ -5,7 +5,6 @@ Also exports detect_stack(), shared with the Quality commands.
|
|
|
5
5
|
"""
|
|
6
6
|
from __future__ import annotations
|
|
7
7
|
|
|
8
|
-
import argparse
|
|
9
8
|
import contextlib
|
|
10
9
|
import json
|
|
11
10
|
import operator
|
|
@@ -40,17 +39,6 @@ from ..errors import BoostError
|
|
|
40
39
|
__all__ = ["detect_stack"]
|
|
41
40
|
|
|
42
41
|
|
|
43
|
-
def _positive_int(s: str) -> int:
|
|
44
|
-
"""argparse type for --limit flags: an int that must be >= 1."""
|
|
45
|
-
try:
|
|
46
|
-
v = int(s)
|
|
47
|
-
except ValueError:
|
|
48
|
-
raise argparse.ArgumentTypeError("invalid int value: %r" % s) from None
|
|
49
|
-
if v < 1:
|
|
50
|
-
raise argparse.ArgumentTypeError("must be >= 1")
|
|
51
|
-
return v
|
|
52
|
-
|
|
53
|
-
|
|
54
42
|
_tilde = paths.tilde
|
|
55
43
|
|
|
56
44
|
|
|
@@ -98,7 +86,7 @@ def cmd_search(argv):
|
|
|
98
86
|
p.add_argument("query", nargs="+", help="search terms")
|
|
99
87
|
p.add_argument("--smart", action="store_true",
|
|
100
88
|
help="rerank the top hits with Claude")
|
|
101
|
-
p.add_argument("--limit", type=
|
|
89
|
+
p.add_argument("--limit", type=util.positive_int, default=15,
|
|
102
90
|
help="max results (default 15)")
|
|
103
91
|
p.add_argument("--json", action="store_true", dest="as_json",
|
|
104
92
|
help="machine-readable output")
|
|
@@ -223,7 +211,7 @@ def cmd_index(argv):
|
|
|
223
211
|
p = cliparse.parser(
|
|
224
212
|
prog="boost index",
|
|
225
213
|
description="Build the discovery registry via GitHub Code Search")
|
|
226
|
-
p.add_argument("--limit", type=
|
|
214
|
+
p.add_argument("--limit", type=util.positive_int, default=300,
|
|
227
215
|
help="max skill files to index (default 300)")
|
|
228
216
|
args = p.parse_args(argv)
|
|
229
217
|
if not shutil.which("gh"):
|
|
@@ -329,7 +317,7 @@ def cmd_discover(argv):
|
|
|
329
317
|
prog="boost discover",
|
|
330
318
|
description="Browse & search the GitHub-wide skill discovery index")
|
|
331
319
|
p.add_argument("query", nargs="*", help="filter terms (repo/path substring)")
|
|
332
|
-
p.add_argument("--limit", type=
|
|
320
|
+
p.add_argument("--limit", type=util.positive_int, default=25,
|
|
333
321
|
help="max rows (default 25)")
|
|
334
322
|
p.add_argument("--json", action="store_true", dest="as_json",
|
|
335
323
|
help="machine-readable output")
|
|
@@ -398,7 +386,7 @@ def cmd_recommend(argv):
|
|
|
398
386
|
prog="boost recommend",
|
|
399
387
|
description="Suggest skills based on your project's tech stack")
|
|
400
388
|
p.add_argument("--path", default=".", help="project directory (default: cwd)")
|
|
401
|
-
p.add_argument("--limit", type=
|
|
389
|
+
p.add_argument("--limit", type=util.positive_int, default=8,
|
|
402
390
|
help="max suggestions (default 8)")
|
|
403
391
|
p.add_argument("--json", action="store_true", dest="as_json",
|
|
404
392
|
help="machine-readable output")
|
|
@@ -885,7 +873,7 @@ def cmd_trending(argv):
|
|
|
885
873
|
p = cliparse.parser(
|
|
886
874
|
prog="boost trending",
|
|
887
875
|
description="Show trending skills by install count")
|
|
888
|
-
p.add_argument("--limit", type=
|
|
876
|
+
p.add_argument("--limit", type=util.positive_int, default=10,
|
|
889
877
|
help="max rows (default 10)")
|
|
890
878
|
args = p.parse_args(argv)
|
|
891
879
|
evs = journal.events(action="install")
|
|
@@ -575,7 +575,7 @@ def cmd_log(argv):
|
|
|
575
575
|
ap = cliparse.parser(prog="boost log",
|
|
576
576
|
description="Git log for a skill, or boost's activity log")
|
|
577
577
|
ap.add_argument("name", nargs="?", help="skill to show upstream history for")
|
|
578
|
-
ap.add_argument("-n", "--limit", type=
|
|
578
|
+
ap.add_argument("-n", "--limit", type=util.positive_int, default=20, metavar="N",
|
|
579
579
|
help="max entries (default 20)")
|
|
580
580
|
ap.add_argument("--diagnostics", action="store_true",
|
|
581
581
|
help="show boost's diagnostic log trail (not skill history)")
|
|
@@ -456,7 +456,8 @@ def cmd_pulse(argv) -> int:
|
|
|
456
456
|
p = cliparse.parser(
|
|
457
457
|
prog="boost pulse",
|
|
458
458
|
description="Team activity feed of skill-management events")
|
|
459
|
-
p.add_argument("-n", type=
|
|
459
|
+
p.add_argument("-n", type=util.positive_int, default=20,
|
|
460
|
+
help="events to show (default 20)")
|
|
460
461
|
p.add_argument("--all", action="store_true", help="show the whole journal")
|
|
461
462
|
p.add_argument("--action", help="filter by action (install, tap, ...)")
|
|
462
463
|
p.add_argument("--json", action="store_true", help="machine-readable output")
|
|
@@ -30,7 +30,13 @@ def log(action: str, subject: str = "", **fields) -> None:
|
|
|
30
30
|
|
|
31
31
|
def events(n: Optional[int] = None, action: Optional[str] = None,
|
|
32
32
|
subject: Optional[str] = None) -> List[dict]:
|
|
33
|
-
"""Most-recent-first list of journal events.
|
|
33
|
+
"""Most-recent-first list of journal events; ``n=None`` means all of them.
|
|
34
|
+
|
|
35
|
+
``n`` must be >= 0: a negative would become a negative slice and silently
|
|
36
|
+
return every event *but* the oldest ones, so it raises instead.
|
|
37
|
+
"""
|
|
38
|
+
if n is not None and n < 0:
|
|
39
|
+
raise ValueError("events(n=%d): n must be >= 0" % n)
|
|
34
40
|
p = paths.pulse_path()
|
|
35
41
|
if not p.exists():
|
|
36
42
|
return []
|
|
@@ -48,7 +54,7 @@ def events(n: Optional[int] = None, action: Optional[str] = None,
|
|
|
48
54
|
continue
|
|
49
55
|
out.append(e)
|
|
50
56
|
out.reverse()
|
|
51
|
-
return out
|
|
57
|
+
return out if n is None else out[:n]
|
|
52
58
|
|
|
53
59
|
|
|
54
60
|
def _line_count(p) -> int:
|
|
@@ -119,6 +119,28 @@ def atomic_write_text(path: Path, text: str, encoding: str = "utf-8") -> None:
|
|
|
119
119
|
raise
|
|
120
120
|
|
|
121
121
|
|
|
122
|
+
def positive_int(s: str) -> int:
|
|
123
|
+
"""argparse ``type=`` for count flags (``-n``/``--limit``): an int >= 1.
|
|
124
|
+
|
|
125
|
+
A bare ``type=int`` lets a negative through, and every count flag in boost
|
|
126
|
+
ends up as a slice bound or a ``git log -n`` argument — where a negative
|
|
127
|
+
silently *inverts* the request instead of failing it. Rejecting it at parse
|
|
128
|
+
time is the only place the user still sees a usable error.
|
|
129
|
+
"""
|
|
130
|
+
# Local import: argparse is not on the `boost --help` startup path, and
|
|
131
|
+
# util is (via core.logs). Every caller of this function is a command
|
|
132
|
+
# module that has already imported argparse through cliparse.
|
|
133
|
+
import argparse
|
|
134
|
+
|
|
135
|
+
try:
|
|
136
|
+
v = int(s)
|
|
137
|
+
except (TypeError, ValueError):
|
|
138
|
+
raise argparse.ArgumentTypeError("invalid int value: %r" % s) from None
|
|
139
|
+
if v < 1:
|
|
140
|
+
raise argparse.ArgumentTypeError("must be >= 1")
|
|
141
|
+
return v
|
|
142
|
+
|
|
143
|
+
|
|
122
144
|
def now_iso() -> str:
|
|
123
145
|
"""Return UTC now as ``'2026-07-16T01:00:00Z'`` (what ``rel_time`` parses)."""
|
|
124
146
|
return datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
|
|
@@ -181,7 +181,7 @@
|
|
|
181
181
|
<a class="cmd-link" href="#cmd-clean" data-search="clean clear stale caches & broken symlinks --dry-run --deep">clean</a>
|
|
182
182
|
<a class="cmd-link" href="#cmd-create" data-search="create scaffold a new skill from a template --description description --dir dir --install name">create</a>
|
|
183
183
|
<a class="cmd-link" href="#cmd-policy" data-search="policy manage & enforce skill governance policies --json {list,set,unset,check} key value">policy</a>
|
|
184
|
-
<a class="cmd-link" href="#cmd-onboard" data-search="onboard add skill-tracker telemetry to a repo & open a pr --repo repo --pr --dry-run">onboard</a>
|
|
184
|
+
<a class="cmd-link" href="#cmd-onboard" data-search="onboard add skill-tracker telemetry to a repo & open a pr --repo repo --pr --dry-run -f, --force">onboard</a>
|
|
185
185
|
<a class="cmd-link" href="#cmd-completions" data-search="completions generate shell tab-completion scripts {bash,zsh,fish}">completions</a>
|
|
186
186
|
<a class="cmd-link" href="#cmd-schedule" data-search="schedule manage automatic skill-sync scheduling --interval {6h,12h,daily} --json {status,enable,disable}">schedule</a>
|
|
187
187
|
<a class="cmd-link" href="#cmd-serve" data-search="serve serve the skill catalog over http (port 8787) --port port --host host">serve</a>
|
|
@@ -991,15 +991,16 @@
|
|
|
991
991
|
<div class="arg"><code>--json</code><span>machine-readable output</span></div>
|
|
992
992
|
</div>
|
|
993
993
|
</section>
|
|
994
|
-
<section class="cmd" id="cmd-onboard" data-search="onboard add skill-tracker telemetry to a repo & open a pr --repo repo --pr --dry-run">
|
|
994
|
+
<section class="cmd" id="cmd-onboard" data-search="onboard add skill-tracker telemetry to a repo & open a pr --repo repo --pr --dry-run -f, --force">
|
|
995
995
|
<h3><span class="cname">onboard</span><span class="gtag">cfg</span></h3>
|
|
996
996
|
<p class="summary">Add skill-tracker telemetry to a repo & open a PR</p>
|
|
997
|
-
<pre class="syn">boost onboard [--repo REPO] [--pr] [--dry-run]</pre>
|
|
997
|
+
<pre class="syn">boost onboard [--repo REPO] [--pr] [--dry-run] [--force]</pre>
|
|
998
998
|
<div class="args-h">Options</div>
|
|
999
999
|
<div class="args">
|
|
1000
1000
|
<div class="arg"><code>--repo REPO</code><span>repository directory (default: .)</span></div>
|
|
1001
1001
|
<div class="arg"><code>--pr</code><span>commit on a branch and open a PR with `gh`</span></div>
|
|
1002
1002
|
<div class="arg"><code>--dry-run</code><span>preview the files without writing anything</span></div>
|
|
1003
|
+
<div class="arg"><code>-f, --force</code><span>overwrite existing files without confirming</span></div>
|
|
1003
1004
|
</div>
|
|
1004
1005
|
</section>
|
|
1005
1006
|
<section class="cmd" id="cmd-completions" data-search="completions generate shell tab-completion scripts {bash,zsh,fish}">
|
{boost_skill_cli-1.0.251 → boost_skill_cli-1.0.253}/tests/functional/test_cli_configuration.py
RENAMED
|
@@ -345,6 +345,154 @@ class TestOnboard:
|
|
|
345
345
|
assert "is not clean" in r.err
|
|
346
346
|
|
|
347
347
|
|
|
348
|
+
class TestOnboardOverwrite:
|
|
349
|
+
"""Re-running onboard must not silently replace a repo's own files.
|
|
350
|
+
|
|
351
|
+
The interesting file is ``.skill-lock.json``: a repo that tracks its own
|
|
352
|
+
lock gets it replaced by whatever *this machine* has installed, and the
|
|
353
|
+
old code still printed "created". Every test here therefore asserts on
|
|
354
|
+
file contents, not just on the message.
|
|
355
|
+
"""
|
|
356
|
+
|
|
357
|
+
LOCK = ".skill-lock.json"
|
|
358
|
+
TELEMETRY = ".boost/telemetry.json"
|
|
359
|
+
WORKFLOW = ".github/workflows/boost-skill-inventory.yml"
|
|
360
|
+
|
|
361
|
+
def _seeded(self, boost, tmp_path):
|
|
362
|
+
"""A repo already onboarded, with a hand-edited lock file."""
|
|
363
|
+
repo = tmp_path / "repo"
|
|
364
|
+
repo.mkdir()
|
|
365
|
+
boost("onboard", "--repo", repo) # BOOST_ASSUME_YES: creates
|
|
366
|
+
(repo / self.LOCK).write_text('{"mine": true}\n', encoding="utf-8")
|
|
367
|
+
return repo
|
|
368
|
+
|
|
369
|
+
def test_declining_leaves_the_existing_file_byte_for_byte(
|
|
370
|
+
self, boost, installed, tmp_path, monkeypatch):
|
|
371
|
+
repo = self._seeded(boost, tmp_path)
|
|
372
|
+
monkeypatch.delenv("BOOST_ASSUME_YES") # stdin is not a tty -> "no"
|
|
373
|
+
r = boost("onboard", "--repo", repo)
|
|
374
|
+
assert (repo / self.LOCK).read_text(encoding="utf-8") == '{"mine": true}\n'
|
|
375
|
+
assert "skipped" in r.out
|
|
376
|
+
assert "created %s" % self.LOCK not in r.out
|
|
377
|
+
|
|
378
|
+
def test_force_overwrites_and_says_updated_not_created(
|
|
379
|
+
self, boost, installed, tmp_path, monkeypatch):
|
|
380
|
+
repo = self._seeded(boost, tmp_path)
|
|
381
|
+
monkeypatch.delenv("BOOST_ASSUME_YES")
|
|
382
|
+
r = boost("onboard", "--repo", repo, "--force")
|
|
383
|
+
lock = json.loads((repo / self.LOCK).read_text(encoding="utf-8"))
|
|
384
|
+
assert "brainstorming" in lock["skills"], "the real lock, not the stub"
|
|
385
|
+
assert "updated" in r.out
|
|
386
|
+
# "created" was the lie the old code told about every overwrite.
|
|
387
|
+
assert "created" not in r.out
|
|
388
|
+
|
|
389
|
+
def test_answering_yes_at_the_prompt_overwrites(
|
|
390
|
+
self, boost, installed, tmp_path):
|
|
391
|
+
# BOOST_ASSUME_YES is the fixture default, i.e. the user said yes.
|
|
392
|
+
repo = self._seeded(boost, tmp_path)
|
|
393
|
+
r = boost("onboard", "--repo", repo)
|
|
394
|
+
lock = json.loads((repo / self.LOCK).read_text(encoding="utf-8"))
|
|
395
|
+
assert "brainstorming" in lock["skills"]
|
|
396
|
+
assert "updated" in r.out
|
|
397
|
+
|
|
398
|
+
def test_an_existing_file_boost_cannot_read_is_still_protected(
|
|
399
|
+
self, boost, installed, tmp_path, monkeypatch):
|
|
400
|
+
# The identical-content shortcut reads the file; a binary or
|
|
401
|
+
# permission-denied file must fall back to asking, not to overwriting.
|
|
402
|
+
repo = self._seeded(boost, tmp_path)
|
|
403
|
+
(repo / self.WORKFLOW).write_bytes(b"\xff\xfe not utf-8")
|
|
404
|
+
monkeypatch.delenv("BOOST_ASSUME_YES")
|
|
405
|
+
r = boost("onboard", "--repo", repo)
|
|
406
|
+
assert (repo / self.WORKFLOW).read_bytes() == b"\xff\xfe not utf-8"
|
|
407
|
+
assert "skipped" in r.out
|
|
408
|
+
|
|
409
|
+
def test_the_hidden_yes_alias_also_overwrites(
|
|
410
|
+
self, boost, installed, tmp_path, monkeypatch):
|
|
411
|
+
repo = self._seeded(boost, tmp_path)
|
|
412
|
+
monkeypatch.delenv("BOOST_ASSUME_YES")
|
|
413
|
+
boost("onboard", "--repo", repo, "--yes")
|
|
414
|
+
assert '{"mine": true}' not in (repo / self.LOCK).read_text(encoding="utf-8")
|
|
415
|
+
|
|
416
|
+
def test_identical_content_is_never_prompted_for(
|
|
417
|
+
self, boost, installed, tmp_path, monkeypatch):
|
|
418
|
+
# The workflow YAML regenerates byte-for-byte, so a second run has
|
|
419
|
+
# nothing to ask about it. Asking anyway trains users to say yes.
|
|
420
|
+
repo = self._seeded(boost, tmp_path)
|
|
421
|
+
# Leave *only* the workflow: telemetry carries a timestamp and the lock
|
|
422
|
+
# is live machine state, so neither is a stable "identical" case.
|
|
423
|
+
(repo / self.TELEMETRY).unlink()
|
|
424
|
+
(repo / self.LOCK).unlink()
|
|
425
|
+
monkeypatch.delenv("BOOST_ASSUME_YES")
|
|
426
|
+
monkeypatch.setattr("boost_cli.core.output.confirm",
|
|
427
|
+
lambda *a, **k: pytest.fail(
|
|
428
|
+
"prompted to overwrite an identical file"))
|
|
429
|
+
r = boost("onboard", "--repo", repo)
|
|
430
|
+
assert "unchanged" in r.out
|
|
431
|
+
assert self.WORKFLOW in r.out
|
|
432
|
+
|
|
433
|
+
def test_dry_run_distinguishes_write_from_overwrite(
|
|
434
|
+
self, boost, installed, tmp_path):
|
|
435
|
+
repo = self._seeded(boost, tmp_path)
|
|
436
|
+
r = boost("onboard", "--repo", repo, "--dry-run")
|
|
437
|
+
assert "would overwrite" in r.out
|
|
438
|
+
assert "would write" not in r.out, "every file already exists here"
|
|
439
|
+
assert (repo / self.LOCK).read_text(encoding="utf-8") == '{"mine": true}\n'
|
|
440
|
+
|
|
441
|
+
def test_declining_everything_journals_nothing(
|
|
442
|
+
self, boost, installed, tmp_path, monkeypatch):
|
|
443
|
+
repo = self._seeded(boost, tmp_path)
|
|
444
|
+
# Make all three differ so all three get a prompt, then decline them.
|
|
445
|
+
(repo / self.TELEMETRY).write_text("{}\n", encoding="utf-8")
|
|
446
|
+
(repo / self.WORKFLOW).write_text("# theirs\n", encoding="utf-8")
|
|
447
|
+
before = len(journal.events(action="onboard"))
|
|
448
|
+
monkeypatch.delenv("BOOST_ASSUME_YES")
|
|
449
|
+
r = boost("onboard", "--repo", repo)
|
|
450
|
+
assert "nothing to do" in r.out
|
|
451
|
+
assert len(journal.events(action="onboard")) == before, \
|
|
452
|
+
"a no-op run must not add an onboard event"
|
|
453
|
+
|
|
454
|
+
def test_pr_stages_only_the_files_it_actually_wrote(
|
|
455
|
+
self, boost, installed, tmp_path, monkeypatch):
|
|
456
|
+
repo = _mk_repo(tmp_path / "repo")
|
|
457
|
+
(repo / self.LOCK).write_text('{"mine": true}\n', encoding="utf-8")
|
|
458
|
+
_git(repo, "add", "-A")
|
|
459
|
+
_git(repo, "commit", "-qm", "our own lock")
|
|
460
|
+
monkeypatch.setattr("boost_cli.commands.configuration.shutil.which",
|
|
461
|
+
lambda c: "/usr/bin/" + c)
|
|
462
|
+
real_run = subprocess.run
|
|
463
|
+
monkeypatch.setattr(
|
|
464
|
+
"boost_cli.commands.configuration.subprocess.run",
|
|
465
|
+
lambda cmd, **kw: _proc(cmd, 0, out="https://github.com/o/r/pull/9\n")
|
|
466
|
+
if cmd and cmd[0] == "gh" else real_run(cmd, **kw))
|
|
467
|
+
monkeypatch.delenv("BOOST_ASSUME_YES") # decline the lock overwrite
|
|
468
|
+
boost("onboard", "--repo", repo, "--pr")
|
|
469
|
+
|
|
470
|
+
names = subprocess.run(["git", "show", "--name-only", "--pretty=", "HEAD"],
|
|
471
|
+
cwd=str(repo), capture_output=True, text=True)
|
|
472
|
+
staged = set(names.stdout.split())
|
|
473
|
+
assert staged == {self.TELEMETRY, self.WORKFLOW}
|
|
474
|
+
assert (repo / self.LOCK).read_text(encoding="utf-8") == '{"mine": true}\n'
|
|
475
|
+
|
|
476
|
+
def test_pr_with_nothing_to_write_leaves_no_branch_behind(
|
|
477
|
+
self, boost, installed, tmp_path, monkeypatch):
|
|
478
|
+
repo = _mk_repo(tmp_path / "repo")
|
|
479
|
+
for rel, body in ((self.TELEMETRY, "{}\n"), (self.WORKFLOW, "# theirs\n"),
|
|
480
|
+
(self.LOCK, '{"mine": true}\n')):
|
|
481
|
+
(repo / rel).parent.mkdir(parents=True, exist_ok=True)
|
|
482
|
+
(repo / rel).write_text(body, encoding="utf-8")
|
|
483
|
+
_git(repo, "add", "-A")
|
|
484
|
+
_git(repo, "commit", "-qm", "already ours")
|
|
485
|
+
monkeypatch.setattr("boost_cli.commands.configuration.shutil.which",
|
|
486
|
+
lambda c: "/usr/bin/" + c)
|
|
487
|
+
monkeypatch.delenv("BOOST_ASSUME_YES")
|
|
488
|
+
r = boost("onboard", "--repo", repo, "--pr")
|
|
489
|
+
assert "nothing to do" in r.out
|
|
490
|
+
head = subprocess.run(["git", "rev-parse", "--abbrev-ref", "HEAD"],
|
|
491
|
+
cwd=str(repo), capture_output=True, text=True)
|
|
492
|
+
assert head.stdout.strip() != "boost/onboard-skill-tracker", \
|
|
493
|
+
"an empty branch would fail on `git commit` with nothing staged"
|
|
494
|
+
|
|
495
|
+
|
|
348
496
|
# ---------------------------------------------------------------- completions
|
|
349
497
|
|
|
350
498
|
class TestCompletions:
|
|
@@ -314,6 +314,11 @@ class TestLog:
|
|
|
314
314
|
assert len(lines) == 1
|
|
315
315
|
assert "install brainstorming" in lines[0]
|
|
316
316
|
|
|
317
|
+
def test_negative_limit_rejected_on_every_branch(self, boost, installed):
|
|
318
|
+
for extra in ([], ["--diagnostics"], ["--crashes"]):
|
|
319
|
+
r = boost("log", *extra, "-n", "-1", expect=2)
|
|
320
|
+
assert "argument -n/--limit: must be >= 1" in r.err
|
|
321
|
+
|
|
317
322
|
def test_skill_git_history(self, boost, installed):
|
|
318
323
|
r = boost("log", "brainstorming")
|
|
319
324
|
assert "brainstorming — history in fixture-tap" in r.out
|
|
@@ -324,6 +324,12 @@ class TestPulse:
|
|
|
324
324
|
rows = [l for l in r.out.splitlines() if USER in l]
|
|
325
325
|
assert len(rows) == 1 and "fixture-tap" in rows[0]
|
|
326
326
|
|
|
327
|
+
def test_negative_or_zero_limit_rejected(self, boost, installed):
|
|
328
|
+
r = boost("pulse", "-n", "-1", expect=2)
|
|
329
|
+
assert "argument -n: must be >= 1" in r.err
|
|
330
|
+
r = boost("pulse", "-n", "0", expect=2)
|
|
331
|
+
assert "argument -n: must be >= 1" in r.err
|
|
332
|
+
|
|
327
333
|
def test_json_purity(self, boost, installed):
|
|
328
334
|
r = boost("pulse", "--json")
|
|
329
335
|
events = json.loads(r.out)
|
|
@@ -5,6 +5,8 @@ import getpass
|
|
|
5
5
|
import json
|
|
6
6
|
import re
|
|
7
7
|
|
|
8
|
+
import pytest
|
|
9
|
+
|
|
8
10
|
from boost_cli.core import journal, paths
|
|
9
11
|
|
|
10
12
|
|
|
@@ -254,3 +256,24 @@ class TestRotationHealthy:
|
|
|
254
256
|
def test_one_over_limit_unhealthy(self, sandbox):
|
|
255
257
|
write_lines(journal.ROTATE_AT + 1)
|
|
256
258
|
assert journal.rotation_healthy() is False
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
class TestEventsLimitGuard:
|
|
262
|
+
"""A negative n used to become a negative slice — see the roadmap item."""
|
|
263
|
+
|
|
264
|
+
def test_negative_n_raises_instead_of_inverting(self, sandbox):
|
|
265
|
+
for i in range(3):
|
|
266
|
+
journal.log("install", "s%d" % i)
|
|
267
|
+
with pytest.raises(ValueError) as exc:
|
|
268
|
+
journal.events(-1)
|
|
269
|
+
assert str(exc.value) == "events(n=-1): n must be >= 0"
|
|
270
|
+
assert len(journal.events()) == 3
|
|
271
|
+
|
|
272
|
+
def test_zero_n_is_empty_not_everything(self, sandbox):
|
|
273
|
+
for i in range(3):
|
|
274
|
+
journal.log("install", "s%d" % i)
|
|
275
|
+
assert journal.events(0) == []
|
|
276
|
+
|
|
277
|
+
def test_n_larger_than_feed_returns_all(self, sandbox):
|
|
278
|
+
journal.log("install", "only")
|
|
279
|
+
assert [e["subject"] for e in journal.events(9)] == ["only"]
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""Unit tests: boost_cli/core/util.py — time, hashing, versions, scoring."""
|
|
2
2
|
from __future__ import annotations
|
|
3
3
|
|
|
4
|
+
import argparse
|
|
4
5
|
import hashlib
|
|
5
6
|
import re
|
|
6
7
|
import time
|
|
@@ -635,3 +636,26 @@ class TestSafeComponent:
|
|
|
635
636
|
# parent directory itself.
|
|
636
637
|
assert util.safe_component("..") == "skill"
|
|
637
638
|
assert util.safe_component(".") == "skill"
|
|
639
|
+
|
|
640
|
+
|
|
641
|
+
class TestPositiveInt:
|
|
642
|
+
"""`util.positive_int` — the argparse type behind every -n/--limit flag."""
|
|
643
|
+
|
|
644
|
+
def test_accepts_one_and_above_exactly(self):
|
|
645
|
+
assert util.positive_int("1") == 1
|
|
646
|
+
assert util.positive_int("20") == 20
|
|
647
|
+
|
|
648
|
+
def test_zero_rejected_with_exact_message(self):
|
|
649
|
+
with pytest.raises(argparse.ArgumentTypeError) as exc:
|
|
650
|
+
util.positive_int("0")
|
|
651
|
+
assert str(exc.value) == "must be >= 1"
|
|
652
|
+
|
|
653
|
+
def test_negative_rejected_with_exact_message(self):
|
|
654
|
+
with pytest.raises(argparse.ArgumentTypeError) as exc:
|
|
655
|
+
util.positive_int("-1")
|
|
656
|
+
assert str(exc.value) == "must be >= 1"
|
|
657
|
+
|
|
658
|
+
def test_non_numeric_rejected_with_exact_message(self):
|
|
659
|
+
with pytest.raises(argparse.ArgumentTypeError) as exc:
|
|
660
|
+
util.positive_int("abc")
|
|
661
|
+
assert str(exc.value) == "invalid int value: 'abc'"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|