boost-skill-cli 1.0.188__tar.gz → 1.0.189__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.188 → boost_skill_cli-1.0.189}/PKG-INFO +1 -1
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/_version.py +2 -2
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/core/scopes.py +24 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/core/store.py +19 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_skill_cli.egg-info/PKG-INFO +1 -1
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_skill_cli.egg-info/SOURCES.txt +1 -0
- boost_skill_cli-1.0.189/docs/roadmap/items/project-scope-symlink-escape-on-write.md +33 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap.html +30 -1
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_scopes.py +38 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_store.py +25 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/.gitattributes +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/.gitignore +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/.gitleaks.toml +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/.htmlvalidate.json +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/.lycheeignore +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/.markdownlint-cli2.jsonc +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/.pre-commit-config.yaml +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/.stylelintrc.json +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/.vale/styles/boost/Terminology.yml +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/.vale/styles/config/vocabularies/boost/accept.txt +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/.vale.ini +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/CLAUDE.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/CONTRIBUTING.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/LICENSE +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/MANIFEST.in +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/Makefile +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/README.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/SECURITY.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/__init__.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/__main__.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/cli.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/cliparse.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/commands/__init__.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/commands/bmad.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/commands/configuration.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/commands/discovery.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/commands/hooks.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/commands/info.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/commands/intelligence.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/commands/pkg.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/commands/quality.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/commands/taps.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/commands/team.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/core/__init__.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/core/adapters.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/core/agents.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/core/ai.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/core/catalog.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/core/claude_settings.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/core/config.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/core/dense.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/core/embed.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/core/frontmatter.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/core/gitutil.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/core/imperative.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/core/injectscan.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/core/journal.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/core/lockfile.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/core/logs.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/core/mcp.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/core/nethttp.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/core/output.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/core/paths.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/core/policy.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/core/projectlock.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/core/rag.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/core/registry.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/core/rules.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/core/secretscan.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/core/serve.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/core/stackprobe.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/core/staleness.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/core/typosquat.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/core/updatediff.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/core/util.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/core/workflows.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/data/registries.json +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/errors.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_cli/spin.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_skill_cli.egg-info/dependency_links.txt +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_skill_cli.egg-info/entry_points.txt +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_skill_cli.egg-info/requires.txt +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_skill_cli.egg-info/top_level.txt +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/.claude/settings.local.json +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/DEBUGGING.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/adapters.html +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/commands.html +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/demo.gif +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/demo.tape +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/design-roadmap.html +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/eval.html +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/index.html +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/mcp-hub.html +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/rag-architecture.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/BOOST-D01.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/BOOST-D02.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/BOOST-D03.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/BOOST-D04.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/BOOST-D05.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/BOOST-D06.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/BOOST-D07.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/BOOST-D08.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/BOOST-D09.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/BOOST-D10.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/BOOST-D11.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/BOOST-D12.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/BOOST-D13.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/BOOST-D14.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/BOOST-D15.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/BOOST-D16.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/BOOST-D17.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/BOOST-D18.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/BOOST-D19.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/BOOST-D20.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/BOOST-D21.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/BOOST-D22.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/BOOST-D23.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/BOOST-D24.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/BOOST-D25.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/BOOST-D26.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/accessibility-audit-pa11y-ci-axe-core.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/atomic-corruption-safe-lock-file-writes.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/atomic-skill-install-temp-dir-swap.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/autonomous-ship-workflow-and-isolated-worktree.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/boost-run-live-agents.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/bring-commands-under-mutation-testing.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/broken-link-and-anchor-checking-lychee.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/browse-crashes-selecting-a-rule-or-workflow.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/build-provenance-slsa-attestations.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/cache-the-catalog-entry-set-across-rag-queries.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/capability-manifest-and-least-privilege-policy.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/clean-env-install-smoke-pip-and-pipx.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/command-reference-docs-site.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/complexity-and-dead-code-radar-xenon-vulture.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/consolidate-skill-staleness-drift-logic-into-cor.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/coverage-dashboard-codecov-free-for-oss.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/coverage-guided-fuzzing-atheris-oss-fuzz.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/crash-recorder-error-paths-core-logs-py.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/dependency-cve-gate-pip-audit.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/docstring-coverage-interrogate.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/doctor-checks-rules-and-workflows.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/end-of-options-guard-on-git-commands.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/extension-free-tests-core-dense-py.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/extract-mcp-http-servers-out-of-configuration-py.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/finish-mutation-hardening-across-core.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/fix-self-update-version-detection-dead-branch.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/fork-safe-network-proxy-handler.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/framework-adapter-langgraph.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/framework-adapter-multi-agent.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/framework-adapters-boost-adapt.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/frontmatter-scalar-over-coercion.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/github-pages-deploy-is-broken-every-push.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/golden-set-statistical-power.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/hash-pinned-reproducible-toolchain-uv-lock.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/html-validation-html-validate.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/install-scope-user-or-project.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/integrity-verification-boost-verify.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/invocation-pid-logging-for-crash-correlation.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/layering-guard-import-linter.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/lighthouse-ci-on-the-pages-site.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/list-rules-and-workflows.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/localize-the-stored-bm25-snippet.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/lockfile-enforcement-and-commit-pinning.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/log-timestamps-mislabeled-utc.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/lowest-version-resolution-uv-resolution-lowest-d.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/make-the-roadmaps-discoverable.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/markdown-consistency-markdownlint-cli2.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/mcp-hub-diagram-node-text-overflow.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/mcp-launch-objc-fork-safety.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/mcp-register-names-server-before-env.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/mcp-startup-self-harden-fork-safety.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/memoize-config-load-in-process.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/modernization-smells-refurb-pyupgrade.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/mutation-hardening-core-frontmatter-py.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/mutation-hardening-core-gitutil-py.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/mutation-hardening-core-store-py.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/one-command-every-env-nox.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/one-shared-atomic-write-helper.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/package-metadata-validation-twine-check-friends.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/patch-coverage-gate-diff-cover.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/performance-regression-gate-pytest-benchmark.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/post-deploy-smoke-headless-load-check.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/pre-release-python-canary-3-14t-free-threaded.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/project-scope-across-every-command.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/promote-nav-footer-into-the-shared-style-system.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/prompt-injection-scanning-of-skill-markdown.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/property-based-tests-hypothesis-on-the-parsers.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/prose-and-terminology-linting-vale.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/prune-ignored-dirs-during-scan-dir-walk.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/quality-dashboard-sonarcloud-free-for-oss.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/ranx-significance-monitor.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/reconcile-the-theme-drift.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/refresh-the-marketing-surface.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/retrieval-quality-eval-harness.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/reuse-helpers-kill-minor-dead-work.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/robust-tag-argument-parsing.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/rule-install-native-materialization.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/runner-egress-monitoring-stepsecurity-harden-run.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/runtime-explain-faithfulness-guardrail.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/sbom-aware-scanning-osv-scanner.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/sbom-on-every-release-cyclonedx-syft.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/scan-and-sync-rules-and-workflows.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/second-type-checker-pyright.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/secret-and-pii-scanning-of-installed-skills.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/secret-scanning-gitleaks-push-protection.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/security-linting-bandit-via-ruff-s-rules.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/shift-left-gate-pre-commit-pre-commit-ci.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/single-imperative-rule-extractor.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/single-tech-stack-prober.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/split-oversized-command-modules.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/startup-and-import-time-budget-x-importtime.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/stop-re-serializing-entry-meta-on-every-search.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/supply-chain-posture-openssf-scorecard.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/surface-every-docs-page-from-the-guide.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/tap-signing-and-provenance-sigstore-minisign.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/theme-asset-linting-stylelint-eslint.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/typo-detection-codespell.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/typosquat-and-name-confusion-detection.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/unify-tilde-two-copies-have-a-boundary-bug.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/untrack-generated-build-noise.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/update-diff-before-apply.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/update-refreshes-rules-and-workflows.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/visual-regression-pass-on-the-guide.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/widen-the-ruff-rule-surface-b-sim-c4-perf-ruf.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/windows-in-the-ci-matrix.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/workflow-install-native-materialization.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/workflow-linting-actionlint.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/workflow-sast-zizmor.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/workspace-scope-install.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/eslint.config.mjs +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/examples/README.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/examples/adapt-demo.sh +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/examples/boost-run-prototype.sh +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/index.html +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/noxfile.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/pyproject.toml +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/scripts/bench_cli.sh +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/scripts/build_command_reference.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/scripts/build_registries.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/scripts/build_roadmap.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/scripts/check_anchors.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/scripts/ensure_eval_corpus.sh +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/scripts/eval_explain.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/scripts/eval_recommend.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/scripts/eval_retrieval.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/scripts/eval_stats_summary.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/scripts/import_budget.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/scripts/mutation_gate.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/scripts/perf_gate.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/setup.cfg +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/style/README.md +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/style/boost.css +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/style/boost.js +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/style/demo.html +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/bdd/features/adapt.feature +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/bdd/features/browse.feature +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/bdd/features/count.feature +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/bdd/features/discover.feature +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/bdd/features/doctor.feature +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/bdd/features/environment.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/bdd/features/explain.feature +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/bdd/features/index.feature +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/bdd/features/install.feature +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/bdd/features/list.feature +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/bdd/features/mcp.feature +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/bdd/features/search.feature +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/bdd/features/steps/cli_steps.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/bdd/features/steps/discovery_steps.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/bdd/features/steps/mcp_steps.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/bdd/features/steps/quality_steps.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/conftest.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/eval/baseline.json +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/eval/explain.jsonl +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/eval/golden.jsonl +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/eval/recommend.jsonl +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/eval/taps.txt +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/functional/test_cli_adapt.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/functional/test_cli_bmad.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/functional/test_cli_configuration.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/functional/test_cli_discovery.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/functional/test_cli_hooks.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/functional/test_cli_info.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/functional/test_cli_intelligence.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/functional/test_cli_pkg.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/functional/test_cli_quality.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/functional/test_cli_taps.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/functional/test_cli_team.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/functional/test_everyday_loop.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/functional/test_property_parsers.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/functional/test_workspace_scope.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/make_fixture.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/perf/test_benchmarks.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/smoke.sh +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_adapters.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_agents.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_ai.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_catalog.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_check_anchors.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_claude_settings.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_cliparse.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_command_reference_fresh.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_config.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_dense.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_dense_fallback.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_docs_pages_linked.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_embed.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_errors_and_cli_table.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_eval_stats_summary.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_frontmatter.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_gitleaks_config.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_gitutil.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_imperative.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_import_budget.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_injectscan.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_journal.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_lockfile.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_logs.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_mcp.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_mutation_hardening.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_nethttp.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_output.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_paths.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_perf_gate.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_pkg_confusions.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_pkg_injection.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_pkg_secrets.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_policy.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_projectlock.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_rag.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_registries_fresh.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_registry.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_roadmap_fresh.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_rules.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_secretscan.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_serve.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_spin.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_stackprobe.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_staleness.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_token_parity.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_typosquat.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_updatediff.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_util.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_version.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/unit/test_workflows.py +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/visual/package.json +0 -0
- {boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/tests/visual/visual_check.mjs +0 -0
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '1.0.
|
|
22
|
-
__version_tuple__ = version_tuple = (1, 0,
|
|
21
|
+
__version__ = version = '1.0.189'
|
|
22
|
+
__version_tuple__ = version_tuple = (1, 0, 189)
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -203,3 +203,27 @@ def contains(base, path) -> bool:
|
|
|
203
203
|
return os.path.commonpath([str(base_r), str(path_r)]) == str(base_r)
|
|
204
204
|
except (OSError, ValueError):
|
|
205
205
|
return False
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
def ensure_in_base(base, path):
|
|
209
|
+
"""Raise if ``path`` would resolve outside ``base`` — the guard before any
|
|
210
|
+
project-scope WRITE, the mirror of :func:`contains` before every delete.
|
|
211
|
+
|
|
212
|
+
A project destination is built from directory names committed in the repo
|
|
213
|
+
(``.claude/skills`` and its per-agent siblings). A hostile repo can ship one
|
|
214
|
+
of those as a symlink pointing outside the tree — at ``~/.ssh``, say — and
|
|
215
|
+
the ``mkdir(parents=True)`` + ``os.replace`` that materializes a skill would
|
|
216
|
+
then run on the far side, escaping the project entirely. The squatter check
|
|
217
|
+
(refuse to overwrite a path boost did not create) does not stop this:
|
|
218
|
+
dropping a *new* name like ``authorized_keys`` collides with nothing, and
|
|
219
|
+
``--force`` waives it regardless. ``contains`` resolves symlinks on both
|
|
220
|
+
ends, so re-deriving containment here — before the write, independent of
|
|
221
|
+
existence or force — is the boundary that actually holds. Returns ``path``
|
|
222
|
+
so a caller can wrap the target inline.
|
|
223
|
+
"""
|
|
224
|
+
if not contains(base, path):
|
|
225
|
+
raise BoostError(
|
|
226
|
+
"refusing to install %s: it resolves outside this project" % path,
|
|
227
|
+
hint="a directory such as .claude/skills in this repo is a symlink "
|
|
228
|
+
"pointing outside it — remove or replace it, then reinstall")
|
|
229
|
+
return Path(path)
|
|
@@ -281,6 +281,15 @@ def _install_project_skill(entry: dict, force: bool = False,
|
|
|
281
281
|
for agent, skills_dir in agents.enabled_agents().items()
|
|
282
282
|
if not only_agents or agent in only_agents]
|
|
283
283
|
|
|
284
|
+
# Refuse to write through a symlink that leaves the repo. An agent dir like
|
|
285
|
+
# ``.claude/skills`` is committed, so a hostile clone can ship it as a
|
|
286
|
+
# symlink to ``~/.ssh`` and the copy below would land on the far side.
|
|
287
|
+
# Checked for every target up front — before existence, force, or any write
|
|
288
|
+
# — so a single escaping dir aborts the whole install rather than writing
|
|
289
|
+
# part of it outside the project first.
|
|
290
|
+
for _agent, dest in targets:
|
|
291
|
+
scopes.ensure_in_base(resolved_base, dest)
|
|
292
|
+
|
|
284
293
|
# Refuse to clobber a directory boost did not put there. In user scope the
|
|
285
294
|
# store is boost's alone, but here the destination is inside someone's repo
|
|
286
295
|
# — a same-named hand-written skill is a real possibility, and overwriting
|
|
@@ -492,6 +501,11 @@ def _install_rule(entry: dict, force: bool = False,
|
|
|
492
501
|
if only_agents and agent not in only_agents:
|
|
493
502
|
continue
|
|
494
503
|
mode, path = rules.rule_target(agent, skills_dir, name, base=resolved_base)
|
|
504
|
+
# Project scope writes into the repo, so a committed agent dir could be
|
|
505
|
+
# a symlink escaping it (see scopes.ensure_in_base). User scope writes
|
|
506
|
+
# into the user's own ~/.claude, which they control — nothing to guard.
|
|
507
|
+
if resolved_base is not None:
|
|
508
|
+
scopes.ensure_in_base(resolved_base, path)
|
|
495
509
|
path.parent.mkdir(parents=True, exist_ok=True)
|
|
496
510
|
if mode == rules.MODE_CLAUDE:
|
|
497
511
|
current = path.read_text(encoding="utf-8") if path.exists() else ""
|
|
@@ -591,6 +605,11 @@ def _install_workflow(entry: dict, force: bool = False,
|
|
|
591
605
|
if only_agents and agent not in only_agents:
|
|
592
606
|
continue
|
|
593
607
|
path = workflows.workflow_target(skills_dir, slot, name, base=resolved_base)
|
|
608
|
+
# Project scope writes into the repo; a committed agent dir could be a
|
|
609
|
+
# symlink escaping it (see scopes.ensure_in_base). User scope writes into
|
|
610
|
+
# the user's own ~/.claude, which they control — nothing to guard.
|
|
611
|
+
if resolved_base is not None:
|
|
612
|
+
scopes.ensure_in_base(resolved_base, path)
|
|
594
613
|
path.parent.mkdir(parents=True, exist_ok=True)
|
|
595
614
|
util.atomic_write_text(path, raw)
|
|
596
615
|
materializations.append({"agent": agent, "slot": slot, "path": str(path)})
|
|
@@ -184,6 +184,7 @@ docs/roadmap/items/performance-regression-gate-pytest-benchmark.md
|
|
|
184
184
|
docs/roadmap/items/post-deploy-smoke-headless-load-check.md
|
|
185
185
|
docs/roadmap/items/pre-release-python-canary-3-14t-free-threaded.md
|
|
186
186
|
docs/roadmap/items/project-scope-across-every-command.md
|
|
187
|
+
docs/roadmap/items/project-scope-symlink-escape-on-write.md
|
|
187
188
|
docs/roadmap/items/promote-nav-footer-into-the-shared-style-system.md
|
|
188
189
|
docs/roadmap/items/prompt-injection-scanning-of-skill-markdown.md
|
|
189
190
|
docs/roadmap/items/property-based-tests-hypothesis-on-the-parsers.md
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: project-scope-symlink-escape-on-write
|
|
3
|
+
board: code
|
|
4
|
+
section: trust
|
|
5
|
+
status: shipped
|
|
6
|
+
category: Security · Integrity
|
|
7
|
+
complexity: S
|
|
8
|
+
impact: High
|
|
9
|
+
wow: 4
|
|
10
|
+
note: hostile repo could write outside itself
|
|
11
|
+
order: 6
|
|
12
|
+
owner: loop/writeguard
|
|
13
|
+
pr: 213
|
|
14
|
+
title: Project scope — refuse to write through an escaping symlink
|
|
15
|
+
---
|
|
16
|
+
Workspace scope (<a href="https://github.com/jonnyeclectic/boost/pull/212">#212</a>)
|
|
17
|
+
guarded the delete side — <code>uninstall --local</code> re-derives every
|
|
18
|
+
recorded path and refuses one that resolves outside the repo — but not
|
|
19
|
+
the <em>write</em> side. A project install builds its destination from
|
|
20
|
+
agent-dir names committed in the repo
|
|
21
|
+
(<code>.claude/skills</code> and its per-agent siblings), and a hostile
|
|
22
|
+
clone can ship one of those as a <strong>symlink pointing outside the
|
|
23
|
+
tree</strong> — at <code>~/.ssh</code>, say. Cloning that repo and
|
|
24
|
+
running <code>boost install <skill> --local</code> then writes on the
|
|
25
|
+
far side: confirmed by reproduction, a skill directory landed in a
|
|
26
|
+
sibling of the repo instead of inside it. The squatter check does not
|
|
27
|
+
stop it (a brand-new leaf name like <code>authorized_keys</code>
|
|
28
|
+
collides with nothing, and <code>--force</code> waives it anyway).
|
|
29
|
+
<code>scopes.ensure_in_base</code> is the write-side mirror of the
|
|
30
|
+
delete guard: it re-derives containment through symlinks for every
|
|
31
|
+
target up front, so one escaping directory aborts the whole install
|
|
32
|
+
before anything is written. Covers all three project-scope kinds —
|
|
33
|
+
skill, rule and workflow.
|
|
@@ -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>110</b><span>Loop finds</span></div>
|
|
122
122
|
<!-- /ROADMAP:stats -->
|
|
123
123
|
</div>
|
|
124
124
|
</section>
|
|
@@ -2082,6 +2082,35 @@ paths.</p>
|
|
|
2082
2082
|
</div>
|
|
2083
2083
|
</article>
|
|
2084
2084
|
|
|
2085
|
+
<article class="cap rcard">
|
|
2086
|
+
<div class="head"><span class="pill shipped">Shipped</span><span class="cat">Security · Integrity</span></div>
|
|
2087
|
+
<h3>Project scope — refuse to write through an escaping symlink</h3>
|
|
2088
|
+
<p>Workspace scope (<a href="https://github.com/jonnyeclectic/boost/pull/212">#212</a>)
|
|
2089
|
+
guarded the delete side — <code>uninstall --local</code> re-derives every
|
|
2090
|
+
recorded path and refuses one that resolves outside the repo — but not
|
|
2091
|
+
the <em>write</em> side. A project install builds its destination from
|
|
2092
|
+
agent-dir names committed in the repo
|
|
2093
|
+
(<code>.claude/skills</code> and its per-agent siblings), and a hostile
|
|
2094
|
+
clone can ship one of those as a <strong>symlink pointing outside the
|
|
2095
|
+
tree</strong> — at <code>~/.ssh</code>, say. Cloning that repo and
|
|
2096
|
+
running <code>boost install <skill> --local</code> then writes on the
|
|
2097
|
+
far side: confirmed by reproduction, a skill directory landed in a
|
|
2098
|
+
sibling of the repo instead of inside it. The squatter check does not
|
|
2099
|
+
stop it (a brand-new leaf name like <code>authorized_keys</code>
|
|
2100
|
+
collides with nothing, and <code>--force</code> waives it anyway).
|
|
2101
|
+
<code>scopes.ensure_in_base</code> is the write-side mirror of the
|
|
2102
|
+
delete guard: it re-derives containment through symlinks for every
|
|
2103
|
+
target up front, so one escaping directory aborts the whole install
|
|
2104
|
+
before anything is written. Covers all three project-scope kinds —
|
|
2105
|
+
skill, rule and workflow.</p>
|
|
2106
|
+
<div class="meta">
|
|
2107
|
+
<span class="m">Complexity <b>S</b></span>
|
|
2108
|
+
<span class="m hi">Impact <b>High</b></span>
|
|
2109
|
+
<span class="m">Wow <b class="wow">★★★★</b></span>
|
|
2110
|
+
<span class="m">hostile repo could write outside itself</span>
|
|
2111
|
+
</div>
|
|
2112
|
+
</article>
|
|
2113
|
+
|
|
2085
2114
|
<article class="cap rcard">
|
|
2086
2115
|
<div class="head"><span class="pill shipped">Shipped</span><span class="cat">Security · Secrets</span></div>
|
|
2087
2116
|
<h3>Secret & PII scanning of installed skills</h3>
|
|
@@ -284,3 +284,41 @@ def test_contains_fails_closed_when_resolution_errors(tmp_path, monkeypatch):
|
|
|
284
284
|
|
|
285
285
|
monkeypatch.setattr(scopes, "Path", ExplodingPath)
|
|
286
286
|
assert scopes.contains(tmp_path, tmp_path / "x") is False
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
# ── ensure_in_base: the write guard ──────────────────────────────────────
|
|
290
|
+
|
|
291
|
+
def test_ensure_in_base_returns_the_path_when_inside(tmp_path):
|
|
292
|
+
dest = tmp_path / ".claude" / "skills" / "x"
|
|
293
|
+
assert scopes.ensure_in_base(tmp_path, dest) == Path(dest)
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
def test_ensure_in_base_raises_on_a_plain_escape(tmp_path):
|
|
297
|
+
(tmp_path / "repo").mkdir()
|
|
298
|
+
with pytest.raises(BoostError) as err:
|
|
299
|
+
scopes.ensure_in_base(tmp_path / "repo", tmp_path / "elsewhere" / "x")
|
|
300
|
+
assert "outside this project" in err.value.message
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
def test_ensure_in_base_raises_when_a_symlinked_dir_escapes(tmp_path):
|
|
304
|
+
"""The write-side attack contains() is reused for: an agent dir committed as
|
|
305
|
+
a symlink pointing outside the repo, targeting a NEW leaf that does not yet
|
|
306
|
+
exist — so nothing but the containment check can catch it."""
|
|
307
|
+
repo = tmp_path / "repo"
|
|
308
|
+
(repo / ".git").mkdir(parents=True)
|
|
309
|
+
(repo / ".claude").mkdir()
|
|
310
|
+
outside = tmp_path / "outside"
|
|
311
|
+
outside.mkdir()
|
|
312
|
+
(repo / ".claude" / "skills").symlink_to(outside, target_is_directory=True)
|
|
313
|
+
# repo/.claude/skills/authorized_keys resolves to outside/authorized_keys.
|
|
314
|
+
dest = repo / ".claude" / "skills" / "authorized_keys"
|
|
315
|
+
with pytest.raises(BoostError):
|
|
316
|
+
scopes.ensure_in_base(repo, dest)
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
def test_ensure_in_base_allows_a_real_nested_dir(tmp_path):
|
|
320
|
+
# A legitimate project dir, even several levels deep, must pass untouched.
|
|
321
|
+
repo = tmp_path / "repo"
|
|
322
|
+
(repo / ".claude" / "skills").mkdir(parents=True)
|
|
323
|
+
dest = repo / ".claude" / "skills" / "ok"
|
|
324
|
+
assert scopes.ensure_in_base(repo, dest) == Path(dest)
|
|
@@ -860,6 +860,31 @@ class TestProjectSkills:
|
|
|
860
860
|
store.install(entry, scope="project", base=str(repo), force=True)
|
|
861
861
|
assert projectlock.get_skill(repo, "brainstorming")["installed_at"] == first
|
|
862
862
|
|
|
863
|
+
def test_symlinked_agent_dir_cannot_escape_the_repo(self, entry, tmp_path):
|
|
864
|
+
"""A committed ``.claude/skills`` symlink pointing outside the repo must
|
|
865
|
+
not let the install write on the far side.
|
|
866
|
+
|
|
867
|
+
The attack: a hostile clone ships an agent dir as a symlink to, say,
|
|
868
|
+
``~/.ssh``; ``_copy_skill`` would then ``mkdir``/``os.replace`` through
|
|
869
|
+
it and land outside the project. Guarded by ``scopes.ensure_in_base``
|
|
870
|
+
before any write. Uses a fresh skill name so the squatter check (which
|
|
871
|
+
only fires on an existing path) is not what does the blocking.
|
|
872
|
+
"""
|
|
873
|
+
repo = self._repo(tmp_path)
|
|
874
|
+
outside = tmp_path / "outside" # stands in for ~/.ssh
|
|
875
|
+
outside.mkdir()
|
|
876
|
+
(repo / ".claude").mkdir()
|
|
877
|
+
(repo / ".claude" / "skills").symlink_to(outside, target_is_directory=True)
|
|
878
|
+
|
|
879
|
+
with pytest.raises(BoostError) as err:
|
|
880
|
+
store.install(entry, scope="project", base=str(repo))
|
|
881
|
+
assert "outside this project" in err.value.message
|
|
882
|
+
# Nothing written through the symlink, and the all-or-nothing pre-check
|
|
883
|
+
# means the other agents' in-repo dirs stay untouched too.
|
|
884
|
+
assert list(outside.iterdir()) == []
|
|
885
|
+
assert not (repo / ".windsurf" / "skills" / "brainstorming").exists()
|
|
886
|
+
assert not (repo / ".cursor" / "skills" / "brainstorming").exists()
|
|
887
|
+
|
|
863
888
|
def test_policy_blocks_a_project_install_too(self, entry, tmp_path):
|
|
864
889
|
# Vendoring into a repo is not an escape hatch around policy.
|
|
865
890
|
policy.save({"blocked_skills": ["brainstorming"]})
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_skill_cli.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/boost_skill_cli.egg-info/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{boost_skill_cli-1.0.188 → boost_skill_cli-1.0.189}/docs/roadmap/items/boost-run-live-agents.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|