plugin-scanner 2.0.155__tar.gz → 2.0.156__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.155 → plugin_scanner-2.0.156}/PKG-INFO +1 -1
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/pyproject.toml +1 -1
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/pyproject.toml.bak +1 -1
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/version.py +1 -1
- plugin_scanner-2.0.156/tests/test_guard_daemon_wake.py +188 -0
- plugin_scanner-2.0.156/tests/test_guard_redaction.py +159 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/.clusterfuzzlite/Dockerfile +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/.clusterfuzzlite/build.sh +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/.clusterfuzzlite/project.yaml +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/.clusterfuzzlite/requirements-atheris.txt +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/.dockerignore +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/.github/CODEOWNERS +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/.github/ISSUE_TEMPLATE/bug-report.yml +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/.github/ISSUE_TEMPLATE/feature-request.yml +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/.github/dependabot.yml +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/.github/workflows/ci.yml +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/.github/workflows/codeql.yml +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/.github/workflows/dependabot-uv-lock.yml +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/.github/workflows/fuzz.yml +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/.github/workflows/harness-smoke.yml +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/.github/workflows/publish.yml +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/.github/workflows/scorecard.yml +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/.gitignore +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/.pre-commit-hooks.yaml +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/CONTRIBUTING.md +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/Dockerfile +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/LICENSE +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/README.md +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/SECURITY.md +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/dashboard/index.html +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/dashboard/package.json +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/dashboard/pnpm-lock.yaml +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/dashboard/public/apple-touch-icon.png +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/dashboard/public/brand/Logo_Icon_Dark.png +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/dashboard/public/brand/Logo_Whole.png +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/dashboard/public/favicon-16x16.png +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/dashboard/public/favicon-32x32.png +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/dashboard/public/favicon.ico +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/dashboard/src/app.tsx +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/dashboard/src/approval-center-layout.test.ts +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/dashboard/src/approval-center-layout.tsx +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/dashboard/src/approval-center-primitives.tsx +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/dashboard/src/approval-center-review-cards.tsx +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/dashboard/src/approval-center-utils.ts +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/dashboard/src/data-flow-evidence-card.tsx +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/dashboard/src/fleet-workspace.tsx +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/dashboard/src/guard-api.test.ts +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/dashboard/src/guard-api.ts +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/dashboard/src/guard-demo.ts +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/dashboard/src/guard-types.ts +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/dashboard/src/home-dashboard.tsx +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/dashboard/src/main.tsx +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/dashboard/src/queue-chip-filter.tsx +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/dashboard/src/queue-state.test.ts +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/dashboard/src/queue-state.ts +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/dashboard/src/receipts-workspace.test.ts +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/dashboard/src/receipts-workspace.tsx +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/dashboard/src/risk-signal-cards.test.ts +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/dashboard/src/risk-signal-cards.tsx +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/dashboard/src/runtime-overview.test.ts +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/dashboard/src/runtime-overview.tsx +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/dashboard/src/scanner-evidence-badge.tsx +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/dashboard/src/settings-workspace.test.ts +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/dashboard/src/settings-workspace.tsx +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/dashboard/src/styles.css +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/dashboard/src/vite-env.d.ts +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/dashboard/src/watched-app-card.tsx +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/dashboard/tsconfig.json +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/dashboard/vite.config.ts +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/docker-requirements.txt +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/docs/guard/approval-audit.md +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/docs/guard/architecture.md +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/docs/guard/get-started.md +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/docs/guard/harness-support.md +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/docs/guard/local-vs-cloud.md +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/docs/guard/release-checklist.md +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/docs/guard/release-notes.md +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/docs/guard/smoke-tests.md +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/docs/guard/testing-matrix.md +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/docs/trust/mcp-trust-draft.md +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/docs/trust/plugin-trust-draft.md +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/docs/trust/skill-trust-local.md +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/fuzzers/manifest_fuzzer.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/requirements.txt +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/schemas/plugin-quality.v1.json +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/schemas/scan-result.v1.json +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/schemas/verify-result.v1.json +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/__init__.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/action_runner.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/argparse_utils.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/checks/__init__.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/checks/best_practices.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/checks/claude.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/checks/code_quality.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/checks/ecosystem_common.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/checks/gemini.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/checks/manifest.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/checks/manifest_support.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/checks/marketplace.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/checks/mcp_security.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/checks/opencode.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/checks/operational_security.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/checks/security.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/checks/skill_security.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/cli.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/cli_ui.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/config.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/ecosystems/__init__.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/ecosystems/base.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/ecosystems/claude.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/ecosystems/codex.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/ecosystems/detect.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/ecosystems/gemini.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/ecosystems/opencode.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/ecosystems/registry.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/ecosystems/types.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/github_reporting.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/__init__.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/access_graph_events.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/adapters/__init__.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/adapters/antigravity.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/adapters/base.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/adapters/claude_code.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/adapters/cloud_identity.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/adapters/codex.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/adapters/contracts.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/adapters/copilot.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/adapters/cursor.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/adapters/gemini.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/adapters/hermes.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/adapters/mcp_servers.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/adapters/openclaw.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/adapters/openclaw_config.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/adapters/openclaw_support.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/adapters/opencode.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/adapters/opencode_artifacts.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/advisory_model.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/approvals.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/bridge/__init__.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/capabilities.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/cli/__init__.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/cli/approval_commands.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/cli/bootstrap.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/cli/commands.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/cli/connect_flow.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/cli/install_commands.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/cli/product.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/cli/prompt.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/cli/render.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/cli/update_commands.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/codex_config.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/config.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/consumer/__init__.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/consumer/service.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/daemon/__init__.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/daemon/client.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/daemon/manager.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/daemon/server.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/daemon/static/apple-touch-icon.png +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/daemon/static/assets/guard-dashboard.js +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/daemon/static/assets/index.css +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/daemon/static/brand/Logo_Icon_Dark.png +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/daemon/static/brand/Logo_Whole.png +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/daemon/static/favicon-16x16.png +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/daemon/static/favicon-32x32.png +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/daemon/static/favicon.ico +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/daemon/static/index.html +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/edge_events.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/incident.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/insights.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/launcher.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/mcp_tool_calls.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/models.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/policy/__init__.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/policy/engine.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/protect.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/proxy/__init__.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/proxy/remote.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/proxy/runtime_mcp.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/proxy/stdio.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/receipts/__init__.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/receipts/manager.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/redaction.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/risk.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/runtime/__init__.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/runtime/action_identity.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/runtime/actions.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/runtime/advisory_escalation.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/runtime/advisory_matchers.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/runtime/cisco_evidence.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/runtime/cisco_preflight.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/runtime/composition_rules.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/runtime/data_flow.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/runtime/data_flow_rules.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/runtime/data_flow_variables.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/runtime/decisions.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/runtime/detectors.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/runtime/false_positive_rules.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/runtime/mcp_protection.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/runtime/persistence_rules.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/runtime/prompt_injection.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/runtime/runner.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/runtime/safe_decode.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/runtime/sandbox.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/runtime/scanner_cache.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/runtime/secret_file_requests.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/runtime/secret_sensitivity.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/runtime/secret_sources.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/runtime/shell_commands.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/runtime/signals.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/runtime/skill_protection.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/runtime/supply_chain.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/runtime/surface_server.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/runtime/temp_files.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/runtime/threat_intel.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/schemas/__init__.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/schemas/consumer_mode.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/schemas/guard_event_v1.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/schemas/surface_server.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/shims.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/store.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/store_approvals.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/store_connect.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/store_evidence.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/store_threat_intel.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/guard/types.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/integrations/__init__.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/integrations/cisco_mcp_scanner.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/integrations/cisco_skill_scanner.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/lint_fixes.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/marketplace_support.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/models.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/path_support.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/policy.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/quality_artifact.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/repo_detect.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/reporting.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/rules/__init__.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/rules/registry.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/rules/specs.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/scanner.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/submission.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/suppressions.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/trust_domain_scoring.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/trust_helpers.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/trust_mcp_scoring.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/trust_models.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/trust_plugin_scoring.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/trust_scoring.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/trust_skill_scoring.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/trust_specs.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/verification.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/__init__.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/conftest.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/__init__.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/bad-plugin/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/bad-plugin/.mcp.json +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/bad-plugin/secrets.js +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/claude-plugin-good/.claude-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/claude-plugin-good/LICENSE +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/claude-plugin-good/README.md +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/claude-plugin-good/SECURITY.md +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/claude-plugin-good/hooks/hooks.json +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/claude-plugin-good/skills/example/SKILL.md +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/code-quality-bad/evil.js +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/code-quality-bad/inject.js +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/gemini-extension-good/GEMINI.md +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/gemini-extension-good/LICENSE +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/gemini-extension-good/README.md +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/gemini-extension-good/SECURITY.md +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/gemini-extension-good/commands/hello.toml +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/gemini-extension-good/gemini-extension.json +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/good-plugin/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/good-plugin/.codexignore +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/good-plugin/LICENSE +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/good-plugin/README.md +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/good-plugin/SECURITY.md +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/good-plugin/assets/icon.svg +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/good-plugin/assets/logo.svg +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/good-plugin/assets/screenshot.svg +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/good-plugin/skills/example/SKILL.md +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/guard-codex-malicious-mcp/.codex/config.toml +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/guard-red-team/README.md +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/guard-red-team/benign-docs-fake-token.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/guard-red-team/benign-health-endpoint.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/guard-red-team/benign-nvmrc-fake-creds.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/guard-red-team/benign-source-search.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/guard-red-team/canary-exfil-encoded.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/guard-red-team/canary-exfil.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/guard-red-team/expected-decisions.json +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/guard-red-team/malicious-dockerfile.txt +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/guard-red-team/malicious-encoded-shell-exfil.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/guard-red-team/malicious-github-action.yml +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/guard-red-team/malicious-mcp-delete.md +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/guard-red-team/malicious-mcp-secret-read.md +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/guard-red-team/malicious-mcp-skill-exfil.md +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/guard-red-team/malicious-npm-postinstall.js +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/guard-red-team/malicious-prompt-env-read.md +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/guard-red-team/malicious-prompt-guard-bypass.md +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/guard-red-team/malicious-prompt-npmrc-read.md +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/guard-red-team/malicious-python-setup.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/guard-red-team/smoke-evidence-template.json +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/hermes-plugin-evil/config.yaml +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/hermes-plugin-evil/mcp_servers.json +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/hermes-plugin-evil/skills/security/malicious/SKILL.md +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/hermes-plugin-evil/skills/stealth/sneaky/SKILL.md +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/hermes-plugin-evil/skills/stealth/sneaky/references/api-setup.md +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/hermes-plugin-evil/skills/stealth/sneaky/scripts/deploy.sh +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/hermes-plugin-evil/skills/utils/benign/SKILL.md +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/malformed-json/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/malicious-skill-plugin/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/malicious-skill-plugin/.codexignore +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/malicious-skill-plugin/LICENSE +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/malicious-skill-plugin/README.md +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/malicious-skill-plugin/SECURITY.md +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/malicious-skill-plugin/skills/leaky-skill/SKILL.md +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/mcp-canary-server.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/minimal-plugin/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/missing-fields/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/mit-license/LICENSE +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/multi-ecosystem-repo/codex-plugin/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/multi-ecosystem-repo/codex-plugin/LICENSE +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/multi-ecosystem-repo/codex-plugin/README.md +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/multi-ecosystem-repo/codex-plugin/SECURITY.md +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/multi-ecosystem-repo/gemini-ext/README.md +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/multi-ecosystem-repo/gemini-ext/gemini-extension.json +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/multi-plugin-repo/.agents/plugins/marketplace.json +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/.codexignore +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/LICENSE +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/README.md +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/SECURITY.md +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/skills/example/SKILL.md +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/multi-plugin-repo/plugins/beta-plugin/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/multi-plugin-repo/plugins/beta-plugin/skills/example/SKILL.md +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/no-version/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/opencode-good/.opencode/commands/hello.md +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/opencode-good/.opencode/plugins/example.ts +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/opencode-good/LICENSE +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/opencode-good/README.md +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/opencode-good/SECURITY.md +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/opencode-good/opencode.jsonc +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/skills-missing-dir/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/skills-no-frontmatter/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/skills-no-frontmatter/skills/bad-skill/SKILL.md +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/supply-chain/benign-npm-package.json +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/supply-chain/benign-pnpm-package.json +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/supply-chain/benign-pyproject.toml +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/supply-chain/malicious-Dockerfile +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/supply-chain/malicious-action.yml +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/supply-chain/malicious-npm-package.json +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/supply-chain/malicious-setup.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/with-marketplace/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/with-marketplace/marketplace-broken.json +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/fixtures/with-marketplace/marketplace.json +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test-trust-scoring.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test-trust-specs.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_action_runner.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_best_practices.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_cisco_install_surfaces.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_cli.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_code_quality.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_config.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_coverage_remaining.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_ecosystems.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_edge_cases.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_final_coverage.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_access_graph.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_action_identity.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_advisory_escalation.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_approval_continuity.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_approval_copy_commands.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_approval_store_dedup.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_approval_store_scale.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_approvals.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_bootstrap.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_bypass_detector.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_canary_fixtures.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_capabilities.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_cisco_evidence.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_cisco_runtime_cli.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_claude_adapter.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_cli.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_cloud_local_sync.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_codex_e2e.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_codex_install.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_codex_proxy.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_config_paths.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_connect_flow.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_consumer_mode.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_copilot_adapter.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_copilot_proxy.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_daemon_cli.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_daemon_manager.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_daemon_perf.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_daemon_repair_perf.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_data_flow.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_decision_propagation.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_detector_fp.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_event_schema_v1.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_events.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_evidence_store.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_harness_contracts.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_harness_setup.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_harness_smoke.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_insights.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_launch_env.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_mcp_detectors.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_mcp_protection.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_opencode_proxy.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_policy_dedup.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_product_flow.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_prompt_injection.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_protect.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_queue_api_contract.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_queue_contract.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_red_team.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_render.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_resolution_copy.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_risk.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_runtime.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_runtime_action_harnesses.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_runtime_actions.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_runtime_decisions.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_runtime_detectors.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_runtime_signals.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_safe_decode.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_sandbox.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_skill_protection.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_store_migrations.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_supply_chain.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_surface_server.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_threat_intel.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_verdicts.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_guard_web_recovery.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_hermes_adapter.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_integration.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_lint_fixes.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_live_cisco_smoke.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_manifest.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_marketplace.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_mcp_security.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_openclaw_adapter.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_operational_security.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_policy.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_quality_artifact.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_rule_registry.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_scanner.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_schema_contracts.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_security.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_security_ops.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_skill_security.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_submission.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_trust_scoring.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_trust_specs.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_verification.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/tests/test_versioning.py +0 -0
- {plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/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.156
|
|
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.156"
|
|
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.156"
|
|
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"
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
"""L314: No-dashboard approval URL wake tests.
|
|
2
|
+
|
|
3
|
+
Verifies that Guard starts the daemon and surfaces the approval URL even when
|
|
4
|
+
no browser dashboard is open (e.g., CLI-only or headless environments).
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import json
|
|
10
|
+
import stat
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
|
|
13
|
+
from codex_plugin_scanner.guard.daemon import manager as daemon_manager_module
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def _make_start_mock(guard_home: Path, port: int = 5700):
|
|
17
|
+
"""Return a Popen-compatible fake that writes a valid state file immediately."""
|
|
18
|
+
|
|
19
|
+
import os
|
|
20
|
+
|
|
21
|
+
state_dir = guard_home / ".guard"
|
|
22
|
+
state_dir.mkdir(parents=True, exist_ok=True)
|
|
23
|
+
|
|
24
|
+
class FakeProcess:
|
|
25
|
+
pid = 12345
|
|
26
|
+
returncode = None
|
|
27
|
+
|
|
28
|
+
def poll(self):
|
|
29
|
+
return None
|
|
30
|
+
|
|
31
|
+
def _popen(*_args, **_kwargs):
|
|
32
|
+
state = {
|
|
33
|
+
"port": port,
|
|
34
|
+
"pid": FakeProcess.pid,
|
|
35
|
+
"compatibility_version": daemon_manager_module.GUARD_DAEMON_COMPATIBILITY_VERSION,
|
|
36
|
+
"source_root": daemon_manager_module._current_guard_daemon_source_root(),
|
|
37
|
+
"runtime_fingerprint": daemon_manager_module._current_guard_daemon_runtime_fingerprint(),
|
|
38
|
+
}
|
|
39
|
+
state_path = state_dir / "daemon-state.json"
|
|
40
|
+
state_path.write_text(json.dumps(state), encoding="utf-8")
|
|
41
|
+
os.chmod(state_path, stat.S_IRUSR | stat.S_IWUSR)
|
|
42
|
+
return FakeProcess()
|
|
43
|
+
|
|
44
|
+
return _popen
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class TestNoDashboardApprovalURLWake:
|
|
48
|
+
"""L314: daemon must start and expose the approval URL with no browser open."""
|
|
49
|
+
|
|
50
|
+
def test_ensure_guard_daemon_returns_url_when_no_daemon_running(self, tmp_path, monkeypatch) -> None:
|
|
51
|
+
"""When no daemon is running and the dashboard is closed, ensure_guard_daemon
|
|
52
|
+
starts the daemon and returns a usable approval URL."""
|
|
53
|
+
guard_home = tmp_path / "guard-home"
|
|
54
|
+
port = 5700
|
|
55
|
+
|
|
56
|
+
monkeypatch.setattr(daemon_manager_module, "_reap_stale_ephemeral_guard_daemons", lambda **_: None)
|
|
57
|
+
|
|
58
|
+
url_iter = iter([None, None, f"http://127.0.0.1:{port}"])
|
|
59
|
+
monkeypatch.setattr(
|
|
60
|
+
daemon_manager_module,
|
|
61
|
+
"load_guard_daemon_url",
|
|
62
|
+
lambda _gh: next(url_iter, f"http://127.0.0.1:{port}"),
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
monkeypatch.setattr(daemon_manager_module, "_load_state", lambda _gh: None)
|
|
66
|
+
monkeypatch.setattr(daemon_manager_module, "_guard_daemon_start_in_progress", lambda _gh: False)
|
|
67
|
+
monkeypatch.setattr(daemon_manager_module.time, "sleep", lambda _: None)
|
|
68
|
+
monkeypatch.setattr(daemon_manager_module.subprocess, "Popen", _make_start_mock(guard_home, port))
|
|
69
|
+
monkeypatch.setattr(
|
|
70
|
+
daemon_manager_module,
|
|
71
|
+
"_wait_for_guard_daemon_url",
|
|
72
|
+
lambda _gh, **_kw: f"http://127.0.0.1:{port}",
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
url = daemon_manager_module.ensure_guard_daemon(guard_home)
|
|
76
|
+
|
|
77
|
+
assert url == f"http://127.0.0.1:{port}"
|
|
78
|
+
assert url.startswith("http://127.0.0.1:")
|
|
79
|
+
|
|
80
|
+
def test_ensure_guard_daemon_does_not_spawn_second_daemon_when_already_running(self, tmp_path, monkeypatch) -> None:
|
|
81
|
+
"""If the daemon state file is already present and healthy, ensure_guard_daemon
|
|
82
|
+
must return the existing URL without spawning a new process."""
|
|
83
|
+
guard_home = tmp_path / "guard-home"
|
|
84
|
+
port = 5701
|
|
85
|
+
spawn_calls: list[str] = []
|
|
86
|
+
|
|
87
|
+
monkeypatch.setattr(daemon_manager_module, "_reap_stale_ephemeral_guard_daemons", lambda **_: None)
|
|
88
|
+
monkeypatch.setattr(
|
|
89
|
+
daemon_manager_module,
|
|
90
|
+
"load_guard_daemon_url",
|
|
91
|
+
lambda _gh: f"http://127.0.0.1:{port}",
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
def _boom(*_args, **_kwargs):
|
|
95
|
+
spawn_calls.append("spawn")
|
|
96
|
+
raise AssertionError("daemon must not be spawned when already running")
|
|
97
|
+
|
|
98
|
+
monkeypatch.setattr(daemon_manager_module.subprocess, "Popen", _boom)
|
|
99
|
+
|
|
100
|
+
url = daemon_manager_module.ensure_guard_daemon(guard_home)
|
|
101
|
+
|
|
102
|
+
assert url == f"http://127.0.0.1:{port}"
|
|
103
|
+
assert spawn_calls == []
|
|
104
|
+
|
|
105
|
+
def test_approval_url_has_expected_structure(self, tmp_path, monkeypatch) -> None:
|
|
106
|
+
"""The returned approval URL must be a valid localhost HTTP URL."""
|
|
107
|
+
guard_home = tmp_path / "guard-home"
|
|
108
|
+
port = 5702
|
|
109
|
+
|
|
110
|
+
monkeypatch.setattr(daemon_manager_module, "_reap_stale_ephemeral_guard_daemons", lambda **_: None)
|
|
111
|
+
monkeypatch.setattr(
|
|
112
|
+
daemon_manager_module,
|
|
113
|
+
"load_guard_daemon_url",
|
|
114
|
+
lambda _gh: f"http://127.0.0.1:{port}",
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
url = daemon_manager_module.ensure_guard_daemon(guard_home)
|
|
118
|
+
|
|
119
|
+
assert url.startswith("http://"), "URL must be HTTP"
|
|
120
|
+
assert "127.0.0.1" in url or "localhost" in url, "URL must be local"
|
|
121
|
+
assert str(port) in url, "URL must include the daemon port"
|
|
122
|
+
|
|
123
|
+
def test_approval_url_exposed_without_browser_open(self, tmp_path, monkeypatch) -> None:
|
|
124
|
+
"""Guard must provide an approval URL for CLI/headless consumers
|
|
125
|
+
even when webbrowser.open is never called."""
|
|
126
|
+
import webbrowser
|
|
127
|
+
|
|
128
|
+
guard_home = tmp_path / "guard-home"
|
|
129
|
+
port = 5703
|
|
130
|
+
browser_opens: list[str] = []
|
|
131
|
+
|
|
132
|
+
def _fake_browser_open(url: str, *_args, **_kwargs) -> None:
|
|
133
|
+
browser_opens.append(url)
|
|
134
|
+
|
|
135
|
+
monkeypatch.setattr(webbrowser, "open", _fake_browser_open)
|
|
136
|
+
monkeypatch.setattr(daemon_manager_module, "_reap_stale_ephemeral_guard_daemons", lambda **_: None)
|
|
137
|
+
monkeypatch.setattr(
|
|
138
|
+
daemon_manager_module,
|
|
139
|
+
"load_guard_daemon_url",
|
|
140
|
+
lambda _gh: f"http://127.0.0.1:{port}",
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
url = daemon_manager_module.ensure_guard_daemon(guard_home)
|
|
144
|
+
|
|
145
|
+
assert url is not None
|
|
146
|
+
assert len(browser_opens) == 0, "ensure_guard_daemon must not open a browser on its own"
|
|
147
|
+
|
|
148
|
+
def test_daemon_wake_survives_stale_state_file(self, tmp_path, monkeypatch) -> None:
|
|
149
|
+
"""When the state file references a dead process, the daemon must be retired
|
|
150
|
+
and a new daemon started to handle the approval URL."""
|
|
151
|
+
guard_home = tmp_path / "guard-home"
|
|
152
|
+
port = 5704
|
|
153
|
+
|
|
154
|
+
monkeypatch.setattr(daemon_manager_module, "_reap_stale_ephemeral_guard_daemons", lambda **_: None)
|
|
155
|
+
|
|
156
|
+
stale_state = {
|
|
157
|
+
"pid": 99999,
|
|
158
|
+
"port": 4000,
|
|
159
|
+
"compatibility_version": "0.0.0-stale",
|
|
160
|
+
"source_root": "/tmp/old-install/guard",
|
|
161
|
+
"runtime_fingerprint": "stale-fingerprint",
|
|
162
|
+
}
|
|
163
|
+
url_iter = iter([None, None, f"http://127.0.0.1:{port}"])
|
|
164
|
+
monkeypatch.setattr(daemon_manager_module, "_load_state", lambda _gh: stale_state)
|
|
165
|
+
monkeypatch.setattr(
|
|
166
|
+
daemon_manager_module,
|
|
167
|
+
"load_guard_daemon_url",
|
|
168
|
+
lambda _gh: next(url_iter, f"http://127.0.0.1:{port}"),
|
|
169
|
+
)
|
|
170
|
+
retire_calls: list[dict] = []
|
|
171
|
+
monkeypatch.setattr(
|
|
172
|
+
daemon_manager_module,
|
|
173
|
+
"_retire_guard_daemon_process",
|
|
174
|
+
lambda state: retire_calls.append(state),
|
|
175
|
+
)
|
|
176
|
+
monkeypatch.setattr(daemon_manager_module, "_guard_daemon_start_in_progress", lambda _gh: False)
|
|
177
|
+
monkeypatch.setattr(daemon_manager_module.time, "sleep", lambda _: None)
|
|
178
|
+
monkeypatch.setattr(daemon_manager_module.subprocess, "Popen", _make_start_mock(guard_home, port))
|
|
179
|
+
monkeypatch.setattr(
|
|
180
|
+
daemon_manager_module,
|
|
181
|
+
"_wait_for_guard_daemon_url",
|
|
182
|
+
lambda _gh, **_kw: f"http://127.0.0.1:{port}",
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
url = daemon_manager_module.ensure_guard_daemon(guard_home)
|
|
186
|
+
|
|
187
|
+
assert url == f"http://127.0.0.1:{port}"
|
|
188
|
+
assert len(retire_calls) >= 1, "_retire_guard_daemon_process must be called to recover stale daemon state"
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
"""L315: Tests for Guard daemon log redaction helpers.
|
|
2
|
+
|
|
3
|
+
Verifies that sensitive values are removed before Guard prints or syncs them.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import pytest
|
|
9
|
+
|
|
10
|
+
from codex_plugin_scanner.guard.redaction import redact_sensitive_text, redact_text
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class TestRedactText:
|
|
14
|
+
"""Core redaction patterns that must fire before logging or syncing."""
|
|
15
|
+
|
|
16
|
+
def test_bearer_token_is_redacted(self) -> None:
|
|
17
|
+
result = redact_text("Authorization: Bearer eyJhbGciOiJSUzI1NiJ9.payload.sig")
|
|
18
|
+
assert "eyJhbGciOiJSUzI1NiJ9" not in result.text
|
|
19
|
+
assert result.count >= 1
|
|
20
|
+
assert "bearer-token" in result.classifiers
|
|
21
|
+
|
|
22
|
+
def test_openai_sk_token_is_redacted(self) -> None:
|
|
23
|
+
result = redact_text("OPENAI_API_KEY=sk-abcdefgh12345678")
|
|
24
|
+
assert "sk-abcdefgh12345678" not in result.text
|
|
25
|
+
assert result.count >= 1
|
|
26
|
+
assert "openai-token" in result.classifiers
|
|
27
|
+
|
|
28
|
+
def test_github_token_is_redacted(self) -> None:
|
|
29
|
+
result = redact_text("Cloning with token ghp_abcdef1234567890abcdef1234567890")
|
|
30
|
+
assert "ghp_abcdef1234567890abcdef1234567890" not in result.text
|
|
31
|
+
assert "github-token" in result.classifiers
|
|
32
|
+
|
|
33
|
+
def test_aws_access_key_is_redacted(self) -> None:
|
|
34
|
+
result = redact_text("AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE")
|
|
35
|
+
assert "AKIAIOSFODNN7EXAMPLE" not in result.text
|
|
36
|
+
assert "aws-access-key" in result.classifiers
|
|
37
|
+
|
|
38
|
+
def test_npm_auth_token_is_redacted(self) -> None:
|
|
39
|
+
result = redact_text("_authToken=npm_my_secret_token_12345678")
|
|
40
|
+
assert "npm_my_secret_token_12345678" not in result.text
|
|
41
|
+
assert "npm-token" in result.classifiers
|
|
42
|
+
|
|
43
|
+
def test_private_key_block_is_redacted(self) -> None:
|
|
44
|
+
pem = "-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEA\n-----END RSA PRIVATE KEY-----"
|
|
45
|
+
result = redact_text(pem)
|
|
46
|
+
assert "MIIEpAIBAAKCAQEA" not in result.text
|
|
47
|
+
assert "private-key" in result.classifiers
|
|
48
|
+
|
|
49
|
+
def test_secret_env_var_is_redacted(self) -> None:
|
|
50
|
+
result = redact_text("MY_APP_SECRET=supersecretvalue123")
|
|
51
|
+
assert "supersecretvalue123" not in result.text
|
|
52
|
+
assert "secret-env" in result.classifiers
|
|
53
|
+
|
|
54
|
+
def test_token_env_var_is_redacted(self) -> None:
|
|
55
|
+
result = redact_text("AUTH_TOKEN=hunter2")
|
|
56
|
+
assert "hunter2" not in result.text
|
|
57
|
+
assert "secret-env" in result.classifiers
|
|
58
|
+
|
|
59
|
+
def test_password_env_var_is_redacted(self) -> None:
|
|
60
|
+
result = redact_text("DB_PASSWORD=correcthorsebatterystaple")
|
|
61
|
+
assert "correcthorsebatterystaple" not in result.text
|
|
62
|
+
assert "secret-env" in result.classifiers
|
|
63
|
+
|
|
64
|
+
def test_database_connection_string_is_redacted(self) -> None:
|
|
65
|
+
result = redact_text("postgresql://user:hunter2@db.example.com:5432/prod")
|
|
66
|
+
assert "hunter2" not in result.text
|
|
67
|
+
assert "connection-string" in result.classifiers
|
|
68
|
+
|
|
69
|
+
def test_redis_url_is_redacted(self) -> None:
|
|
70
|
+
result = redact_text("redis://default:secretpassword@cache.example.com:6379/0")
|
|
71
|
+
assert "secretpassword" not in result.text
|
|
72
|
+
assert "connection-string" in result.classifiers
|
|
73
|
+
|
|
74
|
+
def test_connection_env_url_is_redacted(self) -> None:
|
|
75
|
+
result = redact_text("DATABASE_URL=postgres://user:pw@host/db")
|
|
76
|
+
assert "postgres://user:pw@host/db" not in result.text
|
|
77
|
+
assert "connection-env" in result.classifiers
|
|
78
|
+
|
|
79
|
+
def test_clean_text_returns_zero_count(self) -> None:
|
|
80
|
+
result = redact_text("Running build step: pnpm install")
|
|
81
|
+
assert result.count == 0
|
|
82
|
+
assert result.text == "Running build step: pnpm install"
|
|
83
|
+
assert result.classifiers == ()
|
|
84
|
+
|
|
85
|
+
def test_result_preserves_sha256_of_original(self) -> None:
|
|
86
|
+
import hashlib
|
|
87
|
+
|
|
88
|
+
original = "MY_TOKEN=abcdef"
|
|
89
|
+
result = redact_text(original)
|
|
90
|
+
expected_sha = hashlib.sha256(original.encode("utf-8")).hexdigest()
|
|
91
|
+
assert result.original_sha256 == expected_sha
|
|
92
|
+
|
|
93
|
+
def test_result_is_frozen(self) -> None:
|
|
94
|
+
result = redact_text("clean text")
|
|
95
|
+
with pytest.raises((AttributeError, TypeError)):
|
|
96
|
+
result.count = 99 # type: ignore[misc]
|
|
97
|
+
|
|
98
|
+
def test_multiple_secrets_in_one_string(self) -> None:
|
|
99
|
+
text = "sk-abcdefgh12345678 and ghp_abcdef1234567890abcdef1234567890"
|
|
100
|
+
result = redact_text(text)
|
|
101
|
+
assert "sk-abcdefgh12345678" not in result.text
|
|
102
|
+
assert "ghp_abcdef1234567890abcdef1234567890" not in result.text
|
|
103
|
+
assert result.count >= 2
|
|
104
|
+
|
|
105
|
+
def test_to_dict_excludes_redacted_text(self) -> None:
|
|
106
|
+
result = redact_text("MY_SECRET=hunter2")
|
|
107
|
+
d = result.to_dict()
|
|
108
|
+
assert "text" not in d
|
|
109
|
+
assert "count" in d
|
|
110
|
+
assert "classifiers" in d
|
|
111
|
+
assert "original_sha256" in d
|
|
112
|
+
|
|
113
|
+
def test_classifier_deduplication(self) -> None:
|
|
114
|
+
"""Two tokens of the same type produce one classifier entry, not two."""
|
|
115
|
+
text = "sk-aaaaaaa11111111 sk-bbbbbbb22222222"
|
|
116
|
+
result = redact_text(text)
|
|
117
|
+
assert result.classifiers.count("openai-token") == 1
|
|
118
|
+
|
|
119
|
+
def test_false_positive_curl_header_not_redacted(self) -> None:
|
|
120
|
+
"""Routine health-check Accept header must not be stripped."""
|
|
121
|
+
result = redact_text("curl -H 'Accept: application/json' http://localhost:4000/health")
|
|
122
|
+
assert "application/json" in result.text
|
|
123
|
+
assert result.count == 0
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
class TestRedactSensitiveText:
|
|
127
|
+
"""Quick inline redaction for log lines that do not need full metadata."""
|
|
128
|
+
|
|
129
|
+
def test_sk_token_is_redacted(self) -> None:
|
|
130
|
+
result = redact_sensitive_text("key=sk-abcdef1234567890")
|
|
131
|
+
assert "sk-abcdef1234567890" not in result
|
|
132
|
+
|
|
133
|
+
def test_api_key_assignment_is_redacted(self) -> None:
|
|
134
|
+
result = redact_sensitive_text("api_key: my_secret_value_here")
|
|
135
|
+
assert "my_secret_value_here" not in result
|
|
136
|
+
|
|
137
|
+
def test_clean_text_unchanged(self) -> None:
|
|
138
|
+
text = "Daemon started on port 4001"
|
|
139
|
+
assert redact_sensitive_text(text) == text
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
class TestRedactTextApprovalWakeScenarios:
|
|
143
|
+
"""L314/L315 combined: redaction must apply to approval-request log lines.
|
|
144
|
+
|
|
145
|
+
These scenarios simulate what Guard logs when an approval URL is accessed
|
|
146
|
+
without the browser dashboard open. The auth token embedded in the URL
|
|
147
|
+
fragment must never appear in plain text in any log output.
|
|
148
|
+
"""
|
|
149
|
+
|
|
150
|
+
def test_approval_url_with_token_fragment_is_redacted(self) -> None:
|
|
151
|
+
url_log = "Approval URL opened: http://localhost:4001/#guard-token=ghp_faketoken123456789012"
|
|
152
|
+
result = redact_text(url_log)
|
|
153
|
+
assert "ghp_faketoken123456789012" not in result.text
|
|
154
|
+
|
|
155
|
+
def test_approval_url_without_token_is_not_altered(self) -> None:
|
|
156
|
+
url_log = "Approval URL: http://localhost:4001/approvals/req-abc"
|
|
157
|
+
result = redact_text(url_log)
|
|
158
|
+
assert "http://localhost:4001/approvals/req-abc" in result.text
|
|
159
|
+
assert result.count == 0
|
|
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.155 → plugin_scanner-2.0.156}/.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.155 → plugin_scanner-2.0.156}/dashboard/src/approval-center-layout.test.ts
RENAMED
|
File without changes
|
|
File without changes
|
{plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/dashboard/src/approval-center-primitives.tsx
RENAMED
|
File without changes
|
{plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/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
|
|
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.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/argparse_utils.py
RENAMED
|
File without changes
|
{plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/checks/__init__.py
RENAMED
|
File without changes
|
{plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/checks/best_practices.py
RENAMED
|
File without changes
|
|
File without changes
|
{plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/checks/code_quality.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/checks/manifest.py
RENAMED
|
File without changes
|
|
File without changes
|
{plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/checks/marketplace.py
RENAMED
|
File without changes
|
{plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/checks/mcp_security.py
RENAMED
|
File without changes
|
{plugin_scanner-2.0.155 → plugin_scanner-2.0.156}/src/codex_plugin_scanner/checks/opencode.py
RENAMED
|
File without changes
|
|
File without changes
|