boost-skill-cli 1.0.147__tar.gz → 1.0.149__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.147 → boost_skill_cli-1.0.149}/Makefile +19 -1
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/PKG-INFO +5 -1
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/_version.py +2 -2
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/commands/pkg.py +14 -5
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/core/rules.py +19 -9
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/core/store.py +47 -13
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/core/workflows.py +11 -5
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_skill_cli.egg-info/PKG-INFO +5 -1
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_skill_cli.egg-info/SOURCES.txt +19 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_skill_cli.egg-info/requires.txt +6 -0
- boost_skill_cli-1.0.149/docs/roadmap/items/install-scope-user-or-project.md +27 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap.html +24 -1
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/pyproject.toml +10 -0
- boost_skill_cli-1.0.149/scripts/bench_cli.sh +27 -0
- boost_skill_cli-1.0.149/tests/bdd/features/adapt.feature +46 -0
- boost_skill_cli-1.0.149/tests/bdd/features/browse.feature +26 -0
- boost_skill_cli-1.0.149/tests/bdd/features/count.feature +24 -0
- boost_skill_cli-1.0.149/tests/bdd/features/discover.feature +39 -0
- boost_skill_cli-1.0.149/tests/bdd/features/doctor.feature +30 -0
- boost_skill_cli-1.0.149/tests/bdd/features/environment.py +66 -0
- boost_skill_cli-1.0.149/tests/bdd/features/explain.feature +25 -0
- boost_skill_cli-1.0.149/tests/bdd/features/index.feature +25 -0
- boost_skill_cli-1.0.149/tests/bdd/features/install.feature +43 -0
- boost_skill_cli-1.0.149/tests/bdd/features/list.feature +42 -0
- boost_skill_cli-1.0.149/tests/bdd/features/mcp.feature +31 -0
- boost_skill_cli-1.0.149/tests/bdd/features/search.feature +37 -0
- boost_skill_cli-1.0.149/tests/bdd/features/steps/cli_steps.py +104 -0
- boost_skill_cli-1.0.149/tests/bdd/features/steps/discovery_steps.py +77 -0
- boost_skill_cli-1.0.149/tests/bdd/features/steps/mcp_steps.py +48 -0
- boost_skill_cli-1.0.149/tests/bdd/features/steps/quality_steps.py +12 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/functional/test_cli_pkg.py +16 -0
- boost_skill_cli-1.0.149/tests/perf/test_benchmarks.py +59 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/unit/test_rules.py +18 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/unit/test_store.py +48 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/unit/test_workflows.py +10 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/.gitattributes +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/.gitignore +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/CLAUDE.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/CONTRIBUTING.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/LICENSE +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/MANIFEST.in +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/README.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/SECURITY.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/__init__.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/__main__.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/cli.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/cliparse.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/commands/__init__.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/commands/bmad.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/commands/configuration.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/commands/discovery.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/commands/hooks.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/commands/info.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/commands/intelligence.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/commands/quality.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/commands/taps.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/commands/team.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/core/__init__.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/core/adapters.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/core/agents.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/core/ai.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/core/catalog.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/core/claude_settings.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/core/config.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/core/dense.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/core/embed.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/core/frontmatter.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/core/gitutil.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/core/imperative.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/core/injectscan.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/core/journal.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/core/lockfile.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/core/logs.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/core/mcp.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/core/nethttp.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/core/output.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/core/paths.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/core/policy.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/core/rag.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/core/registry.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/core/secretscan.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/core/serve.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/core/stackprobe.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/core/staleness.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/core/typosquat.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/core/updatediff.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/core/util.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/data/registries.json +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/errors.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_cli/spin.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_skill_cli.egg-info/dependency_links.txt +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_skill_cli.egg-info/entry_points.txt +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/boost_skill_cli.egg-info/top_level.txt +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/.claude/settings.local.json +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/DEBUGGING.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/adapters.html +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/demo.gif +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/demo.tape +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/design-roadmap.html +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/eval.html +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/index.html +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/mcp-hub.html +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/rag-architecture.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/BOOST-D01.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/BOOST-D02.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/BOOST-D03.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/BOOST-D04.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/BOOST-D05.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/BOOST-D06.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/BOOST-D07.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/BOOST-D08.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/BOOST-D09.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/BOOST-D10.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/BOOST-D11.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/BOOST-D12.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/BOOST-D13.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/BOOST-D14.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/BOOST-D15.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/BOOST-D16.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/BOOST-D17.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/BOOST-D18.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/BOOST-D19.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/BOOST-D20.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/BOOST-D21.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/BOOST-D22.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/BOOST-D23.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/BOOST-D24.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/BOOST-D25.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/BOOST-D26.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/accessibility-audit-pa11y-ci-axe-core.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/atomic-corruption-safe-lock-file-writes.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/atomic-skill-install-temp-dir-swap.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/autonomous-ship-workflow-and-isolated-worktree.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/boost-run-live-agents.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/bring-commands-under-mutation-testing.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/broken-link-and-anchor-checking-lychee.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/browse-crashes-selecting-a-rule-or-workflow.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/build-provenance-slsa-attestations.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/cache-the-catalog-entry-set-across-rag-queries.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/capability-manifest-and-least-privilege-policy.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/clean-env-install-smoke-pip-and-pipx.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/command-reference-docs-site.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/complexity-and-dead-code-radar-xenon-vulture.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/consolidate-skill-staleness-drift-logic-into-cor.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/coverage-dashboard-codecov-free-for-oss.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/coverage-guided-fuzzing-atheris-oss-fuzz.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/crash-recorder-error-paths-core-logs-py.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/dependency-cve-gate-pip-audit.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/docstring-coverage-interrogate.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/doctor-checks-rules-and-workflows.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/end-of-options-guard-on-git-commands.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/extension-free-tests-core-dense-py.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/extract-mcp-http-servers-out-of-configuration-py.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/finish-mutation-hardening-across-core.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/fix-self-update-version-detection-dead-branch.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/fork-safe-network-proxy-handler.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/framework-adapter-langgraph.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/framework-adapter-multi-agent.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/framework-adapters-boost-adapt.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/frontmatter-scalar-over-coercion.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/github-pages-deploy-is-broken-every-push.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/golden-set-statistical-power.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/hash-pinned-reproducible-toolchain-uv-lock.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/html-validation-html-validate.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/integrity-verification-boost-verify.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/invocation-pid-logging-for-crash-correlation.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/layering-guard-import-linter.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/lighthouse-ci-on-the-pages-site.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/list-rules-and-workflows.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/localize-the-stored-bm25-snippet.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/lockfile-enforcement-and-commit-pinning.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/log-timestamps-mislabeled-utc.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/lowest-version-resolution-uv-resolution-lowest-d.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/make-the-roadmaps-discoverable.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/markdown-consistency-markdownlint-cli2.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/mcp-hub-diagram-node-text-overflow.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/mcp-launch-objc-fork-safety.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/mcp-register-names-server-before-env.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/mcp-startup-self-harden-fork-safety.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/memoize-config-load-in-process.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/modernization-smells-refurb-pyupgrade.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/mutation-hardening-core-frontmatter-py.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/mutation-hardening-core-gitutil-py.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/mutation-hardening-core-store-py.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/one-command-every-env-nox.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/one-shared-atomic-write-helper.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/package-metadata-validation-twine-check-friends.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/patch-coverage-gate-diff-cover.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/performance-regression-gate-pytest-benchmark.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/post-deploy-smoke-headless-load-check.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/pre-release-python-canary-3-14t-free-threaded.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/promote-nav-footer-into-the-shared-style-system.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/prompt-injection-scanning-of-skill-markdown.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/property-based-tests-hypothesis-on-the-parsers.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/prose-and-terminology-linting-vale.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/prune-ignored-dirs-during-scan-dir-walk.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/quality-dashboard-sonarcloud-free-for-oss.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/ranx-significance-monitor.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/reconcile-the-theme-drift.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/refresh-the-marketing-surface.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/retrieval-quality-eval-harness.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/reuse-helpers-kill-minor-dead-work.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/robust-tag-argument-parsing.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/rule-install-native-materialization.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/runner-egress-monitoring-stepsecurity-harden-run.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/runtime-explain-faithfulness-guardrail.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/sbom-aware-scanning-osv-scanner.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/sbom-on-every-release-cyclonedx-syft.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/scan-and-sync-rules-and-workflows.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/second-type-checker-pyright.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/secret-and-pii-scanning-of-installed-skills.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/secret-scanning-gitleaks-push-protection.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/security-linting-bandit-via-ruff-s-rules.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/shift-left-gate-pre-commit-pre-commit-ci.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/single-imperative-rule-extractor.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/single-tech-stack-prober.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/split-oversized-command-modules.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/startup-and-import-time-budget-x-importtime.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/stop-re-serializing-entry-meta-on-every-search.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/supply-chain-posture-openssf-scorecard.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/surface-every-docs-page-from-the-guide.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/tap-signing-and-provenance-sigstore-minisign.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/theme-asset-linting-stylelint-eslint.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/typo-detection-codespell.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/typosquat-and-name-confusion-detection.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/unify-tilde-two-copies-have-a-boundary-bug.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/untrack-generated-build-noise.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/update-diff-before-apply.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/update-refreshes-rules-and-workflows.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/visual-regression-pass-on-the-guide.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/widen-the-ruff-rule-surface-b-sim-c4-perf-ruf.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/windows-in-the-ci-matrix.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/workflow-install-native-materialization.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/workflow-linting-actionlint.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/workflow-sast-zizmor.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/docs/roadmap/items/workspace-scope-install.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/examples/README.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/examples/adapt-demo.sh +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/examples/boost-run-prototype.sh +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/index.html +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/scripts/build_registries.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/scripts/build_roadmap.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/scripts/ensure_eval_corpus.sh +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/scripts/eval_explain.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/scripts/eval_recommend.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/scripts/eval_retrieval.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/scripts/mutation_gate.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/setup.cfg +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/style/README.md +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/style/boost.css +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/style/boost.js +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/style/demo.html +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/conftest.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/eval/baseline.json +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/eval/explain.jsonl +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/eval/golden.jsonl +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/eval/recommend.jsonl +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/eval/taps.txt +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/functional/test_cli_adapt.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/functional/test_cli_bmad.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/functional/test_cli_configuration.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/functional/test_cli_discovery.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/functional/test_cli_hooks.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/functional/test_cli_info.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/functional/test_cli_intelligence.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/functional/test_cli_quality.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/functional/test_cli_taps.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/functional/test_cli_team.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/functional/test_everyday_loop.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/functional/test_property_parsers.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/make_fixture.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/smoke.sh +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/unit/test_adapters.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/unit/test_agents.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/unit/test_ai.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/unit/test_catalog.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/unit/test_claude_settings.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/unit/test_cliparse.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/unit/test_config.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/unit/test_dense.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/unit/test_dense_fallback.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/unit/test_docs_pages_linked.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/unit/test_embed.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/unit/test_errors_and_cli_table.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/unit/test_frontmatter.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/unit/test_gitutil.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/unit/test_imperative.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/unit/test_injectscan.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/unit/test_journal.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/unit/test_lockfile.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/unit/test_logs.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/unit/test_mcp.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/unit/test_mutation_hardening.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/unit/test_nethttp.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/unit/test_output.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/unit/test_paths.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/unit/test_pkg_confusions.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/unit/test_pkg_injection.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/unit/test_pkg_secrets.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/unit/test_policy.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/unit/test_rag.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/unit/test_registries_fresh.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/unit/test_registry.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/unit/test_roadmap_fresh.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/unit/test_secretscan.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/unit/test_serve.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/unit/test_spin.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/unit/test_stackprobe.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/unit/test_staleness.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/unit/test_token_parity.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/unit/test_typosquat.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/unit/test_updatediff.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/unit/test_util.py +0 -0
- {boost_skill_cli-1.0.147 → boost_skill_cli-1.0.149}/tests/unit/test_version.py +0 -0
|
@@ -10,7 +10,7 @@ PYTEST := $(VENV)/bin/pytest
|
|
|
10
10
|
# pinned taps out of the developer's real ~/.boost.
|
|
11
11
|
EVAL_HOME := $(CURDIR)/.eval-home
|
|
12
12
|
|
|
13
|
-
.PHONY: venv test unit functional smoke coverage mutation lint check demo clean-test eval eval-ai eval-rec eval-stats eval-explain audit dist-check
|
|
13
|
+
.PHONY: venv test unit functional smoke coverage mutation lint check demo clean-test eval eval-ai eval-rec eval-stats eval-explain audit dist-check bdd bench bench-cli
|
|
14
14
|
|
|
15
15
|
venv:
|
|
16
16
|
python3 -m venv $(VENV)
|
|
@@ -96,6 +96,24 @@ eval-explain:
|
|
|
96
96
|
PYTHON=$(PY) BOOST_HOME=$(EVAL_HOME) bash scripts/ensure_eval_corpus.sh
|
|
97
97
|
BOOST_HOME=$(EVAL_HOME) $(PY) scripts/eval_explain.py --fail-under 0.80
|
|
98
98
|
|
|
99
|
+
# Opt-in Gherkin/BDD suite (tests/bdd) — additive to tests/functional, not a
|
|
100
|
+
# replacement. Needs the [bdd] extra (`pip install -e '.[bdd]'`); not part of
|
|
101
|
+
# `make check`.
|
|
102
|
+
bdd:
|
|
103
|
+
$(VENV)/bin/behave tests/bdd/features
|
|
104
|
+
|
|
105
|
+
# Opt-in micro-benchmarks (tests/perf) for perf-sensitive core paths. Needs
|
|
106
|
+
# the [perf] extra (`pip install -e '.[perf]'`); not part of `make check` — a
|
|
107
|
+
# timing regression is informational, not a merge gate.
|
|
108
|
+
bench:
|
|
109
|
+
$(PYTEST) tests/perf --benchmark-only -q
|
|
110
|
+
|
|
111
|
+
# Opt-in wall-clock benchmark of the real `boost` binary via hyperfine. Not
|
|
112
|
+
# part of `make check`; degrades cleanly (prints a skip message, exits 0) when
|
|
113
|
+
# hyperfine isn't installed (`brew install hyperfine`).
|
|
114
|
+
bench-cli:
|
|
115
|
+
@command -v hyperfine >/dev/null 2>&1 && bash scripts/bench_cli.sh || echo "hyperfine not on PATH — install via 'brew install hyperfine', skipping"
|
|
116
|
+
|
|
99
117
|
# regenerate generated artifacts from their source (registries + roadmap boards)
|
|
100
118
|
generate:
|
|
101
119
|
$(PY) scripts/build_registries.py
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: boost-skill-cli
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.149
|
|
4
4
|
Summary: boost — Homebrew for AI coding skills
|
|
5
5
|
Author: Jonathan Reyes
|
|
6
6
|
License: GNU GENERAL PUBLIC LICENSE
|
|
@@ -708,6 +708,10 @@ Requires-Dist: ragas<0.3,>=0.2; extra == "eval"
|
|
|
708
708
|
Requires-Dist: langchain-core<0.4; extra == "eval"
|
|
709
709
|
Requires-Dist: langchain-community<0.4; extra == "eval"
|
|
710
710
|
Requires-Dist: langchain-openai<1; extra == "eval"
|
|
711
|
+
Provides-Extra: bdd
|
|
712
|
+
Requires-Dist: behave>=1.2.6; extra == "bdd"
|
|
713
|
+
Provides-Extra: perf
|
|
714
|
+
Requires-Dist: pytest-benchmark>=4.0; extra == "perf"
|
|
711
715
|
Dynamic: license-file
|
|
712
716
|
|
|
713
717
|
# boost — a package manager for AI coding skills
|
|
@@ -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.149'
|
|
22
|
+
__version_tuple__ = version_tuple = (1, 0, 149)
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -118,7 +118,9 @@ def _warn_secrets(res: store.InstallResult) -> None:
|
|
|
118
118
|
def _report_result(res: store.InstallResult) -> None:
|
|
119
119
|
"""The canonical three-line install report."""
|
|
120
120
|
if res.kind in ("rule", "workflow"):
|
|
121
|
-
|
|
121
|
+
where = " (this repo)" if res.scope == "project" else ""
|
|
122
|
+
out.ok("materialized%s → %s"
|
|
123
|
+
% (where, " · ".join(res.linked) or "(no enabled agents)"))
|
|
122
124
|
out.ok("lock updated (.skill-lock.json)")
|
|
123
125
|
_warn_injection(res)
|
|
124
126
|
_warn_secrets(res)
|
|
@@ -166,6 +168,9 @@ def cmd_install(argv: List[str]) -> int:
|
|
|
166
168
|
help="reinstall even if already installed or pinned")
|
|
167
169
|
ap.add_argument("--agent", action="append", metavar="A",
|
|
168
170
|
help="link only into this agent (repeatable)")
|
|
171
|
+
ap.add_argument("--scope", choices=("user", "project"), default="user",
|
|
172
|
+
help="rules/workflows: install into your user config (default) "
|
|
173
|
+
"or the current repo (project)")
|
|
169
174
|
ap.add_argument("--dry-run", action="store_true",
|
|
170
175
|
help="show what would happen without changing anything")
|
|
171
176
|
args = ap.parse_args(argv)
|
|
@@ -191,8 +196,10 @@ def cmd_install(argv: List[str]) -> int:
|
|
|
191
196
|
seen = (lockfile.get_rule if k == "rule"
|
|
192
197
|
else lockfile.get_workflow)(e["name"])
|
|
193
198
|
verb = "reinstall" if seen else "install"
|
|
194
|
-
|
|
195
|
-
|
|
199
|
+
where = "into this repo" if args.scope == "project" else "user config"
|
|
200
|
+
out.info("would %s %s %s v%s from %s (%s)" % (verb, k, e["name"],
|
|
201
|
+
e["version"], e["tap"],
|
|
202
|
+
where))
|
|
196
203
|
out.info(" materialize → %s" % (" · ".join(targets)
|
|
197
204
|
or "(no enabled agents)"))
|
|
198
205
|
continue
|
|
@@ -210,7 +217,7 @@ def cmd_install(argv: List[str]) -> int:
|
|
|
210
217
|
if multi:
|
|
211
218
|
out.heading("%s v%s (%s)" % (e["name"], e["version"], e["tap"]))
|
|
212
219
|
try:
|
|
213
|
-
res = store.install(e, force=args.force, only_agents=only)
|
|
220
|
+
res = store.install(e, force=args.force, only_agents=only, scope=args.scope)
|
|
214
221
|
except BoostError as err:
|
|
215
222
|
if not multi:
|
|
216
223
|
raise
|
|
@@ -414,7 +421,9 @@ def _update_materialized(kind: str, installed: Dict[str, dict], results) -> int:
|
|
|
414
421
|
if not changed:
|
|
415
422
|
continue
|
|
416
423
|
try:
|
|
417
|
-
|
|
424
|
+
# keep the item where it was installed (user vs a specific repo).
|
|
425
|
+
store.install(entry, force=True,
|
|
426
|
+
scope=lk.get("scope", "user"), base=lk.get("base"))
|
|
418
427
|
except BoostError as err:
|
|
419
428
|
out.warn("%s: %s" % (name, err.message))
|
|
420
429
|
continue
|
|
@@ -15,7 +15,7 @@ the filesystem writes and the lock record so uninstall can reverse them.
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
17
|
from pathlib import Path
|
|
18
|
-
from typing import Tuple
|
|
18
|
+
from typing import Optional, Tuple
|
|
19
19
|
|
|
20
20
|
# Name-scoped managed-block markers for CLAUDE.md. Stable + per-rule so install
|
|
21
21
|
# is idempotent (a re-install replaces the block) and uninstall strips exactly
|
|
@@ -40,17 +40,27 @@ def markers(name: str) -> Tuple[str, str]:
|
|
|
40
40
|
return BLOCK_START % name, BLOCK_END % name
|
|
41
41
|
|
|
42
42
|
|
|
43
|
-
def rule_target(agent: str, skills_dir: Path, name: str
|
|
44
|
-
|
|
43
|
+
def rule_target(agent: str, skills_dir: Path, name: str,
|
|
44
|
+
base: "Optional[Path]" = None) -> Tuple[str, Path]:
|
|
45
|
+
"""Where rule ``name`` materializes for ``agent``.
|
|
45
46
|
|
|
46
|
-
Returns ``(mode, path)``: ``MODE_CLAUDE`` writes/merges
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
Returns ``(mode, path)``: ``MODE_CLAUDE`` writes/merges a CLAUDE.md;
|
|
48
|
+
``MODE_FILE`` drops a file into the agent's ``rules/`` dir.
|
|
49
|
+
|
|
50
|
+
``base`` selects the scope:
|
|
51
|
+
* ``None`` (user scope) — the agent's user config: the parent of its
|
|
52
|
+
configured skills dir (``~/.cursor/skills`` -> ``~/.cursor``), and
|
|
53
|
+
``~/.claude/CLAUDE.md`` for Claude.
|
|
54
|
+
* a directory (project scope) — that repo: ``<base>/.cursor/rules/…`` and,
|
|
55
|
+
since Claude reads per-repo memory from the root, ``<base>/CLAUDE.local.md``
|
|
56
|
+
(the personal, git-ignored file) for Claude.
|
|
50
57
|
"""
|
|
51
|
-
|
|
58
|
+
dotdir = Path(skills_dir).parent.name # ".claude" / ".cursor" / …
|
|
52
59
|
if agent in CLAUDE_MD_AGENTS:
|
|
53
|
-
|
|
60
|
+
if base is not None:
|
|
61
|
+
return MODE_CLAUDE, Path(base) / "CLAUDE.local.md"
|
|
62
|
+
return MODE_CLAUDE, Path(skills_dir).parent / "CLAUDE.md"
|
|
63
|
+
root = (Path(base) / dotdir) if base is not None else Path(skills_dir).parent
|
|
54
64
|
ext = RULE_DIR_EXT.get(agent, DEFAULT_RULE_EXT)
|
|
55
65
|
return MODE_FILE, root / "rules" / (name + ext)
|
|
56
66
|
|
|
@@ -26,6 +26,7 @@ class InstallResult:
|
|
|
26
26
|
score: int = 0
|
|
27
27
|
upgraded: bool = False
|
|
28
28
|
kind: str = "skill"
|
|
29
|
+
scope: str = "user" # "user" or "project" — where a rule/workflow landed
|
|
29
30
|
# For rules/workflows the installed content is a single file (or a merged
|
|
30
31
|
# CLAUDE.md block), not a SKILL.md tree — carry the raw source so the caller
|
|
31
32
|
# scans exactly what it installed instead of a non-existent SKILL.md.
|
|
@@ -117,14 +118,32 @@ def _copy_skill(src: Path, dest: Path) -> None:
|
|
|
117
118
|
shutil.rmtree(backup, ignore_errors=True)
|
|
118
119
|
|
|
119
120
|
|
|
121
|
+
def _resolve_base(scope: str, base) -> Optional[Path]:
|
|
122
|
+
"""Directory a project-scoped install materializes under (the repo), or None
|
|
123
|
+
for user scope. An explicit ``base`` (e.g. from a lock record on update/sync)
|
|
124
|
+
wins so a re-materialization lands where the original install did, not in
|
|
125
|
+
whatever the current working directory happens to be."""
|
|
126
|
+
if base:
|
|
127
|
+
return Path(base)
|
|
128
|
+
return Path.cwd() if scope == "project" else None
|
|
129
|
+
|
|
130
|
+
|
|
120
131
|
def install(entry: dict, force: bool = False,
|
|
121
|
-
only_agents: Optional[List[str]] = None
|
|
122
|
-
|
|
132
|
+
only_agents: Optional[List[str]] = None,
|
|
133
|
+
scope: str = "user", base=None) -> InstallResult:
|
|
134
|
+
"""Install a catalog entry. Raises BoostError on policy block or conflict.
|
|
135
|
+
|
|
136
|
+
``scope`` is ``"user"`` (default — the agent's user config dirs) or
|
|
137
|
+
``"project"`` (the current repo). Skills ignore scope (they always live in
|
|
138
|
+
the canonical store); rules/workflows honor it.
|
|
139
|
+
"""
|
|
123
140
|
kind = entry.get("kind", "skill")
|
|
124
141
|
if kind == "rule":
|
|
125
|
-
return _install_rule(entry, force=force, only_agents=only_agents
|
|
142
|
+
return _install_rule(entry, force=force, only_agents=only_agents,
|
|
143
|
+
scope=scope, base=base)
|
|
126
144
|
if kind == "workflow":
|
|
127
|
-
return _install_workflow(entry, force=force, only_agents=only_agents
|
|
145
|
+
return _install_workflow(entry, force=force, only_agents=only_agents,
|
|
146
|
+
scope=scope, base=base)
|
|
128
147
|
if kind != "skill":
|
|
129
148
|
raise BoostError(
|
|
130
149
|
"%s is a %s, which boost does not know how to install" % (entry["name"], kind),
|
|
@@ -172,14 +191,16 @@ def install(entry: dict, force: bool = False,
|
|
|
172
191
|
|
|
173
192
|
|
|
174
193
|
def _install_rule(entry: dict, force: bool = False,
|
|
175
|
-
only_agents: Optional[List[str]] = None
|
|
194
|
+
only_agents: Optional[List[str]] = None,
|
|
195
|
+
scope: str = "user", base=None) -> InstallResult:
|
|
176
196
|
"""Materialize a rule into each enabled agent's native format.
|
|
177
197
|
|
|
178
198
|
Cursor/Windsurf/Cline get a verbatim file drop in their ``rules/`` dir
|
|
179
199
|
(frontmatter preserved — it is native rule metadata); Claude Code has no
|
|
180
200
|
rules folder, so the rule merges into ``CLAUDE.md`` as an idempotent managed
|
|
181
|
-
block.
|
|
182
|
-
|
|
201
|
+
block. With ``scope="project"`` these land under the repo (and Claude uses
|
|
202
|
+
``CLAUDE.local.md``). Every materialization is recorded so ``uninstall``
|
|
203
|
+
reverses exactly what was written.
|
|
183
204
|
"""
|
|
184
205
|
import hashlib
|
|
185
206
|
|
|
@@ -204,13 +225,14 @@ def _install_rule(entry: dict, force: bool = False,
|
|
|
204
225
|
meta, body = frontmatter.parse(raw)
|
|
205
226
|
claude_body = rules.render_claude_body(str(meta.get("name") or name), body)
|
|
206
227
|
|
|
228
|
+
resolved_base = _resolve_base(scope, base)
|
|
207
229
|
paths.ensure_dirs()
|
|
208
230
|
materializations: List[dict] = []
|
|
209
231
|
linked: List[str] = []
|
|
210
232
|
for agent, skills_dir in agents.enabled_agents().items():
|
|
211
233
|
if only_agents and agent not in only_agents:
|
|
212
234
|
continue
|
|
213
|
-
mode, path = rules.rule_target(agent, skills_dir, name)
|
|
235
|
+
mode, path = rules.rule_target(agent, skills_dir, name, base=resolved_base)
|
|
214
236
|
path.parent.mkdir(parents=True, exist_ok=True)
|
|
215
237
|
if mode == rules.MODE_CLAUDE:
|
|
216
238
|
current = path.read_text(encoding="utf-8") if path.exists() else ""
|
|
@@ -228,6 +250,8 @@ def _install_rule(entry: dict, force: bool = False,
|
|
|
228
250
|
"source_file": entry.get("skill_md", ""),
|
|
229
251
|
"commit": gitutil.head_commit(tap.path),
|
|
230
252
|
"sha256": hashlib.sha256(raw.encode("utf-8")).hexdigest(),
|
|
253
|
+
"scope": scope,
|
|
254
|
+
"base": str(resolved_base) if resolved_base is not None else None,
|
|
231
255
|
"installed_at": (existing or {}).get("installed_at", now),
|
|
232
256
|
"updated_at": now,
|
|
233
257
|
"materializations": materializations,
|
|
@@ -240,6 +264,7 @@ def _install_rule(entry: dict, force: bool = False,
|
|
|
240
264
|
kind="rule", scan_text=raw)
|
|
241
265
|
res.linked = linked
|
|
242
266
|
res.upgraded = existing is not None
|
|
267
|
+
res.scope = scope
|
|
243
268
|
return res
|
|
244
269
|
|
|
245
270
|
|
|
@@ -266,12 +291,14 @@ def _uninstall_rule(name: str, rule: dict) -> dict:
|
|
|
266
291
|
|
|
267
292
|
|
|
268
293
|
def _install_workflow(entry: dict, force: bool = False,
|
|
269
|
-
only_agents: Optional[List[str]] = None
|
|
294
|
+
only_agents: Optional[List[str]] = None,
|
|
295
|
+
scope: str = "user", base=None) -> InstallResult:
|
|
270
296
|
"""Materialize a workflow (slash command / subagent) into each enabled agent.
|
|
271
297
|
|
|
272
298
|
A verbatim Markdown drop into the agent's ``commands/`` or ``agents/`` dir —
|
|
273
|
-
the slot derived from the source path — with no transformation.
|
|
274
|
-
|
|
299
|
+
the slot derived from the source path — with no transformation. With
|
|
300
|
+
``scope="project"`` the drop lands under the repo (``<repo>/.claude/…``).
|
|
301
|
+
Every drop is recorded so ``uninstall`` removes exactly the files it wrote.
|
|
275
302
|
"""
|
|
276
303
|
import hashlib
|
|
277
304
|
|
|
@@ -296,13 +323,14 @@ def _install_workflow(entry: dict, force: bool = False,
|
|
|
296
323
|
raw = src.read_text(encoding="utf-8", errors="replace")
|
|
297
324
|
slot = workflows.detect_slot(source_rel)
|
|
298
325
|
|
|
326
|
+
resolved_base = _resolve_base(scope, base)
|
|
299
327
|
paths.ensure_dirs()
|
|
300
328
|
materializations: List[dict] = []
|
|
301
329
|
linked: List[str] = []
|
|
302
330
|
for agent, skills_dir in agents.enabled_agents().items():
|
|
303
331
|
if only_agents and agent not in only_agents:
|
|
304
332
|
continue
|
|
305
|
-
path = workflows.workflow_target(skills_dir, slot, name)
|
|
333
|
+
path = workflows.workflow_target(skills_dir, slot, name, base=resolved_base)
|
|
306
334
|
path.parent.mkdir(parents=True, exist_ok=True)
|
|
307
335
|
util.atomic_write_text(path, raw)
|
|
308
336
|
materializations.append({"agent": agent, "slot": slot, "path": str(path)})
|
|
@@ -317,6 +345,8 @@ def _install_workflow(entry: dict, force: bool = False,
|
|
|
317
345
|
"source_file": source_rel,
|
|
318
346
|
"commit": gitutil.head_commit(tap.path),
|
|
319
347
|
"sha256": hashlib.sha256(raw.encode("utf-8")).hexdigest(),
|
|
348
|
+
"scope": scope,
|
|
349
|
+
"base": str(resolved_base) if resolved_base is not None else None,
|
|
320
350
|
"installed_at": (existing or {}).get("installed_at", now),
|
|
321
351
|
"updated_at": now,
|
|
322
352
|
"materializations": materializations,
|
|
@@ -329,6 +359,7 @@ def _install_workflow(entry: dict, force: bool = False,
|
|
|
329
359
|
kind="workflow", scan_text=raw)
|
|
330
360
|
res.linked = linked
|
|
331
361
|
res.upgraded = existing is not None
|
|
362
|
+
res.scope = scope
|
|
332
363
|
return res
|
|
333
364
|
|
|
334
365
|
|
|
@@ -506,7 +537,10 @@ def sync_apply(plan: Dict[str, list]) -> List[str]:
|
|
|
506
537
|
matches = [e for e in catalog.find(name)
|
|
507
538
|
if e["tap"] == tap_name and e.get("kind", "skill") == kind]
|
|
508
539
|
if matches:
|
|
509
|
-
|
|
540
|
+
# preserve the original scope/base so a project rule repairs
|
|
541
|
+
# into its repo, not wherever sync happens to run.
|
|
542
|
+
install(matches[0], force=True,
|
|
543
|
+
scope=entry.get("scope", "user"), base=entry.get("base"))
|
|
510
544
|
actions.append("re-materialized %s %s from %s"
|
|
511
545
|
% (kind, name, tap_name))
|
|
512
546
|
continue
|
|
@@ -14,6 +14,7 @@ the filesystem writes and the lock record so uninstall can reverse them.
|
|
|
14
14
|
from __future__ import annotations
|
|
15
15
|
|
|
16
16
|
from pathlib import Path
|
|
17
|
+
from typing import Optional
|
|
17
18
|
|
|
18
19
|
SLOT_COMMANDS = "commands"
|
|
19
20
|
SLOT_AGENTS = "agents"
|
|
@@ -36,11 +37,16 @@ def detect_slot(source_rel: str) -> str:
|
|
|
36
37
|
return SLOT_AGENTS if parts & AGENT_DIRS else SLOT_COMMANDS
|
|
37
38
|
|
|
38
39
|
|
|
39
|
-
def workflow_target(skills_dir: Path, slot: str, name: str
|
|
40
|
+
def workflow_target(skills_dir: Path, slot: str, name: str,
|
|
41
|
+
base: Optional[Path] = None) -> Path:
|
|
40
42
|
"""Where workflow ``name`` (in ``slot``) materializes for an agent.
|
|
41
43
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
44
|
+
``base`` selects the scope:
|
|
45
|
+
* ``None`` (user scope) — the parent of the agent's configured skills dir
|
|
46
|
+
(``~/.claude/skills`` -> ``~/.claude/<slot>/<name>.md``).
|
|
47
|
+
* a directory (project scope) — that repo's per-agent dotdir
|
|
48
|
+
(``<base>/.claude/<slot>/<name>.md``).
|
|
45
49
|
"""
|
|
46
|
-
|
|
50
|
+
root = (Path(base) / Path(skills_dir).parent.name) if base is not None \
|
|
51
|
+
else Path(skills_dir).parent
|
|
52
|
+
return root / slot / (name + ".md")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: boost-skill-cli
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.149
|
|
4
4
|
Summary: boost — Homebrew for AI coding skills
|
|
5
5
|
Author: Jonathan Reyes
|
|
6
6
|
License: GNU GENERAL PUBLIC LICENSE
|
|
@@ -708,6 +708,10 @@ Requires-Dist: ragas<0.3,>=0.2; extra == "eval"
|
|
|
708
708
|
Requires-Dist: langchain-core<0.4; extra == "eval"
|
|
709
709
|
Requires-Dist: langchain-community<0.4; extra == "eval"
|
|
710
710
|
Requires-Dist: langchain-openai<1; extra == "eval"
|
|
711
|
+
Provides-Extra: bdd
|
|
712
|
+
Requires-Dist: behave>=1.2.6; extra == "bdd"
|
|
713
|
+
Provides-Extra: perf
|
|
714
|
+
Requires-Dist: pytest-benchmark>=4.0; extra == "perf"
|
|
711
715
|
Dynamic: license-file
|
|
712
716
|
|
|
713
717
|
# boost — a package manager for AI coding skills
|
|
@@ -141,6 +141,7 @@ docs/roadmap/items/github-pages-deploy-is-broken-every-push.md
|
|
|
141
141
|
docs/roadmap/items/golden-set-statistical-power.md
|
|
142
142
|
docs/roadmap/items/hash-pinned-reproducible-toolchain-uv-lock.md
|
|
143
143
|
docs/roadmap/items/html-validation-html-validate.md
|
|
144
|
+
docs/roadmap/items/install-scope-user-or-project.md
|
|
144
145
|
docs/roadmap/items/integrity-verification-boost-verify.md
|
|
145
146
|
docs/roadmap/items/invocation-pid-logging-for-crash-correlation.md
|
|
146
147
|
docs/roadmap/items/layering-guard-import-linter.md
|
|
@@ -216,6 +217,7 @@ docs/roadmap/items/workspace-scope-install.md
|
|
|
216
217
|
examples/README.md
|
|
217
218
|
examples/adapt-demo.sh
|
|
218
219
|
examples/boost-run-prototype.sh
|
|
220
|
+
scripts/bench_cli.sh
|
|
219
221
|
scripts/build_registries.py
|
|
220
222
|
scripts/build_roadmap.py
|
|
221
223
|
scripts/ensure_eval_corpus.sh
|
|
@@ -230,6 +232,22 @@ style/demo.html
|
|
|
230
232
|
tests/conftest.py
|
|
231
233
|
tests/make_fixture.py
|
|
232
234
|
tests/smoke.sh
|
|
235
|
+
tests/bdd/features/adapt.feature
|
|
236
|
+
tests/bdd/features/browse.feature
|
|
237
|
+
tests/bdd/features/count.feature
|
|
238
|
+
tests/bdd/features/discover.feature
|
|
239
|
+
tests/bdd/features/doctor.feature
|
|
240
|
+
tests/bdd/features/environment.py
|
|
241
|
+
tests/bdd/features/explain.feature
|
|
242
|
+
tests/bdd/features/index.feature
|
|
243
|
+
tests/bdd/features/install.feature
|
|
244
|
+
tests/bdd/features/list.feature
|
|
245
|
+
tests/bdd/features/mcp.feature
|
|
246
|
+
tests/bdd/features/search.feature
|
|
247
|
+
tests/bdd/features/steps/cli_steps.py
|
|
248
|
+
tests/bdd/features/steps/discovery_steps.py
|
|
249
|
+
tests/bdd/features/steps/mcp_steps.py
|
|
250
|
+
tests/bdd/features/steps/quality_steps.py
|
|
233
251
|
tests/eval/baseline.json
|
|
234
252
|
tests/eval/explain.jsonl
|
|
235
253
|
tests/eval/golden.jsonl
|
|
@@ -248,6 +266,7 @@ tests/functional/test_cli_taps.py
|
|
|
248
266
|
tests/functional/test_cli_team.py
|
|
249
267
|
tests/functional/test_everyday_loop.py
|
|
250
268
|
tests/functional/test_property_parsers.py
|
|
269
|
+
tests/perf/test_benchmarks.py
|
|
251
270
|
tests/unit/test_adapters.py
|
|
252
271
|
tests/unit/test_agents.py
|
|
253
272
|
tests/unit/test_ai.py
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: install-scope-user-or-project
|
|
3
|
+
board: code
|
|
4
|
+
section: internals
|
|
5
|
+
status: shipped
|
|
6
|
+
category: Install engine · UX
|
|
7
|
+
complexity: M
|
|
8
|
+
impact: High
|
|
9
|
+
wow: 3
|
|
10
|
+
note: rules/workflows were user-global only
|
|
11
|
+
order: 27
|
|
12
|
+
owner: loop/install-scope
|
|
13
|
+
pr: 169
|
|
14
|
+
title: <code>boost install --scope user|project</code> for rules/workflows
|
|
15
|
+
---
|
|
16
|
+
Rule and workflow install always materialized into user-global agent config
|
|
17
|
+
(<code>~/.claude/CLAUDE.md</code>, <code>~/.cursor/rules</code>, …), so a
|
|
18
|
+
rule meant for one repo leaked into every session. Add
|
|
19
|
+
<code>--scope project</code>: materialize into the current repo instead —
|
|
20
|
+
<code><repo>/.cursor/rules/</code>, <code><repo>/.claude/commands|agents/</code>,
|
|
21
|
+
and, since Claude reads per-repo memory from the root and has no rules
|
|
22
|
+
folder, <code><repo>/CLAUDE.local.md</code> (the personal, git-ignored
|
|
23
|
+
file). The chosen scope + base dir are recorded in the lock so
|
|
24
|
+
<code>update</code>/<code>sync</code> re-materialize back into the same
|
|
25
|
+
repo rather than wherever they happen to run. Default stays
|
|
26
|
+
<code>--scope user</code> (unchanged behavior). Uninstall already reverses
|
|
27
|
+
by recorded path, so it works for either scope.
|
|
@@ -118,7 +118,7 @@
|
|
|
118
118
|
<div class="stat"><b>16</b><span>Shipped</span></div>
|
|
119
119
|
<div class="stat"><b>1</b><span>Next up</span></div>
|
|
120
120
|
<div class="stat"><b>4</b><span>Planned</span></div>
|
|
121
|
-
<div class="stat"><b>
|
|
121
|
+
<div class="stat"><b>108</b><span>Loop finds</span></div>
|
|
122
122
|
<!-- /ROADMAP:stats -->
|
|
123
123
|
</div>
|
|
124
124
|
</section>
|
|
@@ -840,6 +840,29 @@ chunks instead cost ~70%.</p>
|
|
|
840
840
|
<span class="m">close the last skill-only gaps for rules/workflows</span>
|
|
841
841
|
</div>
|
|
842
842
|
</article>
|
|
843
|
+
|
|
844
|
+
<article class="cap rcard">
|
|
845
|
+
<div class="head"><span class="pill shipped">Shipped</span><span class="cat">Install engine · UX</span></div>
|
|
846
|
+
<h3><code>boost install --scope user|project</code> for rules/workflows</h3>
|
|
847
|
+
<p>Rule and workflow install always materialized into user-global agent config
|
|
848
|
+
(<code>~/.claude/CLAUDE.md</code>, <code>~/.cursor/rules</code>, …), so a
|
|
849
|
+
rule meant for one repo leaked into every session. Add
|
|
850
|
+
<code>--scope project</code>: materialize into the current repo instead —
|
|
851
|
+
<code><repo>/.cursor/rules/</code>, <code><repo>/.claude/commands|agents/</code>,
|
|
852
|
+
and, since Claude reads per-repo memory from the root and has no rules
|
|
853
|
+
folder, <code><repo>/CLAUDE.local.md</code> (the personal, git-ignored
|
|
854
|
+
file). The chosen scope + base dir are recorded in the lock so
|
|
855
|
+
<code>update</code>/<code>sync</code> re-materialize back into the same
|
|
856
|
+
repo rather than wherever they happen to run. Default stays
|
|
857
|
+
<code>--scope user</code> (unchanged behavior). Uninstall already reverses
|
|
858
|
+
by recorded path, so it works for either scope.</p>
|
|
859
|
+
<div class="meta">
|
|
860
|
+
<span class="m">Complexity <b>M</b></span>
|
|
861
|
+
<span class="m hi">Impact <b>High</b></span>
|
|
862
|
+
<span class="m">Wow <b class="wow">★★★</b></span>
|
|
863
|
+
<span class="m">rules/workflows were user-global only</span>
|
|
864
|
+
</div>
|
|
865
|
+
</article>
|
|
843
866
|
<!-- /ROADMAP:cards -->
|
|
844
867
|
|
|
845
868
|
</div>
|
|
@@ -55,6 +55,16 @@ eval = [
|
|
|
55
55
|
"langchain-community<0.4",
|
|
56
56
|
"langchain-openai<1",
|
|
57
57
|
]
|
|
58
|
+
# Opt-in Gherkin/BDD functional suite (tests/bdd) — reusable Given/When/Then
|
|
59
|
+
# scenarios over the same in-process CLI entrypoint tests/functional drives.
|
|
60
|
+
# Additive to, not a replacement for, the pytest functional suite; not part of
|
|
61
|
+
# `make check`. `pip install -e '.[bdd]'`.
|
|
62
|
+
bdd = ["behave>=1.2.6"]
|
|
63
|
+
# Opt-in micro-benchmarks (tests/perf, `make bench`) for perf-sensitive core
|
|
64
|
+
# paths (BM25 indexing/search, catalog scan). Not part of `make check` — a
|
|
65
|
+
# timing regression shouldn't block a merge the way a correctness gate does.
|
|
66
|
+
# `pip install -e '.[perf]'`.
|
|
67
|
+
perf = ["pytest-benchmark>=4.0"]
|
|
58
68
|
|
|
59
69
|
[project.scripts]
|
|
60
70
|
boost = "boost_cli.cli:main"
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Wall-clock benchmark of the real `boost` binary via hyperfine — the actual
|
|
3
|
+
# fork+exec CLI, not the in-process pytest-benchmark suite (tests/perf).
|
|
4
|
+
# Opt-in (`make bench-cli`); not part of `make check`. Degrades cleanly if
|
|
5
|
+
# hyperfine isn't installed.
|
|
6
|
+
set -uo pipefail
|
|
7
|
+
|
|
8
|
+
if ! command -v hyperfine >/dev/null 2>&1; then
|
|
9
|
+
echo "hyperfine not installed — install via 'brew install hyperfine', skipping"
|
|
10
|
+
exit 0
|
|
11
|
+
fi
|
|
12
|
+
|
|
13
|
+
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
14
|
+
SB="$(mktemp -d "${TMPDIR:-/tmp}/boost-bench-XXXXXX")"
|
|
15
|
+
trap 'rm -rf "$SB"' EXIT
|
|
16
|
+
export HOME="$SB" BOOST_NO_AI=1 BOOST_ASSUME_YES=1 NO_COLOR=1
|
|
17
|
+
|
|
18
|
+
FIX="$(python3 "$ROOT/tests/make_fixture.py" "$SB/fixture-tap")"
|
|
19
|
+
"$ROOT/boost" tap "$FIX" >/dev/null
|
|
20
|
+
"$ROOT/boost" install brainstorming >/dev/null
|
|
21
|
+
|
|
22
|
+
echo "== hyperfine: $(command -v hyperfine) over $ROOT/boost (sandbox: $SB)"
|
|
23
|
+
hyperfine --warmup 3 \
|
|
24
|
+
"$ROOT/boost --help" \
|
|
25
|
+
"$ROOT/boost list" \
|
|
26
|
+
"$ROOT/boost search brainstorming" \
|
|
27
|
+
"$ROOT/boost count"
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
Feature: boost adapt
|
|
2
|
+
Render a skill as another agent framework's native source (CrewAI, Agents SDK).
|
|
3
|
+
|
|
4
|
+
Background:
|
|
5
|
+
Given a fresh boost environment
|
|
6
|
+
And the fixture tap is added
|
|
7
|
+
|
|
8
|
+
Scenario: adapting an installed skill to CrewAI
|
|
9
|
+
Given the "brainstorming" skill is installed
|
|
10
|
+
When I run "boost adapt brainstorming --to crewai"
|
|
11
|
+
Then the exit code should be 0
|
|
12
|
+
And the output should contain "from crewai import Agent"
|
|
13
|
+
And the output should contain "brainstorming = Agent("
|
|
14
|
+
|
|
15
|
+
Scenario: adapting an installed skill to the Agents SDK
|
|
16
|
+
Given the "brainstorming" skill is installed
|
|
17
|
+
When I run "boost adapt brainstorming --to agents-sdk"
|
|
18
|
+
Then the exit code should be 0
|
|
19
|
+
And the output should contain "from agents import Agent"
|
|
20
|
+
And the output should match "name=\"brainstorming\""
|
|
21
|
+
|
|
22
|
+
Scenario: adapting a tapped-but-not-installed skill still resolves
|
|
23
|
+
When I run "boost adapt brainstorming --to crewai"
|
|
24
|
+
Then the exit code should be 0
|
|
25
|
+
And the output should contain "brainstorming = Agent("
|
|
26
|
+
|
|
27
|
+
Scenario: --model none opts out of pinning an LLM
|
|
28
|
+
Given the "brainstorming" skill is installed
|
|
29
|
+
When I run "boost adapt brainstorming --to crewai --model none"
|
|
30
|
+
Then the exit code should be 0
|
|
31
|
+
And the output should not contain "llm="
|
|
32
|
+
|
|
33
|
+
Scenario: an unknown framework is rejected
|
|
34
|
+
Given the "brainstorming" skill is installed
|
|
35
|
+
When I run "boost adapt brainstorming --to langchain"
|
|
36
|
+
Then the exit code should be 1
|
|
37
|
+
And the output should contain "unknown framework"
|
|
38
|
+
|
|
39
|
+
Scenario: --to is required
|
|
40
|
+
Given the "brainstorming" skill is installed
|
|
41
|
+
When I run "boost adapt brainstorming"
|
|
42
|
+
Then the exit code should be 2
|
|
43
|
+
|
|
44
|
+
Scenario: adapting an unknown skill fails
|
|
45
|
+
When I run "boost adapt does-not-exist --to crewai"
|
|
46
|
+
Then the exit code should be 1
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
Feature: boost browse
|
|
2
|
+
Interactive full-screen TUI with fuzzy search. There is no TTY in these
|
|
3
|
+
scenarios, so `browse` takes its documented non-interactive escape hatch
|
|
4
|
+
and prints the full catalog instead of launching curses.
|
|
5
|
+
|
|
6
|
+
Background:
|
|
7
|
+
Given a fresh boost environment
|
|
8
|
+
|
|
9
|
+
Scenario: no skills available to browse
|
|
10
|
+
When I run "boost browse"
|
|
11
|
+
Then the exit code should be 1
|
|
12
|
+
And the output should contain "no skills available to browse"
|
|
13
|
+
|
|
14
|
+
Scenario: without a TTY, prints the full catalog instead of the TUI
|
|
15
|
+
Given the fixture tap is added
|
|
16
|
+
When I run "boost browse"
|
|
17
|
+
Then the exit code should be 0
|
|
18
|
+
And the output should contain "interactive mode needs a TTY — showing the full catalog"
|
|
19
|
+
And the output should contain "brainstorming"
|
|
20
|
+
And the output should contain "commit-messages"
|
|
21
|
+
And the output should contain "5 skills · install with `boost install <name>`"
|
|
22
|
+
|
|
23
|
+
Scenario: --help documents the command without touching the catalog
|
|
24
|
+
When I run "boost browse --help"
|
|
25
|
+
Then the exit code should be 0
|
|
26
|
+
And the output should contain "Interactive full-screen TUI with fuzzy search"
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
Feature: boost count
|
|
2
|
+
A one-line inventory summary: installed / available / taps / discovery index.
|
|
3
|
+
|
|
4
|
+
Background:
|
|
5
|
+
Given a fresh boost environment
|
|
6
|
+
|
|
7
|
+
Scenario: an empty environment
|
|
8
|
+
When I run "boost count"
|
|
9
|
+
Then the exit code should be 0
|
|
10
|
+
And the output should contain "installed 0 · available 0 (across 0 taps) · discovery index not built"
|
|
11
|
+
|
|
12
|
+
Scenario: one tap with one installed skill
|
|
13
|
+
Given the "brainstorming" skill is installed
|
|
14
|
+
When I run "boost count"
|
|
15
|
+
Then the exit code should be 0
|
|
16
|
+
And the output should contain "installed 1 · available 5 (across 1 tap) · discovery index not built"
|
|
17
|
+
And the output should contain "╭─ inventory"
|
|
18
|
+
|
|
19
|
+
Scenario: --json is machine readable
|
|
20
|
+
Given the "brainstorming" skill is installed
|
|
21
|
+
When I run "boost count --json"
|
|
22
|
+
Then the exit code should be 0
|
|
23
|
+
And the output should match "\"installed\": 1"
|
|
24
|
+
And the output should match "\"taps\": 1"
|