plugin-scanner 2.0.132__tar.gz → 2.0.133__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.132 → plugin_scanner-2.0.133}/PKG-INFO +1 -1
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/pyproject.toml +1 -1
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/pyproject.toml.bak +1 -1
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/approvals.py +10 -2
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/daemon/server.py +76 -7
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/version.py +1 -1
- plugin_scanner-2.0.133/tests/test_guard_web_recovery.py +190 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/.clusterfuzzlite/Dockerfile +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/.clusterfuzzlite/build.sh +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/.clusterfuzzlite/project.yaml +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/.clusterfuzzlite/requirements-atheris.txt +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/.dockerignore +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/.github/CODEOWNERS +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/.github/ISSUE_TEMPLATE/bug-report.yml +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/.github/ISSUE_TEMPLATE/feature-request.yml +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/.github/dependabot.yml +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/.github/workflows/ci.yml +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/.github/workflows/codeql.yml +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/.github/workflows/dependabot-uv-lock.yml +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/.github/workflows/fuzz.yml +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/.github/workflows/harness-smoke.yml +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/.github/workflows/publish.yml +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/.github/workflows/scorecard.yml +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/.gitignore +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/.pre-commit-hooks.yaml +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/CONTRIBUTING.md +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/Dockerfile +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/LICENSE +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/README.md +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/SECURITY.md +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/dashboard/index.html +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/dashboard/package.json +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/dashboard/pnpm-lock.yaml +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/dashboard/public/apple-touch-icon.png +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/dashboard/public/brand/Logo_Icon_Dark.png +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/dashboard/public/brand/Logo_Whole.png +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/dashboard/public/favicon-16x16.png +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/dashboard/public/favicon-32x32.png +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/dashboard/public/favicon.ico +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/dashboard/src/app.tsx +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/dashboard/src/approval-center-layout.test.ts +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/dashboard/src/approval-center-layout.tsx +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/dashboard/src/approval-center-primitives.tsx +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/dashboard/src/approval-center-review-cards.tsx +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/dashboard/src/approval-center-utils.ts +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/dashboard/src/data-flow-evidence-card.tsx +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/dashboard/src/fleet-workspace.tsx +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/dashboard/src/guard-api.test.ts +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/dashboard/src/guard-api.ts +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/dashboard/src/guard-demo.ts +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/dashboard/src/guard-types.ts +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/dashboard/src/main.tsx +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/dashboard/src/receipts-workspace.test.ts +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/dashboard/src/receipts-workspace.tsx +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/dashboard/src/runtime-overview.test.ts +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/dashboard/src/runtime-overview.tsx +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/dashboard/src/settings-workspace.test.ts +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/dashboard/src/settings-workspace.tsx +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/dashboard/src/styles.css +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/dashboard/src/vite-env.d.ts +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/dashboard/tsconfig.json +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/dashboard/vite.config.ts +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/docker-requirements.txt +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/docs/guard/approval-audit.md +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/docs/guard/architecture.md +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/docs/guard/get-started.md +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/docs/guard/harness-support.md +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/docs/guard/local-vs-cloud.md +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/docs/guard/release-checklist.md +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/docs/guard/smoke-tests.md +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/docs/guard/testing-matrix.md +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/docs/trust/mcp-trust-draft.md +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/docs/trust/plugin-trust-draft.md +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/docs/trust/skill-trust-local.md +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/fuzzers/manifest_fuzzer.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/requirements.txt +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/schemas/plugin-quality.v1.json +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/schemas/scan-result.v1.json +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/schemas/verify-result.v1.json +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/__init__.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/action_runner.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/argparse_utils.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/checks/__init__.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/checks/best_practices.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/checks/claude.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/checks/code_quality.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/checks/ecosystem_common.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/checks/gemini.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/checks/manifest.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/checks/manifest_support.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/checks/marketplace.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/checks/mcp_security.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/checks/opencode.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/checks/operational_security.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/checks/security.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/checks/skill_security.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/cli.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/cli_ui.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/config.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/ecosystems/__init__.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/ecosystems/base.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/ecosystems/claude.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/ecosystems/codex.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/ecosystems/detect.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/ecosystems/gemini.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/ecosystems/opencode.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/ecosystems/registry.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/ecosystems/types.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/github_reporting.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/__init__.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/access_graph_events.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/adapters/__init__.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/adapters/antigravity.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/adapters/base.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/adapters/claude_code.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/adapters/cloud_identity.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/adapters/codex.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/adapters/contracts.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/adapters/copilot.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/adapters/cursor.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/adapters/gemini.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/adapters/hermes.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/adapters/mcp_servers.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/adapters/openclaw.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/adapters/openclaw_config.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/adapters/openclaw_support.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/adapters/opencode.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/adapters/opencode_artifacts.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/advisory_model.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/bridge/__init__.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/capabilities.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/cli/__init__.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/cli/approval_commands.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/cli/bootstrap.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/cli/commands.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/cli/connect_flow.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/cli/install_commands.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/cli/product.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/cli/prompt.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/cli/render.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/cli/update_commands.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/codex_config.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/config.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/consumer/__init__.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/consumer/service.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/daemon/__init__.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/daemon/client.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/daemon/manager.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/daemon/static/apple-touch-icon.png +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/daemon/static/assets/guard-dashboard.js +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/daemon/static/assets/index.css +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/daemon/static/brand/Logo_Icon_Dark.png +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/daemon/static/brand/Logo_Whole.png +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/daemon/static/favicon-16x16.png +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/daemon/static/favicon-32x32.png +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/daemon/static/favicon.ico +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/daemon/static/index.html +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/edge_events.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/incident.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/launcher.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/mcp_tool_calls.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/models.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/policy/__init__.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/policy/engine.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/protect.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/proxy/__init__.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/proxy/remote.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/proxy/runtime_mcp.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/proxy/stdio.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/receipts/__init__.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/receipts/manager.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/redaction.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/risk.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/runtime/__init__.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/runtime/actions.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/runtime/advisory_escalation.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/runtime/advisory_matchers.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/runtime/data_flow.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/runtime/data_flow_rules.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/runtime/data_flow_variables.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/runtime/decisions.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/runtime/detectors.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/runtime/mcp_protection.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/runtime/prompt_injection.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/runtime/runner.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/runtime/safe_decode.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/runtime/sandbox.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/runtime/secret_file_requests.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/runtime/secret_sensitivity.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/runtime/secret_sources.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/runtime/shell_commands.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/runtime/signals.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/runtime/skill_protection.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/runtime/supply_chain.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/runtime/surface_server.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/runtime/temp_files.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/runtime/threat_intel.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/schemas/__init__.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/schemas/consumer_mode.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/schemas/guard_event_v1.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/schemas/surface_server.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/shims.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/store.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/store_approvals.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/store_connect.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/store_evidence.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/store_threat_intel.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/types.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/integrations/__init__.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/integrations/cisco_mcp_scanner.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/integrations/cisco_skill_scanner.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/lint_fixes.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/marketplace_support.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/models.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/path_support.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/policy.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/quality_artifact.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/repo_detect.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/reporting.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/rules/__init__.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/rules/registry.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/rules/specs.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/scanner.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/submission.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/suppressions.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/trust_domain_scoring.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/trust_helpers.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/trust_mcp_scoring.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/trust_models.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/trust_plugin_scoring.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/trust_scoring.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/trust_skill_scoring.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/trust_specs.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/verification.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/__init__.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/conftest.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/__init__.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/bad-plugin/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/bad-plugin/.mcp.json +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/bad-plugin/secrets.js +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/claude-plugin-good/.claude-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/claude-plugin-good/LICENSE +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/claude-plugin-good/README.md +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/claude-plugin-good/SECURITY.md +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/claude-plugin-good/hooks/hooks.json +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/claude-plugin-good/skills/example/SKILL.md +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/code-quality-bad/evil.js +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/code-quality-bad/inject.js +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/gemini-extension-good/GEMINI.md +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/gemini-extension-good/LICENSE +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/gemini-extension-good/README.md +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/gemini-extension-good/SECURITY.md +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/gemini-extension-good/commands/hello.toml +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/gemini-extension-good/gemini-extension.json +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/good-plugin/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/good-plugin/.codexignore +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/good-plugin/LICENSE +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/good-plugin/README.md +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/good-plugin/SECURITY.md +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/good-plugin/assets/icon.svg +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/good-plugin/assets/logo.svg +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/good-plugin/assets/screenshot.svg +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/good-plugin/skills/example/SKILL.md +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/guard-codex-malicious-mcp/.codex/config.toml +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/guard-red-team/README.md +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/guard-red-team/benign-docs-fake-token.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/guard-red-team/benign-health-endpoint.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/guard-red-team/benign-nvmrc-fake-creds.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/guard-red-team/benign-source-search.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/guard-red-team/canary-exfil-encoded.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/guard-red-team/canary-exfil.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/guard-red-team/expected-decisions.json +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/guard-red-team/malicious-dockerfile.txt +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/guard-red-team/malicious-encoded-shell-exfil.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/guard-red-team/malicious-github-action.yml +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/guard-red-team/malicious-mcp-delete.md +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/guard-red-team/malicious-mcp-secret-read.md +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/guard-red-team/malicious-mcp-skill-exfil.md +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/guard-red-team/malicious-npm-postinstall.js +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/guard-red-team/malicious-prompt-env-read.md +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/guard-red-team/malicious-prompt-guard-bypass.md +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/guard-red-team/malicious-prompt-npmrc-read.md +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/guard-red-team/malicious-python-setup.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/guard-red-team/smoke-evidence-template.json +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/hermes-plugin-evil/config.yaml +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/hermes-plugin-evil/mcp_servers.json +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/hermes-plugin-evil/skills/security/malicious/SKILL.md +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/hermes-plugin-evil/skills/stealth/sneaky/SKILL.md +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/hermes-plugin-evil/skills/stealth/sneaky/references/api-setup.md +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/hermes-plugin-evil/skills/stealth/sneaky/scripts/deploy.sh +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/hermes-plugin-evil/skills/utils/benign/SKILL.md +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/malformed-json/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/malicious-skill-plugin/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/malicious-skill-plugin/.codexignore +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/malicious-skill-plugin/LICENSE +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/malicious-skill-plugin/README.md +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/malicious-skill-plugin/SECURITY.md +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/malicious-skill-plugin/skills/leaky-skill/SKILL.md +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/mcp-canary-server.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/minimal-plugin/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/missing-fields/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/mit-license/LICENSE +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/multi-ecosystem-repo/codex-plugin/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/multi-ecosystem-repo/codex-plugin/LICENSE +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/multi-ecosystem-repo/codex-plugin/README.md +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/multi-ecosystem-repo/codex-plugin/SECURITY.md +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/multi-ecosystem-repo/gemini-ext/README.md +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/multi-ecosystem-repo/gemini-ext/gemini-extension.json +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/multi-plugin-repo/.agents/plugins/marketplace.json +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/.codexignore +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/LICENSE +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/README.md +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/SECURITY.md +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/skills/example/SKILL.md +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/multi-plugin-repo/plugins/beta-plugin/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/multi-plugin-repo/plugins/beta-plugin/skills/example/SKILL.md +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/no-version/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/opencode-good/.opencode/commands/hello.md +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/opencode-good/.opencode/plugins/example.ts +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/opencode-good/LICENSE +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/opencode-good/README.md +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/opencode-good/SECURITY.md +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/opencode-good/opencode.jsonc +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/skills-missing-dir/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/skills-no-frontmatter/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/skills-no-frontmatter/skills/bad-skill/SKILL.md +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/supply-chain/benign-npm-package.json +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/supply-chain/benign-pnpm-package.json +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/supply-chain/benign-pyproject.toml +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/supply-chain/malicious-Dockerfile +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/supply-chain/malicious-action.yml +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/supply-chain/malicious-npm-package.json +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/supply-chain/malicious-setup.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/with-marketplace/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/with-marketplace/marketplace-broken.json +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/fixtures/with-marketplace/marketplace.json +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test-trust-scoring.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test-trust-specs.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_action_runner.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_best_practices.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_cisco_install_surfaces.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_cli.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_code_quality.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_config.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_coverage_remaining.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_ecosystems.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_edge_cases.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_final_coverage.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_guard_access_graph.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_guard_advisory_escalation.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_guard_approval_continuity.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_guard_approval_store_scale.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_guard_approvals.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_guard_bootstrap.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_guard_canary_fixtures.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_guard_capabilities.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_guard_claude_adapter.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_guard_cli.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_guard_cloud_local_sync.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_guard_codex_e2e.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_guard_codex_install.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_guard_codex_proxy.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_guard_config_paths.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_guard_connect_flow.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_guard_consumer_mode.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_guard_copilot_adapter.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_guard_copilot_proxy.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_guard_daemon_manager.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_guard_daemon_perf.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_guard_data_flow.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_guard_event_schema_v1.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_guard_events.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_guard_evidence_store.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_guard_harness_contracts.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_guard_launch_env.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_guard_mcp_protection.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_guard_opencode_proxy.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_guard_product_flow.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_guard_prompt_injection.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_guard_protect.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_guard_red_team.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_guard_render.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_guard_risk.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_guard_runtime.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_guard_runtime_action_harnesses.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_guard_runtime_actions.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_guard_runtime_decisions.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_guard_runtime_detectors.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_guard_runtime_signals.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_guard_safe_decode.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_guard_sandbox.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_guard_skill_protection.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_guard_store_migrations.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_guard_supply_chain.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_guard_surface_server.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_guard_threat_intel.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_guard_verdicts.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_hermes_adapter.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_integration.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_lint_fixes.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_live_cisco_smoke.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_manifest.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_marketplace.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_mcp_security.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_openclaw_adapter.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_operational_security.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_policy.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_quality_artifact.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_rule_registry.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_scanner.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_schema_contracts.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_security.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_security_ops.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_skill_security.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_submission.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_trust_scoring.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_trust_specs.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_verification.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/tests/test_versioning.py +0 -0
- {plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/uv.lock +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.133
|
|
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.133"
|
|
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.133"
|
|
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"
|
{plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/approvals.py
RENAMED
|
@@ -24,6 +24,14 @@ GUARD_FLEET_URL = f"{GUARD_DASHBOARD_URL}/fleet"
|
|
|
24
24
|
GUARD_CONNECT_URL = f"{GUARD_DASHBOARD_URL}/connect"
|
|
25
25
|
|
|
26
26
|
|
|
27
|
+
class ApprovalRequestNotFoundError(ValueError):
|
|
28
|
+
"""Raised when an approval request ID does not exist."""
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class ApprovalRequestAlreadyResolvedError(ValueError):
|
|
32
|
+
"""Raised when an approval request was already resolved."""
|
|
33
|
+
|
|
34
|
+
|
|
27
35
|
def queue_blocked_approvals(
|
|
28
36
|
*,
|
|
29
37
|
detection: HarnessDetection,
|
|
@@ -114,9 +122,9 @@ def apply_approval_resolution(
|
|
|
114
122
|
) -> dict[str, object]:
|
|
115
123
|
request = store.get_approval_request(request_id)
|
|
116
124
|
if request is None:
|
|
117
|
-
raise
|
|
125
|
+
raise ApprovalRequestNotFoundError(f"Unknown approval request: {request_id}")
|
|
118
126
|
if request["status"] != "pending":
|
|
119
|
-
raise
|
|
127
|
+
raise ApprovalRequestAlreadyResolvedError(f"Approval request already resolved: {request_id}")
|
|
120
128
|
if scope == "workspace" and not workspace:
|
|
121
129
|
raise ValueError(f"Approval request {request_id} requires --workspace for workspace scope.")
|
|
122
130
|
if scope == "publisher" and not isinstance(request.get("publisher"), str):
|
{plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/guard/daemon/server.py
RENAMED
|
@@ -18,7 +18,12 @@ from typing import Any
|
|
|
18
18
|
from urllib.parse import parse_qs, parse_qsl, unquote, urlencode, urlparse, urlunparse
|
|
19
19
|
|
|
20
20
|
from ...version import __version__
|
|
21
|
-
from ..approvals import
|
|
21
|
+
from ..approvals import (
|
|
22
|
+
ApprovalRequestAlreadyResolvedError,
|
|
23
|
+
ApprovalRequestNotFoundError,
|
|
24
|
+
apply_approval_resolution,
|
|
25
|
+
build_runtime_snapshot,
|
|
26
|
+
)
|
|
22
27
|
from ..config import editable_guard_settings, load_guard_config, update_guard_settings
|
|
23
28
|
from ..models import DECISION_SCOPE_VALUES, GUARD_ACTION_VALUES
|
|
24
29
|
from ..runtime.surface_server import GuardSurfaceRuntime
|
|
@@ -183,7 +188,17 @@ class _GuardDaemonHandler(BaseHTTPRequestHandler):
|
|
|
183
188
|
if len(path_parts) == 3 and path_parts[:2] == ["v1", "requests"]:
|
|
184
189
|
approval = store.get_approval_request(path_parts[2])
|
|
185
190
|
if approval is None:
|
|
186
|
-
self._write_json(
|
|
191
|
+
self._write_json(
|
|
192
|
+
{
|
|
193
|
+
"error": "not_found",
|
|
194
|
+
"recovery": {
|
|
195
|
+
"code": "request_unknown",
|
|
196
|
+
"title": "This request is no longer waiting.",
|
|
197
|
+
"body": "The request was either already resolved or expired. You can close this tab.",
|
|
198
|
+
},
|
|
199
|
+
},
|
|
200
|
+
status=404,
|
|
201
|
+
)
|
|
187
202
|
return
|
|
188
203
|
self._write_json(approval)
|
|
189
204
|
return
|
|
@@ -313,11 +328,29 @@ class _GuardDaemonHandler(BaseHTTPRequestHandler):
|
|
|
313
328
|
self._write_json({"error": "forbidden_origin"}, status=403)
|
|
314
329
|
return
|
|
315
330
|
if self._requires_header_token(parsed.path, path_parts) and not self._header_token_is_valid():
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
331
|
+
if len(path_parts) == 4 and path_parts[:2] == ["v1", "requests"] and path_parts[3] in {"approve", "block"}:
|
|
332
|
+
host = self.server.server_address[0] # type: ignore[attr-defined]
|
|
333
|
+
port = self.server.server_address[1] # type: ignore[attr-defined]
|
|
334
|
+
reconnect_url = _build_local_url(host, port, "/#/reconnect")
|
|
335
|
+
self._write_json(
|
|
336
|
+
{
|
|
337
|
+
"error": "unauthorized",
|
|
338
|
+
"recovery": {
|
|
339
|
+
"code": "session_stale",
|
|
340
|
+
"title": "Your session with the local Guard daemon has expired.",
|
|
341
|
+
"body": "Click the link below to reconnect, then retry your approval.",
|
|
342
|
+
"reconnect_url": reconnect_url,
|
|
343
|
+
},
|
|
344
|
+
},
|
|
345
|
+
status=401,
|
|
346
|
+
extra_headers=self._cors_headers_for_request(),
|
|
347
|
+
)
|
|
348
|
+
else:
|
|
349
|
+
self._write_json(
|
|
350
|
+
{"error": "unauthorized"},
|
|
351
|
+
status=401,
|
|
352
|
+
extra_headers=self._cors_headers_for_request(),
|
|
353
|
+
)
|
|
321
354
|
return
|
|
322
355
|
payload, body_error = self._load_request_body()
|
|
323
356
|
if body_error is not None:
|
|
@@ -389,6 +422,37 @@ class _GuardDaemonHandler(BaseHTTPRequestHandler):
|
|
|
389
422
|
workspace=self._optional_string(payload.get("workspace")),
|
|
390
423
|
reason=self._optional_string(payload.get("reason")),
|
|
391
424
|
)
|
|
425
|
+
except ApprovalRequestNotFoundError:
|
|
426
|
+
self._write_json(
|
|
427
|
+
{
|
|
428
|
+
"resolved": False,
|
|
429
|
+
"error": "not_found",
|
|
430
|
+
"recovery": {
|
|
431
|
+
"code": "request_unknown",
|
|
432
|
+
"title": "This request is no longer waiting.",
|
|
433
|
+
"body": "The request was either already resolved or expired. You can close this tab.",
|
|
434
|
+
},
|
|
435
|
+
},
|
|
436
|
+
status=404,
|
|
437
|
+
)
|
|
438
|
+
return
|
|
439
|
+
except ApprovalRequestAlreadyResolvedError:
|
|
440
|
+
self._write_json(
|
|
441
|
+
{
|
|
442
|
+
"resolved": False,
|
|
443
|
+
"error": "already_resolved",
|
|
444
|
+
"recovery": {
|
|
445
|
+
"code": "request_resolved",
|
|
446
|
+
"title": "This request has already been resolved.",
|
|
447
|
+
"body": (
|
|
448
|
+
"If the action is blocked and you believe it should be allowed, "
|
|
449
|
+
"you can re-submit from your AI assistant."
|
|
450
|
+
),
|
|
451
|
+
},
|
|
452
|
+
},
|
|
453
|
+
status=409,
|
|
454
|
+
)
|
|
455
|
+
return
|
|
392
456
|
except ValueError as error:
|
|
393
457
|
self._write_json({"resolved": False, "error": str(error)}, status=400)
|
|
394
458
|
return
|
|
@@ -1319,6 +1383,11 @@ def _approval_center_browser_url(approval_center_url: str, auth_token: str) -> s
|
|
|
1319
1383
|
return urlunparse(parsed._replace(fragment=urlencode(fragment_pairs)))
|
|
1320
1384
|
|
|
1321
1385
|
|
|
1386
|
+
def _build_local_url(host: str, port: int, path: str) -> str:
|
|
1387
|
+
host_part = f"[{host}]" if ":" in host else host
|
|
1388
|
+
return f"http://{host_part}:{port}{path}"
|
|
1389
|
+
|
|
1390
|
+
|
|
1322
1391
|
def _now() -> str:
|
|
1323
1392
|
from datetime import datetime, timezone
|
|
1324
1393
|
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
"""Tests for approval web recovery screens (T695-T699)."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
import urllib.error
|
|
7
|
+
import urllib.request
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
import pytest
|
|
11
|
+
|
|
12
|
+
from codex_plugin_scanner.guard.daemon import GuardDaemonServer
|
|
13
|
+
from codex_plugin_scanner.guard.models import GuardApprovalRequest
|
|
14
|
+
from codex_plugin_scanner.guard.store import GuardStore
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _guard_json_headers(auth_token: str | None = None) -> dict[str, str]:
|
|
18
|
+
headers = {"Content-Type": "application/json"}
|
|
19
|
+
if auth_token is not None:
|
|
20
|
+
headers["X-Guard-Token"] = auth_token
|
|
21
|
+
return headers
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _add_pending_request(store: GuardStore, request_id: str = "req-test-001") -> None:
|
|
25
|
+
store.add_approval_request(
|
|
26
|
+
GuardApprovalRequest(
|
|
27
|
+
request_id=request_id,
|
|
28
|
+
harness="codex",
|
|
29
|
+
artifact_id="codex:project:test_tool",
|
|
30
|
+
artifact_name="test_tool",
|
|
31
|
+
artifact_hash="hash-test",
|
|
32
|
+
policy_action="block",
|
|
33
|
+
recommended_scope="artifact",
|
|
34
|
+
changed_fields=(),
|
|
35
|
+
source_scope="local",
|
|
36
|
+
config_path="/tmp/config",
|
|
37
|
+
review_command=f"hol-guard approvals approve {request_id}",
|
|
38
|
+
approval_url=f"http://127.0.0.1:6174/#/approve/{request_id}",
|
|
39
|
+
),
|
|
40
|
+
"2026-01-01T00:00:00+00:00",
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class TestApproveBlockRecoveryPayloads:
|
|
45
|
+
"""T695-T697: approve/block endpoints return structured recovery payloads on error."""
|
|
46
|
+
|
|
47
|
+
def test_approve_unknown_request_returns_recovery_payload(self, tmp_path: Path) -> None:
|
|
48
|
+
"""T695: Approving an unknown request ID returns recovery copy, not a bare error."""
|
|
49
|
+
store = GuardStore(tmp_path / "guard")
|
|
50
|
+
daemon = GuardDaemonServer(store, host="127.0.0.1", port=0)
|
|
51
|
+
daemon.start()
|
|
52
|
+
|
|
53
|
+
try:
|
|
54
|
+
request = urllib.request.Request(
|
|
55
|
+
f"http://127.0.0.1:{daemon.port}/v1/requests/req-nonexistent/approve",
|
|
56
|
+
data=json.dumps({"scope": "artifact"}).encode("utf-8"),
|
|
57
|
+
headers=_guard_json_headers(daemon._server.auth_token),
|
|
58
|
+
method="POST",
|
|
59
|
+
)
|
|
60
|
+
try:
|
|
61
|
+
urllib.request.urlopen(request, timeout=5)
|
|
62
|
+
pytest.fail("Expected HTTP error")
|
|
63
|
+
except urllib.error.HTTPError as err:
|
|
64
|
+
payload = json.loads(err.read().decode("utf-8"))
|
|
65
|
+
finally:
|
|
66
|
+
daemon.stop()
|
|
67
|
+
|
|
68
|
+
assert payload.get("resolved") is False
|
|
69
|
+
recovery = payload.get("recovery")
|
|
70
|
+
assert isinstance(recovery, dict), "Recovery payload must be a dict"
|
|
71
|
+
assert recovery.get("code") == "request_unknown"
|
|
72
|
+
assert "no longer waiting" in recovery.get("title", "").lower()
|
|
73
|
+
|
|
74
|
+
def test_approve_already_resolved_request_returns_recovery_payload(self, tmp_path: Path) -> None:
|
|
75
|
+
"""T696: Approving an already-resolved request returns recovery copy with decision info."""
|
|
76
|
+
store = GuardStore(tmp_path / "guard")
|
|
77
|
+
_add_pending_request(store, "req-resolved-001")
|
|
78
|
+
store.resolve_approval_request(
|
|
79
|
+
"req-resolved-001",
|
|
80
|
+
resolution_action="allow",
|
|
81
|
+
resolution_scope="artifact",
|
|
82
|
+
reason=None,
|
|
83
|
+
resolved_at="2026-01-01T01:00:00+00:00",
|
|
84
|
+
)
|
|
85
|
+
daemon = GuardDaemonServer(store, host="127.0.0.1", port=0)
|
|
86
|
+
daemon.start()
|
|
87
|
+
|
|
88
|
+
try:
|
|
89
|
+
request = urllib.request.Request(
|
|
90
|
+
f"http://127.0.0.1:{daemon.port}/v1/requests/req-resolved-001/approve",
|
|
91
|
+
data=json.dumps({"scope": "artifact"}).encode("utf-8"),
|
|
92
|
+
headers=_guard_json_headers(daemon._server.auth_token),
|
|
93
|
+
method="POST",
|
|
94
|
+
)
|
|
95
|
+
try:
|
|
96
|
+
urllib.request.urlopen(request, timeout=5)
|
|
97
|
+
pytest.fail("Expected HTTP error")
|
|
98
|
+
except urllib.error.HTTPError as err:
|
|
99
|
+
payload = json.loads(err.read().decode("utf-8"))
|
|
100
|
+
finally:
|
|
101
|
+
daemon.stop()
|
|
102
|
+
|
|
103
|
+
assert payload.get("resolved") is False
|
|
104
|
+
recovery = payload.get("recovery")
|
|
105
|
+
assert isinstance(recovery, dict), "Recovery payload must be a dict"
|
|
106
|
+
assert recovery.get("code") == "request_resolved"
|
|
107
|
+
title = recovery.get("title", "")
|
|
108
|
+
assert "already" in title.lower() or "resolved" in title.lower()
|
|
109
|
+
|
|
110
|
+
def test_approve_with_wrong_token_returns_recovery_payload_not_bare_401(self, tmp_path: Path) -> None:
|
|
111
|
+
"""T697/T698: approve/block with wrong token returns structured recovery payload."""
|
|
112
|
+
store = GuardStore(tmp_path / "guard")
|
|
113
|
+
_add_pending_request(store, "req-auth-001")
|
|
114
|
+
daemon = GuardDaemonServer(store, host="127.0.0.1", port=0)
|
|
115
|
+
daemon.start()
|
|
116
|
+
|
|
117
|
+
try:
|
|
118
|
+
request = urllib.request.Request(
|
|
119
|
+
f"http://127.0.0.1:{daemon.port}/v1/requests/req-auth-001/approve",
|
|
120
|
+
data=json.dumps({"scope": "artifact"}).encode("utf-8"),
|
|
121
|
+
headers=_guard_json_headers("wrong-token-xyz"),
|
|
122
|
+
method="POST",
|
|
123
|
+
)
|
|
124
|
+
try:
|
|
125
|
+
urllib.request.urlopen(request, timeout=5)
|
|
126
|
+
pytest.fail("Expected HTTP error")
|
|
127
|
+
except urllib.error.HTTPError as err:
|
|
128
|
+
assert err.code == 401
|
|
129
|
+
payload = json.loads(err.read().decode("utf-8"))
|
|
130
|
+
finally:
|
|
131
|
+
daemon.stop()
|
|
132
|
+
|
|
133
|
+
recovery = payload.get("recovery")
|
|
134
|
+
assert isinstance(recovery, dict), "401 response must include a recovery payload"
|
|
135
|
+
assert recovery.get("code") == "session_stale"
|
|
136
|
+
assert recovery.get("reconnect_url") is not None
|
|
137
|
+
|
|
138
|
+
def test_block_with_wrong_token_returns_recovery_payload(self, tmp_path: Path) -> None:
|
|
139
|
+
"""T698: block with wrong token returns structured recovery payload."""
|
|
140
|
+
store = GuardStore(tmp_path / "guard")
|
|
141
|
+
_add_pending_request(store, "req-auth-002")
|
|
142
|
+
daemon = GuardDaemonServer(store, host="127.0.0.1", port=0)
|
|
143
|
+
daemon.start()
|
|
144
|
+
|
|
145
|
+
try:
|
|
146
|
+
request = urllib.request.Request(
|
|
147
|
+
f"http://127.0.0.1:{daemon.port}/v1/requests/req-auth-002/block",
|
|
148
|
+
data=json.dumps({"scope": "artifact"}).encode("utf-8"),
|
|
149
|
+
headers=_guard_json_headers("bad-token"),
|
|
150
|
+
method="POST",
|
|
151
|
+
)
|
|
152
|
+
try:
|
|
153
|
+
urllib.request.urlopen(request, timeout=5)
|
|
154
|
+
pytest.fail("Expected HTTP error")
|
|
155
|
+
except urllib.error.HTTPError as err:
|
|
156
|
+
assert err.code == 401
|
|
157
|
+
payload = json.loads(err.read().decode("utf-8"))
|
|
158
|
+
finally:
|
|
159
|
+
daemon.stop()
|
|
160
|
+
|
|
161
|
+
recovery = payload.get("recovery")
|
|
162
|
+
assert isinstance(recovery, dict), "401 block response must include recovery payload"
|
|
163
|
+
assert recovery.get("code") == "session_stale"
|
|
164
|
+
|
|
165
|
+
def test_stale_approval_page_shows_recovery_copy_not_blank(self, tmp_path: Path) -> None:
|
|
166
|
+
"""T699: GET on stale/nonexistent approval request returns recovery copy instead of bare 404."""
|
|
167
|
+
store = GuardStore(tmp_path / "guard")
|
|
168
|
+
daemon = GuardDaemonServer(store, host="127.0.0.1", port=0)
|
|
169
|
+
daemon.start()
|
|
170
|
+
|
|
171
|
+
try:
|
|
172
|
+
try:
|
|
173
|
+
with urllib.request.urlopen(
|
|
174
|
+
urllib.request.Request(
|
|
175
|
+
f"http://127.0.0.1:{daemon.port}/v1/requests/req-stale-999",
|
|
176
|
+
headers=_guard_json_headers(daemon._server.auth_token),
|
|
177
|
+
method="GET",
|
|
178
|
+
),
|
|
179
|
+
timeout=5,
|
|
180
|
+
):
|
|
181
|
+
pytest.fail("Expected HTTP error")
|
|
182
|
+
except urllib.error.HTTPError as err:
|
|
183
|
+
payload = json.loads(err.read().decode("utf-8"))
|
|
184
|
+
finally:
|
|
185
|
+
daemon.stop()
|
|
186
|
+
|
|
187
|
+
recovery = payload.get("recovery")
|
|
188
|
+
assert isinstance(recovery, dict), "404 GET on stale request must include recovery payload"
|
|
189
|
+
assert recovery.get("code") in {"request_unknown", "not_found"}
|
|
190
|
+
assert recovery.get("title") is not None
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/.github/ISSUE_TEMPLATE/feature-request.yml
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
|
{plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/dashboard/src/approval-center-layout.test.ts
RENAMED
|
File without changes
|
|
File without changes
|
{plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/dashboard/src/approval-center-primitives.tsx
RENAMED
|
File without changes
|
{plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/dashboard/src/approval-center-review-cards.tsx
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
|
{plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/argparse_utils.py
RENAMED
|
File without changes
|
{plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/checks/__init__.py
RENAMED
|
File without changes
|
{plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/checks/best_practices.py
RENAMED
|
File without changes
|
|
File without changes
|
{plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/checks/code_quality.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/checks/manifest.py
RENAMED
|
File without changes
|
|
File without changes
|
{plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/checks/marketplace.py
RENAMED
|
File without changes
|
{plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/checks/mcp_security.py
RENAMED
|
File without changes
|
{plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/checks/opencode.py
RENAMED
|
File without changes
|
|
File without changes
|
{plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/checks/security.py
RENAMED
|
File without changes
|
{plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/checks/skill_security.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/ecosystems/__init__.py
RENAMED
|
File without changes
|
{plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/ecosystems/base.py
RENAMED
|
File without changes
|
{plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/ecosystems/claude.py
RENAMED
|
File without changes
|
{plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/ecosystems/codex.py
RENAMED
|
File without changes
|
{plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/ecosystems/detect.py
RENAMED
|
File without changes
|
{plugin_scanner-2.0.132 → plugin_scanner-2.0.133}/src/codex_plugin_scanner/ecosystems/gemini.py
RENAMED
|
File without changes
|