plugin-scanner 2.0.168__tar.gz → 2.0.169__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.168 → plugin_scanner-2.0.169}/PKG-INFO +1 -1
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/dashboard/src/approval-center-layout.test.ts +17 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/dashboard/src/approval-center-layout.tsx +40 -8
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/dashboard/src/approval-center-primitives.tsx +18 -14
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/dashboard/src/approval-center-utils.ts +4 -4
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/dashboard/src/home-dashboard.tsx +72 -13
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/dashboard/src/queue-state.ts +24 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/dashboard/src/runtime-overview.tsx +4 -2
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/pyproject.toml +1 -1
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/pyproject.toml.bak +1 -1
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/approvals.py +24 -4
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/cli/commands.py +7 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/daemon/static/assets/guard-dashboard.js +110 -29
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/store.py +32 -7
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/version.py +1 -1
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_runtime.py +171 -1
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/.clusterfuzzlite/Dockerfile +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/.clusterfuzzlite/build.sh +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/.clusterfuzzlite/project.yaml +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/.clusterfuzzlite/requirements-atheris.txt +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/.dockerignore +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/.github/CODEOWNERS +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/.github/ISSUE_TEMPLATE/bug-report.yml +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/.github/ISSUE_TEMPLATE/feature-request.yml +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/.github/dependabot.yml +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/.github/workflows/ci.yml +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/.github/workflows/codeql.yml +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/.github/workflows/dependabot-uv-lock.yml +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/.github/workflows/fuzz.yml +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/.github/workflows/harness-smoke.yml +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/.github/workflows/publish.yml +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/.github/workflows/scorecard.yml +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/.gitignore +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/.pre-commit-hooks.yaml +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/CONTRIBUTING.md +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/Dockerfile +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/LICENSE +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/README.md +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/SECURITY.md +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/dashboard/index.html +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/dashboard/package.json +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/dashboard/pnpm-lock.yaml +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/dashboard/public/apple-touch-icon.png +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/dashboard/public/brand/Logo_Icon_Dark.png +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/dashboard/public/brand/Logo_Whole.png +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/dashboard/public/favicon-16x16.png +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/dashboard/public/favicon-32x32.png +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/dashboard/public/favicon.ico +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/dashboard/src/app.tsx +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/dashboard/src/approval-center-mobile.test.ts +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/dashboard/src/approval-center-review-cards.tsx +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/dashboard/src/data-flow-evidence-card.tsx +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/dashboard/src/fleet-workspace.tsx +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/dashboard/src/guard-api.test.ts +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/dashboard/src/guard-api.ts +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/dashboard/src/guard-demo.ts +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/dashboard/src/guard-types.ts +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/dashboard/src/home-dashboard.test.ts +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/dashboard/src/main.tsx +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/dashboard/src/queue-chip-filter.tsx +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/dashboard/src/queue-state.test.ts +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/dashboard/src/receipts-workspace.test.ts +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/dashboard/src/receipts-workspace.tsx +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/dashboard/src/risk-signal-cards.test.ts +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/dashboard/src/risk-signal-cards.tsx +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/dashboard/src/runtime-overview.test.ts +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/dashboard/src/scanner-evidence-badge.tsx +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/dashboard/src/settings-workspace.test.ts +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/dashboard/src/settings-workspace.tsx +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/dashboard/src/styles.css +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/dashboard/src/vite-env.d.ts +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/dashboard/src/watched-app-card.tsx +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/dashboard/tsconfig.json +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/dashboard/vite.config.ts +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/docker-requirements.txt +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/docs/guard/approval-audit.md +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/docs/guard/architecture.md +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/docs/guard/get-started.md +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/docs/guard/harness-support.md +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/docs/guard/local-vs-cloud.md +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/docs/guard/release-checklist.md +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/docs/guard/release-notes.md +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/docs/guard/smoke-tests.md +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/docs/guard/testing-matrix.md +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/docs/trust/mcp-trust-draft.md +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/docs/trust/plugin-trust-draft.md +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/docs/trust/skill-trust-local.md +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/fuzzers/manifest_fuzzer.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/requirements.txt +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/schemas/plugin-quality.v1.json +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/schemas/scan-result.v1.json +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/schemas/verify-result.v1.json +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/__init__.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/action_runner.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/argparse_utils.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/checks/__init__.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/checks/best_practices.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/checks/claude.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/checks/code_quality.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/checks/ecosystem_common.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/checks/gemini.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/checks/manifest.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/checks/manifest_support.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/checks/marketplace.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/checks/mcp_security.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/checks/opencode.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/checks/operational_security.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/checks/security.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/checks/skill_security.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/cli.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/cli_ui.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/config.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/ecosystems/__init__.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/ecosystems/base.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/ecosystems/claude.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/ecosystems/codex.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/ecosystems/detect.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/ecosystems/gemini.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/ecosystems/opencode.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/ecosystems/registry.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/ecosystems/types.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/github_reporting.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/__init__.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/access_graph_events.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/adapters/__init__.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/adapters/antigravity.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/adapters/base.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/adapters/claude_code.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/adapters/cloud_identity.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/adapters/codex.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/adapters/contracts.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/adapters/copilot.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/adapters/cursor.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/adapters/gemini.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/adapters/hermes.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/adapters/mcp_servers.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/adapters/openclaw.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/adapters/openclaw_config.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/adapters/openclaw_support.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/adapters/opencode.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/adapters/opencode_artifacts.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/advisory_model.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/bridge/__init__.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/capabilities.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/cli/__init__.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/cli/approval_commands.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/cli/bootstrap.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/cli/connect_flow.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/cli/install_commands.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/cli/product.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/cli/prompt.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/cli/render.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/cli/update_commands.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/codex_config.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/config.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/consumer/__init__.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/consumer/service.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/daemon/__init__.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/daemon/client.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/daemon/manager.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/daemon/server.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/daemon/static/apple-touch-icon.png +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/daemon/static/assets/index.css +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/daemon/static/brand/Logo_Icon_Dark.png +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/daemon/static/brand/Logo_Whole.png +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/daemon/static/favicon-16x16.png +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/daemon/static/favicon-32x32.png +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/daemon/static/favicon.ico +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/daemon/static/index.html +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/edge_events.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/incident.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/insights.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/launcher.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/mcp_tool_calls.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/models.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/policy/__init__.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/policy/engine.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/protect.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/proxy/__init__.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/proxy/remote.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/proxy/runtime_mcp.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/proxy/stdio.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/receipts/__init__.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/receipts/manager.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/redaction.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/risk.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/runtime/__init__.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/runtime/action_identity.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/runtime/actions.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/runtime/advisory_escalation.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/runtime/advisory_matchers.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/runtime/cisco_evidence.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/runtime/cisco_preflight.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/runtime/composition_rules.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/runtime/data_flow.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/runtime/data_flow_rules.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/runtime/data_flow_variables.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/runtime/decisions.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/runtime/detectors.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/runtime/false_positive_rules.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/runtime/mcp_protection.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/runtime/persistence_rules.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/runtime/prompt_injection.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/runtime/runner.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/runtime/safe_decode.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/runtime/sandbox.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/runtime/scanner_cache.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/runtime/secret_file_requests.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/runtime/secret_sensitivity.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/runtime/secret_sources.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/runtime/shell_commands.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/runtime/signals.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/runtime/skill_protection.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/runtime/supply_chain.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/runtime/surface_server.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/runtime/temp_files.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/runtime/threat_intel.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/schemas/__init__.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/schemas/consumer_mode.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/schemas/guard_event_v1.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/schemas/surface_server.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/shims.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/store_approvals.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/store_connect.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/store_evidence.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/store_threat_intel.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/types.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/integrations/__init__.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/integrations/cisco_mcp_scanner.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/integrations/cisco_skill_scanner.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/lint_fixes.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/marketplace_support.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/models.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/path_support.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/policy.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/quality_artifact.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/repo_detect.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/reporting.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/rules/__init__.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/rules/registry.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/rules/specs.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/scanner.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/submission.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/suppressions.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/trust_domain_scoring.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/trust_helpers.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/trust_mcp_scoring.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/trust_models.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/trust_plugin_scoring.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/trust_scoring.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/trust_skill_scoring.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/trust_specs.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/verification.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/__init__.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/conftest.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/__init__.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/bad-plugin/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/bad-plugin/.mcp.json +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/bad-plugin/secrets.js +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/claude-plugin-good/.claude-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/claude-plugin-good/LICENSE +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/claude-plugin-good/README.md +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/claude-plugin-good/SECURITY.md +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/claude-plugin-good/hooks/hooks.json +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/claude-plugin-good/skills/example/SKILL.md +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/code-quality-bad/evil.js +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/code-quality-bad/inject.js +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/gemini-extension-good/GEMINI.md +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/gemini-extension-good/LICENSE +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/gemini-extension-good/README.md +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/gemini-extension-good/SECURITY.md +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/gemini-extension-good/commands/hello.toml +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/gemini-extension-good/gemini-extension.json +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/good-plugin/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/good-plugin/.codexignore +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/good-plugin/LICENSE +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/good-plugin/README.md +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/good-plugin/SECURITY.md +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/good-plugin/assets/icon.svg +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/good-plugin/assets/logo.svg +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/good-plugin/assets/screenshot.svg +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/good-plugin/skills/example/SKILL.md +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/guard-codex-malicious-mcp/.codex/config.toml +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/guard-red-team/README.md +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/guard-red-team/benign-docs-fake-token.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/guard-red-team/benign-health-endpoint.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/guard-red-team/benign-nvmrc-fake-creds.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/guard-red-team/benign-source-search.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/guard-red-team/canary-exfil-encoded.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/guard-red-team/canary-exfil.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/guard-red-team/expected-decisions.json +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/guard-red-team/malicious-dockerfile.txt +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/guard-red-team/malicious-encoded-shell-exfil.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/guard-red-team/malicious-github-action.yml +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/guard-red-team/malicious-mcp-delete.md +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/guard-red-team/malicious-mcp-secret-read.md +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/guard-red-team/malicious-mcp-skill-exfil.md +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/guard-red-team/malicious-npm-postinstall.js +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/guard-red-team/malicious-prompt-env-read.md +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/guard-red-team/malicious-prompt-guard-bypass.md +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/guard-red-team/malicious-prompt-npmrc-read.md +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/guard-red-team/malicious-python-setup.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/guard-red-team/smoke-evidence-template.json +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/hermes-plugin-evil/config.yaml +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/hermes-plugin-evil/mcp_servers.json +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/hermes-plugin-evil/skills/security/malicious/SKILL.md +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/hermes-plugin-evil/skills/stealth/sneaky/SKILL.md +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/hermes-plugin-evil/skills/stealth/sneaky/references/api-setup.md +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/hermes-plugin-evil/skills/stealth/sneaky/scripts/deploy.sh +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/hermes-plugin-evil/skills/utils/benign/SKILL.md +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/malformed-json/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/malicious-skill-plugin/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/malicious-skill-plugin/.codexignore +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/malicious-skill-plugin/LICENSE +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/malicious-skill-plugin/README.md +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/malicious-skill-plugin/SECURITY.md +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/malicious-skill-plugin/skills/leaky-skill/SKILL.md +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/mcp-canary-server.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/minimal-plugin/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/missing-fields/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/mit-license/LICENSE +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/multi-ecosystem-repo/codex-plugin/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/multi-ecosystem-repo/codex-plugin/LICENSE +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/multi-ecosystem-repo/codex-plugin/README.md +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/multi-ecosystem-repo/codex-plugin/SECURITY.md +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/multi-ecosystem-repo/gemini-ext/README.md +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/multi-ecosystem-repo/gemini-ext/gemini-extension.json +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/multi-plugin-repo/.agents/plugins/marketplace.json +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/.codexignore +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/LICENSE +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/README.md +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/SECURITY.md +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/skills/example/SKILL.md +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/multi-plugin-repo/plugins/beta-plugin/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/multi-plugin-repo/plugins/beta-plugin/skills/example/SKILL.md +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/no-version/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/opencode-good/.opencode/commands/hello.md +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/opencode-good/.opencode/plugins/example.ts +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/opencode-good/LICENSE +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/opencode-good/README.md +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/opencode-good/SECURITY.md +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/opencode-good/opencode.jsonc +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/skills-missing-dir/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/skills-no-frontmatter/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/skills-no-frontmatter/skills/bad-skill/SKILL.md +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/supply-chain/benign-npm-package.json +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/supply-chain/benign-pnpm-package.json +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/supply-chain/benign-pyproject.toml +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/supply-chain/malicious-Dockerfile +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/supply-chain/malicious-action.yml +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/supply-chain/malicious-npm-package.json +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/supply-chain/malicious-setup.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/with-marketplace/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/with-marketplace/marketplace-broken.json +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/fixtures/with-marketplace/marketplace.json +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test-trust-scoring.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test-trust-specs.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_action_runner.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_best_practices.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_cisco_install_surfaces.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_cli.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_code_quality.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_config.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_coverage_remaining.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_ecosystems.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_edge_cases.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_final_coverage.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_access_graph.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_action_identity.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_advisory_escalation.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_approval_continuity.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_approval_copy_commands.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_approval_store_dedup.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_approval_store_scale.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_approvals.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_bootstrap.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_bypass_detector.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_canary_fixtures.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_capabilities.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_cisco_evidence.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_cisco_runtime_cli.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_claude_adapter.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_cli.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_cloud_local_sync.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_codex_e2e.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_codex_install.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_codex_proxy.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_config_paths.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_connect_flow.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_consumer_mode.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_copilot_adapter.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_copilot_proxy.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_daemon_cli.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_daemon_manager.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_daemon_perf.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_daemon_registry.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_daemon_repair_perf.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_daemon_wake.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_data_flow.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_decision_propagation.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_detector_fp.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_event_schema_v1.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_events.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_evidence_store.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_harness_contracts.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_harness_setup.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_harness_smoke.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_insights.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_launch_env.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_mcp_detectors.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_mcp_protection.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_opencode_proxy.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_policy_dedup.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_product_flow.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_prompt_injection.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_protect.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_queue_api_contract.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_queue_contract.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_red_team.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_red_team_e2e.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_redaction.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_render.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_resolution_copy.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_risk.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_runtime_action_harnesses.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_runtime_actions.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_runtime_decisions.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_runtime_detectors.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_runtime_signals.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_safe_decode.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_sandbox.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_settings_presets.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_skill_protection.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_store_migrations.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_supply_chain.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_surface_server.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_threat_intel.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_verdicts.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_guard_web_recovery.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_hermes_adapter.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_integration.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_lint_fixes.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_live_cisco_smoke.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_manifest.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_marketplace.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_mcp_security.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_openclaw_adapter.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_operational_security.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_policy.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_quality_artifact.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_rule_registry.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_scanner.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_schema_contracts.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_security.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_security_ops.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_skill_security.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_submission.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_trust_scoring.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_trust_specs.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_verification.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/tests/test_versioning.py +0 -0
- {plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/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.169
|
|
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
|
{plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/dashboard/src/approval-center-layout.test.ts
RENAMED
|
@@ -5,6 +5,8 @@ import {
|
|
|
5
5
|
displayArtifactName,
|
|
6
6
|
EMPTY_QUEUE_TITLE,
|
|
7
7
|
STALE_REQUEST_COPY,
|
|
8
|
+
buildRecommendation,
|
|
9
|
+
scopeLabel,
|
|
8
10
|
} from "./approval-center-utils";
|
|
9
11
|
import type { GuardActionEnvelope, GuardApprovalRequest } from "./guard-types";
|
|
10
12
|
|
|
@@ -208,3 +210,18 @@ assert(
|
|
|
208
210
|
STALE_REQUEST_COPY.toLowerCase().includes("already decided"),
|
|
209
211
|
'C6: Stale request copy contains "already decided" — not approve/block buttons'
|
|
210
212
|
);
|
|
213
|
+
|
|
214
|
+
assert(
|
|
215
|
+
scopeLabel("artifact") === "This retry only",
|
|
216
|
+
"C7: Artifact scope copy makes one-retry behavior clear"
|
|
217
|
+
);
|
|
218
|
+
|
|
219
|
+
assert(
|
|
220
|
+
scopeLabel("workspace") === "Same action in this project",
|
|
221
|
+
"C8: Workspace scope copy makes same-action project behavior clear"
|
|
222
|
+
);
|
|
223
|
+
|
|
224
|
+
assert(
|
|
225
|
+
buildRecommendation(BASE_REQUEST).includes("Project approval remembers this same action"),
|
|
226
|
+
"C9: Recommendation explains project approval does not trust new sensitive actions"
|
|
227
|
+
);
|
|
@@ -59,6 +59,7 @@ import {
|
|
|
59
59
|
} from "./approval-center-review-cards";
|
|
60
60
|
import {
|
|
61
61
|
buildProgressCopy,
|
|
62
|
+
buildNextUpChipText,
|
|
62
63
|
sortQueue,
|
|
63
64
|
searchQueue,
|
|
64
65
|
groupDuplicates,
|
|
@@ -130,8 +131,16 @@ type LayoutProps = {
|
|
|
130
131
|
};
|
|
131
132
|
|
|
132
133
|
const scopeOptions: Array<{ value: DecisionScope; label: string; description: string }> = [
|
|
133
|
-
{
|
|
134
|
-
|
|
134
|
+
{
|
|
135
|
+
value: "artifact",
|
|
136
|
+
label: "This retry only",
|
|
137
|
+
description: "Remember this exact prompt, command, tool, path, or host fingerprint."
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
value: "workspace",
|
|
141
|
+
label: "Same action in this project",
|
|
142
|
+
description: "Skip the next prompt for this same action here; different sensitive actions still ask."
|
|
143
|
+
},
|
|
135
144
|
{ value: "publisher", label: "This source", description: "Trust future actions from the same source in this app." },
|
|
136
145
|
{ value: "harness", label: "This app", description: "Trust matching actions from this app." },
|
|
137
146
|
{ value: "global", label: "Every project", description: "Use this choice across this machine." }
|
|
@@ -279,15 +288,25 @@ function QueueWorkspace(props: {
|
|
|
279
288
|
if (props.requests.kind === "error") {
|
|
280
289
|
const approvalUrl =
|
|
281
290
|
props.runtime.kind === "ready" ? props.runtime.snapshot.approval_center_url : null;
|
|
291
|
+
const handleOpenDaemon = () => {
|
|
292
|
+
if (approvalUrl !== null) {
|
|
293
|
+
window.open(approvalUrl, "_blank", "noopener,noreferrer");
|
|
294
|
+
} else {
|
|
295
|
+
void handleRepair();
|
|
296
|
+
}
|
|
297
|
+
};
|
|
282
298
|
return (
|
|
283
299
|
<div className="space-y-4">
|
|
284
300
|
<Surface tone="danger">
|
|
285
|
-
<p className="text-sm font-semibold text-brand-purple">Guard
|
|
301
|
+
<p className="text-sm font-semibold text-brand-purple">Guard daemon not responding — click to reconnect.</p>
|
|
286
302
|
<p className="mt-1 text-sm text-brand-purple/80">{props.requests.message}</p>
|
|
287
303
|
<div className="mt-4 flex flex-wrap gap-3">
|
|
304
|
+
<ActionButton onClick={handleOpenDaemon}>
|
|
305
|
+
Repair
|
|
306
|
+
</ActionButton>
|
|
288
307
|
{props.onRepair !== undefined && (
|
|
289
|
-
<ActionButton onClick={handleRepair} disabled={repairing}>
|
|
290
|
-
{repairing ? "Repairing…" : "
|
|
308
|
+
<ActionButton onClick={handleRepair} disabled={repairing} variant="outline">
|
|
309
|
+
{repairing ? "Repairing…" : "Reconnect"}
|
|
291
310
|
</ActionButton>
|
|
292
311
|
)}
|
|
293
312
|
<code className="inline-flex min-h-10 items-center rounded-lg border border-brand-purple/30 bg-slate-50 px-3 py-2 font-mono text-sm text-brand-purple select-all">hol-guard start</code>
|
|
@@ -515,7 +534,7 @@ function QueueBrowser(props: {
|
|
|
515
534
|
className="min-h-11 w-full rounded-lg border border-slate-200 bg-white px-3 text-sm text-brand-dark placeholder:text-slate-400 transition-colors duration-150 focus:border-brand-blue focus:outline-none focus:ring-2 focus:ring-brand-blue/20"
|
|
516
535
|
/>
|
|
517
536
|
</label>
|
|
518
|
-
{harnesses.length
|
|
537
|
+
{harnesses.length >= 2 && (
|
|
519
538
|
<QueueChipFilter
|
|
520
539
|
harnesses={harnesses}
|
|
521
540
|
activeFilter={harnessFilter}
|
|
@@ -589,8 +608,8 @@ function QueueCardRow(props: {
|
|
|
589
608
|
{props.nextUpItem !== null && (
|
|
590
609
|
<div className="border-t border-slate-100 bg-slate-50/60 px-4 py-2">
|
|
591
610
|
<p className="truncate text-[11px] text-muted-foreground">
|
|
592
|
-
<span className="font-semibold">Next
|
|
593
|
-
{
|
|
611
|
+
<span className="font-semibold">Next:</span>{" "}
|
|
612
|
+
{buildNextUpChipText(props.nextUpItem)}
|
|
594
613
|
</p>
|
|
595
614
|
</div>
|
|
596
615
|
)}
|
|
@@ -687,6 +706,7 @@ function DecisionWorkspace(props: {
|
|
|
687
706
|
const [errorMessage, setErrorMessage] = useState<string | null>(null);
|
|
688
707
|
const [confirmPending, setConfirmPending] = useState<"allow" | "block" | null>(null);
|
|
689
708
|
const [resolvedBanner, setResolvedBanner] = useState<"allow" | "block" | null>(null);
|
|
709
|
+
const [resolvedState, setResolvedState] = useState<"idle" | "decided" | "loaded">("idle");
|
|
690
710
|
const bannerTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
691
711
|
const prevRequestIdRef = useRef<string | null>(null);
|
|
692
712
|
|
|
@@ -696,6 +716,7 @@ function DecisionWorkspace(props: {
|
|
|
696
716
|
prevRequestIdRef.current = props.detail.item.request_id;
|
|
697
717
|
if (isNewItem) {
|
|
698
718
|
setResolvedBanner(null);
|
|
719
|
+
setResolvedState("loaded");
|
|
699
720
|
if (bannerTimerRef.current !== null) {
|
|
700
721
|
clearTimeout(bannerTimerRef.current);
|
|
701
722
|
bannerTimerRef.current = null;
|
|
@@ -731,6 +752,7 @@ function DecisionWorkspace(props: {
|
|
|
731
752
|
reason,
|
|
732
753
|
workspace: scope === "workspace" ? readyWorkspace : undefined,
|
|
733
754
|
});
|
|
755
|
+
setResolvedState("decided");
|
|
734
756
|
setResolvedBanner(action);
|
|
735
757
|
bannerTimerRef.current = setTimeout(() => {
|
|
736
758
|
setResolvedBanner(null);
|
|
@@ -800,6 +822,16 @@ function DecisionWorkspace(props: {
|
|
|
800
822
|
if (props.detail.kind === "loading") {
|
|
801
823
|
return (
|
|
802
824
|
<div className="space-y-4">
|
|
825
|
+
{resolvedState === "decided" && (
|
|
826
|
+
<div
|
|
827
|
+
className="flex items-center gap-3 rounded-2xl border border-brand-green/25 bg-brand-green-bg/30 px-4 py-3"
|
|
828
|
+
role="status"
|
|
829
|
+
aria-live="polite"
|
|
830
|
+
>
|
|
831
|
+
<HiMiniCheckCircle className="h-4 w-4 shrink-0 text-brand-green" aria-hidden="true" />
|
|
832
|
+
<p className="text-sm font-medium text-brand-green-text">Decided — loading next…</p>
|
|
833
|
+
</div>
|
|
834
|
+
)}
|
|
803
835
|
<div className="guard-skeleton h-8 w-48" />
|
|
804
836
|
<div className="guard-skeleton h-40 w-full" />
|
|
805
837
|
<div className="guard-skeleton h-56 w-full" />
|
{plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/dashboard/src/approval-center-primitives.tsx
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ChangeEvent, ReactNode } from "react";
|
|
1
|
+
import type { ButtonHTMLAttributes, ChangeEvent, ReactNode } from "react";
|
|
2
2
|
import {
|
|
3
3
|
HiMiniArrowTopRightOnSquare,
|
|
4
4
|
HiMiniCloud,
|
|
@@ -92,11 +92,13 @@ export function ShellHeader(props: {
|
|
|
92
92
|
<button
|
|
93
93
|
type="button"
|
|
94
94
|
onClick={props.onOpenMobileQueue}
|
|
95
|
-
aria-label=
|
|
95
|
+
aria-label={`Open queue list — ${props.queuedCount} decisions waiting`}
|
|
96
96
|
className="inline-flex min-h-11 shrink-0 items-center gap-1.5 rounded-full border border-white/25 bg-white/10 px-3 py-2 text-sm font-semibold text-white no-underline transition-colors duration-150 hover:bg-white/15"
|
|
97
97
|
>
|
|
98
98
|
<HiBars3 className="h-4 w-4" aria-hidden="true" />
|
|
99
|
-
{props.queuedCount >
|
|
99
|
+
{props.queuedCount > 1
|
|
100
|
+
? `${props.queuedCount > 99 ? "99+" : props.queuedCount} decisions waiting`
|
|
101
|
+
: props.queuedCount}
|
|
100
102
|
</button>
|
|
101
103
|
)}
|
|
102
104
|
{(!props.onOpenMobileQueue || props.view !== "inbox" || props.queuedCount === 0) && (
|
|
@@ -294,29 +296,31 @@ export function EmptyState(props: {
|
|
|
294
296
|
);
|
|
295
297
|
}
|
|
296
298
|
|
|
297
|
-
|
|
299
|
+
type ActionButtonProps = {
|
|
298
300
|
children: ReactNode;
|
|
299
301
|
onClick?: () => void;
|
|
300
302
|
href?: string;
|
|
301
303
|
variant?: "primary" | "secondary" | "danger" | "outline" | "ghost" | "success";
|
|
302
304
|
disabled?: boolean;
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
|
|
305
|
+
} & Omit<ButtonHTMLAttributes<HTMLButtonElement>, "children" | "className" | "onClick" | "type">;
|
|
306
|
+
|
|
307
|
+
export function ActionButton({ children, href, variant, disabled, onClick, ...buttonProps }: ActionButtonProps) {
|
|
308
|
+
const className = actionButtonClass(variant);
|
|
309
|
+
if (href) {
|
|
306
310
|
return (
|
|
307
311
|
<a
|
|
308
|
-
href={guardAwareHref(
|
|
309
|
-
target={
|
|
310
|
-
rel={
|
|
312
|
+
href={guardAwareHref(href)}
|
|
313
|
+
target={href.startsWith("https://") ? "_blank" : undefined}
|
|
314
|
+
rel={href.startsWith("https://") ? "noreferrer" : undefined}
|
|
311
315
|
className={className}
|
|
312
316
|
>
|
|
313
|
-
{
|
|
317
|
+
{children}
|
|
314
318
|
</a>
|
|
315
319
|
);
|
|
316
320
|
}
|
|
317
321
|
return (
|
|
318
|
-
<button type="button" className={className} onClick={
|
|
319
|
-
{
|
|
322
|
+
<button type="button" className={className} onClick={onClick} disabled={disabled} {...buttonProps}>
|
|
323
|
+
{children}
|
|
320
324
|
</button>
|
|
321
325
|
);
|
|
322
326
|
}
|
|
@@ -541,7 +545,7 @@ export function WelcomeState(props: {
|
|
|
541
545
|
</div>
|
|
542
546
|
<h2 className="text-2xl font-semibold tracking-tight text-brand-dark sm:text-3xl">{EMPTY_QUEUE_TITLE}</h2>
|
|
543
547
|
<p className="mx-auto mt-4 max-w-lg text-[15px] leading-relaxed text-muted-foreground">
|
|
544
|
-
Guard is still watching your apps.
|
|
548
|
+
Guard is still watching your apps.
|
|
545
549
|
</p>
|
|
546
550
|
|
|
547
551
|
<div className="mt-12 text-left w-full max-w-3xl">
|
|
@@ -131,12 +131,12 @@ export function buildPauseLine(item: GuardApprovalRequest): string {
|
|
|
131
131
|
|
|
132
132
|
export function buildRecommendation(item: GuardApprovalRequest): string {
|
|
133
133
|
if (item.changed_fields.length === 1 && item.changed_fields[0] === "first_seen") {
|
|
134
|
-
return "If this is what you expected, approve
|
|
134
|
+
return "If this is what you expected, approve this retry. Project approval remembers this same action here without trusting new sensitive actions.";
|
|
135
135
|
}
|
|
136
136
|
if (item.policy_action === "block") {
|
|
137
137
|
return "Keep it blocked unless you are sure this action is safe and expected.";
|
|
138
138
|
}
|
|
139
|
-
return "Approve the smallest choice that matches what you meant to do.
|
|
139
|
+
return "Approve the smallest choice that matches what you meant to do. Different commands, prompts, paths, hosts, or tools should ask again.";
|
|
140
140
|
}
|
|
141
141
|
|
|
142
142
|
export function buildQueueSummary(item: GuardApprovalRequest): string {
|
|
@@ -162,9 +162,9 @@ export function buildMemorySummary(
|
|
|
162
162
|
export function scopeLabel(scope: string): string {
|
|
163
163
|
switch (scope) {
|
|
164
164
|
case "artifact":
|
|
165
|
-
return "This
|
|
165
|
+
return "This retry only";
|
|
166
166
|
case "workspace":
|
|
167
|
-
return "
|
|
167
|
+
return "Same action in this project";
|
|
168
168
|
case "publisher":
|
|
169
169
|
return "This source in this app";
|
|
170
170
|
case "harness":
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
HiMiniCheckCircle,
|
|
5
5
|
HiMiniExclamationCircle,
|
|
6
6
|
HiMiniMinusCircle,
|
|
7
|
+
HiMiniArrowTopRightOnSquare,
|
|
7
8
|
} from "react-icons/hi2";
|
|
8
9
|
import {
|
|
9
10
|
ActionButton,
|
|
@@ -50,6 +51,55 @@ function heroBackgroundClass(status: HomeProtectionStatus): string {
|
|
|
50
51
|
return "bg-[radial-gradient(circle_at_top_left,rgba(85,153,254,0.12),transparent_32%),linear-gradient(135deg,#ffffff_0%,#ffffff_58%,rgba(72,223,123,0.10)_100%)]";
|
|
51
52
|
}
|
|
52
53
|
|
|
54
|
+
const KNOWN_HARNESSES = [
|
|
55
|
+
"codex",
|
|
56
|
+
"claude-code",
|
|
57
|
+
"opencode",
|
|
58
|
+
"copilot",
|
|
59
|
+
"gemini",
|
|
60
|
+
"cursor",
|
|
61
|
+
"hermes",
|
|
62
|
+
"openclaw",
|
|
63
|
+
] as const;
|
|
64
|
+
|
|
65
|
+
type SetupSuggestionRowProps = {
|
|
66
|
+
harness: string;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
function SetupSuggestionRow(props: SetupSuggestionRowProps) {
|
|
70
|
+
return (
|
|
71
|
+
<li className="flex items-center justify-between gap-3 border-b border-slate-200/70 px-4 py-3 last:border-b-0">
|
|
72
|
+
<p className="text-sm text-brand-dark">
|
|
73
|
+
Set up <span className="font-medium">{harnessDisplayName(props.harness)}</span> →{" "}
|
|
74
|
+
<span className="font-mono text-xs text-brand-blue">
|
|
75
|
+
hol-guard apps connect {props.harness}
|
|
76
|
+
</span>
|
|
77
|
+
</p>
|
|
78
|
+
</li>
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
type SetupSuggestionsSectionProps = {
|
|
83
|
+
configuredHarnesses: string[];
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
function SetupSuggestionsSection(props: SetupSuggestionsSectionProps) {
|
|
87
|
+
const unconfigured = KNOWN_HARNESSES.filter(
|
|
88
|
+
(h) => !props.configuredHarnesses.includes(h)
|
|
89
|
+
);
|
|
90
|
+
if (unconfigured.length === 0) return null;
|
|
91
|
+
return (
|
|
92
|
+
<section className="rounded-[1.75rem] border border-slate-200/70 bg-white/80 p-5 shadow-sm sm:p-6">
|
|
93
|
+
<SectionLabel>Connect more apps</SectionLabel>
|
|
94
|
+
<ul className="mt-3 overflow-hidden rounded-[1.25rem] border border-slate-200/70">
|
|
95
|
+
{unconfigured.slice(0, 4).map((harness) => (
|
|
96
|
+
<SetupSuggestionRow key={harness} harness={harness} />
|
|
97
|
+
))}
|
|
98
|
+
</ul>
|
|
99
|
+
</section>
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
|
|
53
103
|
function ClearHarnessButton(props: {
|
|
54
104
|
harness: string;
|
|
55
105
|
onClearPolicies: (scope: { harness?: string; all?: boolean }) => Promise<void>;
|
|
@@ -126,8 +176,6 @@ export function HomeWorkspace(props: {
|
|
|
126
176
|
cloudState={snapshot.cloud_state}
|
|
127
177
|
connectUrl={snapshot.connect_url}
|
|
128
178
|
fleetUrl={snapshot.fleet_url}
|
|
129
|
-
activeInstallsCount={activeInstalls.length}
|
|
130
|
-
latestReceiptsCount={snapshot.latest_receipts.length}
|
|
131
179
|
onOpenInbox={props.onOpenInbox}
|
|
132
180
|
onOpenFleet={props.onOpenFleet}
|
|
133
181
|
/>
|
|
@@ -145,6 +193,10 @@ export function HomeWorkspace(props: {
|
|
|
145
193
|
observedHarnesses={observedHarnesses}
|
|
146
194
|
/>
|
|
147
195
|
|
|
196
|
+
{primaryState.status === "setup_needed" && (
|
|
197
|
+
<SetupSuggestionsSection configuredHarnesses={observedHarnesses} />
|
|
198
|
+
)}
|
|
199
|
+
|
|
148
200
|
{snapshot.latest_receipts.length > 0 && (
|
|
149
201
|
<RecentProtectionSection receipts={snapshot.latest_receipts} />
|
|
150
202
|
)}
|
|
@@ -185,8 +237,6 @@ function ProtectionHero(props: {
|
|
|
185
237
|
cloudState: "local_only" | "paired_waiting" | "paired_active";
|
|
186
238
|
connectUrl: string;
|
|
187
239
|
fleetUrl: string;
|
|
188
|
-
activeInstallsCount: number;
|
|
189
|
-
latestReceiptsCount: number;
|
|
190
240
|
onOpenInbox: () => void;
|
|
191
241
|
onOpenFleet: () => void;
|
|
192
242
|
}) {
|
|
@@ -211,34 +261,43 @@ function ProtectionHero(props: {
|
|
|
211
261
|
const showConnectCta =
|
|
212
262
|
props.cloudState === "local_only" && !props.syncConfigured;
|
|
213
263
|
|
|
214
|
-
const
|
|
215
|
-
props.activeInstallsCount > 0 && props.latestReceiptsCount === 0;
|
|
264
|
+
const showGuardCloud = props.cloudState !== "local_only";
|
|
216
265
|
|
|
217
266
|
return (
|
|
218
267
|
<section
|
|
219
268
|
className={`guard-surface-in relative overflow-hidden rounded-[2rem] border border-brand-blue/15 ${heroBg} p-5 shadow-[0_20px_60px_rgba(63,65,116,0.08)] sm:p-6 lg:p-7`}
|
|
269
|
+
role="region"
|
|
270
|
+
aria-label="Protection status"
|
|
220
271
|
>
|
|
221
272
|
<div className="pointer-events-none absolute right-10 top-8 h-24 w-24 rounded-full bg-brand-blue/20 blur-3xl" />
|
|
222
273
|
<div className="relative space-y-4">
|
|
223
274
|
<div className="flex flex-wrap items-center gap-2">
|
|
224
275
|
<SectionLabel>Protection status</SectionLabel>
|
|
225
276
|
{statusBadge}
|
|
226
|
-
{props.cloudState !== "local_only" && <Tag tone="blue">Cloud
|
|
277
|
+
{props.cloudState !== "local_only" && <Tag tone="blue">Cloud backup up to date</Tag>}
|
|
227
278
|
</div>
|
|
228
279
|
<h2 className="text-xl font-semibold tracking-tight text-brand-dark">{props.copy}</h2>
|
|
229
280
|
<div className="flex flex-wrap gap-3">
|
|
230
|
-
<ActionButton onClick={handlePrimaryCta}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
Test protection
|
|
234
|
-
</ActionButton>
|
|
235
|
-
)}
|
|
281
|
+
<ActionButton onClick={handlePrimaryCta} data-primary="true" aria-label={props.ctaLabel}>
|
|
282
|
+
{props.ctaLabel}
|
|
283
|
+
</ActionButton>
|
|
236
284
|
{showConnectCta && props.status !== "needs_decision" && (
|
|
237
285
|
<ActionButton href={props.connectUrl} variant="secondary">
|
|
238
286
|
Connect this machine
|
|
239
287
|
</ActionButton>
|
|
240
288
|
)}
|
|
241
289
|
</div>
|
|
290
|
+
{showGuardCloud && (
|
|
291
|
+
<a
|
|
292
|
+
href={props.fleetUrl}
|
|
293
|
+
target="_blank"
|
|
294
|
+
rel="noreferrer"
|
|
295
|
+
className="inline-flex items-center gap-1 text-sm font-medium text-brand-blue transition-colors hover:text-brand-blue/70"
|
|
296
|
+
>
|
|
297
|
+
Open Guard Cloud
|
|
298
|
+
<HiMiniArrowTopRightOnSquare className="h-3.5 w-3.5" aria-hidden="true" />
|
|
299
|
+
</a>
|
|
300
|
+
)}
|
|
242
301
|
</div>
|
|
243
302
|
</section>
|
|
244
303
|
);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { useRef, useCallback } from "react";
|
|
1
2
|
import type { GuardApprovalRequest, GuardQueueResolutionResult } from "./guard-types";
|
|
2
3
|
|
|
3
4
|
export type QueueSortDirection = "newest" | "oldest";
|
|
@@ -163,6 +164,29 @@ export function resolveStaleRequestRecovery(
|
|
|
163
164
|
return items[0]?.request_id ?? null;
|
|
164
165
|
}
|
|
165
166
|
|
|
167
|
+
export type IsResolvingGuard = {
|
|
168
|
+
isResolvingRef: React.RefObject<boolean>;
|
|
169
|
+
setResolving: (value: boolean) => void;
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
export function useIsResolving(): IsResolvingGuard {
|
|
173
|
+
const isResolvingRef = useRef(false);
|
|
174
|
+
const setResolving = useCallback((value: boolean) => {
|
|
175
|
+
isResolvingRef.current = value;
|
|
176
|
+
}, []);
|
|
177
|
+
return { isResolvingRef, setResolving };
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export function buildNextUpChipText(item: GuardApprovalRequest): string {
|
|
181
|
+
const envelope = item.action_envelope_json;
|
|
182
|
+
const preview =
|
|
183
|
+
envelope?.command?.slice(0, 40) ??
|
|
184
|
+
envelope?.mcp_tool ??
|
|
185
|
+
envelope?.prompt_excerpt?.slice(0, 40) ??
|
|
186
|
+
item.artifact_type;
|
|
187
|
+
return `${item.harness} — ${preview}`;
|
|
188
|
+
}
|
|
189
|
+
|
|
166
190
|
export function buildHomePrimaryState(
|
|
167
191
|
pendingCount: number,
|
|
168
192
|
watchedAppsCount: number
|
|
@@ -120,7 +120,9 @@ function cloudSyncHealthTone(state: GuardCloudSyncHealth["state"]): "blue" | "sl
|
|
|
120
120
|
|
|
121
121
|
function humanizeCloudSyncHealthLabel(label: string): string {
|
|
122
122
|
const labels: Record<string, string> = {
|
|
123
|
-
"Cloud sync stale": "
|
|
123
|
+
"Cloud sync stale": "Cloud backup is out of date",
|
|
124
|
+
"Cloud sync healthy": "Cloud backup up to date",
|
|
125
|
+
"First shared proof": "First cloud backup",
|
|
124
126
|
};
|
|
125
127
|
return labels[label] ?? label;
|
|
126
128
|
}
|
|
@@ -131,7 +133,7 @@ function CloudSyncHealthCard(props: { health: GuardCloudSyncHealth }) {
|
|
|
131
133
|
<div className="rounded-xl border border-border bg-white px-5 py-4">
|
|
132
134
|
<div className="flex flex-wrap items-center justify-between gap-2">
|
|
133
135
|
<p className="text-xs font-semibold uppercase tracking-[0.18em] text-brand-blue">
|
|
134
|
-
|
|
136
|
+
Guard cloud backup
|
|
135
137
|
</p>
|
|
136
138
|
<Tag tone={cloudSyncHealthTone(props.health.state)}>{humanizeCloudSyncHealthLabel(copy.label)}</Tag>
|
|
137
139
|
</div>
|
|
@@ -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.169"
|
|
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.169"
|
|
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.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/approvals.py
RENAMED
|
@@ -23,6 +23,13 @@ GUARD_DASHBOARD_URL = "https://hol.org/guard"
|
|
|
23
23
|
GUARD_INBOX_URL = f"{GUARD_DASHBOARD_URL}/inbox"
|
|
24
24
|
GUARD_FLEET_URL = f"{GUARD_DASHBOARD_URL}/fleet"
|
|
25
25
|
GUARD_CONNECT_URL = f"{GUARD_DASHBOARD_URL}/connect"
|
|
26
|
+
_WORKSPACE_SCOPED_RUNTIME_ARTIFACT_TYPES = frozenset(
|
|
27
|
+
{
|
|
28
|
+
"file_read_request",
|
|
29
|
+
"prompt_request",
|
|
30
|
+
"tool_action_request",
|
|
31
|
+
}
|
|
32
|
+
)
|
|
26
33
|
|
|
27
34
|
|
|
28
35
|
class ApprovalRequestNotFoundError(ValueError):
|
|
@@ -133,12 +140,13 @@ def apply_approval_resolution(
|
|
|
133
140
|
raise ValueError(f"Approval request {request_id} requires --workspace for workspace scope.")
|
|
134
141
|
if scope == "publisher" and not isinstance(request.get("publisher"), str):
|
|
135
142
|
raise ValueError(f"Approval request {request_id} has no publisher scope to approve.")
|
|
143
|
+
workspace_artifact_id, workspace_artifact_hash = _workspace_policy_artifact_keys(request, scope)
|
|
136
144
|
decision = PolicyDecision(
|
|
137
145
|
harness="*" if scope == "global" else str(request["harness"]),
|
|
138
146
|
scope=scope,
|
|
139
147
|
action="allow" if action == "allow" else "block",
|
|
140
|
-
artifact_id=str(request["artifact_id"]) if scope == "artifact" else
|
|
141
|
-
artifact_hash=str(request["artifact_hash"]) if scope == "artifact" else
|
|
148
|
+
artifact_id=str(request["artifact_id"]) if scope == "artifact" else workspace_artifact_id,
|
|
149
|
+
artifact_hash=str(request["artifact_hash"]) if scope == "artifact" else workspace_artifact_hash,
|
|
142
150
|
workspace=workspace if scope == "workspace" else None,
|
|
143
151
|
publisher=str(request["publisher"]) if scope == "publisher" else None,
|
|
144
152
|
reason=reason,
|
|
@@ -164,7 +172,7 @@ def apply_approval_resolution(
|
|
|
164
172
|
resolved_scope_ids = store.resolve_matching_approval_requests(
|
|
165
173
|
harness=resolution_harness,
|
|
166
174
|
scope=scope,
|
|
167
|
-
artifact_id=str(request["artifact_id"]) if scope == "artifact" else
|
|
175
|
+
artifact_id=str(request["artifact_id"]) if scope == "artifact" else workspace_artifact_id,
|
|
168
176
|
workspace=workspace if scope == "workspace" else None,
|
|
169
177
|
publisher=(
|
|
170
178
|
str(request["publisher"])
|
|
@@ -184,7 +192,7 @@ def apply_approval_resolution(
|
|
|
184
192
|
resolved_ids = store.resolve_matching_approval_requests(
|
|
185
193
|
harness=resolution_harness,
|
|
186
194
|
scope=scope,
|
|
187
|
-
artifact_id=str(request["artifact_id"]) if scope == "artifact" else
|
|
195
|
+
artifact_id=str(request["artifact_id"]) if scope == "artifact" else workspace_artifact_id,
|
|
188
196
|
workspace=workspace if scope == "workspace" else None,
|
|
189
197
|
publisher=(
|
|
190
198
|
str(request["publisher"])
|
|
@@ -210,6 +218,18 @@ def apply_approval_resolution(
|
|
|
210
218
|
return updated
|
|
211
219
|
|
|
212
220
|
|
|
221
|
+
def _workspace_policy_artifact_keys(request: Mapping[str, object], scope: str) -> tuple[str | None, str | None]:
|
|
222
|
+
if scope != "workspace" or request.get("artifact_type") not in _WORKSPACE_SCOPED_RUNTIME_ARTIFACT_TYPES:
|
|
223
|
+
return None, None
|
|
224
|
+
artifact_id = request.get("artifact_id")
|
|
225
|
+
artifact_hash = request.get("artifact_hash")
|
|
226
|
+
if not isinstance(artifact_id, str) or not artifact_id:
|
|
227
|
+
return None, None
|
|
228
|
+
if not isinstance(artifact_hash, str) or not artifact_hash:
|
|
229
|
+
return artifact_id, None
|
|
230
|
+
return artifact_id, artifact_hash
|
|
231
|
+
|
|
232
|
+
|
|
213
233
|
def _refresh_queue_result(
|
|
214
234
|
store: GuardStore,
|
|
215
235
|
result: dict[str, object],
|
{plugin_scanner-2.0.168 → plugin_scanner-2.0.169}/src/codex_plugin_scanner/guard/cli/commands.py
RENAMED
|
@@ -3399,6 +3399,13 @@ def _runtime_stored_policy_action(
|
|
|
3399
3399
|
and scope in {"workspace", "publisher", "harness", "global"}
|
|
3400
3400
|
and _runtime_artifact_risk_classes(artifact)
|
|
3401
3401
|
):
|
|
3402
|
+
if scope == "workspace":
|
|
3403
|
+
decision_artifact_id = _optional_string(decision.get("artifact_id"))
|
|
3404
|
+
decision_artifact_hash = _optional_string(decision.get("artifact_hash"))
|
|
3405
|
+
if decision_artifact_id == artifact_id and (
|
|
3406
|
+
decision_artifact_hash is None or decision_artifact_hash == artifact_hash
|
|
3407
|
+
):
|
|
3408
|
+
return action
|
|
3402
3409
|
return None
|
|
3403
3410
|
return action
|
|
3404
3411
|
|