boost-skill-cli 1.0.135__tar.gz → 1.0.136__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.135 → boost_skill_cli-1.0.136}/PKG-INFO +4 -3
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/README.md +3 -2
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/_version.py +2 -2
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/commands/configuration.py +1 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/commands/discovery.py +7 -2
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/commands/pkg.py +44 -16
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/core/adapters.py +55 -11
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/core/rag.py +19 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/core/store.py +51 -3
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_skill_cli.egg-info/PKG-INFO +4 -3
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_skill_cli.egg-info/SOURCES.txt +1 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/adapters.html +9 -4
- boost_skill_cli-1.0.136/docs/roadmap/items/scan-and-sync-rules-and-workflows.md +27 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap.html +24 -1
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/examples/README.md +5 -2
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/examples/adapt-demo.sh +16 -10
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/functional/test_cli_adapt.py +29 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/functional/test_cli_discovery.py +41 -16
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/functional/test_cli_pkg.py +36 -1
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/functional/test_everyday_loop.py +1 -1
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/unit/test_adapters.py +108 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/unit/test_rag.py +38 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/unit/test_store.py +59 -1
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/.gitattributes +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/.gitignore +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/CLAUDE.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/CONTRIBUTING.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/LICENSE +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/MANIFEST.in +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/Makefile +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/SECURITY.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/__init__.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/__main__.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/cli.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/cliparse.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/commands/__init__.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/commands/bmad.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/commands/hooks.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/commands/info.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/commands/intelligence.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/commands/quality.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/commands/taps.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/commands/team.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/core/__init__.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/core/agents.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/core/ai.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/core/catalog.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/core/claude_settings.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/core/config.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/core/dense.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/core/embed.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/core/frontmatter.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/core/gitutil.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/core/imperative.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/core/injectscan.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/core/journal.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/core/lockfile.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/core/logs.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/core/mcp.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/core/nethttp.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/core/output.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/core/paths.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/core/policy.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/core/registry.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/core/rules.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/core/secretscan.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/core/serve.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/core/stackprobe.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/core/staleness.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/core/typosquat.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/core/updatediff.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/core/util.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/core/workflows.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/data/registries.json +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/errors.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_cli/spin.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_skill_cli.egg-info/dependency_links.txt +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_skill_cli.egg-info/entry_points.txt +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_skill_cli.egg-info/requires.txt +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/boost_skill_cli.egg-info/top_level.txt +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/.claude/settings.local.json +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/DEBUGGING.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/demo.gif +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/demo.tape +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/design-roadmap.html +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/eval.html +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/index.html +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/mcp-hub.html +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/rag-architecture.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/BOOST-D01.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/BOOST-D02.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/BOOST-D03.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/BOOST-D04.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/BOOST-D05.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/BOOST-D06.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/BOOST-D07.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/BOOST-D08.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/BOOST-D09.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/BOOST-D10.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/BOOST-D11.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/BOOST-D12.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/BOOST-D13.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/BOOST-D14.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/BOOST-D15.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/BOOST-D16.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/BOOST-D17.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/BOOST-D18.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/BOOST-D19.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/BOOST-D20.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/BOOST-D21.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/BOOST-D22.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/BOOST-D23.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/BOOST-D24.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/BOOST-D25.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/BOOST-D26.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/accessibility-audit-pa11y-ci-axe-core.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/atomic-corruption-safe-lock-file-writes.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/atomic-skill-install-temp-dir-swap.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/autonomous-ship-workflow-and-isolated-worktree.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/bring-commands-under-mutation-testing.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/broken-link-and-anchor-checking-lychee.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/browse-crashes-selecting-a-rule-or-workflow.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/build-provenance-slsa-attestations.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/cache-the-catalog-entry-set-across-rag-queries.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/capability-manifest-and-least-privilege-policy.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/clean-env-install-smoke-pip-and-pipx.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/command-reference-docs-site.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/complexity-and-dead-code-radar-xenon-vulture.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/consolidate-skill-staleness-drift-logic-into-cor.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/coverage-dashboard-codecov-free-for-oss.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/coverage-guided-fuzzing-atheris-oss-fuzz.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/crash-recorder-error-paths-core-logs-py.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/dependency-cve-gate-pip-audit.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/docstring-coverage-interrogate.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/doctor-checks-rules-and-workflows.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/end-of-options-guard-on-git-commands.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/extension-free-tests-core-dense-py.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/extract-mcp-http-servers-out-of-configuration-py.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/finish-mutation-hardening-across-core.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/fix-self-update-version-detection-dead-branch.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/fork-safe-network-proxy-handler.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/framework-adapter-langgraph.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/framework-adapters-boost-adapt.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/frontmatter-scalar-over-coercion.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/github-pages-deploy-is-broken-every-push.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/hash-pinned-reproducible-toolchain-uv-lock.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/html-validation-html-validate.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/integrity-verification-boost-verify.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/invocation-pid-logging-for-crash-correlation.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/layering-guard-import-linter.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/lighthouse-ci-on-the-pages-site.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/list-rules-and-workflows.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/localize-the-stored-bm25-snippet.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/lockfile-enforcement-and-commit-pinning.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/log-timestamps-mislabeled-utc.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/lowest-version-resolution-uv-resolution-lowest-d.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/make-the-roadmaps-discoverable.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/markdown-consistency-markdownlint-cli2.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/mcp-hub-diagram-node-text-overflow.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/mcp-launch-objc-fork-safety.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/mcp-register-names-server-before-env.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/memoize-config-load-in-process.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/modernization-smells-refurb-pyupgrade.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/mutation-hardening-core-frontmatter-py.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/mutation-hardening-core-gitutil-py.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/mutation-hardening-core-store-py.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/one-command-every-env-nox.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/one-shared-atomic-write-helper.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/package-metadata-validation-twine-check-friends.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/patch-coverage-gate-diff-cover.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/performance-regression-gate-pytest-benchmark.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/post-deploy-smoke-headless-load-check.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/pre-release-python-canary-3-14t-free-threaded.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/promote-nav-footer-into-the-shared-style-system.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/prompt-injection-scanning-of-skill-markdown.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/property-based-tests-hypothesis-on-the-parsers.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/prose-and-terminology-linting-vale.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/prune-ignored-dirs-during-scan-dir-walk.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/quality-dashboard-sonarcloud-free-for-oss.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/reconcile-the-theme-drift.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/refresh-the-marketing-surface.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/retrieval-quality-eval-harness.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/reuse-helpers-kill-minor-dead-work.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/robust-tag-argument-parsing.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/rule-install-native-materialization.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/runner-egress-monitoring-stepsecurity-harden-run.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/sbom-aware-scanning-osv-scanner.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/sbom-on-every-release-cyclonedx-syft.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/second-type-checker-pyright.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/secret-and-pii-scanning-of-installed-skills.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/secret-scanning-gitleaks-push-protection.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/security-linting-bandit-via-ruff-s-rules.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/shift-left-gate-pre-commit-pre-commit-ci.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/single-imperative-rule-extractor.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/single-tech-stack-prober.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/split-oversized-command-modules.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/startup-and-import-time-budget-x-importtime.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/stop-re-serializing-entry-meta-on-every-search.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/supply-chain-posture-openssf-scorecard.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/surface-every-docs-page-from-the-guide.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/tap-signing-and-provenance-sigstore-minisign.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/theme-asset-linting-stylelint-eslint.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/typo-detection-codespell.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/typosquat-and-name-confusion-detection.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/unify-tilde-two-copies-have-a-boundary-bug.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/untrack-generated-build-noise.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/update-diff-before-apply.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/update-refreshes-rules-and-workflows.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/visual-regression-pass-on-the-guide.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/widen-the-ruff-rule-surface-b-sim-c4-perf-ruf.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/windows-in-the-ci-matrix.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/workflow-install-native-materialization.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/workflow-linting-actionlint.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/workflow-sast-zizmor.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/docs/roadmap/items/workspace-scope-install.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/index.html +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/pyproject.toml +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/scripts/build_registries.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/scripts/build_roadmap.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/scripts/ensure_eval_corpus.sh +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/scripts/eval_explain.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/scripts/eval_recommend.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/scripts/eval_retrieval.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/scripts/mutation_gate.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/setup.cfg +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/style/README.md +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/style/boost.css +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/style/boost.js +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/style/demo.html +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/conftest.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/eval/baseline.json +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/eval/explain.jsonl +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/eval/golden.jsonl +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/eval/recommend.jsonl +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/eval/taps.txt +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/functional/test_cli_bmad.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/functional/test_cli_configuration.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/functional/test_cli_hooks.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/functional/test_cli_info.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/functional/test_cli_intelligence.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/functional/test_cli_quality.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/functional/test_cli_taps.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/functional/test_cli_team.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/functional/test_property_parsers.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/make_fixture.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/smoke.sh +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/unit/test_agents.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/unit/test_ai.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/unit/test_catalog.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/unit/test_claude_settings.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/unit/test_cliparse.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/unit/test_config.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/unit/test_dense.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/unit/test_dense_fallback.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/unit/test_docs_pages_linked.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/unit/test_embed.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/unit/test_errors_and_cli_table.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/unit/test_frontmatter.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/unit/test_gitutil.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/unit/test_imperative.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/unit/test_injectscan.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/unit/test_journal.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/unit/test_lockfile.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/unit/test_logs.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/unit/test_mcp.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/unit/test_mutation_hardening.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/unit/test_nethttp.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/unit/test_output.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/unit/test_paths.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/unit/test_pkg_confusions.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/unit/test_pkg_injection.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/unit/test_pkg_secrets.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/unit/test_policy.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/unit/test_registries_fresh.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/unit/test_registry.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/unit/test_roadmap_fresh.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/unit/test_rules.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/unit/test_secretscan.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/unit/test_serve.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/unit/test_spin.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/unit/test_stackprobe.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/unit/test_staleness.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/unit/test_token_parity.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/unit/test_typosquat.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/unit/test_updatediff.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/unit/test_util.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/unit/test_version.py +0 -0
- {boost_skill_cli-1.0.135 → boost_skill_cli-1.0.136}/tests/unit/test_workflows.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: boost-skill-cli
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.136
|
|
4
4
|
Summary: boost — Homebrew for AI coding skills
|
|
5
5
|
Author: Jonathan Reyes
|
|
6
6
|
License: GNU GENERAL PUBLIC LICENSE
|
|
@@ -766,8 +766,9 @@ boost tap --defaults # pull in the 5 starter registries
|
|
|
766
766
|
```
|
|
767
767
|
|
|
768
768
|
The default install is **zero-dependency** (pure stdlib). `boost search` and the
|
|
769
|
-
`boost_search` MCP tool rank results with a built-in full-content BM25 engine
|
|
770
|
-
|
|
769
|
+
`boost_search` MCP tool rank results with a built-in full-content BM25 engine —
|
|
770
|
+
the index builds automatically on your first search, so BM25 is the default with
|
|
771
|
+
no setup (`boost reindex` just forces a rebuild). For optional **dense semantic
|
|
771
772
|
search**, install the `[rag]` extra and set an embeddings key — retrieval then
|
|
772
773
|
embeds every skill and ranks by vector similarity, falling back to BM25 whenever
|
|
773
774
|
the extra or key is absent:
|
|
@@ -54,8 +54,9 @@ boost tap --defaults # pull in the 5 starter registries
|
|
|
54
54
|
```
|
|
55
55
|
|
|
56
56
|
The default install is **zero-dependency** (pure stdlib). `boost search` and the
|
|
57
|
-
`boost_search` MCP tool rank results with a built-in full-content BM25 engine
|
|
58
|
-
|
|
57
|
+
`boost_search` MCP tool rank results with a built-in full-content BM25 engine —
|
|
58
|
+
the index builds automatically on your first search, so BM25 is the default with
|
|
59
|
+
no setup (`boost reindex` just forces a rebuild). For optional **dense semantic
|
|
59
60
|
search**, install the `[rag]` extra and set an embeddings key — retrieval then
|
|
60
61
|
embeds every skill and ranks by vector similarity, falling back to BM25 whenever
|
|
61
62
|
the extra or key is absent:
|
|
@@ -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.136'
|
|
22
|
+
__version_tuple__ = version_tuple = (1, 0, 136)
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -745,6 +745,7 @@ REGISTRY = mcp.Registry()
|
|
|
745
745
|
|
|
746
746
|
def _tool_search(args: dict):
|
|
747
747
|
query = str(args.get("query", ""))
|
|
748
|
+
rag.ensure() # build the full-content index on first use (BM25 by default)
|
|
748
749
|
rag_result = rag.search(query, limit=10)
|
|
749
750
|
if rag_result is not None: # full-content index is built
|
|
750
751
|
hits, _ranker = rag_result
|
|
@@ -91,9 +91,14 @@ def cmd_search(argv):
|
|
|
91
91
|
if not registry.list_taps():
|
|
92
92
|
raise BoostError("no taps configured — nothing to search",
|
|
93
93
|
hint="add the recommended registries with `boost tap --defaults`")
|
|
94
|
-
#
|
|
95
|
-
#
|
|
94
|
+
# Full-content (RAG) search is the default: build the index on first use so
|
|
95
|
+
# every user gets BM25 ranking without having to know about `boost reindex`.
|
|
96
|
+
# rag.ensure() is incremental, offline, and degrades to frontmatter search
|
|
97
|
+
# if the build fails — so a search never hard-fails on an indexing problem.
|
|
96
98
|
use_rag = rag.ready()
|
|
99
|
+
if not use_rag:
|
|
100
|
+
with spin.Spinner("building the search index (first run)"):
|
|
101
|
+
use_rag = rag.ensure()
|
|
97
102
|
if use_rag:
|
|
98
103
|
scored = [(h["entry"], h["score"])
|
|
99
104
|
for h in rag.retrieve(query, k=max(60, args.limit * 4))]
|
|
@@ -15,7 +15,7 @@ from pathlib import Path
|
|
|
15
15
|
from typing import Dict, List, Optional
|
|
16
16
|
|
|
17
17
|
from .. import cliparse
|
|
18
|
-
from ..core import (adapters, agents, catalog, frontmatter, gitutil,
|
|
18
|
+
from ..core import (adapters, agents, catalog, config, frontmatter, gitutil,
|
|
19
19
|
injectscan, journal, lockfile, paths, registry,
|
|
20
20
|
secretscan, staleness, store, typosquat, updatediff, util)
|
|
21
21
|
from ..core import output as out
|
|
@@ -66,36 +66,51 @@ def _check_agents(names: Optional[List[str]]) -> Optional[List[str]]:
|
|
|
66
66
|
return names
|
|
67
67
|
|
|
68
68
|
|
|
69
|
+
def _scan_label(res: store.InstallResult) -> str:
|
|
70
|
+
"""What was scanned, for the warning text: skills ship a SKILL.md; rules and
|
|
71
|
+
workflows ship a single file, so name the kind instead."""
|
|
72
|
+
return "SKILL.md" if res.kind == "skill" else "%s content" % res.kind
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def _scan_findings(res: store.InstallResult, scanner):
|
|
76
|
+
"""Findings for the content boost just installed. Skills scan their
|
|
77
|
+
SKILL.md; rules/workflows scan the raw source (res.scan_text) — the exact
|
|
78
|
+
Markdown that landed, not a non-existent SKILL.md under the dest file."""
|
|
79
|
+
if res.scan_text is not None:
|
|
80
|
+
return scanner.scan_text(res.scan_text)
|
|
81
|
+
return scanner.scan_file(res.dest / "SKILL.md")
|
|
82
|
+
|
|
83
|
+
|
|
69
84
|
def _warn_injection(res: store.InstallResult) -> None:
|
|
70
|
-
"""Flag prompt-injection / risky-content patterns in
|
|
85
|
+
"""Flag prompt-injection / risky-content patterns in what was just installed.
|
|
71
86
|
|
|
72
|
-
boost installs Markdown the agent then executes, so the installed
|
|
73
|
-
|
|
74
|
-
|
|
87
|
+
boost installs Markdown the agent then executes, so the installed content is
|
|
88
|
+
scanned (core.injectscan) and any hits are surfaced worst-first. Advisory
|
|
89
|
+
only — it warns, it never blocks the install.
|
|
75
90
|
"""
|
|
76
|
-
findings =
|
|
91
|
+
findings = _scan_findings(res, injectscan)
|
|
77
92
|
if not findings:
|
|
78
93
|
return
|
|
79
|
-
out.warn("%s: %d suspicious pattern%s in
|
|
94
|
+
out.warn("%s: %d suspicious pattern%s in %s (%s) — review before use"
|
|
80
95
|
% (res.name, len(findings), "" if len(findings) == 1 else "s",
|
|
81
|
-
injectscan.worst_severity(findings)))
|
|
96
|
+
_scan_label(res), injectscan.worst_severity(findings)))
|
|
82
97
|
for f in findings[:3]:
|
|
83
98
|
out.warn(" L%d [%s] %s" % (f.line, f.severity, f.description))
|
|
84
99
|
|
|
85
100
|
|
|
86
101
|
def _warn_secrets(res: store.InstallResult) -> None:
|
|
87
|
-
"""Flag embedded credentials / secrets in
|
|
102
|
+
"""Flag embedded credentials / secrets in what was just installed.
|
|
88
103
|
|
|
89
|
-
Scans the installed
|
|
90
|
-
|
|
104
|
+
Scans the installed content (core.secretscan) for known secret shapes and
|
|
105
|
+
surfaces any hits worst-first, with the secret value redacted. Advisory
|
|
91
106
|
only — it warns, it never blocks the install.
|
|
92
107
|
"""
|
|
93
|
-
findings =
|
|
108
|
+
findings = _scan_findings(res, secretscan)
|
|
94
109
|
if not findings:
|
|
95
110
|
return
|
|
96
|
-
out.warn("%s: %d possible secret%s in
|
|
111
|
+
out.warn("%s: %d possible secret%s in %s (%s) — do not commit"
|
|
97
112
|
% (res.name, len(findings), "" if len(findings) == 1 else "s",
|
|
98
|
-
secretscan.worst_severity(findings)))
|
|
113
|
+
_scan_label(res), secretscan.worst_severity(findings)))
|
|
99
114
|
for f in findings[:3]:
|
|
100
115
|
out.warn(" L%d [%s] %s" % (f.line, f.severity, f.description))
|
|
101
116
|
|
|
@@ -106,6 +121,7 @@ def _report_result(res: store.InstallResult) -> None:
|
|
|
106
121
|
out.ok("materialized → %s" % (" · ".join(res.linked) or "(no enabled agents)"))
|
|
107
122
|
out.ok("lock updated (.skill-lock.json)")
|
|
108
123
|
_warn_injection(res)
|
|
124
|
+
_warn_secrets(res)
|
|
109
125
|
return
|
|
110
126
|
out.ok("copied to %s" % _tilde(res.dest))
|
|
111
127
|
if res.linked:
|
|
@@ -268,6 +284,7 @@ _PLAN_LABELS = [
|
|
|
268
284
|
("missing_links", "missing agent links"),
|
|
269
285
|
("stale_links", "stale links"),
|
|
270
286
|
("orphaned_store", "orphaned store dirs"),
|
|
287
|
+
("missing_materializations", "missing rule/workflow files"),
|
|
271
288
|
]
|
|
272
289
|
|
|
273
290
|
|
|
@@ -297,6 +314,8 @@ def cmd_sync(argv: List[str]) -> int:
|
|
|
297
314
|
for item in plan[key]:
|
|
298
315
|
if key == "missing_links":
|
|
299
316
|
out.info("%s → %s" % (item[0], item[1]))
|
|
317
|
+
elif key == "missing_materializations":
|
|
318
|
+
out.info("%s %s" % (item[0], item[1])) # (kind, name)
|
|
300
319
|
else:
|
|
301
320
|
out.info(_tilde(item))
|
|
302
321
|
return 0
|
|
@@ -1020,14 +1039,22 @@ def cmd_adapt(argv: List[str]) -> int:
|
|
|
1020
1039
|
ap.add_argument("name", help="skill to adapt")
|
|
1021
1040
|
ap.add_argument("--to", metavar="FRAMEWORK", required=True,
|
|
1022
1041
|
help="target framework: %s" % ", ".join(adapters.formats()))
|
|
1042
|
+
ap.add_argument("--model", metavar="M", default=None,
|
|
1043
|
+
help="LLM the exported agent runs on (default: boost's "
|
|
1044
|
+
"ai.model; pass 'none' for the framework's own default)")
|
|
1023
1045
|
ap.add_argument("-o", "--out", metavar="FILE",
|
|
1024
1046
|
help="write to FILE instead of stdout")
|
|
1025
1047
|
args = ap.parse_args(argv)
|
|
1026
1048
|
if args.to not in adapters.FORMATS:
|
|
1027
1049
|
raise BoostError("unknown framework: %s" % args.to,
|
|
1028
1050
|
hint="supported: %s" % ", ".join(adapters.formats()))
|
|
1051
|
+
# Default to boost's configured model so exported agents run on the same LLM
|
|
1052
|
+
# boost uses; `--model none` opts out and lets the framework pick.
|
|
1053
|
+
model = args.model if args.model is not None else str(config.get("ai.model") or "")
|
|
1054
|
+
if model.strip().lower() in ("none", "off", ""):
|
|
1055
|
+
model = None
|
|
1029
1056
|
display, description, body = _resolve_skill_source(args.name)
|
|
1030
|
-
source = adapters.render(args.to, display, description, body)
|
|
1057
|
+
source = adapters.render(args.to, display, description, body, model)
|
|
1031
1058
|
if args.out:
|
|
1032
1059
|
dest = paths.expand(args.out)
|
|
1033
1060
|
try:
|
|
@@ -1035,7 +1062,8 @@ def cmd_adapt(argv: List[str]) -> int:
|
|
|
1035
1062
|
except OSError as e:
|
|
1036
1063
|
raise BoostError("cannot write %s: %s" % (_tilde(dest), e.strerror or e),
|
|
1037
1064
|
hint="check the output path exists and is writable")
|
|
1038
|
-
out.ok("adapted %s → %s (%s)" % (display, _tilde(dest.resolve()),
|
|
1065
|
+
out.ok("adapted %s → %s (%s · %s)" % (display, _tilde(dest.resolve()),
|
|
1066
|
+
args.to, model or "framework default"))
|
|
1039
1067
|
else:
|
|
1040
1068
|
sys.stdout.write(source)
|
|
1041
1069
|
return 0
|
|
@@ -18,11 +18,11 @@ from __future__ import annotations
|
|
|
18
18
|
import json
|
|
19
19
|
import keyword
|
|
20
20
|
import re
|
|
21
|
-
from typing import Callable, Dict, List
|
|
21
|
+
from typing import Callable, Dict, List, Optional
|
|
22
22
|
|
|
23
23
|
# Public: the format id shown in `--to`/errors -> its renderer.
|
|
24
24
|
# Populated at the bottom once the render_* functions are defined.
|
|
25
|
-
FORMATS: Dict[str, "Callable[
|
|
25
|
+
FORMATS: Dict[str, "Callable[..., str]"] = {}
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
def formats() -> List[str]:
|
|
@@ -30,12 +30,15 @@ def formats() -> List[str]:
|
|
|
30
30
|
return sorted(FORMATS)
|
|
31
31
|
|
|
32
32
|
|
|
33
|
-
def render(fmt: str, name: str, description: str, body: str
|
|
33
|
+
def render(fmt: str, name: str, description: str, body: str,
|
|
34
|
+
model: Optional[str] = None) -> str:
|
|
34
35
|
"""Dispatch to the renderer for `fmt`. Raises KeyError on unknown fmt.
|
|
35
36
|
|
|
36
|
-
|
|
37
|
+
`model` (a boost/LiteLLM model id) wires the emitted agent to a specific
|
|
38
|
+
LLM; when falsy the agent inherits its framework's default provider. The
|
|
39
|
+
command layer turns a KeyError into a BoostError listing formats().
|
|
37
40
|
"""
|
|
38
|
-
return FORMATS[fmt](name, description, body)
|
|
41
|
+
return FORMATS[fmt](name, description, body, model)
|
|
39
42
|
|
|
40
43
|
|
|
41
44
|
# --- shared helpers -------------------------------------------------------
|
|
@@ -68,47 +71,88 @@ def _clean(text: str) -> str:
|
|
|
68
71
|
return text.strip()
|
|
69
72
|
|
|
70
73
|
|
|
74
|
+
def _litellm_model(model: str) -> str:
|
|
75
|
+
"""Normalize a boost model id to a LiteLLM `provider/model` string.
|
|
76
|
+
|
|
77
|
+
boost's AI bridge is Anthropic (the `claude` CLI / Anthropic API), so a bare
|
|
78
|
+
Claude id like `claude-haiku-4-5-20251001` gets an `anthropic/` prefix.
|
|
79
|
+
A value that already names a provider (`anthropic/…`, `openai/gpt-4o`) is
|
|
80
|
+
passed through unchanged. Both CrewAI and the Agents SDK route through
|
|
81
|
+
LiteLLM, so this one form serves both.
|
|
82
|
+
"""
|
|
83
|
+
m = model.strip()
|
|
84
|
+
return m if "/" in m else "anthropic/" + m
|
|
85
|
+
|
|
86
|
+
|
|
71
87
|
# --- renderers ------------------------------------------------------------
|
|
72
88
|
|
|
73
|
-
def render_crewai(name: str, description: str, body: str
|
|
74
|
-
|
|
89
|
+
def render_crewai(name: str, description: str, body: str,
|
|
90
|
+
model: Optional[str] = None) -> str:
|
|
91
|
+
"""A CrewAI Agent: role=name, goal=description, backstory=instructions.
|
|
92
|
+
|
|
93
|
+
With `model`, pins the agent's LLM via `crewai.LLM` (LiteLLM under the
|
|
94
|
+
hood); without it, the agent uses CrewAI's default provider.
|
|
95
|
+
"""
|
|
75
96
|
var = _ident(name)
|
|
97
|
+
imports = "from crewai import Agent\n"
|
|
98
|
+
llm = ""
|
|
99
|
+
if model:
|
|
100
|
+
imports = "from crewai import Agent, LLM\n"
|
|
101
|
+
llm = " llm=LLM(model=%s),\n" % _py_str(_litellm_model(model))
|
|
76
102
|
return (
|
|
77
103
|
"# Generated by `boost adapt %s --to crewai`. Do not edit by hand.\n"
|
|
78
|
-
"
|
|
104
|
+
"%s"
|
|
79
105
|
"\n"
|
|
80
106
|
"%s = Agent(\n"
|
|
81
107
|
" role=%s,\n"
|
|
82
108
|
" goal=%s,\n"
|
|
83
109
|
" backstory=%s,\n"
|
|
110
|
+
"%s"
|
|
84
111
|
")\n"
|
|
85
112
|
) % (
|
|
86
113
|
name,
|
|
114
|
+
imports,
|
|
87
115
|
var,
|
|
88
116
|
_py_str(name),
|
|
89
117
|
_py_str(_clean(description)),
|
|
90
118
|
_py_str(_clean(body)),
|
|
119
|
+
llm,
|
|
91
120
|
)
|
|
92
121
|
|
|
93
122
|
|
|
94
|
-
def render_agents_sdk(name: str, description: str, body: str
|
|
95
|
-
|
|
123
|
+
def render_agents_sdk(name: str, description: str, body: str,
|
|
124
|
+
model: Optional[str] = None) -> str:
|
|
125
|
+
"""An OpenAI Agents SDK Agent: instructions carry the skill body.
|
|
126
|
+
|
|
127
|
+
With `model`, pins the agent's LLM via the SDK's LiteLLM extension
|
|
128
|
+
(`pip install "openai-agents[litellm]"`); without it, the agent uses the
|
|
129
|
+
SDK's default OpenAI model.
|
|
130
|
+
"""
|
|
96
131
|
var = _ident(name)
|
|
132
|
+
imports = "from agents import Agent\n"
|
|
133
|
+
llm = ""
|
|
134
|
+
if model:
|
|
135
|
+
imports = ("from agents import Agent\n"
|
|
136
|
+
"from agents.extensions.models.litellm_model import LitellmModel\n")
|
|
137
|
+
llm = " model=LitellmModel(model=%s),\n" % _py_str(_litellm_model(model))
|
|
97
138
|
return (
|
|
98
139
|
"# Generated by `boost adapt %s --to agents-sdk`. Do not edit by hand.\n"
|
|
99
|
-
"
|
|
140
|
+
"%s"
|
|
100
141
|
"\n"
|
|
101
142
|
"%s = Agent(\n"
|
|
102
143
|
" name=%s,\n"
|
|
103
144
|
" handoff_description=%s,\n"
|
|
104
145
|
" instructions=%s,\n"
|
|
146
|
+
"%s"
|
|
105
147
|
")\n"
|
|
106
148
|
) % (
|
|
107
149
|
name,
|
|
150
|
+
imports,
|
|
108
151
|
var,
|
|
109
152
|
_py_str(name),
|
|
110
153
|
_py_str(_clean(description)),
|
|
111
154
|
_py_str(_clean(body)),
|
|
155
|
+
llm,
|
|
112
156
|
)
|
|
113
157
|
|
|
114
158
|
|
|
@@ -303,6 +303,25 @@ def ready() -> bool:
|
|
|
303
303
|
return bool(raw and raw.get("docs"))
|
|
304
304
|
|
|
305
305
|
|
|
306
|
+
def ensure() -> bool:
|
|
307
|
+
"""Ensure a usable full-content index exists, building it on first use.
|
|
308
|
+
|
|
309
|
+
This makes BM25 search the default for every surface (CLI + MCP) without the
|
|
310
|
+
user having to run ``boost reindex`` first. Returns True when RAG is usable.
|
|
311
|
+
Never raises: with no taps, or if the build fails, it returns False so the
|
|
312
|
+
caller degrades to frontmatter search instead of erroring.
|
|
313
|
+
"""
|
|
314
|
+
if ready():
|
|
315
|
+
return True
|
|
316
|
+
if not registry.list_taps():
|
|
317
|
+
return False
|
|
318
|
+
try:
|
|
319
|
+
build()
|
|
320
|
+
except Exception: # noqa: BLE001 — degrade to heuristic, never crash search
|
|
321
|
+
return False
|
|
322
|
+
return ready()
|
|
323
|
+
|
|
324
|
+
|
|
306
325
|
def _bm25(query_terms: List[str], raw: dict) -> Dict[int, float]:
|
|
307
326
|
docs = raw["docs"]
|
|
308
327
|
n = len(docs)
|
|
@@ -26,6 +26,10 @@ class InstallResult:
|
|
|
26
26
|
score: int = 0
|
|
27
27
|
upgraded: bool = False
|
|
28
28
|
kind: str = "skill"
|
|
29
|
+
# For rules/workflows the installed content is a single file (or a merged
|
|
30
|
+
# CLAUDE.md block), not a SKILL.md tree — carry the raw source so the caller
|
|
31
|
+
# scans exactly what it installed instead of a non-existent SKILL.md.
|
|
32
|
+
scan_text: Optional[str] = None
|
|
29
33
|
|
|
30
34
|
|
|
31
35
|
def skill_store_dir(name: str) -> Path:
|
|
@@ -233,7 +237,7 @@ def _install_rule(entry: dict, force: bool = False,
|
|
|
233
237
|
res = InstallResult(
|
|
234
238
|
name=name,
|
|
235
239
|
dest=Path(materializations[0]["path"]) if materializations else paths.store_dir(),
|
|
236
|
-
kind="rule")
|
|
240
|
+
kind="rule", scan_text=raw)
|
|
237
241
|
res.linked = linked
|
|
238
242
|
res.upgraded = existing is not None
|
|
239
243
|
return res
|
|
@@ -322,7 +326,7 @@ def _install_workflow(entry: dict, force: bool = False,
|
|
|
322
326
|
res = InstallResult(
|
|
323
327
|
name=name,
|
|
324
328
|
dest=Path(materializations[0]["path"]) if materializations else paths.store_dir(),
|
|
325
|
-
kind="workflow")
|
|
329
|
+
kind="workflow", scan_text=raw)
|
|
326
330
|
res.linked = linked
|
|
327
331
|
res.upgraded = existing is not None
|
|
328
332
|
return res
|
|
@@ -408,7 +412,8 @@ def sync_plan() -> Dict[str, list]:
|
|
|
408
412
|
"""
|
|
409
413
|
lock = lockfile.installed()
|
|
410
414
|
plan: dict[str, list] = {"missing_store": [], "missing_links": [],
|
|
411
|
-
"stale_links": [], "orphaned_store": []
|
|
415
|
+
"stale_links": [], "orphaned_store": [],
|
|
416
|
+
"missing_materializations": []}
|
|
412
417
|
for name, entry in lock.items():
|
|
413
418
|
sdir = skill_store_dir(name)
|
|
414
419
|
if not sdir.is_dir():
|
|
@@ -434,9 +439,34 @@ def sync_plan() -> Dict[str, list]:
|
|
|
434
439
|
link.resolve() if link.exists() else link.readlink())
|
|
435
440
|
if not link.exists() or (points_into_store and link.name not in lock):
|
|
436
441
|
plan["stale_links"].append(str(link))
|
|
442
|
+
# Rules/workflows don't live in the store — they materialize into agent dirs.
|
|
443
|
+
# A materialization whose file (or CLAUDE.md block) is gone can be repaired
|
|
444
|
+
# by re-materializing from the tap, same as a missing skill store dir.
|
|
445
|
+
for name, entry in lockfile.installed_rules().items():
|
|
446
|
+
if any(not _rule_materialization_ok(name, m)
|
|
447
|
+
for m in entry.get("materializations") or []):
|
|
448
|
+
plan["missing_materializations"].append(("rule", name))
|
|
449
|
+
for name, entry in lockfile.installed_workflows().items():
|
|
450
|
+
if any(not Path(m.get("path", "")).is_file()
|
|
451
|
+
for m in entry.get("materializations") or []):
|
|
452
|
+
plan["missing_materializations"].append(("workflow", name))
|
|
437
453
|
return plan
|
|
438
454
|
|
|
439
455
|
|
|
456
|
+
def _rule_materialization_ok(name: str, m: dict) -> bool:
|
|
457
|
+
"""True if a rule materialization is still present: a file drop must exist,
|
|
458
|
+
and a Claude rule's CLAUDE.md must still carry its managed block."""
|
|
459
|
+
from . import rules
|
|
460
|
+
p = Path(m.get("path", ""))
|
|
461
|
+
if m.get("mode") == rules.MODE_CLAUDE:
|
|
462
|
+
try:
|
|
463
|
+
return p.exists() and ("boost:rule:%s start" % name) in \
|
|
464
|
+
p.read_text(encoding="utf-8")
|
|
465
|
+
except OSError:
|
|
466
|
+
return False
|
|
467
|
+
return p.is_file()
|
|
468
|
+
|
|
469
|
+
|
|
440
470
|
def sync_apply(plan: Dict[str, list]) -> List[str]:
|
|
441
471
|
"""Fix what sync_plan found. Returns human-readable actions taken."""
|
|
442
472
|
actions = []
|
|
@@ -466,6 +496,24 @@ def sync_apply(plan: Dict[str, list]) -> List[str]:
|
|
|
466
496
|
if not restored:
|
|
467
497
|
lockfile.remove_skill(name)
|
|
468
498
|
actions.append("dropped %s from lock (store dir missing, source gone)" % name)
|
|
499
|
+
for kind, name in plan.get("missing_materializations", []):
|
|
500
|
+
getter = lockfile.get_rule if kind == "rule" else lockfile.get_workflow
|
|
501
|
+
entry = getter(name) or {}
|
|
502
|
+
tap_name = entry.get("tap")
|
|
503
|
+
if tap_name and tap_name != "local":
|
|
504
|
+
try:
|
|
505
|
+
from . import catalog
|
|
506
|
+
matches = [e for e in catalog.find(name)
|
|
507
|
+
if e["tap"] == tap_name and e.get("kind", "skill") == kind]
|
|
508
|
+
if matches:
|
|
509
|
+
install(matches[0], force=True)
|
|
510
|
+
actions.append("re-materialized %s %s from %s"
|
|
511
|
+
% (kind, name, tap_name))
|
|
512
|
+
continue
|
|
513
|
+
except BoostError:
|
|
514
|
+
pass
|
|
515
|
+
actions.append("%s %s has a missing materialization but its source is "
|
|
516
|
+
"gone — run `boost update` or reinstall" % (kind, name))
|
|
469
517
|
if actions:
|
|
470
518
|
journal.log("sync", "%d fixes" % len(actions))
|
|
471
519
|
return actions
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: boost-skill-cli
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.136
|
|
4
4
|
Summary: boost — Homebrew for AI coding skills
|
|
5
5
|
Author: Jonathan Reyes
|
|
6
6
|
License: GNU GENERAL PUBLIC LICENSE
|
|
@@ -766,8 +766,9 @@ boost tap --defaults # pull in the 5 starter registries
|
|
|
766
766
|
```
|
|
767
767
|
|
|
768
768
|
The default install is **zero-dependency** (pure stdlib). `boost search` and the
|
|
769
|
-
`boost_search` MCP tool rank results with a built-in full-content BM25 engine
|
|
770
|
-
|
|
769
|
+
`boost_search` MCP tool rank results with a built-in full-content BM25 engine —
|
|
770
|
+
the index builds automatically on your first search, so BM25 is the default with
|
|
771
|
+
no setup (`boost reindex` just forces a rebuild). For optional **dense semantic
|
|
771
772
|
search**, install the `[rag]` extra and set an embeddings key — retrieval then
|
|
772
773
|
embeds every skill and ranks by vector similarity, falling back to BM25 whenever
|
|
773
774
|
the extra or key is absent:
|
|
@@ -179,6 +179,7 @@ docs/roadmap/items/rule-install-native-materialization.md
|
|
|
179
179
|
docs/roadmap/items/runner-egress-monitoring-stepsecurity-harden-run.md
|
|
180
180
|
docs/roadmap/items/sbom-aware-scanning-osv-scanner.md
|
|
181
181
|
docs/roadmap/items/sbom-on-every-release-cyclonedx-syft.md
|
|
182
|
+
docs/roadmap/items/scan-and-sync-rules-and-workflows.md
|
|
182
183
|
docs/roadmap/items/second-type-checker-pyright.md
|
|
183
184
|
docs/roadmap/items/secret-and-pii-scanning-of-installed-skills.md
|
|
184
185
|
docs/roadmap/items/secret-scanning-gitleaks-push-protection.md
|
|
@@ -311,10 +311,15 @@ code_reviewer = <span class="fn">Agent</span>(
|
|
|
311
311
|
boost adapt code-reviewer --to crewai -o reviewer.py
|
|
312
312
|
|
|
313
313
|
<span class="c"># 2 — in a throwaway venv, install the framework and load it</span>
|
|
314
|
-
python3 -m venv /tmp/crew && /tmp/crew/bin/pip install crewai
|
|
315
|
-
/tmp/crew/bin/python -c <span class="s">"import reviewer; print(reviewer.code_reviewer.role)"</span>
|
|
316
|
-
<span class="c"># → code-reviewer ✦
|
|
317
|
-
<p class="sec-sub" style="margin-top:22px">
|
|
314
|
+
python3 -m venv /tmp/crew && /tmp/crew/bin/pip install <span class="s">"crewai[anthropic]"</span>
|
|
315
|
+
/tmp/crew/bin/python -c <span class="s">"import reviewer; print(reviewer.code_reviewer.role, reviewer.code_reviewer.llm.model)"</span>
|
|
316
|
+
<span class="c"># → code-reviewer claude-haiku-4-5-20251001 ✦ imported, instantiated, on boost's model</span></pre>
|
|
317
|
+
<p class="sec-sub" style="margin-top:22px"><b>Runs on boost's model by default.</b> With no
|
|
318
|
+
<code>--model</code>, the exported agent is wired to boost's configured <code>ai.model</code>
|
|
319
|
+
(Claude) via each framework's LiteLLM path — so it runs on the same LLM boost uses, no OpenAI key.
|
|
320
|
+
Override with <code>--model openai/gpt-4o</code>, or <code>--model none</code> for the framework's
|
|
321
|
+
own default. (The <code>[anthropic]</code>/<code>[litellm]</code> extras carry that provider.)</p>
|
|
322
|
+
<p class="sec-sub" style="margin-top:14px">Supported targets today: <code>crewai</code>,
|
|
318
323
|
<code>agents-sdk</code>. Adding another framework is one <code>render_*</code> function plus a row in
|
|
319
324
|
the <code>FORMATS</code> registry and its golden test.</p>
|
|
320
325
|
</div>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: scan-and-sync-rules-and-workflows
|
|
3
|
+
board: code
|
|
4
|
+
section: internals
|
|
5
|
+
status: shipped
|
|
6
|
+
category: Install engine · Safety
|
|
7
|
+
complexity: M
|
|
8
|
+
impact: Med
|
|
9
|
+
wow: 2
|
|
10
|
+
note: close the last skill-only gaps for rules/workflows
|
|
11
|
+
order: 26
|
|
12
|
+
owner: loop/scan-sync-all-kinds
|
|
13
|
+
pr: 160
|
|
14
|
+
title: Scan and <code>sync</code> rules/workflows like skills
|
|
15
|
+
---
|
|
16
|
+
Two skill-only gaps remained after rule (<code>#141</code>) / workflow
|
|
17
|
+
(<code>#150</code>) install: the install-time injection + secret scan
|
|
18
|
+
read <code>res.dest/SKILL.md</code>, which doesn't exist for a
|
|
19
|
+
rule/workflow (a single file / merged block), so their executable
|
|
20
|
+
Markdown went unscanned; and <code>boost sync</code> only reconciled
|
|
21
|
+
skills, so a deleted rule/workflow materialization couldn't be
|
|
22
|
+
repaired. Fix both: carry the raw source on the install result
|
|
23
|
+
(<code>scan_text</code>) so injectscan/secretscan see exactly what was
|
|
24
|
+
installed, and extend <code>sync_plan</code>/<code>sync_apply</code>
|
|
25
|
+
with a <code>missing_materializations</code> pass that re-materializes
|
|
26
|
+
a rule/workflow from its tap when a drop file or CLAUDE.md block is
|
|
27
|
+
gone — mirroring the missing-store-dir repair for skills.
|
|
@@ -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>101</b><span>Loop finds</span></div>
|
|
122
122
|
<!-- /ROADMAP:stats -->
|
|
123
123
|
</div>
|
|
124
124
|
</section>
|
|
@@ -817,6 +817,29 @@ chunks instead cost ~70%.</p>
|
|
|
817
817
|
<span class="m">update was skill-only after rule/workflow install</span>
|
|
818
818
|
</div>
|
|
819
819
|
</article>
|
|
820
|
+
|
|
821
|
+
<article class="cap rcard">
|
|
822
|
+
<div class="head"><span class="pill shipped">Shipped</span><span class="cat">Install engine · Safety</span></div>
|
|
823
|
+
<h3>Scan and <code>sync</code> rules/workflows like skills</h3>
|
|
824
|
+
<p>Two skill-only gaps remained after rule (<code>#141</code>) / workflow
|
|
825
|
+
(<code>#150</code>) install: the install-time injection + secret scan
|
|
826
|
+
read <code>res.dest/SKILL.md</code>, which doesn't exist for a
|
|
827
|
+
rule/workflow (a single file / merged block), so their executable
|
|
828
|
+
Markdown went unscanned; and <code>boost sync</code> only reconciled
|
|
829
|
+
skills, so a deleted rule/workflow materialization couldn't be
|
|
830
|
+
repaired. Fix both: carry the raw source on the install result
|
|
831
|
+
(<code>scan_text</code>) so injectscan/secretscan see exactly what was
|
|
832
|
+
installed, and extend <code>sync_plan</code>/<code>sync_apply</code>
|
|
833
|
+
with a <code>missing_materializations</code> pass that re-materializes
|
|
834
|
+
a rule/workflow from its tap when a drop file or CLAUDE.md block is
|
|
835
|
+
gone — mirroring the missing-store-dir repair for skills.</p>
|
|
836
|
+
<div class="meta">
|
|
837
|
+
<span class="m">Complexity <b>M</b></span>
|
|
838
|
+
<span class="m">Impact <b>Med</b></span>
|
|
839
|
+
<span class="m">Wow <b class="wow">★★</b></span>
|
|
840
|
+
<span class="m">close the last skill-only gaps for rules/workflows</span>
|
|
841
|
+
</div>
|
|
842
|
+
</article>
|
|
820
843
|
<!-- /ROADMAP:cards -->
|
|
821
844
|
|
|
822
845
|
</div>
|
|
@@ -19,11 +19,14 @@ What it does (all offline — **no `OPENAI_API_KEY` needed**):
|
|
|
19
19
|
2. Authors **one** `SKILL.md` and imports it into boost.
|
|
20
20
|
3. **Value 1** — renders it to *both* frameworks and instantiates each:
|
|
21
21
|
a real `crewai.Agent` and a real `agents.Agent` from the same source, no
|
|
22
|
-
hand-porting.
|
|
22
|
+
hand-porting. Both are wired to **boost's configured `ai.model` (Claude)** by
|
|
23
|
+
default, so they run on the same LLM boost uses — no OpenAI key. Override per
|
|
24
|
+
run with `boost adapt … --model openai/gpt-4o`, or `--model none` for the
|
|
25
|
+
framework's own default.
|
|
23
26
|
4. **Value 2** — edits the skill **once** and re-adapts; the change appears in
|
|
24
27
|
**both** generated files (before/after `0 0` → `1 1`). That is the
|
|
25
28
|
drift-killing payoff: one edit, every runtime current.
|
|
26
|
-
5. Optional: if `
|
|
29
|
+
5. Optional: if `ANTHROPIC_API_KEY` is set, actually runs the agent on Claude.
|
|
27
30
|
|
|
28
31
|
Requirements: **Python 3.11–3.13** (CrewAI's `tiktoken` dependency has no 3.14
|
|
29
32
|
wheel yet; boost itself supports 3.9–3.14). Clean up with
|