boost-skill-cli 1.0.97__tar.gz → 1.0.99__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.97 → boost_skill_cli-1.0.99}/Makefile +18 -1
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/PKG-INFO +1 -1
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost_cli/_version.py +2 -2
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost_cli/commands/configuration.py +1 -1
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost_cli/commands/discovery.py +32 -26
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost_cli/commands/info.py +22 -22
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost_cli/commands/intelligence.py +18 -19
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost_cli/commands/pkg.py +3 -4
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost_cli/commands/quality.py +34 -34
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost_cli/commands/taps.py +5 -6
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost_cli/commands/team.py +20 -21
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost_cli/core/ai.py +2 -2
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost_cli/core/embed.py +3 -1
- boost_skill_cli-1.0.99/boost_cli/core/nethttp.py +41 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost_cli/core/output.py +45 -9
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost_skill_cli.egg-info/PKG-INFO +1 -1
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost_skill_cli.egg-info/SOURCES.txt +11 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/design-roadmap.html +3 -3
- boost_skill_cli-1.0.99/docs/roadmap/items/BOOST-D04.md +16 -0
- boost_skill_cli-1.0.99/docs/roadmap/items/browse-crashes-selecting-a-rule-or-workflow.md +26 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/fork-safe-network-proxy-handler.md +3 -3
- boost_skill_cli-1.0.99/docs/roadmap/items/mcp-hub-diagram-node-text-overflow.md +22 -0
- boost_skill_cli-1.0.99/docs/roadmap/items/retrieval-quality-eval-harness.md +39 -0
- boost_skill_cli-1.0.99/docs/roadmap/items/surface-every-docs-page-from-the-guide.md +24 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap.html +97 -3
- boost_skill_cli-1.0.99/scripts/eval_recommend.py +272 -0
- boost_skill_cli-1.0.99/scripts/eval_retrieval.py +384 -0
- boost_skill_cli-1.0.99/tests/eval/baseline.json +17 -0
- boost_skill_cli-1.0.99/tests/eval/golden.jsonl +52 -0
- boost_skill_cli-1.0.99/tests/eval/recommend.jsonl +19 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/tests/functional/test_cli_discovery.py +16 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/tests/unit/test_ai.py +6 -6
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/tests/unit/test_embed.py +3 -3
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/tests/unit/test_mutation_hardening.py +6 -2
- boost_skill_cli-1.0.99/tests/unit/test_nethttp.py +85 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/tests/unit/test_output.py +65 -4
- boost_skill_cli-1.0.97/docs/roadmap/items/BOOST-D04.md +0 -16
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/.gitattributes +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/.gitignore +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/CLAUDE.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/CONTRIBUTING.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/LICENSE +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/MANIFEST.in +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/README.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/SECURITY.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost_cli/__init__.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost_cli/__main__.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost_cli/cli.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost_cli/cliparse.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost_cli/commands/__init__.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost_cli/commands/bmad.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost_cli/commands/hooks.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost_cli/core/__init__.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost_cli/core/agents.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost_cli/core/catalog.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost_cli/core/claude_settings.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost_cli/core/config.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost_cli/core/dense.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost_cli/core/frontmatter.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost_cli/core/gitutil.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost_cli/core/journal.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost_cli/core/lockfile.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost_cli/core/logs.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost_cli/core/mcp.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost_cli/core/paths.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost_cli/core/policy.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost_cli/core/rag.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost_cli/core/registry.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost_cli/core/serve.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost_cli/core/staleness.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost_cli/core/store.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost_cli/core/typosquat.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost_cli/core/util.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost_cli/data/registries.json +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost_cli/errors.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost_cli/spin.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost_skill_cli.egg-info/dependency_links.txt +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost_skill_cli.egg-info/entry_points.txt +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost_skill_cli.egg-info/requires.txt +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/boost_skill_cli.egg-info/top_level.txt +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/.claude/settings.local.json +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/DEBUGGING.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/demo.gif +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/demo.tape +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/index.html +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/mcp-hub.html +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/rag-architecture.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/BOOST-D01.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/BOOST-D02.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/BOOST-D03.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/BOOST-D05.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/BOOST-D06.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/BOOST-D07.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/BOOST-D08.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/BOOST-D09.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/BOOST-D10.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/BOOST-D11.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/BOOST-D12.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/BOOST-D13.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/BOOST-D14.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/BOOST-D15.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/BOOST-D16.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/BOOST-D17.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/BOOST-D18.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/BOOST-D19.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/BOOST-D20.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/BOOST-D21.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/BOOST-D22.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/BOOST-D23.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/BOOST-D24.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/BOOST-D25.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/BOOST-D26.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/accessibility-audit-pa11y-ci-axe-core.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/atomic-corruption-safe-lock-file-writes.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/atomic-skill-install-temp-dir-swap.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/autonomous-ship-workflow-and-isolated-worktree.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/bring-commands-under-mutation-testing.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/broken-link-and-anchor-checking-lychee.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/build-provenance-slsa-attestations.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/cache-the-catalog-entry-set-across-rag-queries.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/capability-manifest-and-least-privilege-policy.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/clean-env-install-smoke-pip-and-pipx.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/command-reference-docs-site.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/complexity-and-dead-code-radar-xenon-vulture.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/consolidate-skill-staleness-drift-logic-into-cor.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/coverage-dashboard-codecov-free-for-oss.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/coverage-guided-fuzzing-atheris-oss-fuzz.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/crash-recorder-error-paths-core-logs-py.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/dependency-cve-gate-pip-audit.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/docstring-coverage-interrogate.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/end-of-options-guard-on-git-commands.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/extension-free-tests-core-dense-py.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/extract-mcp-http-servers-out-of-configuration-py.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/finish-mutation-hardening-across-core.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/fix-self-update-version-detection-dead-branch.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/frontmatter-scalar-over-coercion.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/github-pages-deploy-is-broken-every-push.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/hash-pinned-reproducible-toolchain-uv-lock.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/html-validation-html-validate.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/integrity-verification-boost-verify.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/invocation-pid-logging-for-crash-correlation.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/layering-guard-import-linter.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/lighthouse-ci-on-the-pages-site.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/localize-the-stored-bm25-snippet.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/lockfile-enforcement-and-commit-pinning.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/log-timestamps-mislabeled-utc.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/lowest-version-resolution-uv-resolution-lowest-d.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/make-the-roadmaps-discoverable.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/markdown-consistency-markdownlint-cli2.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/mcp-launch-objc-fork-safety.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/memoize-config-load-in-process.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/modernization-smells-refurb-pyupgrade.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/mutation-hardening-core-frontmatter-py.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/mutation-hardening-core-gitutil-py.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/mutation-hardening-core-store-py.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/one-command-every-env-nox.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/one-shared-atomic-write-helper.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/package-metadata-validation-twine-check-friends.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/patch-coverage-gate-diff-cover.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/performance-regression-gate-pytest-benchmark.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/post-deploy-smoke-headless-load-check.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/pre-release-python-canary-3-14t-free-threaded.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/promote-nav-footer-into-the-shared-style-system.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/prompt-injection-scanning-of-skill-markdown.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/property-based-tests-hypothesis-on-the-parsers.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/prose-and-terminology-linting-vale.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/prune-ignored-dirs-during-scan-dir-walk.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/quality-dashboard-sonarcloud-free-for-oss.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/reconcile-the-theme-drift.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/refresh-the-marketing-surface.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/reuse-helpers-kill-minor-dead-work.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/robust-tag-argument-parsing.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/rule-install-native-materialization.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/runner-egress-monitoring-stepsecurity-harden-run.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/sbom-aware-scanning-osv-scanner.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/sbom-on-every-release-cyclonedx-syft.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/second-type-checker-pyright.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/secret-and-pii-scanning-of-installed-skills.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/secret-scanning-gitleaks-push-protection.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/security-linting-bandit-via-ruff-s-rules.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/shift-left-gate-pre-commit-pre-commit-ci.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/single-imperative-rule-extractor.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/single-tech-stack-prober.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/split-oversized-command-modules.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/startup-and-import-time-budget-x-importtime.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/stop-re-serializing-entry-meta-on-every-search.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/supply-chain-posture-openssf-scorecard.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/tap-signing-and-provenance-sigstore-minisign.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/theme-asset-linting-stylelint-eslint.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/typo-detection-codespell.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/typosquat-and-name-confusion-detection.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/unify-tilde-two-copies-have-a-boundary-bug.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/untrack-generated-build-noise.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/update-diff-before-apply.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/visual-regression-pass-on-the-guide.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/widen-the-ruff-rule-surface-b-sim-c4-perf-ruf.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/windows-in-the-ci-matrix.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/workflow-linting-actionlint.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/workflow-sast-zizmor.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/docs/roadmap/items/workspace-scope-install.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/index.html +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/pyproject.toml +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/scripts/build_registries.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/scripts/build_roadmap.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/scripts/mutation_gate.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/setup.cfg +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/style/README.md +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/style/boost.css +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/style/boost.js +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/style/demo.html +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/tests/conftest.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/tests/functional/test_cli_bmad.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/tests/functional/test_cli_configuration.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/tests/functional/test_cli_hooks.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/tests/functional/test_cli_info.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/tests/functional/test_cli_intelligence.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/tests/functional/test_cli_pkg.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/tests/functional/test_cli_quality.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/tests/functional/test_cli_taps.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/tests/functional/test_cli_team.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/tests/functional/test_everyday_loop.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/tests/make_fixture.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/tests/smoke.sh +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/tests/unit/test_agents.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/tests/unit/test_catalog.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/tests/unit/test_claude_settings.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/tests/unit/test_cliparse.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/tests/unit/test_config.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/tests/unit/test_dense.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/tests/unit/test_dense_fallback.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/tests/unit/test_errors_and_cli_table.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/tests/unit/test_frontmatter.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/tests/unit/test_gitutil.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/tests/unit/test_journal.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/tests/unit/test_lockfile.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/tests/unit/test_logs.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/tests/unit/test_mcp.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/tests/unit/test_paths.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/tests/unit/test_pkg_confusions.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/tests/unit/test_policy.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/tests/unit/test_rag.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/tests/unit/test_registries_fresh.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/tests/unit/test_registry.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/tests/unit/test_roadmap_fresh.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/tests/unit/test_serve.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/tests/unit/test_spin.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/tests/unit/test_staleness.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/tests/unit/test_store.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/tests/unit/test_token_parity.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/tests/unit/test_typosquat.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/tests/unit/test_util.py +0 -0
- {boost_skill_cli-1.0.97 → boost_skill_cli-1.0.99}/tests/unit/test_version.py +0 -0
|
@@ -6,7 +6,7 @@ VENV := .venv
|
|
|
6
6
|
PY := $(VENV)/bin/python
|
|
7
7
|
PYTEST := $(VENV)/bin/pytest
|
|
8
8
|
|
|
9
|
-
.PHONY: venv test unit functional smoke coverage mutation lint check demo clean-test
|
|
9
|
+
.PHONY: venv test unit functional smoke coverage mutation lint check demo clean-test eval eval-ai eval-rec
|
|
10
10
|
|
|
11
11
|
venv:
|
|
12
12
|
python3 -m venv $(VENV)
|
|
@@ -39,6 +39,23 @@ lint:
|
|
|
39
39
|
$(PY) scripts/build_registries.py --check
|
|
40
40
|
$(PY) scripts/build_roadmap.py --check
|
|
41
41
|
|
|
42
|
+
# Tier 1 retrieval quality gate: golden-set recall@k over the tapped catalog.
|
|
43
|
+
# Deterministic + offline; a release-quality gate, kept separate from `check`.
|
|
44
|
+
eval:
|
|
45
|
+
$(PY) scripts/eval_retrieval.py --build -k 10 --fail-under 0.85
|
|
46
|
+
|
|
47
|
+
# Tier 2a: LLM rerank lift over BM25 on the same golden set. Opt-in and
|
|
48
|
+
# key-gated — needs the `claude` CLI on PATH or ANTHROPIC_API_KEY; skips
|
|
49
|
+
# cleanly otherwise. Not part of `check` (network + cost).
|
|
50
|
+
eval-ai:
|
|
51
|
+
$(PY) scripts/eval_retrieval.py --rerank -k 10
|
|
52
|
+
|
|
53
|
+
# Tier 2b: recommendation quality — heuristic vs `_ai_picks` over golden
|
|
54
|
+
# stacks, with a hard grounding gate (no off-shortlist / hallucinated picks).
|
|
55
|
+
# Same opt-in/key-gated contract as eval-ai; the heuristic arm always runs.
|
|
56
|
+
eval-rec:
|
|
57
|
+
$(PY) scripts/eval_recommend.py --build -k 5 --fail-hallucination
|
|
58
|
+
|
|
42
59
|
# regenerate generated artifacts from their source (registries + roadmap boards)
|
|
43
60
|
generate:
|
|
44
61
|
$(PY) scripts/build_registries.py
|
|
@@ -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.99'
|
|
22
|
+
__version_tuple__ = version_tuple = (1, 0, 99)
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -165,7 +165,7 @@ def cmd_clean(argv) -> int:
|
|
|
165
165
|
out.warn("could not remove %s: %s" % (_tilde(pth), e))
|
|
166
166
|
continue
|
|
167
167
|
freed += size
|
|
168
|
-
out.info("%s %s %s" % (verb, _tilde(pth), out.
|
|
168
|
+
out.info("%s %s %s" % (verb, _tilde(pth), out.role("(%s)" % kind, "muted")))
|
|
169
169
|
if args.dry_run:
|
|
170
170
|
out.dim(" %d item(s) · %s would be freed" % (len(items), util.human_size(freed)))
|
|
171
171
|
else:
|
|
@@ -193,8 +193,7 @@ def cmd_search(argv):
|
|
|
193
193
|
return 0
|
|
194
194
|
if not scored:
|
|
195
195
|
out.info("no matches for %r" % query)
|
|
196
|
-
out.info(out.
|
|
197
|
-
out.DIM))
|
|
196
|
+
out.info(out.role("try `boost discover %s` to search all of GitHub" % query, "muted"))
|
|
198
197
|
return 0
|
|
199
198
|
ranker = "full-content BM25" if use_rag else "heuristic relevance"
|
|
200
199
|
if args.smart:
|
|
@@ -216,15 +215,14 @@ def cmd_search(argv):
|
|
|
216
215
|
frac = sc / top
|
|
217
216
|
hue = "cyan" if frac >= 0.66 else "violet" if frac >= 0.33 else "pink"
|
|
218
217
|
bar = out.aurora(out.meter(frac), hue)
|
|
219
|
-
tag = " " + out.
|
|
218
|
+
tag = " " + out.role("★ curated", "warn") if e.get("curated") else ""
|
|
220
219
|
tag_w = len(" ★ curated") if e.get("curated") else 0
|
|
221
220
|
desc_w = max(cols - 2 - 5 - name_w - 2 - tag_w, 8) # 5 = meter + space
|
|
222
|
-
name_cell = out.
|
|
221
|
+
name_cell = out.role(out.truncate(e["name"], name_w).ljust(name_w), "accent")
|
|
223
222
|
out.info(bar + " " + name_cell + " "
|
|
224
223
|
+ out.truncate(e["description"] or "", desc_w) + tag)
|
|
225
|
-
out.info(out.
|
|
226
|
-
% (len(scored), "" if len(scored) == 1 else "es", ranker),
|
|
227
|
-
out.DIM))
|
|
224
|
+
out.info(out.role("%d match%s · ranked by %s"
|
|
225
|
+
% (len(scored), "" if len(scored) == 1 else "es", ranker), "muted"))
|
|
228
226
|
return 0
|
|
229
227
|
|
|
230
228
|
|
|
@@ -258,11 +256,10 @@ def cmd_reindex(argv):
|
|
|
258
256
|
% (stats["docs"], stats["entries"], stats["taps"],
|
|
259
257
|
"" if stats["taps"] == 1 else "s"))
|
|
260
258
|
if stats["reused"]:
|
|
261
|
-
out.info(out.
|
|
259
|
+
out.info(out.role("reused %d unchanged tap%s; reindexed: %s"
|
|
262
260
|
% (len(stats["reused"]),
|
|
263
261
|
"" if len(stats["reused"]) == 1 else "s",
|
|
264
|
-
", ".join(stats["reindexed"]) or "none"),
|
|
265
|
-
out.DIM))
|
|
262
|
+
", ".join(stats["reindexed"]) or "none"), "muted"))
|
|
266
263
|
if args.dense:
|
|
267
264
|
if dense_stats is None:
|
|
268
265
|
out.warn("dense index skipped — %s" % embed.fallback_note())
|
|
@@ -426,15 +423,15 @@ def cmd_discover(argv):
|
|
|
426
423
|
return 0
|
|
427
424
|
if not shown:
|
|
428
425
|
out.info("no indexed skills match %r" % " ".join(args.query))
|
|
429
|
-
out.info(out.
|
|
430
|
-
% len(all_items),
|
|
426
|
+
out.info(out.role("the index holds %d entries — rebuild with `boost index`"
|
|
427
|
+
% len(all_items), "muted"))
|
|
431
428
|
return 0
|
|
432
429
|
out.table([(it.get("repo", "?"), it.get("path", ""),
|
|
433
|
-
out.
|
|
430
|
+
out.role(it.get("url", ""), "muted")) for it in shown],
|
|
434
431
|
headers=("repo", "path", "url"))
|
|
435
|
-
out.info(out.
|
|
432
|
+
out.info(out.role("%d of %d indexed skills · GitHub reports ~%d total"
|
|
436
433
|
% (len(shown), len(all_items),
|
|
437
|
-
int(data.get("github_total") or 0)),
|
|
434
|
+
int(data.get("github_total") or 0)), "muted"))
|
|
438
435
|
return 0
|
|
439
436
|
|
|
440
437
|
|
|
@@ -494,7 +491,7 @@ def cmd_recommend(argv):
|
|
|
494
491
|
line = "stack: " + (", ".join(stack["languages"]) or "unknown")
|
|
495
492
|
if stack["frameworks"]:
|
|
496
493
|
line += " · frameworks: " + ", ".join(stack["frameworks"])
|
|
497
|
-
out.info(out.
|
|
494
|
+
out.info(out.role("%s (%s)" % (line, _tilde(target)), "muted"))
|
|
498
495
|
shown = ranked[:args.limit]
|
|
499
496
|
if not shown:
|
|
500
497
|
shown = [{"entry": e, "score": 0, "because": {"curated"}}
|
|
@@ -509,15 +506,15 @@ def cmd_recommend(argv):
|
|
|
509
506
|
e = r["entry"]
|
|
510
507
|
because = "because: %s" % ", ".join(sorted(r["because"]))
|
|
511
508
|
desc_w = max(cols - 2 - width - 2 - (len(because) + 2), 8)
|
|
512
|
-
name_cell = out.
|
|
509
|
+
name_cell = out.role(out.truncate(e["name"], width).ljust(width), "accent")
|
|
513
510
|
out.info(name_cell + " " + out.truncate(e["description"] or "", desc_w)
|
|
514
|
-
+ " " + out.
|
|
511
|
+
+ " " + out.role(because, "muted"))
|
|
515
512
|
if ai.available():
|
|
516
513
|
picks = _ai_picks(stack, [r["entry"] for r in ranked[:20]])
|
|
517
514
|
if picks:
|
|
518
515
|
out.heading("AI picks")
|
|
519
516
|
for pk in picks:
|
|
520
|
-
out.info(out.
|
|
517
|
+
out.info(out.role(str(pk.get("name", "?")), "accent") + " "
|
|
521
518
|
+ str(pk.get("reason", "")))
|
|
522
519
|
return 0
|
|
523
520
|
|
|
@@ -533,8 +530,8 @@ def _browse_plain(entries, why: str):
|
|
|
533
530
|
out.table([(e["name"], "v" + e["version"], e["tap"],
|
|
534
531
|
"★" if e.get("curated") else "") for e in entries],
|
|
535
532
|
headers=("name", "version", "tap", ""))
|
|
536
|
-
out.info(out.
|
|
537
|
-
% len(entries),
|
|
533
|
+
out.info(out.role("%d skills · install with `boost install <name>`"
|
|
534
|
+
% len(entries), "muted"))
|
|
538
535
|
return 0
|
|
539
536
|
|
|
540
537
|
|
|
@@ -801,7 +798,16 @@ def cmd_browse(argv):
|
|
|
801
798
|
picked = _browse_tui(curses, entries)
|
|
802
799
|
if picked is None:
|
|
803
800
|
return 0
|
|
804
|
-
|
|
801
|
+
try:
|
|
802
|
+
res = store.install(picked)
|
|
803
|
+
except BoostError as e:
|
|
804
|
+
# browse lists every catalog kind (skills, rules, workflows), but only
|
|
805
|
+
# skills install; a rule/workflow pick — or an already-installed/pinned
|
|
806
|
+
# skill — must not exit the interactive TUI with a fatal error.
|
|
807
|
+
out.warn(e.message)
|
|
808
|
+
if e.hint:
|
|
809
|
+
out.info(out.c(e.hint, out.DIM))
|
|
810
|
+
return 0
|
|
805
811
|
out.ok("installed %s v%s → %s"
|
|
806
812
|
% (picked["name"], picked["version"], _tilde(res.dest)))
|
|
807
813
|
if res.linked:
|
|
@@ -844,7 +850,7 @@ def cmd_trending(argv):
|
|
|
844
850
|
out.truncate(by_name.get(name, {}).get("description", ""), descw))
|
|
845
851
|
for name, rec in ranked[:args.limit]],
|
|
846
852
|
headers=("name", "installs", "last", "description"))
|
|
847
|
-
out.info(out.
|
|
853
|
+
out.info(out.role("based on local install activity", "muted"))
|
|
848
854
|
return 0
|
|
849
855
|
|
|
850
856
|
|
|
@@ -901,14 +907,14 @@ def cmd_stats(argv):
|
|
|
901
907
|
out.kv("version", cat["version"])
|
|
902
908
|
out.kv("tap", cat["tap"])
|
|
903
909
|
out.kv("description", cat["description"])
|
|
904
|
-
out.info(out.
|
|
910
|
+
out.info(out.role("not installed — `boost install %s`" % name, "muted"))
|
|
905
911
|
out.kv("activity", "%d installs · %d updates · %d uninstalls"
|
|
906
912
|
% (acts["install"], acts["update"], acts["uninstall"]))
|
|
907
913
|
if lock and latest:
|
|
908
914
|
if util.semver_gt(latest, lock.get("version", "0")):
|
|
909
|
-
out.kv("latest", "%s %s" % (latest, out.
|
|
915
|
+
out.kv("latest", "%s %s" % (latest, out.role("(update available)", "warn")))
|
|
910
916
|
else:
|
|
911
|
-
out.kv("latest", "%s %s" % (latest, out.
|
|
917
|
+
out.kv("latest", "%s %s" % (latest, out.role("(up to date)", "muted")))
|
|
912
918
|
if upstream:
|
|
913
919
|
out.kv("upstream", upstream)
|
|
914
920
|
return 0
|
|
@@ -78,8 +78,8 @@ def _file_count(d: Path) -> int:
|
|
|
78
78
|
|
|
79
79
|
|
|
80
80
|
def _mark(installed: bool) -> str:
|
|
81
|
-
return (out.
|
|
82
|
-
else out.
|
|
81
|
+
return (out.role("✓ installed", "success") if installed
|
|
82
|
+
else out.role("✗ not installed", "danger"))
|
|
83
83
|
|
|
84
84
|
|
|
85
85
|
def _print_wrapped(text: str) -> None:
|
|
@@ -122,7 +122,7 @@ def cmd_list(argv):
|
|
|
122
122
|
flags = ([out.aurora("pinned", "yellow")] if e.get("pinned") else []) + \
|
|
123
123
|
([out.aurora("quarantined", "pink")] if e.get("quarantined")
|
|
124
124
|
else []) + \
|
|
125
|
-
[out.
|
|
125
|
+
[out.role("#" + t, "muted") for t in e.get("tags") or []]
|
|
126
126
|
rows.append((name, e.get("version", "?"), e.get("tap", "?"),
|
|
127
127
|
"·".join(a.split("-")[0] for a in e.get("agents") or []),
|
|
128
128
|
" ".join(flags)))
|
|
@@ -204,8 +204,8 @@ def cmd_info(argv):
|
|
|
204
204
|
out.kv("version", inst_v)
|
|
205
205
|
latest = str((cat or {}).get("version") or "")
|
|
206
206
|
if cat and latest != inst_v:
|
|
207
|
-
out.kv("latest", out.
|
|
208
|
-
+ out.
|
|
207
|
+
out.kv("latest", out.role(latest, "warn", bold=True)
|
|
208
|
+
+ out.role(" (update available)", "muted"))
|
|
209
209
|
else:
|
|
210
210
|
out.kv("latest", str(cat.get("version", "?")))
|
|
211
211
|
out.kv("tap", (lock or cat).get("tap", "?"))
|
|
@@ -251,10 +251,10 @@ def cmd_cat(argv):
|
|
|
251
251
|
return 0
|
|
252
252
|
block, body = frontmatter.split(text)
|
|
253
253
|
if block:
|
|
254
|
-
print(out.
|
|
254
|
+
print(out.role("---", "muted"))
|
|
255
255
|
for line in block.splitlines():
|
|
256
|
-
print(out.
|
|
257
|
-
print(out.
|
|
256
|
+
print(out.role(line, "muted"))
|
|
257
|
+
print(out.role("---", "muted"))
|
|
258
258
|
print()
|
|
259
259
|
for line in body.splitlines():
|
|
260
260
|
print(out.c(line, out.BOLD) if re.match(r"^#{1,6} ", line) else line)
|
|
@@ -297,7 +297,7 @@ def cmd_edit(argv):
|
|
|
297
297
|
|
|
298
298
|
|
|
299
299
|
def _inline(s: str) -> str:
|
|
300
|
-
s = re.sub(r"`([^`]+)`", lambda m: out.
|
|
300
|
+
s = re.sub(r"`([^`]+)`", lambda m: out.role(m.group(1), "accent"), s)
|
|
301
301
|
return re.sub(r"\*\*([^*]+)\*\*", lambda m: out.c(m.group(1), out.BOLD), s)
|
|
302
302
|
|
|
303
303
|
|
|
@@ -310,7 +310,7 @@ def _render_markdown(body: str) -> None:
|
|
|
310
310
|
in_fence = not in_fence
|
|
311
311
|
continue
|
|
312
312
|
if in_fence:
|
|
313
|
-
print(out.
|
|
313
|
+
print(out.role(" " + line, "muted"))
|
|
314
314
|
prev_blank = False
|
|
315
315
|
continue
|
|
316
316
|
if not line:
|
|
@@ -323,12 +323,12 @@ def _render_markdown(body: str) -> None:
|
|
|
323
323
|
if m:
|
|
324
324
|
level, txt = len(m.group(1)), m.group(2)
|
|
325
325
|
if level == 1:
|
|
326
|
-
print(out.
|
|
327
|
-
print(out.
|
|
326
|
+
print(out.role(txt, "warn", bold=True))
|
|
327
|
+
print(out.role("─" * min(len(txt), 60), "muted"))
|
|
328
328
|
elif level == 2:
|
|
329
329
|
print(out.c(txt, out.BOLD))
|
|
330
330
|
else:
|
|
331
|
-
print(out.
|
|
331
|
+
print(out.role(txt, "muted", bold=True))
|
|
332
332
|
continue
|
|
333
333
|
m = re.match(r"^(\s*)[-*]\s+(.*)$", line)
|
|
334
334
|
if m:
|
|
@@ -470,7 +470,7 @@ def cmd_log(argv):
|
|
|
470
470
|
if not events:
|
|
471
471
|
out.info("no activity yet")
|
|
472
472
|
return 0
|
|
473
|
-
|
|
473
|
+
action_roles = {"install": "success", "uninstall": "danger"}
|
|
474
474
|
w_time = max(len(util.rel_time(e.get("ts", ""))) for e in events)
|
|
475
475
|
w_user = max(len(e.get("user", "?")) for e in events)
|
|
476
476
|
for e in events:
|
|
@@ -478,7 +478,7 @@ def cmd_log(argv):
|
|
|
478
478
|
out.info(("%s %s %s %s" % (
|
|
479
479
|
util.rel_time(e.get("ts", "")).ljust(w_time),
|
|
480
480
|
e.get("user", "?").ljust(w_user),
|
|
481
|
-
out.
|
|
481
|
+
out.role(action, action_roles.get(action, "accent")),
|
|
482
482
|
e.get("subject", ""))).rstrip())
|
|
483
483
|
return 0
|
|
484
484
|
|
|
@@ -539,16 +539,16 @@ def cmd_deps(argv):
|
|
|
539
539
|
return 1 if problems else 0
|
|
540
540
|
out.info(out.c(args.name, out.BOLD))
|
|
541
541
|
if not requires:
|
|
542
|
-
out.info(" requires: " + out.
|
|
542
|
+
out.info(" requires: " + out.role("(none)", "muted"))
|
|
543
543
|
for r in requires:
|
|
544
544
|
out.info(" requires: %s %s" % (r, _mark(r in inst)))
|
|
545
545
|
for sub in _as_list((_skill_meta(r) or {}).get("requires")):
|
|
546
546
|
out.info(" ↳ %s %s" % (sub, _mark(sub in inst)))
|
|
547
547
|
if not conflicts:
|
|
548
|
-
out.info(" conflicts: " + out.
|
|
548
|
+
out.info(" conflicts: " + out.role("(none)", "muted"))
|
|
549
549
|
for c_name in conflicts:
|
|
550
|
-
state = (out.
|
|
551
|
-
else out.
|
|
550
|
+
state = (out.role("✗ installed (conflict!)", "danger") if c_name in inst
|
|
551
|
+
else out.role("not installed", "muted"))
|
|
552
552
|
out.info(" conflicts: %s %s" % (c_name, state))
|
|
553
553
|
return 1 if problems else 0
|
|
554
554
|
|
|
@@ -575,7 +575,7 @@ def cmd_deps(argv):
|
|
|
575
575
|
% (out.c(u["skill"], out.BOLD), u["requires"], _mark(False)))
|
|
576
576
|
for a, b in pairs:
|
|
577
577
|
out.info("%s %s %s" % (out.c(a, out.BOLD),
|
|
578
|
-
out.
|
|
578
|
+
out.role("conflicts with", "danger"), out.c(b, out.BOLD)))
|
|
579
579
|
if not unmet and not pairs:
|
|
580
580
|
out.ok("no unmet requirements or conflicts across %d skill%s"
|
|
581
581
|
% (len(inst), "" if len(inst) == 1 else "s"))
|
|
@@ -613,7 +613,7 @@ def cmd_tag(argv):
|
|
|
613
613
|
return 0
|
|
614
614
|
if not mapping:
|
|
615
615
|
out.info("no tags yet")
|
|
616
|
-
out.info(out.
|
|
616
|
+
out.info(out.role("hint: boost tag <skill> +mytag", "muted"))
|
|
617
617
|
return 0
|
|
618
618
|
out.table([("#" + t, ", ".join(mapping[t])) for t in sorted(mapping)],
|
|
619
619
|
headers=("TAG", "SKILLS"))
|
|
@@ -649,6 +649,6 @@ def cmd_tag(argv):
|
|
|
649
649
|
if args.json:
|
|
650
650
|
print(json.dumps({"name": args.name, "tags": tags}, indent=2))
|
|
651
651
|
return 0
|
|
652
|
-
shown = " ".join(out.
|
|
652
|
+
shown = " ".join(out.role("#" + t, "accent") for t in tags) or out.role("(no tags)", "muted")
|
|
653
653
|
(out.ok if changed else out.info)("%s %s" % (args.name, shown))
|
|
654
654
|
return 0
|
|
@@ -78,7 +78,7 @@ def _install_generated(name: str, text: str) -> None:
|
|
|
78
78
|
res = store.install_from_path(src, name=name, tap_label="local")
|
|
79
79
|
out.ok("installed %s → %s" % (name, _tilde(res.dest)))
|
|
80
80
|
if res.linked:
|
|
81
|
-
out.info(out.
|
|
81
|
+
out.info(out.role("linked into: %s" % ", ".join(res.linked), "muted"))
|
|
82
82
|
|
|
83
83
|
|
|
84
84
|
def _write_generated(dest: Path, text: str) -> bool:
|
|
@@ -139,7 +139,7 @@ def cmd_distill(argv: List[str]) -> int:
|
|
|
139
139
|
dest = Path.cwd() / new / "SKILL.md"
|
|
140
140
|
if not _write_generated(dest, merged):
|
|
141
141
|
return 1
|
|
142
|
-
out.info(out.
|
|
142
|
+
out.info(out.role("install it with `boost import ./%s`" % new, "muted"))
|
|
143
143
|
journal.log("distill", new, sources=names)
|
|
144
144
|
return 0
|
|
145
145
|
|
|
@@ -212,7 +212,7 @@ def cmd_simulate(argv: List[str]) -> int:
|
|
|
212
212
|
|
|
213
213
|
text, origin = _skill_text(args.name)
|
|
214
214
|
task = args.task or "a typical coding task in this repo"
|
|
215
|
-
out.heading("simulating %s %s" % (args.name, out.
|
|
215
|
+
out.heading("simulating %s %s" % (args.name, out.role("(%s)" % origin, "muted")))
|
|
216
216
|
|
|
217
217
|
if ai.available():
|
|
218
218
|
reply = ai.ask(
|
|
@@ -236,13 +236,13 @@ def cmd_simulate(argv: List[str]) -> int:
|
|
|
236
236
|
for rule in rules[:8]:
|
|
237
237
|
out.info(" • " + rule)
|
|
238
238
|
if len(rules) > 8:
|
|
239
|
-
out.info(out.
|
|
239
|
+
out.info(out.role(" … and %d more rules" % (len(rules) - 8), "muted"))
|
|
240
240
|
else:
|
|
241
241
|
out.info(" • (no imperative rules found in the skill body)")
|
|
242
242
|
desc = str(meta.get("description") or "").strip()
|
|
243
243
|
if desc:
|
|
244
|
-
out.info(out.
|
|
245
|
-
% desc[:100],
|
|
244
|
+
out.info(out.role('likely triggers when the task involves: "%s"'
|
|
245
|
+
% desc[:100], "muted"))
|
|
246
246
|
return 0
|
|
247
247
|
|
|
248
248
|
|
|
@@ -526,8 +526,8 @@ def cmd_absorb(argv: List[str]) -> int:
|
|
|
526
526
|
src = paths.home() / ".claude" / "projects"
|
|
527
527
|
if not src.exists():
|
|
528
528
|
out.info("no chat history found under ~/.claude — nothing to absorb")
|
|
529
|
-
out.info(out.
|
|
530
|
-
"--history PATH",
|
|
529
|
+
out.info(out.role("point at a .jsonl file or directory with "
|
|
530
|
+
"--history PATH", "muted"))
|
|
531
531
|
return 0
|
|
532
532
|
files = [src] if src.is_file() else sorted(src.rglob("*.jsonl"))
|
|
533
533
|
if not files:
|
|
@@ -663,7 +663,7 @@ def cmd_evolve(argv: List[str]) -> int:
|
|
|
663
663
|
old_meta, _ = frontmatter.parse(old)
|
|
664
664
|
old_ver = str(old_meta.get("version") or "0.0.0")
|
|
665
665
|
|
|
666
|
-
out.heading("evolving %s %s" % (args.name, out.
|
|
666
|
+
out.heading("evolving %s %s" % (args.name, out.role("(v%s)" % old_ver, "muted")))
|
|
667
667
|
new = _evolve_ai(old, old_ver, args.feedback) if ai.available() else None
|
|
668
668
|
if new is None:
|
|
669
669
|
_note_fallback()
|
|
@@ -673,7 +673,7 @@ def cmd_evolve(argv: List[str]) -> int:
|
|
|
673
673
|
new_ver = str(new_meta.get("version") or old_ver)
|
|
674
674
|
|
|
675
675
|
if not args.apply:
|
|
676
|
-
out.info(out.
|
|
676
|
+
out.info(out.role("re-run with --apply to write these changes", "muted"))
|
|
677
677
|
return 0
|
|
678
678
|
skill_md.write_text(new)
|
|
679
679
|
entry["sha256"] = util.sha256_dir(store.skill_store_dir(args.name))
|
|
@@ -726,11 +726,11 @@ def _print_diff(old: str, new: str) -> None:
|
|
|
726
726
|
if line.startswith(("+++", "---")):
|
|
727
727
|
print(out.c(line, out.BOLD))
|
|
728
728
|
elif line.startswith("@@"):
|
|
729
|
-
print(out.
|
|
729
|
+
print(out.role(line, "accent"))
|
|
730
730
|
elif line.startswith("+"):
|
|
731
|
-
print(out.
|
|
731
|
+
print(out.role(line, "success"))
|
|
732
732
|
elif line.startswith("-"):
|
|
733
|
-
print(out.
|
|
733
|
+
print(out.role(line, "danger"))
|
|
734
734
|
else:
|
|
735
735
|
print(line)
|
|
736
736
|
|
|
@@ -776,7 +776,7 @@ def cmd_context(argv: List[str]) -> int:
|
|
|
776
776
|
journal.log("context", args.pattern, op="map", skills=skills)
|
|
777
777
|
out.ok("mapped %s → %s" % (args.pattern, ", ".join(skills)))
|
|
778
778
|
if missing:
|
|
779
|
-
out.info(out.
|
|
779
|
+
out.info(out.role("not installed yet: %s" % ", ".join(missing), "muted"))
|
|
780
780
|
return 0
|
|
781
781
|
if action == "unmap":
|
|
782
782
|
rules = [r for r in state["rules"] if r.get("pattern") != args.pattern]
|
|
@@ -872,7 +872,7 @@ def _context_apply(state: dict) -> int:
|
|
|
872
872
|
if not linked and not unlinked:
|
|
873
873
|
out.info("nothing to change")
|
|
874
874
|
if missing:
|
|
875
|
-
out.info(out.
|
|
875
|
+
out.info(out.role("mapped but not installed: %s" % ", ".join(missing), "muted"))
|
|
876
876
|
if linked or unlinked:
|
|
877
877
|
journal.log("context", branch, op="apply",
|
|
878
878
|
linked=linked or None, unlinked=unlinked or None)
|
|
@@ -921,9 +921,8 @@ def cmd_focus(argv: List[str]) -> int:
|
|
|
921
921
|
if state.get("active"):
|
|
922
922
|
out.info("⌁ focus: %s %s"
|
|
923
923
|
% (", ".join(state["active"]),
|
|
924
|
-
out.
|
|
925
|
-
|
|
926
|
-
out.info(out.c("end it with `boost focus --clear`", out.DIM))
|
|
924
|
+
out.role("(since %s)" % util.rel_time(state.get("since", "")), "muted")))
|
|
925
|
+
out.info(out.role("end it with `boost focus --clear`", "muted"))
|
|
927
926
|
else:
|
|
928
927
|
out.info("no focus session — start one with `boost focus SKILL...`")
|
|
929
928
|
return 0
|
|
@@ -950,7 +949,7 @@ def cmd_focus(argv: List[str]) -> int:
|
|
|
950
949
|
journal.log("focus", ",".join(names))
|
|
951
950
|
out.info("⌁ focus: %s %s"
|
|
952
951
|
% (", ".join(names),
|
|
953
|
-
out.
|
|
952
|
+
out.role("(other %d skills sidelined)" % sidelined, "muted")))
|
|
954
953
|
return 0
|
|
955
954
|
|
|
956
955
|
|
|
@@ -164,9 +164,8 @@ def cmd_install(argv: List[str]) -> int:
|
|
|
164
164
|
if len(results) == 1:
|
|
165
165
|
r0 = results[0]
|
|
166
166
|
if r0.linked:
|
|
167
|
-
lines.append(out.
|
|
168
|
-
|
|
169
|
-
lines.append(out.c("next: boost info %s" % r0.name, out.DIM))
|
|
167
|
+
lines.append(out.role("%s → %s" % (r0.name, " · ".join(r0.linked)), "muted"))
|
|
168
|
+
lines.append(out.role("next: boost info %s" % r0.name, "muted"))
|
|
170
169
|
print(out.panel(lines, title="installed", hue="green"))
|
|
171
170
|
return 1 if failed else 0
|
|
172
171
|
|
|
@@ -197,7 +196,7 @@ def cmd_uninstall(argv: List[str]) -> int:
|
|
|
197
196
|
if removed:
|
|
198
197
|
lines = ["Uninstalled %s" % _plural(removed, "skill")]
|
|
199
198
|
if removed == 1 and len(args.names) == 1:
|
|
200
|
-
lines.append(out.
|
|
199
|
+
lines.append(out.role("next: boost list", "muted"))
|
|
201
200
|
print(out.panel(lines, title="removed", hue="pink"))
|
|
202
201
|
return 1 if failed else 0
|
|
203
202
|
|