plugin-scanner 2.0.60__tar.gz → 2.0.62__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.
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/PKG-INFO +1 -1
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/pyproject.toml +1 -1
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/pyproject.toml.bak +1 -1
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/adapters/claude_code.py +67 -4
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/cli/commands.py +410 -14
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/version.py +1 -1
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_guard_claude_adapter.py +69 -4
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_guard_cli.py +4 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_guard_runtime.py +373 -10
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_guard_surface_server.py +3 -8
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/uv.lock +22 -22
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/.clusterfuzzlite/Dockerfile +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/.clusterfuzzlite/build.sh +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/.clusterfuzzlite/project.yaml +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/.clusterfuzzlite/requirements-atheris.txt +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/.dockerignore +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/.github/CODEOWNERS +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/.github/ISSUE_TEMPLATE/bug-report.yml +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/.github/ISSUE_TEMPLATE/feature-request.yml +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/.github/dependabot.yml +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/.github/workflows/ci.yml +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/.github/workflows/codeql.yml +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/.github/workflows/dependabot-uv-lock.yml +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/.github/workflows/fuzz.yml +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/.github/workflows/harness-smoke.yml +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/.github/workflows/publish.yml +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/.github/workflows/scorecard.yml +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/.gitignore +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/.pre-commit-hooks.yaml +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/CONTRIBUTING.md +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/Dockerfile +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/LICENSE +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/README.md +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/SECURITY.md +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/dashboard/index.html +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/dashboard/package.json +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/dashboard/pnpm-lock.yaml +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/dashboard/public/brand/Logo_Whole.png +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/dashboard/src/app.tsx +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/dashboard/src/approval-center-layout.tsx +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/dashboard/src/approval-center-primitives.tsx +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/dashboard/src/approval-center-utils.ts +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/dashboard/src/fleet-workspace.tsx +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/dashboard/src/guard-api.ts +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/dashboard/src/guard-demo.ts +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/dashboard/src/guard-types.ts +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/dashboard/src/main.tsx +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/dashboard/src/receipts-workspace.tsx +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/dashboard/src/runtime-overview.tsx +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/dashboard/src/styles.css +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/dashboard/src/vite-env.d.ts +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/dashboard/tsconfig.json +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/dashboard/vite.config.ts +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/docker-requirements.txt +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/docs/guard/approval-audit.md +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/docs/guard/architecture.md +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/docs/guard/get-started.md +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/docs/guard/harness-support.md +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/docs/guard/local-vs-cloud.md +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/docs/guard/testing-matrix.md +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/docs/trust/mcp-trust-draft.md +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/docs/trust/plugin-trust-draft.md +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/docs/trust/skill-trust-local.md +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/fuzzers/manifest_fuzzer.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/requirements.txt +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/schemas/plugin-quality.v1.json +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/schemas/scan-result.v1.json +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/schemas/verify-result.v1.json +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/__init__.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/action_runner.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/argparse_utils.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/checks/__init__.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/checks/best_practices.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/checks/claude.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/checks/code_quality.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/checks/ecosystem_common.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/checks/gemini.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/checks/manifest.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/checks/manifest_support.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/checks/marketplace.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/checks/mcp_security.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/checks/opencode.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/checks/operational_security.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/checks/security.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/checks/skill_security.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/cli.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/cli_ui.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/config.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/ecosystems/__init__.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/ecosystems/base.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/ecosystems/claude.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/ecosystems/codex.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/ecosystems/detect.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/ecosystems/gemini.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/ecosystems/opencode.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/ecosystems/registry.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/ecosystems/types.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/github_reporting.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/__init__.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/adapters/__init__.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/adapters/antigravity.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/adapters/base.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/adapters/codex.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/adapters/copilot.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/adapters/cursor.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/adapters/gemini.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/adapters/hermes.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/adapters/mcp_servers.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/adapters/opencode.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/adapters/opencode_artifacts.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/approvals.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/bridge/__init__.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/capabilities.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/cli/__init__.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/cli/approval_commands.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/cli/bootstrap.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/cli/connect_flow.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/cli/install_commands.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/cli/product.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/cli/prompt.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/cli/render.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/cli/update_commands.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/codex_config.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/config.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/consumer/__init__.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/consumer/service.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/daemon/__init__.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/daemon/client.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/daemon/manager.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/daemon/server.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/daemon/static/assets/guard-dashboard.js +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/daemon/static/assets/index.css +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/daemon/static/brand/Logo_Whole.png +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/daemon/static/index.html +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/incident.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/launcher.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/mcp_tool_calls.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/models.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/policy/__init__.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/policy/engine.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/protect.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/proxy/__init__.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/proxy/remote.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/proxy/runtime_mcp.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/proxy/stdio.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/receipts/__init__.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/receipts/manager.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/risk.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/runtime/__init__.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/runtime/runner.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/runtime/secret_file_requests.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/runtime/surface_server.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/schemas/__init__.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/schemas/consumer_mode.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/schemas/surface_server.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/shims.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/store.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/store_approvals.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/store_connect.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/guard/types.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/integrations/__init__.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/integrations/cisco_mcp_scanner.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/integrations/cisco_skill_scanner.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/lint_fixes.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/marketplace_support.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/models.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/path_support.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/policy.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/quality_artifact.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/repo_detect.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/reporting.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/rules/__init__.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/rules/registry.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/rules/specs.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/scanner.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/submission.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/suppressions.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/trust_domain_scoring.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/trust_helpers.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/trust_mcp_scoring.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/trust_models.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/trust_plugin_scoring.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/trust_scoring.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/trust_skill_scoring.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/trust_specs.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/src/codex_plugin_scanner/verification.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/__init__.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/conftest.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/__init__.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/bad-plugin/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/bad-plugin/.mcp.json +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/bad-plugin/secrets.js +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/claude-plugin-good/.claude-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/claude-plugin-good/LICENSE +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/claude-plugin-good/README.md +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/claude-plugin-good/SECURITY.md +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/claude-plugin-good/hooks/hooks.json +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/claude-plugin-good/skills/example/SKILL.md +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/code-quality-bad/evil.js +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/code-quality-bad/inject.js +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/gemini-extension-good/GEMINI.md +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/gemini-extension-good/LICENSE +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/gemini-extension-good/README.md +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/gemini-extension-good/SECURITY.md +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/gemini-extension-good/commands/hello.toml +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/gemini-extension-good/gemini-extension.json +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/good-plugin/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/good-plugin/.codexignore +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/good-plugin/LICENSE +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/good-plugin/README.md +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/good-plugin/SECURITY.md +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/good-plugin/assets/icon.svg +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/good-plugin/assets/logo.svg +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/good-plugin/assets/screenshot.svg +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/good-plugin/skills/example/SKILL.md +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/guard-codex-malicious-mcp/.codex/config.toml +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/hermes-plugin-evil/config.yaml +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/hermes-plugin-evil/mcp_servers.json +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/hermes-plugin-evil/skills/security/malicious/SKILL.md +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/hermes-plugin-evil/skills/stealth/sneaky/SKILL.md +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/hermes-plugin-evil/skills/stealth/sneaky/references/api-setup.md +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/hermes-plugin-evil/skills/stealth/sneaky/scripts/deploy.sh +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/hermes-plugin-evil/skills/utils/benign/SKILL.md +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/malformed-json/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/malicious-skill-plugin/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/malicious-skill-plugin/.codexignore +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/malicious-skill-plugin/LICENSE +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/malicious-skill-plugin/README.md +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/malicious-skill-plugin/SECURITY.md +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/malicious-skill-plugin/skills/leaky-skill/SKILL.md +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/mcp-canary-server.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/minimal-plugin/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/missing-fields/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/mit-license/LICENSE +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/multi-ecosystem-repo/codex-plugin/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/multi-ecosystem-repo/codex-plugin/LICENSE +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/multi-ecosystem-repo/codex-plugin/README.md +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/multi-ecosystem-repo/codex-plugin/SECURITY.md +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/multi-ecosystem-repo/gemini-ext/README.md +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/multi-ecosystem-repo/gemini-ext/gemini-extension.json +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/multi-plugin-repo/.agents/plugins/marketplace.json +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/.codexignore +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/LICENSE +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/README.md +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/SECURITY.md +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/skills/example/SKILL.md +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/multi-plugin-repo/plugins/beta-plugin/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/multi-plugin-repo/plugins/beta-plugin/skills/example/SKILL.md +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/no-version/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/opencode-good/.opencode/commands/hello.md +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/opencode-good/.opencode/plugins/example.ts +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/opencode-good/LICENSE +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/opencode-good/README.md +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/opencode-good/SECURITY.md +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/opencode-good/opencode.jsonc +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/skills-missing-dir/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/skills-no-frontmatter/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/skills-no-frontmatter/skills/bad-skill/SKILL.md +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/with-marketplace/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/with-marketplace/marketplace-broken.json +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/fixtures/with-marketplace/marketplace.json +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test-trust-scoring.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test-trust-specs.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_action_runner.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_best_practices.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_cisco_install_surfaces.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_cli.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_code_quality.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_config.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_coverage_remaining.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_ecosystems.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_edge_cases.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_final_coverage.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_guard_approvals.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_guard_bootstrap.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_guard_capabilities.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_guard_codex_e2e.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_guard_codex_install.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_guard_codex_proxy.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_guard_config_paths.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_guard_connect_flow.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_guard_consumer_mode.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_guard_copilot_adapter.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_guard_copilot_proxy.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_guard_daemon_manager.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_guard_events.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_guard_launch_env.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_guard_opencode_proxy.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_guard_product_flow.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_guard_protect.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_guard_render.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_guard_risk.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_guard_store_migrations.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_guard_verdicts.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_hermes_adapter.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_integration.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_lint_fixes.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_live_cisco_smoke.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_manifest.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_marketplace.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_mcp_security.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_operational_security.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_policy.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_quality_artifact.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_rule_registry.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_scanner.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_schema_contracts.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_security.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_security_ops.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_skill_security.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_submission.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_trust_scoring.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_trust_specs.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_verification.py +0 -0
- {plugin_scanner-2.0.60 → plugin_scanner-2.0.62}/tests/test_versioning.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: plugin-scanner
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.62
|
|
4
4
|
Summary: Lint, verify, and gate plugin ecosystems for maintainers, CI, and publish workflows.
|
|
5
5
|
Project-URL: Homepage, https://github.com/hashgraph-online/ai-plugin-scanner
|
|
6
6
|
Project-URL: Repository, https://github.com/hashgraph-online/ai-plugin-scanner
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "plugin-scanner"
|
|
7
|
-
version = "2.0.
|
|
7
|
+
version = "2.0.62"
|
|
8
8
|
description = "Lint, verify, and gate plugin ecosystems for maintainers, CI, and publish workflows."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "Apache-2.0"
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "hol-guard"
|
|
7
|
-
version = "2.0.
|
|
7
|
+
version = "2.0.62"
|
|
8
8
|
description = "Protect local AI harnesses with HOL Guard and run scanner checks for Codex, Claude, Cursor, Gemini, and OpenCode."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "Apache-2.0"
|
|
@@ -25,6 +25,7 @@ CLAUDE_GUARD_TOOL_TIMEOUT_SECONDS = 30
|
|
|
25
25
|
CLAUDE_GUARD_PROMPT_TIMEOUT_SECONDS = 20
|
|
26
26
|
CLAUDE_GUARD_NOTIFICATION_TIMEOUT_SECONDS = 10
|
|
27
27
|
CLAUDE_GUARD_SESSION_START_TIMEOUT_SECONDS = 10
|
|
28
|
+
CLAUDE_GUARD_STOP_TIMEOUT_SECONDS = 10
|
|
28
29
|
CLAUDE_SETTINGS_FILES = ("settings.json", "settings.local.json")
|
|
29
30
|
CLAUDE_GUARD_DAEMON_HOOK_MARKER = "HOL_GUARD_CLAUDE_DAEMON_HOOK"
|
|
30
31
|
|
|
@@ -43,9 +44,11 @@ def _shell_command(command: tuple[str, ...], *, windows: bool | None = None) ->
|
|
|
43
44
|
def _sync_runtime_hook_groups(hooks: dict[str, object], hook_command: str) -> None:
|
|
44
45
|
for key, matcher, timeout in (
|
|
45
46
|
("PreToolUse", CLAUDE_GUARD_TOOL_MATCHER, CLAUDE_GUARD_TOOL_TIMEOUT_SECONDS),
|
|
47
|
+
("PermissionRequest", CLAUDE_GUARD_TOOL_MATCHER, CLAUDE_GUARD_NOTIFICATION_TIMEOUT_SECONDS),
|
|
46
48
|
("PostToolUse", CLAUDE_GUARD_TOOL_MATCHER, CLAUDE_GUARD_TOOL_TIMEOUT_SECONDS),
|
|
47
49
|
("UserPromptSubmit", None, CLAUDE_GUARD_PROMPT_TIMEOUT_SECONDS),
|
|
48
50
|
("Notification", CLAUDE_GUARD_NOTIFICATION_MATCHER, CLAUDE_GUARD_NOTIFICATION_TIMEOUT_SECONDS),
|
|
51
|
+
("Stop", None, CLAUDE_GUARD_STOP_TIMEOUT_SECONDS),
|
|
49
52
|
):
|
|
50
53
|
existing_entries = hooks.get(key)
|
|
51
54
|
hooks[key] = _merge_hook_group(
|
|
@@ -55,6 +58,18 @@ def _sync_runtime_hook_groups(hooks: dict[str, object], hook_command: str) -> No
|
|
|
55
58
|
)
|
|
56
59
|
|
|
57
60
|
|
|
61
|
+
def _remove_unsupported_guard_hook_groups(hooks: dict[str, object]) -> None:
|
|
62
|
+
for key in ("PermissionDenied",):
|
|
63
|
+
entries = hooks.get(key)
|
|
64
|
+
if not isinstance(entries, list):
|
|
65
|
+
continue
|
|
66
|
+
remaining = _prune_guard_hook_entries(entries)
|
|
67
|
+
if remaining:
|
|
68
|
+
hooks[key] = remaining
|
|
69
|
+
else:
|
|
70
|
+
hooks.pop(key, None)
|
|
71
|
+
|
|
72
|
+
|
|
58
73
|
def _guard_hook_group(matcher: str | None, handler: dict[str, object]) -> dict[str, object]:
|
|
59
74
|
payload: dict[str, object] = {"hooks": [handler]}
|
|
60
75
|
if isinstance(matcher, str) and matcher.strip():
|
|
@@ -472,6 +487,7 @@ class ClaudeCodeHarnessAdapter(HarnessAdapter):
|
|
|
472
487
|
def _daemon_hook_command_parts(context: HarnessContext) -> tuple[str, ...]:
|
|
473
488
|
fallback_daemon_url = load_guard_daemon_url(context.guard_home) or guard_daemon_url_for_home(context.guard_home)
|
|
474
489
|
state_path = context.guard_home / "daemon-state.json"
|
|
490
|
+
fallback_command = ClaudeCodeHarnessAdapter._hook_command_parts(context)
|
|
475
491
|
query: dict[str, str] = {"guard-home": str(context.guard_home)}
|
|
476
492
|
if context.home_dir.resolve() != Path.home().resolve():
|
|
477
493
|
query["home"] = str(context.home_dir)
|
|
@@ -482,9 +498,11 @@ class ClaudeCodeHarnessAdapter(HarnessAdapter):
|
|
|
482
498
|
"void MARKER;"
|
|
483
499
|
"const fs=require('fs');"
|
|
484
500
|
"const http=require('http');"
|
|
501
|
+
"const cp=require('child_process');"
|
|
485
502
|
"const {URL}=require('url');"
|
|
486
503
|
f"const statePath={str(state_path)!r};"
|
|
487
504
|
f"const fallbackUrl={fallback_daemon_url!r};"
|
|
505
|
+
f"const fallbackCommand={list(fallback_command)!r};"
|
|
488
506
|
f"const query={urlencode(query)!r};"
|
|
489
507
|
"function daemonUrl(){"
|
|
490
508
|
"try{"
|
|
@@ -493,9 +511,41 @@ class ClaudeCodeHarnessAdapter(HarnessAdapter):
|
|
|
493
511
|
"}catch(_error){}"
|
|
494
512
|
"return fallbackUrl;"
|
|
495
513
|
"}"
|
|
514
|
+
"function eventName(data){"
|
|
515
|
+
"try{const payload=JSON.parse(data||'{}');"
|
|
516
|
+
"return String(payload.hook_event_name||payload.event||'PreToolUse');}"
|
|
517
|
+
"catch(_error){return 'PreToolUse';}"
|
|
518
|
+
"}"
|
|
519
|
+
"function degraded(reason,data){"
|
|
520
|
+
"const event=eventName(data);"
|
|
521
|
+
"const message=`HOL Guard could not reach the local daemon (${reason}), so it is using Claude's native "
|
|
522
|
+
"approval prompt as a safety fallback.`;"
|
|
523
|
+
"if(event==='UserPromptSubmit'){return '';}"
|
|
524
|
+
"if(event==='PreToolUse'){return JSON.stringify({systemMessage:'HOL Guard opened this Claude approval "
|
|
525
|
+
"prompt because local daemon evaluation was unavailable.',hookSpecificOutput:{hookEventName:'PreToolUse',"
|
|
526
|
+
"permissionDecision:'ask',permissionDecisionReason:`${message} Choose Yes to allow it once, Yes during "
|
|
527
|
+
"this session to trust the same action for this session, or No to keep it blocked.`}});}"
|
|
528
|
+
"return '{}';"
|
|
529
|
+
"}"
|
|
530
|
+
"function shouldSuppressOutput(data,responseBody){"
|
|
531
|
+
"if(eventName(data)!=='UserPromptSubmit')return false;"
|
|
532
|
+
"const trimmed=(responseBody||'').trim();"
|
|
533
|
+
"return trimmed===''||trimmed==='{}';"
|
|
534
|
+
"}"
|
|
535
|
+
"function runLocalFallback(reason,data){"
|
|
536
|
+
"try{"
|
|
537
|
+
"const result=cp.spawnSync(fallbackCommand[0],fallbackCommand.slice(1),{input:data,encoding:'utf8',"
|
|
538
|
+
"timeout:30000,env:process.env});"
|
|
539
|
+
"if(result.error)return degraded(`${reason}; fallback failed: ${result.error.message}`,data);"
|
|
540
|
+
"if(result.status===0){"
|
|
541
|
+
"if(shouldSuppressOutput(data,result.stdout)){process.exit(0);}"
|
|
542
|
+
"process.stdout.write(result.stdout&&result.stdout.trim()?result.stdout:'{}');"
|
|
543
|
+
"process.exit(0);}"
|
|
544
|
+
"return degraded(`${reason}; fallback exited ${result.status}`,data);"
|
|
545
|
+
"}catch(error){return degraded(`${reason}; fallback crashed: ${error.message}`,data);}"
|
|
546
|
+
"}"
|
|
496
547
|
"function fail(reason){"
|
|
497
|
-
"
|
|
498
|
-
"process.stdout.write(JSON.stringify({decision:'block',reason:message}));"
|
|
548
|
+
"process.stdout.write(runLocalFallback(reason,body.trim()?body:'{}'));"
|
|
499
549
|
"process.exit(0);"
|
|
500
550
|
"}"
|
|
501
551
|
"let body='';"
|
|
@@ -512,7 +562,9 @@ class ClaudeCodeHarnessAdapter(HarnessAdapter):
|
|
|
512
562
|
"response.setEncoding('utf8');"
|
|
513
563
|
"response.on('data',chunk=>{responseBody+=chunk;});"
|
|
514
564
|
"response.on('end',()=>{"
|
|
515
|
-
"if(response.statusCode>=200&&response.statusCode<300){
|
|
565
|
+
"if(response.statusCode>=200&&response.statusCode<300){"
|
|
566
|
+
"if(shouldSuppressOutput(data,responseBody)){process.exit(0);}"
|
|
567
|
+
"process.stdout.write(responseBody);process.exit(0);}"
|
|
516
568
|
"fail(`daemon returned HTTP ${response.statusCode||0}`);"
|
|
517
569
|
"});"
|
|
518
570
|
"});"
|
|
@@ -577,6 +629,7 @@ class ClaudeCodeHarnessAdapter(HarnessAdapter):
|
|
|
577
629
|
if not isinstance(hooks, dict):
|
|
578
630
|
return
|
|
579
631
|
_sync_runtime_hook_groups(hooks, self._daemon_hook_command(context))
|
|
632
|
+
_remove_unsupported_guard_hook_groups(hooks)
|
|
580
633
|
settings_path.parent.mkdir(parents=True, exist_ok=True)
|
|
581
634
|
settings_path.write_text(json.dumps(payload, indent=2), encoding="utf-8")
|
|
582
635
|
|
|
@@ -620,6 +673,7 @@ class ClaudeCodeHarnessAdapter(HarnessAdapter):
|
|
|
620
673
|
session_start_entries = _merge_hook_group(session_start_entries, matcher, session_start_handler)
|
|
621
674
|
hooks["SessionStart"] = session_start_entries
|
|
622
675
|
_sync_runtime_hook_groups(hooks, hook_command)
|
|
676
|
+
_remove_unsupported_guard_hook_groups(hooks)
|
|
623
677
|
settings_path.parent.mkdir(parents=True, exist_ok=True)
|
|
624
678
|
settings_path.write_text(json.dumps(payload, indent=2), encoding="utf-8")
|
|
625
679
|
return {
|
|
@@ -653,9 +707,18 @@ class ClaudeCodeHarnessAdapter(HarnessAdapter):
|
|
|
653
707
|
payload = _json_payload(settings_path)
|
|
654
708
|
hooks = payload.get("hooks")
|
|
655
709
|
if isinstance(hooks, dict):
|
|
656
|
-
for key in (
|
|
710
|
+
for key in (
|
|
711
|
+
"SessionStart",
|
|
712
|
+
"PreToolUse",
|
|
713
|
+
"PermissionRequest",
|
|
714
|
+
"PostToolUse",
|
|
715
|
+
"UserPromptSubmit",
|
|
716
|
+
"Notification",
|
|
717
|
+
"Stop",
|
|
718
|
+
):
|
|
657
719
|
entries = hooks.get(key)
|
|
658
720
|
hooks[key] = _prune_guard_hook_entries(entries if isinstance(entries, list) else [])
|
|
721
|
+
_remove_unsupported_guard_hook_groups(hooks)
|
|
659
722
|
settings_path.parent.mkdir(parents=True, exist_ok=True)
|
|
660
723
|
settings_path.write_text(json.dumps(payload, indent=2), encoding="utf-8")
|
|
661
724
|
return {
|