plugin-scanner 2.0.73__tar.gz → 2.0.75__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.73 → plugin_scanner-2.0.75}/PKG-INFO +2 -2
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/docker-requirements.txt +50 -50
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/pyproject.toml +2 -2
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/pyproject.toml.bak +2 -2
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/cli/commands.py +77 -4
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/cli/render.py +9 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/runtime/surface_server.py +7 -2
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/version.py +1 -1
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_guard_cli.py +94 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_guard_surface_server.py +43 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/uv.lock +52 -52
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/.clusterfuzzlite/Dockerfile +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/.clusterfuzzlite/build.sh +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/.clusterfuzzlite/project.yaml +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/.clusterfuzzlite/requirements-atheris.txt +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/.dockerignore +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/.github/CODEOWNERS +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/.github/ISSUE_TEMPLATE/bug-report.yml +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/.github/ISSUE_TEMPLATE/feature-request.yml +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/.github/dependabot.yml +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/.github/workflows/ci.yml +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/.github/workflows/codeql.yml +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/.github/workflows/dependabot-uv-lock.yml +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/.github/workflows/fuzz.yml +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/.github/workflows/harness-smoke.yml +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/.github/workflows/publish.yml +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/.github/workflows/scorecard.yml +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/.gitignore +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/.pre-commit-hooks.yaml +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/CONTRIBUTING.md +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/Dockerfile +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/LICENSE +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/README.md +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/SECURITY.md +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/dashboard/index.html +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/dashboard/package.json +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/dashboard/pnpm-lock.yaml +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/dashboard/public/apple-touch-icon.png +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/dashboard/public/brand/Logo_Icon_Dark.png +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/dashboard/public/brand/Logo_Whole.png +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/dashboard/public/favicon-16x16.png +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/dashboard/public/favicon-32x32.png +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/dashboard/public/favicon.ico +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/dashboard/src/app.tsx +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/dashboard/src/approval-center-layout.tsx +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/dashboard/src/approval-center-primitives.tsx +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/dashboard/src/approval-center-utils.ts +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/dashboard/src/fleet-workspace.tsx +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/dashboard/src/guard-api.ts +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/dashboard/src/guard-demo.ts +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/dashboard/src/guard-types.ts +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/dashboard/src/main.tsx +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/dashboard/src/receipts-workspace.tsx +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/dashboard/src/runtime-overview.tsx +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/dashboard/src/settings-workspace.tsx +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/dashboard/src/styles.css +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/dashboard/src/vite-env.d.ts +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/dashboard/tsconfig.json +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/dashboard/vite.config.ts +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/docs/guard/approval-audit.md +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/docs/guard/architecture.md +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/docs/guard/get-started.md +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/docs/guard/harness-support.md +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/docs/guard/local-vs-cloud.md +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/docs/guard/testing-matrix.md +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/docs/trust/mcp-trust-draft.md +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/docs/trust/plugin-trust-draft.md +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/docs/trust/skill-trust-local.md +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/fuzzers/manifest_fuzzer.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/requirements.txt +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/schemas/plugin-quality.v1.json +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/schemas/scan-result.v1.json +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/schemas/verify-result.v1.json +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/__init__.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/action_runner.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/argparse_utils.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/checks/__init__.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/checks/best_practices.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/checks/claude.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/checks/code_quality.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/checks/ecosystem_common.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/checks/gemini.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/checks/manifest.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/checks/manifest_support.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/checks/marketplace.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/checks/mcp_security.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/checks/opencode.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/checks/operational_security.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/checks/security.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/checks/skill_security.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/cli.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/cli_ui.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/config.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/ecosystems/__init__.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/ecosystems/base.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/ecosystems/claude.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/ecosystems/codex.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/ecosystems/detect.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/ecosystems/gemini.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/ecosystems/opencode.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/ecosystems/registry.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/ecosystems/types.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/github_reporting.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/__init__.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/adapters/__init__.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/adapters/antigravity.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/adapters/base.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/adapters/claude_code.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/adapters/codex.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/adapters/copilot.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/adapters/cursor.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/adapters/gemini.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/adapters/hermes.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/adapters/mcp_servers.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/adapters/opencode.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/adapters/opencode_artifacts.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/approvals.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/bridge/__init__.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/capabilities.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/cli/__init__.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/cli/approval_commands.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/cli/bootstrap.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/cli/connect_flow.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/cli/install_commands.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/cli/product.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/cli/prompt.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/cli/update_commands.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/codex_config.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/config.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/consumer/__init__.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/consumer/service.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/daemon/__init__.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/daemon/client.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/daemon/manager.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/daemon/server.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/daemon/static/apple-touch-icon.png +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/daemon/static/assets/guard-dashboard.js +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/daemon/static/assets/index.css +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/daemon/static/brand/Logo_Icon_Dark.png +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/daemon/static/brand/Logo_Whole.png +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/daemon/static/favicon-16x16.png +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/daemon/static/favicon-32x32.png +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/daemon/static/favicon.ico +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/daemon/static/index.html +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/edge_events.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/incident.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/launcher.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/mcp_tool_calls.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/models.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/policy/__init__.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/policy/engine.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/protect.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/proxy/__init__.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/proxy/remote.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/proxy/runtime_mcp.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/proxy/stdio.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/receipts/__init__.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/receipts/manager.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/risk.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/runtime/__init__.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/runtime/runner.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/runtime/secret_file_requests.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/schemas/__init__.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/schemas/consumer_mode.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/schemas/guard_event_v1.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/schemas/surface_server.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/shims.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/store.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/store_approvals.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/store_connect.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/types.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/integrations/__init__.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/integrations/cisco_mcp_scanner.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/integrations/cisco_skill_scanner.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/lint_fixes.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/marketplace_support.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/models.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/path_support.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/policy.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/quality_artifact.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/repo_detect.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/reporting.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/rules/__init__.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/rules/registry.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/rules/specs.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/scanner.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/submission.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/suppressions.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/trust_domain_scoring.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/trust_helpers.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/trust_mcp_scoring.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/trust_models.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/trust_plugin_scoring.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/trust_scoring.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/trust_skill_scoring.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/trust_specs.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/verification.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/__init__.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/conftest.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/__init__.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/bad-plugin/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/bad-plugin/.mcp.json +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/bad-plugin/secrets.js +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/claude-plugin-good/.claude-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/claude-plugin-good/LICENSE +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/claude-plugin-good/README.md +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/claude-plugin-good/SECURITY.md +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/claude-plugin-good/hooks/hooks.json +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/claude-plugin-good/skills/example/SKILL.md +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/code-quality-bad/evil.js +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/code-quality-bad/inject.js +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/gemini-extension-good/GEMINI.md +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/gemini-extension-good/LICENSE +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/gemini-extension-good/README.md +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/gemini-extension-good/SECURITY.md +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/gemini-extension-good/commands/hello.toml +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/gemini-extension-good/gemini-extension.json +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/good-plugin/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/good-plugin/.codexignore +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/good-plugin/LICENSE +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/good-plugin/README.md +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/good-plugin/SECURITY.md +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/good-plugin/assets/icon.svg +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/good-plugin/assets/logo.svg +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/good-plugin/assets/screenshot.svg +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/good-plugin/skills/example/SKILL.md +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/guard-codex-malicious-mcp/.codex/config.toml +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/hermes-plugin-evil/config.yaml +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/hermes-plugin-evil/mcp_servers.json +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/hermes-plugin-evil/skills/security/malicious/SKILL.md +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/hermes-plugin-evil/skills/stealth/sneaky/SKILL.md +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/hermes-plugin-evil/skills/stealth/sneaky/references/api-setup.md +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/hermes-plugin-evil/skills/stealth/sneaky/scripts/deploy.sh +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/hermes-plugin-evil/skills/utils/benign/SKILL.md +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/malformed-json/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/malicious-skill-plugin/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/malicious-skill-plugin/.codexignore +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/malicious-skill-plugin/LICENSE +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/malicious-skill-plugin/README.md +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/malicious-skill-plugin/SECURITY.md +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/malicious-skill-plugin/skills/leaky-skill/SKILL.md +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/mcp-canary-server.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/minimal-plugin/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/missing-fields/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/mit-license/LICENSE +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/multi-ecosystem-repo/codex-plugin/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/multi-ecosystem-repo/codex-plugin/LICENSE +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/multi-ecosystem-repo/codex-plugin/README.md +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/multi-ecosystem-repo/codex-plugin/SECURITY.md +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/multi-ecosystem-repo/gemini-ext/README.md +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/multi-ecosystem-repo/gemini-ext/gemini-extension.json +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/multi-plugin-repo/.agents/plugins/marketplace.json +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/.codexignore +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/LICENSE +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/README.md +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/SECURITY.md +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/skills/example/SKILL.md +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/multi-plugin-repo/plugins/beta-plugin/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/multi-plugin-repo/plugins/beta-plugin/skills/example/SKILL.md +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/no-version/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/opencode-good/.opencode/commands/hello.md +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/opencode-good/.opencode/plugins/example.ts +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/opencode-good/LICENSE +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/opencode-good/README.md +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/opencode-good/SECURITY.md +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/opencode-good/opencode.jsonc +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/skills-missing-dir/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/skills-no-frontmatter/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/skills-no-frontmatter/skills/bad-skill/SKILL.md +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/with-marketplace/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/with-marketplace/marketplace-broken.json +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/fixtures/with-marketplace/marketplace.json +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test-trust-scoring.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test-trust-specs.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_action_runner.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_best_practices.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_cisco_install_surfaces.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_cli.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_code_quality.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_config.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_coverage_remaining.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_ecosystems.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_edge_cases.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_final_coverage.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_guard_approvals.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_guard_bootstrap.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_guard_capabilities.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_guard_claude_adapter.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_guard_codex_e2e.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_guard_codex_install.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_guard_codex_proxy.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_guard_config_paths.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_guard_connect_flow.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_guard_consumer_mode.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_guard_copilot_adapter.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_guard_copilot_proxy.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_guard_daemon_manager.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_guard_event_schema_v1.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_guard_events.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_guard_launch_env.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_guard_opencode_proxy.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_guard_product_flow.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_guard_protect.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_guard_render.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_guard_risk.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_guard_runtime.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_guard_store_migrations.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_guard_verdicts.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_hermes_adapter.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_integration.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_lint_fixes.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_live_cisco_smoke.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_manifest.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_marketplace.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_mcp_security.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_operational_security.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_policy.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_quality_artifact.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_rule_registry.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_scanner.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_schema_contracts.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_security.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_security_ops.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_skill_security.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_submission.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_trust_scoring.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_trust_specs.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_verification.py +0 -0
- {plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/tests/test_versioning.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: plugin-scanner
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.75
|
|
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
|
|
@@ -22,7 +22,7 @@ Classifier: Topic :: Security
|
|
|
22
22
|
Classifier: Topic :: Software Development :: Quality Assurance
|
|
23
23
|
Requires-Python: >=3.10
|
|
24
24
|
Requires-Dist: cisco-ai-skill-scanner~=2.0.9
|
|
25
|
-
Requires-Dist: cryptography>=
|
|
25
|
+
Requires-Dist: cryptography>=47.0.0
|
|
26
26
|
Requires-Dist: rich>=13.0
|
|
27
27
|
Requires-Dist: tomli>=2.0; python_version < '3.11'
|
|
28
28
|
Provides-Extra: cisco
|
|
@@ -366,56 +366,56 @@ confusable-homoglyphs==3.3.1 \
|
|
|
366
366
|
--hash=sha256:84c92cb79dc7f55aa290d0762b2349abd8dee4c16fbe6f99eac978d394e2e6a1 \
|
|
367
367
|
--hash=sha256:b995001c9b2e1b4cea0cf5f3840a7c79188a8cbbad053d693572bd8c1c1ec460
|
|
368
368
|
# via cisco-ai-skill-scanner
|
|
369
|
-
cryptography==
|
|
370
|
-
--hash=sha256:
|
|
371
|
-
--hash=sha256:
|
|
372
|
-
--hash=sha256:
|
|
373
|
-
--hash=sha256:
|
|
374
|
-
--hash=sha256:
|
|
375
|
-
--hash=sha256:
|
|
376
|
-
--hash=sha256:
|
|
377
|
-
--hash=sha256:
|
|
378
|
-
--hash=sha256:
|
|
379
|
-
--hash=sha256:
|
|
380
|
-
--hash=sha256:
|
|
381
|
-
--hash=sha256:
|
|
382
|
-
--hash=sha256:
|
|
383
|
-
--hash=sha256:
|
|
384
|
-
--hash=sha256:
|
|
385
|
-
--hash=sha256:
|
|
386
|
-
--hash=sha256:
|
|
387
|
-
--hash=sha256:
|
|
388
|
-
--hash=sha256:
|
|
389
|
-
--hash=sha256:
|
|
390
|
-
--hash=sha256:
|
|
391
|
-
--hash=sha256:
|
|
392
|
-
--hash=sha256:
|
|
393
|
-
--hash=sha256:
|
|
394
|
-
--hash=sha256:
|
|
395
|
-
--hash=sha256:
|
|
396
|
-
--hash=sha256:
|
|
397
|
-
--hash=sha256:
|
|
398
|
-
--hash=sha256:
|
|
399
|
-
--hash=sha256:
|
|
400
|
-
--hash=sha256:
|
|
401
|
-
--hash=sha256:
|
|
402
|
-
--hash=sha256:
|
|
403
|
-
--hash=sha256:
|
|
404
|
-
--hash=sha256:
|
|
405
|
-
--hash=sha256:
|
|
406
|
-
--hash=sha256:
|
|
407
|
-
--hash=sha256:
|
|
408
|
-
--hash=sha256:
|
|
409
|
-
--hash=sha256:
|
|
410
|
-
--hash=sha256:
|
|
411
|
-
--hash=sha256:
|
|
412
|
-
--hash=sha256:
|
|
413
|
-
--hash=sha256:
|
|
414
|
-
--hash=sha256:
|
|
415
|
-
--hash=sha256:
|
|
416
|
-
--hash=sha256:
|
|
417
|
-
--hash=sha256:
|
|
418
|
-
--hash=sha256:
|
|
369
|
+
cryptography==47.0.0 \
|
|
370
|
+
--hash=sha256:0024b87d47ae2399165a6bfb20d24888881eeab83ae2566d62467c5ff0030ce7 \
|
|
371
|
+
--hash=sha256:07efe86201817e7d3c18781ca9770bc0db04e1e48c994be384e4602bc38f8f27 \
|
|
372
|
+
--hash=sha256:09f6d7bf6724f8db8b32f11eccf23efc8e759924bc5603800335cf8859a3ddbd \
|
|
373
|
+
--hash=sha256:11438c7518132d95f354fa01a4aa2f806d172a061a7bed18cf18cbdacdb204d7 \
|
|
374
|
+
--hash=sha256:11dbb9f50a0f1bb9757b3d8c27c1101780efb8f0bdecfb12439c22a74d64c001 \
|
|
375
|
+
--hash=sha256:14432c8a9bcb37009784f9594a62fae211a2ae9543e96c92b2a8e4c3cd5cd0c4 \
|
|
376
|
+
--hash=sha256:1581aef4219f7ca2849d0250edaa3866212fb74bf5667284f46aa92f9e65c1ca \
|
|
377
|
+
--hash=sha256:160ad728f128972d362e714054f6ba0067cab7fb350c5202a9ae8ae4ce3ef1a0 \
|
|
378
|
+
--hash=sha256:1a405c08857258c11016777e11c02bacbe7ef596faf259305d282272a3a05cbe \
|
|
379
|
+
--hash=sha256:1e47422b5557bb82d3fff997e8d92cff4e28b9789576984f08c248d2b3535d93 \
|
|
380
|
+
--hash=sha256:20fdbe3e38fb67c385d233c89371fa27f9909f6ebca1cecc20c13518dae65475 \
|
|
381
|
+
--hash=sha256:2207a498b03275d0051589e326b79d4cf59985c99031b05bb292ac52631c37fe \
|
|
382
|
+
--hash=sha256:256d07c78a04d6b276f5df935a9923275f53bd1522f214447fdf365494e2d515 \
|
|
383
|
+
--hash=sha256:2b45761c6ec22b7c726d6a829558777e32d0f1c8be7c3f3480f9c912d5ee8a10 \
|
|
384
|
+
--hash=sha256:2ebd84adf0728c039a3be2700289378e1c164afc6748df1a5ed456767bef9ba7 \
|
|
385
|
+
--hash=sha256:34b4358b925a5ea3e14384ca781a2c0ef7ac219b57bb9eacc4457078e2b19f92 \
|
|
386
|
+
--hash=sha256:3fb8fa48075fad7193f2e5496135c6a76ac4b2aa5a38433df0a539296b377829 \
|
|
387
|
+
--hash=sha256:4e1de79e047e25d6e9f8cea71c86b4a53aced64134f0f003bbcbf3655fd172c8 \
|
|
388
|
+
--hash=sha256:4f7722c97826770bab8ae92959a2e7b20a5e9e9bf4deae68fd86c3ca457bab52 \
|
|
389
|
+
--hash=sha256:51c9313e90bd1690ec5a75ed047c27c0b8e6c570029712943d6116ef9a90620b \
|
|
390
|
+
--hash=sha256:5d0e362ff51041b0c0d219cc7d6924d7b8996f57ce5712bdcef71eb3c65a59cc \
|
|
391
|
+
--hash=sha256:6651d32eff255423503aa276739da98c30f26c40cbeffcc6048e0d54ef704c0c \
|
|
392
|
+
--hash=sha256:6eebcaf0df1d21ce1f90605c9b432dd2c4f4ab665ac29a40d5e3fc68f51b5e63 \
|
|
393
|
+
--hash=sha256:6f29f36582e6151d9686235e586dd35bb67491f024767d10b842e520dc6a07ac \
|
|
394
|
+
--hash=sha256:7a02675e2fabd0c0fc04c868b8781863cbf1967691543c22f5470500ff840b31 \
|
|
395
|
+
--hash=sha256:7f1207974a904e005f762869996cf620e9bf79ecb4622f148550bb48e0eb35a7 \
|
|
396
|
+
--hash=sha256:7f68d6fbc7fbbcfb0939fea72c3b96a9f9a6edfc0e1b1d29778a2066030418b1 \
|
|
397
|
+
--hash=sha256:7fda2f02c9015db3f42bb8a22324a454516ed10a8c29ca6ece6cdbb5efe2a203 \
|
|
398
|
+
--hash=sha256:80887c5cbd1774683cb126f0ab4184567f080071d5acf62205acb354b4b753b7 \
|
|
399
|
+
--hash=sha256:835d2d7f47cdc53b3224e90810fb1d36ca94ea29cc1801fb4c1bc43876735769 \
|
|
400
|
+
--hash=sha256:8c1a736bbb3288005796c3f7ccb9453360d7fed483b13b9f468aea5171432923 \
|
|
401
|
+
--hash=sha256:9af828c0d5a65c70ec729cd7495a4bf1a67ecb66417b8f02ff125ab8a6326a74 \
|
|
402
|
+
--hash=sha256:9c59ab0e0fa3a180a5a9c59f3a5abe3ef90d474bc56d7fadfbe80359491b615b \
|
|
403
|
+
--hash=sha256:9f8e55fe4e63613a5e1cc5819030f27b97742d720203a087802ce4ce9ceb52bb \
|
|
404
|
+
--hash=sha256:9fe6b7c64926c765f9dff301f9c1b867febcda5768868ca084e18589113732ab \
|
|
405
|
+
--hash=sha256:a49a3eb5341b9503fa3000a9a0db033161db90d47285291f53c2a9d2cd1b7f76 \
|
|
406
|
+
--hash=sha256:a9b761f012a943b7de0e828843c5688d0de94a0578d44d6c85a1bae32f87791f \
|
|
407
|
+
--hash=sha256:b1c76fca783aa7698eb21eb14f9c4aa09452248ee54a627d125025a43f83e7a7 \
|
|
408
|
+
--hash=sha256:b9a8943e359b7615db1a3ba587994618e094ff3d6fa5a390c73d079ce18b3973 \
|
|
409
|
+
--hash=sha256:be12cb6a204f77ed968bcefe68086eb061695b540a3dd05edac507a3111b25f0 \
|
|
410
|
+
--hash=sha256:cffbba3392df0fa8629bb7f43454ee2925059ee158e23c54620b9063912b86c8 \
|
|
411
|
+
--hash=sha256:ed67ea4e0cfb5faa5bc7ecb6e2b8838f3807a03758eec239d6c21c8769355310 \
|
|
412
|
+
--hash=sha256:edd4da498015da5b9f26d38d3bfc2e90257bfa9cbed1f6767c282a0025ae649b \
|
|
413
|
+
--hash=sha256:ef6b3634087f18d2155b1e8ce264e5345a753da2c5fa9815e7d41315c90f8318 \
|
|
414
|
+
--hash=sha256:f1557695e5c2b86e204f6ce9470497848634100787935ab7adc5397c54abd7ab \
|
|
415
|
+
--hash=sha256:f5c15764f261394b22aef6b00252f5195f46f2ca300bec57149474e2538b31f8 \
|
|
416
|
+
--hash=sha256:f5c3296dab66202f1b18a91fa266be93d6aa0c2806ea3d67762c69f60adc71aa \
|
|
417
|
+
--hash=sha256:f7db373287273d8af1414cf95dc4118b13ffdc62be521997b0f2b270771fef50 \
|
|
418
|
+
--hash=sha256:f9a034b642b960767fb343766ae5ba6ad653f2e890ddd82955aef288ffea8736
|
|
419
419
|
# via
|
|
420
420
|
# hol-guard
|
|
421
421
|
# msoffcrypto-tool
|
|
@@ -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.75"
|
|
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"
|
|
@@ -28,7 +28,7 @@ classifiers = [
|
|
|
28
28
|
]
|
|
29
29
|
dependencies = [
|
|
30
30
|
"rich>=13.0",
|
|
31
|
-
"cryptography>=
|
|
31
|
+
"cryptography>=47.0.0",
|
|
32
32
|
"tomli>=2.0; python_version < '3.11'",
|
|
33
33
|
"cisco-ai-skill-scanner~=2.0.9",
|
|
34
34
|
]
|
|
@@ -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.75"
|
|
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"
|
|
@@ -28,7 +28,7 @@ classifiers = [
|
|
|
28
28
|
]
|
|
29
29
|
dependencies = [
|
|
30
30
|
"rich>=13.0",
|
|
31
|
-
"cryptography>=
|
|
31
|
+
"cryptography>=47.0.0",
|
|
32
32
|
"tomli>=2.0; python_version < '3.11'",
|
|
33
33
|
"cisco-ai-skill-scanner~=2.0.9",
|
|
34
34
|
]
|
{plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/cli/commands.py
RENAMED
|
@@ -112,6 +112,7 @@ _GUARD_HELP_GROUPS = (
|
|
|
112
112
|
"Everyday protection:\n"
|
|
113
113
|
" start First-run setup and the Guard operating loop\n"
|
|
114
114
|
" status Current local protection state and next actions\n"
|
|
115
|
+
" dashboard Open the local Guard dashboard in your browser\n"
|
|
115
116
|
" run Enforce Guard before a harness launch\n"
|
|
116
117
|
" approvals Resolve the current request queue\n"
|
|
117
118
|
" receipts Review recent local decisions\n"
|
|
@@ -204,7 +205,7 @@ def _configure_guard_parser(guard_parser: argparse.ArgumentParser) -> None:
|
|
|
204
205
|
required=True,
|
|
205
206
|
parser_class=FriendlyArgumentParser,
|
|
206
207
|
metavar=(
|
|
207
|
-
"{start,status,bootstrap,detect,install,update,uninstall,run,protect,preflight,scan,diff,receipts,inventory,abom,"
|
|
208
|
+
"{start,status,dashboard,bootstrap,detect,install,update,uninstall,run,protect,preflight,scan,diff,receipts,inventory,abom,"
|
|
208
209
|
"approvals,explain,allow,deny,policies,exceptions,advisories,events,doctor,connect,login,sync,device,bridge}"
|
|
209
210
|
),
|
|
210
211
|
)
|
|
@@ -217,6 +218,17 @@ def _configure_guard_parser(guard_parser: argparse.ArgumentParser) -> None:
|
|
|
217
218
|
_add_guard_common_args(status_parser)
|
|
218
219
|
status_parser.add_argument("--json", action="store_true")
|
|
219
220
|
|
|
221
|
+
dashboard_parser = guard_subparsers.add_parser(
|
|
222
|
+
"dashboard",
|
|
223
|
+
help="Open the local Guard dashboard in your browser",
|
|
224
|
+
)
|
|
225
|
+
_add_guard_common_args(dashboard_parser)
|
|
226
|
+
dashboard_parser.add_argument("--json", action="store_true")
|
|
227
|
+
|
|
228
|
+
admin_parser = guard_subparsers.add_parser("admin", help=argparse.SUPPRESS)
|
|
229
|
+
_add_guard_common_args(admin_parser)
|
|
230
|
+
admin_parser.add_argument("--json", action="store_true")
|
|
231
|
+
|
|
220
232
|
bootstrap_parser = guard_subparsers.add_parser(
|
|
221
233
|
"bootstrap",
|
|
222
234
|
help="Detect a harness, start the approval center, and install Guard for the best local target",
|
|
@@ -513,6 +525,7 @@ def _configure_guard_parser(guard_parser: argparse.ArgumentParser) -> None:
|
|
|
513
525
|
hermes_mcp_proxy_parser.add_argument("--server", required=True)
|
|
514
526
|
hermes_mcp_proxy_parser.add_argument("--stdio", action="store_true")
|
|
515
527
|
hidden_commands = {
|
|
528
|
+
"admin",
|
|
516
529
|
"hook",
|
|
517
530
|
"daemon",
|
|
518
531
|
"codex-mcp-proxy",
|
|
@@ -660,6 +673,43 @@ def run_guard_command(
|
|
|
660
673
|
_emit("status", payload, getattr(args, "json", False))
|
|
661
674
|
return 0
|
|
662
675
|
|
|
676
|
+
if args.guard_command in {"dashboard", "admin"}:
|
|
677
|
+
try:
|
|
678
|
+
approval_center_url = ensure_guard_daemon(guard_home)
|
|
679
|
+
except RuntimeError as error:
|
|
680
|
+
if getattr(args, "json", False):
|
|
681
|
+
_emit(
|
|
682
|
+
"dashboard",
|
|
683
|
+
{
|
|
684
|
+
"generated_at": _now(),
|
|
685
|
+
"opened": False,
|
|
686
|
+
"error": str(error),
|
|
687
|
+
},
|
|
688
|
+
True,
|
|
689
|
+
)
|
|
690
|
+
else:
|
|
691
|
+
print(str(error), file=sys.stderr)
|
|
692
|
+
return 1
|
|
693
|
+
open_result = _open_approval_center(
|
|
694
|
+
approval_center_url,
|
|
695
|
+
store=store,
|
|
696
|
+
config=config,
|
|
697
|
+
open_key="dashboard",
|
|
698
|
+
force_open=True,
|
|
699
|
+
)
|
|
700
|
+
_emit(
|
|
701
|
+
"dashboard",
|
|
702
|
+
{
|
|
703
|
+
"generated_at": _now(),
|
|
704
|
+
"approval_center_url": approval_center_url,
|
|
705
|
+
"browser_url": open_result.get("browser_url"),
|
|
706
|
+
"opened": bool(open_result.get("opened")),
|
|
707
|
+
"reason": str(open_result.get("reason") or "unknown"),
|
|
708
|
+
},
|
|
709
|
+
getattr(args, "json", False),
|
|
710
|
+
)
|
|
711
|
+
return 0
|
|
712
|
+
|
|
663
713
|
if args.guard_command == "bootstrap":
|
|
664
714
|
try:
|
|
665
715
|
payload = build_guard_bootstrap_payload(
|
|
@@ -3278,17 +3328,28 @@ def _headless_approval_resolver(
|
|
|
3278
3328
|
return resolve
|
|
3279
3329
|
|
|
3280
3330
|
|
|
3281
|
-
def _open_approval_center(
|
|
3331
|
+
def _open_approval_center(
|
|
3332
|
+
approval_center_url: str,
|
|
3333
|
+
*,
|
|
3334
|
+
store: GuardStore,
|
|
3335
|
+
config: GuardConfig,
|
|
3336
|
+
open_key: str | None = None,
|
|
3337
|
+
force_open: bool = False,
|
|
3338
|
+
) -> dict[str, object]:
|
|
3282
3339
|
surface_runtime = GuardSurfaceRuntime(store)
|
|
3283
3340
|
auth_token = load_guard_daemon_auth_token(store.guard_home)
|
|
3284
|
-
|
|
3341
|
+
browser_url = _approval_center_browser_url(approval_center_url, auth_token)
|
|
3342
|
+
open_result = surface_runtime.ensure_surface(
|
|
3285
3343
|
surface="approval-center",
|
|
3286
3344
|
approval_center_url=approval_center_url,
|
|
3287
|
-
browser_url=
|
|
3345
|
+
browser_url=browser_url,
|
|
3288
3346
|
approval_surface_policy=config.approval_surface_policy,
|
|
3289
3347
|
open_key=open_key or approval_center_url,
|
|
3348
|
+
force_open=force_open,
|
|
3290
3349
|
opener=webbrowser.open,
|
|
3291
3350
|
)
|
|
3351
|
+
open_result["browser_url"] = _public_approval_center_url(browser_url) or approval_center_url
|
|
3352
|
+
return open_result
|
|
3292
3353
|
|
|
3293
3354
|
|
|
3294
3355
|
def _approval_center_browser_url(approval_center_url: str, auth_token: str | None) -> str | None:
|
|
@@ -3304,6 +3365,18 @@ def _approval_center_browser_url(approval_center_url: str, auth_token: str | Non
|
|
|
3304
3365
|
return urllib.parse.urlunparse(parsed._replace(fragment=urllib.parse.urlencode(fragment_pairs)))
|
|
3305
3366
|
|
|
3306
3367
|
|
|
3368
|
+
def _public_approval_center_url(browser_url: str | None) -> str | None:
|
|
3369
|
+
if browser_url is None:
|
|
3370
|
+
return None
|
|
3371
|
+
parsed = urllib.parse.urlparse(browser_url)
|
|
3372
|
+
fragment_pairs = [
|
|
3373
|
+
(key, value)
|
|
3374
|
+
for key, value in urllib.parse.parse_qsl(parsed.fragment, keep_blank_values=True)
|
|
3375
|
+
if key != "guard-token"
|
|
3376
|
+
]
|
|
3377
|
+
return urllib.parse.urlunparse(parsed._replace(fragment=urllib.parse.urlencode(fragment_pairs)))
|
|
3378
|
+
|
|
3379
|
+
|
|
3307
3380
|
def _approval_surface_policy_for_flow(config_policy: str, approval_flow: dict[str, object]) -> str:
|
|
3308
3381
|
if approval_flow.get("tier") != "approval-center":
|
|
3309
3382
|
return "notify-only"
|
{plugin_scanner-2.0.73 → plugin_scanner-2.0.75}/src/codex_plugin_scanner/guard/cli/render.py
RENAMED
|
@@ -654,6 +654,14 @@ def _render_connect(console: Console, payload: dict[str, object]) -> None:
|
|
|
654
654
|
console.print(_build_steps_panel(_coerce_dict_list(payload.get("next_steps"))))
|
|
655
655
|
|
|
656
656
|
|
|
657
|
+
def _render_dashboard(console: Console, payload: dict[str, object]) -> None:
|
|
658
|
+
body = Table.grid(padding=(0, 1))
|
|
659
|
+
body.add_row("Dashboard", str(payload.get("approval_center_url") or "unknown"))
|
|
660
|
+
if payload.get("opened") is not None:
|
|
661
|
+
body.add_row("Browser opened", _bool_label(bool(payload.get("opened"))))
|
|
662
|
+
console.print(Panel(body, title="HOL Guard dashboard", border_style="cyan"))
|
|
663
|
+
|
|
664
|
+
|
|
657
665
|
def _render_sync(console: Console, payload: dict[str, object]) -> None:
|
|
658
666
|
body = Table.grid(padding=(0, 1))
|
|
659
667
|
body.add_row("Synced at", str(payload.get("synced_at") or "unknown"))
|
|
@@ -1615,6 +1623,7 @@ _RENDERERS: dict[str, Any] = {
|
|
|
1615
1623
|
"approvals": _render_approvals,
|
|
1616
1624
|
"start": _render_start,
|
|
1617
1625
|
"status": _render_status,
|
|
1626
|
+
"dashboard": _render_dashboard,
|
|
1618
1627
|
"connect": _render_connect,
|
|
1619
1628
|
"bootstrap": _render_bootstrap,
|
|
1620
1629
|
"detect": _render_detect,
|
|
@@ -332,10 +332,15 @@ class GuardSurfaceRuntime:
|
|
|
332
332
|
approval_surface_policy: str,
|
|
333
333
|
open_key: str,
|
|
334
334
|
opener: Callable[[str], object],
|
|
335
|
+
force_open: bool = False,
|
|
335
336
|
) -> dict[str, object]:
|
|
336
|
-
if approval_surface_policy in {"notify-only", "never-auto-open"}:
|
|
337
|
+
if approval_surface_policy in {"notify-only", "never-auto-open"} and not force_open:
|
|
337
338
|
return {"surface": surface, "opened": False, "reason": "policy-disabled", "open_key": open_key}
|
|
338
|
-
if
|
|
339
|
+
if (
|
|
340
|
+
approval_surface_policy == "auto-open-once"
|
|
341
|
+
and not force_open
|
|
342
|
+
and self.has_surface_opened(surface, open_key)
|
|
343
|
+
):
|
|
339
344
|
return {"surface": surface, "opened": False, "reason": "already-opened", "open_key": open_key}
|
|
340
345
|
if self.has_live_surface(surface):
|
|
341
346
|
return {"surface": surface, "opened": False, "reason": "live-client", "open_key": open_key}
|
|
@@ -6048,6 +6048,100 @@ url = http://127.0.0.1:8787/guard-canary
|
|
|
6048
6048
|
assert connect_output["reason"] == "Guard sync requires a Pro or Team plan."
|
|
6049
6049
|
assert connect_output["sync_message"] == "Guard sync requires a Pro or Team plan."
|
|
6050
6050
|
|
|
6051
|
+
def test_guard_dashboard_opens_local_approval_center(self, tmp_path, capsys, monkeypatch):
|
|
6052
|
+
home_dir = tmp_path / "home"
|
|
6053
|
+
opened_urls: list[str] = []
|
|
6054
|
+
open_keys: list[str | None] = []
|
|
6055
|
+
force_open_flags: list[bool] = []
|
|
6056
|
+
|
|
6057
|
+
monkeypatch.setattr(
|
|
6058
|
+
guard_commands_module,
|
|
6059
|
+
"ensure_guard_daemon",
|
|
6060
|
+
lambda guard_home: "http://127.0.0.1:5474",
|
|
6061
|
+
)
|
|
6062
|
+
monkeypatch.setattr(
|
|
6063
|
+
guard_commands_module,
|
|
6064
|
+
"_open_approval_center",
|
|
6065
|
+
lambda approval_center_url, *, store, config, open_key=None, force_open=False: (
|
|
6066
|
+
opened_urls.append(approval_center_url),
|
|
6067
|
+
open_keys.append(open_key),
|
|
6068
|
+
force_open_flags.append(force_open),
|
|
6069
|
+
{"opened": True, "reason": "opened", "browser_url": approval_center_url},
|
|
6070
|
+
)[-1],
|
|
6071
|
+
)
|
|
6072
|
+
|
|
6073
|
+
rc = main(["guard", "dashboard", "--home", str(home_dir), "--json"])
|
|
6074
|
+
output = json.loads(capsys.readouterr().out)
|
|
6075
|
+
|
|
6076
|
+
assert rc == 0
|
|
6077
|
+
assert opened_urls == ["http://127.0.0.1:5474"]
|
|
6078
|
+
assert open_keys == ["dashboard"]
|
|
6079
|
+
assert force_open_flags == [True]
|
|
6080
|
+
assert output["approval_center_url"] == "http://127.0.0.1:5474"
|
|
6081
|
+
assert output["browser_url"] == "http://127.0.0.1:5474"
|
|
6082
|
+
assert output["opened"] is True
|
|
6083
|
+
assert output["reason"] == "opened"
|
|
6084
|
+
|
|
6085
|
+
def test_guard_admin_alias_opens_local_approval_center(self, tmp_path, capsys, monkeypatch):
|
|
6086
|
+
home_dir = tmp_path / "home"
|
|
6087
|
+
opened_urls: list[str] = []
|
|
6088
|
+
open_keys: list[str | None] = []
|
|
6089
|
+
force_open_flags: list[bool] = []
|
|
6090
|
+
|
|
6091
|
+
monkeypatch.setattr(
|
|
6092
|
+
guard_commands_module,
|
|
6093
|
+
"ensure_guard_daemon",
|
|
6094
|
+
lambda guard_home: "http://127.0.0.1:5474",
|
|
6095
|
+
)
|
|
6096
|
+
monkeypatch.setattr(
|
|
6097
|
+
guard_commands_module,
|
|
6098
|
+
"_open_approval_center",
|
|
6099
|
+
lambda approval_center_url, *, store, config, open_key=None, force_open=False: (
|
|
6100
|
+
opened_urls.append(approval_center_url),
|
|
6101
|
+
open_keys.append(open_key),
|
|
6102
|
+
force_open_flags.append(force_open),
|
|
6103
|
+
{"opened": False, "reason": "policy-disabled", "browser_url": approval_center_url},
|
|
6104
|
+
)[-1],
|
|
6105
|
+
)
|
|
6106
|
+
|
|
6107
|
+
rc = main(["guard", "admin", "--home", str(home_dir), "--json"])
|
|
6108
|
+
output = json.loads(capsys.readouterr().out)
|
|
6109
|
+
|
|
6110
|
+
assert rc == 0
|
|
6111
|
+
assert opened_urls == ["http://127.0.0.1:5474"]
|
|
6112
|
+
assert open_keys == ["dashboard"]
|
|
6113
|
+
assert force_open_flags == [True]
|
|
6114
|
+
assert output["approval_center_url"] == "http://127.0.0.1:5474"
|
|
6115
|
+
assert output["browser_url"] == "http://127.0.0.1:5474"
|
|
6116
|
+
assert output["opened"] is False
|
|
6117
|
+
assert output["reason"] == "policy-disabled"
|
|
6118
|
+
|
|
6119
|
+
def test_guard_dashboard_returns_error_when_daemon_start_fails(self, tmp_path, capsys, monkeypatch):
|
|
6120
|
+
home_dir = tmp_path / "home"
|
|
6121
|
+
|
|
6122
|
+
monkeypatch.setattr(
|
|
6123
|
+
guard_commands_module,
|
|
6124
|
+
"ensure_guard_daemon",
|
|
6125
|
+
lambda guard_home: (_ for _ in ()).throw(RuntimeError("dashboard_unavailable")),
|
|
6126
|
+
)
|
|
6127
|
+
|
|
6128
|
+
rc = main(["guard", "dashboard", "--home", str(home_dir), "--json"])
|
|
6129
|
+
output = json.loads(capsys.readouterr().out)
|
|
6130
|
+
|
|
6131
|
+
assert rc == 1
|
|
6132
|
+
assert output["opened"] is False
|
|
6133
|
+
assert output["error"] == "dashboard_unavailable"
|
|
6134
|
+
|
|
6135
|
+
def test_public_approval_center_url_strips_guard_token(self):
|
|
6136
|
+
browser_url = guard_commands_module._approval_center_browser_url(
|
|
6137
|
+
"http://127.0.0.1:5474#section=inbox",
|
|
6138
|
+
"secret-token",
|
|
6139
|
+
)
|
|
6140
|
+
|
|
6141
|
+
assert browser_url is not None
|
|
6142
|
+
assert "guard-token=secret-token" in browser_url
|
|
6143
|
+
assert "guard-token=" not in guard_commands_module._public_approval_center_url(browser_url)
|
|
6144
|
+
|
|
6051
6145
|
def test_guard_connect_pending_output_uses_product_copy_for_sign_in_gap(self, capsys):
|
|
6052
6146
|
emit_guard_payload(
|
|
6053
6147
|
"connect",
|
|
@@ -1620,3 +1620,46 @@ class TestGuardSurfaceServer:
|
|
|
1620
1620
|
assert operation["operation_type"] == "run"
|
|
1621
1621
|
assert approval["request_ids"] == ["req-1", "req-2"]
|
|
1622
1622
|
assert resumed["status"] == "completed"
|
|
1623
|
+
|
|
1624
|
+
def test_guard_surface_runtime_force_open_bypasses_auto_open_once(self, tmp_path) -> None:
|
|
1625
|
+
store = GuardStore(tmp_path / "guard-home")
|
|
1626
|
+
runtime = GuardSurfaceRuntime(store)
|
|
1627
|
+
opened_urls: list[str] = []
|
|
1628
|
+
|
|
1629
|
+
first_result = runtime.ensure_surface(
|
|
1630
|
+
surface="approval-center",
|
|
1631
|
+
approval_center_url="http://127.0.0.1:5474",
|
|
1632
|
+
approval_surface_policy="auto-open-once",
|
|
1633
|
+
open_key="dashboard",
|
|
1634
|
+
opener=lambda url: opened_urls.append(url) or True,
|
|
1635
|
+
)
|
|
1636
|
+
second_result = runtime.ensure_surface(
|
|
1637
|
+
surface="approval-center",
|
|
1638
|
+
approval_center_url="http://127.0.0.1:5474",
|
|
1639
|
+
approval_surface_policy="auto-open-once",
|
|
1640
|
+
open_key="dashboard",
|
|
1641
|
+
force_open=True,
|
|
1642
|
+
opener=lambda url: opened_urls.append(url) or True,
|
|
1643
|
+
)
|
|
1644
|
+
|
|
1645
|
+
assert first_result["opened"] is True
|
|
1646
|
+
assert second_result["opened"] is True
|
|
1647
|
+
assert opened_urls == ["http://127.0.0.1:5474", "http://127.0.0.1:5474"]
|
|
1648
|
+
|
|
1649
|
+
def test_guard_surface_runtime_force_open_overrides_disabled_policy(self, tmp_path) -> None:
|
|
1650
|
+
store = GuardStore(tmp_path / "guard-home")
|
|
1651
|
+
runtime = GuardSurfaceRuntime(store)
|
|
1652
|
+
opened_urls: list[str] = []
|
|
1653
|
+
|
|
1654
|
+
result = runtime.ensure_surface(
|
|
1655
|
+
surface="approval-center",
|
|
1656
|
+
approval_center_url="http://127.0.0.1:5474",
|
|
1657
|
+
approval_surface_policy="never-auto-open",
|
|
1658
|
+
open_key="dashboard",
|
|
1659
|
+
force_open=True,
|
|
1660
|
+
opener=lambda url: opened_urls.append(url) or True,
|
|
1661
|
+
)
|
|
1662
|
+
|
|
1663
|
+
assert result["opened"] is True
|
|
1664
|
+
assert result["reason"] == "opened"
|
|
1665
|
+
assert opened_urls == ["http://127.0.0.1:5474"]
|