plugin-scanner 2.0.83__tar.gz → 2.0.84__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.83 → plugin_scanner-2.0.84}/PKG-INFO +1 -1
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/pyproject.toml +1 -1
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/pyproject.toml.bak +1 -1
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/cli/commands.py +31 -4
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/integrations/cisco_mcp_scanner.py +57 -15
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/version.py +1 -1
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_guard_runtime.py +131 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_mcp_security.py +124 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/.clusterfuzzlite/Dockerfile +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/.clusterfuzzlite/build.sh +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/.clusterfuzzlite/project.yaml +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/.clusterfuzzlite/requirements-atheris.txt +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/.dockerignore +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/.github/CODEOWNERS +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/.github/ISSUE_TEMPLATE/bug-report.yml +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/.github/ISSUE_TEMPLATE/feature-request.yml +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/.github/dependabot.yml +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/.github/workflows/ci.yml +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/.github/workflows/codeql.yml +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/.github/workflows/dependabot-uv-lock.yml +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/.github/workflows/fuzz.yml +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/.github/workflows/harness-smoke.yml +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/.github/workflows/publish.yml +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/.github/workflows/scorecard.yml +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/.gitignore +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/.pre-commit-hooks.yaml +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/CONTRIBUTING.md +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/Dockerfile +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/LICENSE +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/README.md +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/SECURITY.md +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/dashboard/index.html +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/dashboard/package.json +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/dashboard/pnpm-lock.yaml +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/dashboard/public/apple-touch-icon.png +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/dashboard/public/brand/Logo_Icon_Dark.png +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/dashboard/public/brand/Logo_Whole.png +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/dashboard/public/favicon-16x16.png +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/dashboard/public/favicon-32x32.png +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/dashboard/public/favicon.ico +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/dashboard/src/app.tsx +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/dashboard/src/approval-center-layout.tsx +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/dashboard/src/approval-center-primitives.tsx +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/dashboard/src/approval-center-utils.ts +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/dashboard/src/fleet-workspace.tsx +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/dashboard/src/guard-api.ts +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/dashboard/src/guard-demo.ts +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/dashboard/src/guard-types.ts +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/dashboard/src/main.tsx +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/dashboard/src/receipts-workspace.tsx +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/dashboard/src/runtime-overview.tsx +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/dashboard/src/settings-workspace.tsx +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/dashboard/src/styles.css +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/dashboard/src/vite-env.d.ts +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/dashboard/tsconfig.json +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/dashboard/vite.config.ts +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/docker-requirements.txt +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/docs/guard/approval-audit.md +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/docs/guard/architecture.md +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/docs/guard/get-started.md +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/docs/guard/harness-support.md +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/docs/guard/local-vs-cloud.md +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/docs/guard/testing-matrix.md +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/docs/trust/mcp-trust-draft.md +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/docs/trust/plugin-trust-draft.md +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/docs/trust/skill-trust-local.md +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/fuzzers/manifest_fuzzer.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/requirements.txt +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/schemas/plugin-quality.v1.json +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/schemas/scan-result.v1.json +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/schemas/verify-result.v1.json +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/__init__.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/action_runner.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/argparse_utils.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/checks/__init__.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/checks/best_practices.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/checks/claude.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/checks/code_quality.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/checks/ecosystem_common.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/checks/gemini.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/checks/manifest.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/checks/manifest_support.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/checks/marketplace.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/checks/mcp_security.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/checks/opencode.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/checks/operational_security.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/checks/security.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/checks/skill_security.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/cli.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/cli_ui.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/config.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/ecosystems/__init__.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/ecosystems/base.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/ecosystems/claude.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/ecosystems/codex.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/ecosystems/detect.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/ecosystems/gemini.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/ecosystems/opencode.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/ecosystems/registry.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/ecosystems/types.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/github_reporting.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/__init__.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/adapters/__init__.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/adapters/antigravity.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/adapters/base.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/adapters/claude_code.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/adapters/codex.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/adapters/copilot.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/adapters/cursor.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/adapters/gemini.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/adapters/hermes.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/adapters/mcp_servers.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/adapters/opencode.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/adapters/opencode_artifacts.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/advisory_model.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/approvals.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/bridge/__init__.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/capabilities.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/cli/__init__.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/cli/approval_commands.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/cli/bootstrap.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/cli/connect_flow.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/cli/install_commands.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/cli/product.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/cli/prompt.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/cli/render.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/cli/update_commands.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/codex_config.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/config.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/consumer/__init__.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/consumer/service.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/daemon/__init__.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/daemon/client.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/daemon/manager.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/daemon/server.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/daemon/static/apple-touch-icon.png +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/daemon/static/assets/guard-dashboard.js +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/daemon/static/assets/index.css +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/daemon/static/brand/Logo_Icon_Dark.png +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/daemon/static/brand/Logo_Whole.png +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/daemon/static/favicon-16x16.png +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/daemon/static/favicon-32x32.png +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/daemon/static/favicon.ico +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/daemon/static/index.html +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/edge_events.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/incident.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/launcher.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/mcp_tool_calls.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/models.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/policy/__init__.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/policy/engine.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/protect.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/proxy/__init__.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/proxy/remote.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/proxy/runtime_mcp.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/proxy/stdio.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/receipts/__init__.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/receipts/manager.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/redaction.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/risk.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/runtime/__init__.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/runtime/runner.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/runtime/secret_file_requests.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/runtime/surface_server.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/schemas/__init__.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/schemas/consumer_mode.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/schemas/guard_event_v1.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/schemas/surface_server.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/shims.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/store.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/store_approvals.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/store_connect.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/types.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/integrations/__init__.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/integrations/cisco_skill_scanner.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/lint_fixes.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/marketplace_support.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/models.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/path_support.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/policy.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/quality_artifact.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/repo_detect.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/reporting.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/rules/__init__.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/rules/registry.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/rules/specs.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/scanner.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/submission.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/suppressions.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/trust_domain_scoring.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/trust_helpers.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/trust_mcp_scoring.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/trust_models.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/trust_plugin_scoring.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/trust_scoring.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/trust_skill_scoring.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/trust_specs.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/verification.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/__init__.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/conftest.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/__init__.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/bad-plugin/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/bad-plugin/.mcp.json +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/bad-plugin/secrets.js +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/claude-plugin-good/.claude-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/claude-plugin-good/LICENSE +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/claude-plugin-good/README.md +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/claude-plugin-good/SECURITY.md +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/claude-plugin-good/hooks/hooks.json +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/claude-plugin-good/skills/example/SKILL.md +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/code-quality-bad/evil.js +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/code-quality-bad/inject.js +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/gemini-extension-good/GEMINI.md +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/gemini-extension-good/LICENSE +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/gemini-extension-good/README.md +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/gemini-extension-good/SECURITY.md +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/gemini-extension-good/commands/hello.toml +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/gemini-extension-good/gemini-extension.json +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/good-plugin/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/good-plugin/.codexignore +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/good-plugin/LICENSE +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/good-plugin/README.md +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/good-plugin/SECURITY.md +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/good-plugin/assets/icon.svg +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/good-plugin/assets/logo.svg +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/good-plugin/assets/screenshot.svg +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/good-plugin/skills/example/SKILL.md +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/guard-codex-malicious-mcp/.codex/config.toml +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/hermes-plugin-evil/config.yaml +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/hermes-plugin-evil/mcp_servers.json +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/hermes-plugin-evil/skills/security/malicious/SKILL.md +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/hermes-plugin-evil/skills/stealth/sneaky/SKILL.md +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/hermes-plugin-evil/skills/stealth/sneaky/references/api-setup.md +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/hermes-plugin-evil/skills/stealth/sneaky/scripts/deploy.sh +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/hermes-plugin-evil/skills/utils/benign/SKILL.md +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/malformed-json/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/malicious-skill-plugin/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/malicious-skill-plugin/.codexignore +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/malicious-skill-plugin/LICENSE +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/malicious-skill-plugin/README.md +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/malicious-skill-plugin/SECURITY.md +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/malicious-skill-plugin/skills/leaky-skill/SKILL.md +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/mcp-canary-server.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/minimal-plugin/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/missing-fields/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/mit-license/LICENSE +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/multi-ecosystem-repo/codex-plugin/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/multi-ecosystem-repo/codex-plugin/LICENSE +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/multi-ecosystem-repo/codex-plugin/README.md +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/multi-ecosystem-repo/codex-plugin/SECURITY.md +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/multi-ecosystem-repo/gemini-ext/README.md +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/multi-ecosystem-repo/gemini-ext/gemini-extension.json +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/multi-plugin-repo/.agents/plugins/marketplace.json +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/.codexignore +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/LICENSE +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/README.md +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/SECURITY.md +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/skills/example/SKILL.md +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/multi-plugin-repo/plugins/beta-plugin/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/multi-plugin-repo/plugins/beta-plugin/skills/example/SKILL.md +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/no-version/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/opencode-good/.opencode/commands/hello.md +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/opencode-good/.opencode/plugins/example.ts +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/opencode-good/LICENSE +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/opencode-good/README.md +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/opencode-good/SECURITY.md +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/opencode-good/opencode.jsonc +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/skills-missing-dir/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/skills-no-frontmatter/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/skills-no-frontmatter/skills/bad-skill/SKILL.md +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/with-marketplace/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/with-marketplace/marketplace-broken.json +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/fixtures/with-marketplace/marketplace.json +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test-trust-scoring.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test-trust-specs.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_action_runner.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_best_practices.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_cisco_install_surfaces.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_cli.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_code_quality.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_config.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_coverage_remaining.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_ecosystems.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_edge_cases.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_final_coverage.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_guard_approvals.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_guard_bootstrap.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_guard_capabilities.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_guard_claude_adapter.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_guard_cli.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_guard_codex_e2e.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_guard_codex_install.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_guard_codex_proxy.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_guard_config_paths.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_guard_connect_flow.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_guard_consumer_mode.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_guard_copilot_adapter.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_guard_copilot_proxy.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_guard_daemon_manager.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_guard_event_schema_v1.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_guard_events.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_guard_launch_env.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_guard_opencode_proxy.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_guard_product_flow.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_guard_protect.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_guard_render.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_guard_risk.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_guard_store_migrations.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_guard_surface_server.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_guard_verdicts.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_hermes_adapter.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_integration.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_lint_fixes.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_live_cisco_smoke.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_manifest.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_marketplace.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_operational_security.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_policy.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_quality_artifact.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_rule_registry.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_scanner.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_schema_contracts.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_security.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_security_ops.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_skill_security.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_submission.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_trust_scoring.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_trust_specs.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_verification.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/tests/test_versioning.py +0 -0
- {plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/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.84
|
|
4
4
|
Summary: Lint, verify, and gate plugin ecosystems for maintainers, CI, and publish workflows.
|
|
5
5
|
Project-URL: Homepage, https://github.com/hashgraph-online/ai-plugin-scanner
|
|
6
6
|
Project-URL: Repository, https://github.com/hashgraph-online/ai-plugin-scanner
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "plugin-scanner"
|
|
7
|
-
version = "2.0.
|
|
7
|
+
version = "2.0.84"
|
|
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.84"
|
|
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.83 → plugin_scanner-2.0.84}/src/codex_plugin_scanner/guard/cli/commands.py
RENAMED
|
@@ -3816,7 +3816,13 @@ _CODEX_SEARCH_OPTION_VALUE_FLAGS = frozenset(
|
|
|
3816
3816
|
_CODEX_SEARCH_OPTION_VALUE_FLAGS_BY_EXECUTABLE = {
|
|
3817
3817
|
"rg": frozenset({"-T"}),
|
|
3818
3818
|
}
|
|
3819
|
-
_CODEX_SEARCH_UNSAFE_FLAGS = frozenset({"--pre"})
|
|
3819
|
+
_CODEX_SEARCH_UNSAFE_FLAGS = frozenset({"--dereference-recursive", "--follow", "--pre"})
|
|
3820
|
+
_CODEX_SEARCH_UNSAFE_SHORT_FLAGS_BY_EXECUTABLE = {
|
|
3821
|
+
"egrep": frozenset({"R"}),
|
|
3822
|
+
"fgrep": frozenset({"R"}),
|
|
3823
|
+
"grep": frozenset({"R"}),
|
|
3824
|
+
"rg": frozenset({"L"}),
|
|
3825
|
+
}
|
|
3820
3826
|
_CODEX_GIT_GLOBAL_VALUE_FLAGS = frozenset(
|
|
3821
3827
|
{"-c", "--config-env", "--exec-path", "--git-dir", "--work-tree", "--namespace"}
|
|
3822
3828
|
)
|
|
@@ -3988,6 +3994,7 @@ def _codex_search_targets_are_source_like(args: list[str], *, cwd: Path | None,
|
|
|
3988
3994
|
positional: list[str] = []
|
|
3989
3995
|
skip_next = False
|
|
3990
3996
|
pattern_from_option = False
|
|
3997
|
+
after_option_terminator = False
|
|
3991
3998
|
option_value_flags = _CODEX_SEARCH_OPTION_VALUE_FLAGS | _CODEX_SEARCH_OPTION_VALUE_FLAGS_BY_EXECUTABLE.get(
|
|
3992
3999
|
executable, frozenset()
|
|
3993
4000
|
)
|
|
@@ -3995,7 +4002,13 @@ def _codex_search_targets_are_source_like(args: list[str], *, cwd: Path | None,
|
|
|
3995
4002
|
if skip_next:
|
|
3996
4003
|
skip_next = False
|
|
3997
4004
|
continue
|
|
3998
|
-
if
|
|
4005
|
+
if after_option_terminator:
|
|
4006
|
+
positional.append(arg)
|
|
4007
|
+
continue
|
|
4008
|
+
if arg == "--":
|
|
4009
|
+
after_option_terminator = True
|
|
4010
|
+
continue
|
|
4011
|
+
if _codex_search_arg_is_unsafe(arg, executable=executable, option_value_flags=option_value_flags):
|
|
3999
4012
|
return False
|
|
4000
4013
|
if arg in _CODEX_SEARCH_PATTERN_VALUE_FLAGS:
|
|
4001
4014
|
pattern_from_option = True
|
|
@@ -4012,8 +4025,6 @@ def _codex_search_targets_are_source_like(args: list[str], *, cwd: Path | None,
|
|
|
4012
4025
|
continue
|
|
4013
4026
|
if any(arg.startswith(f"{flag}=") for flag in option_value_flags):
|
|
4014
4027
|
continue
|
|
4015
|
-
if arg == "--":
|
|
4016
|
-
continue
|
|
4017
4028
|
if arg.startswith("-"):
|
|
4018
4029
|
continue
|
|
4019
4030
|
positional.append(arg)
|
|
@@ -4026,6 +4037,22 @@ def _codex_search_targets_are_source_like(args: list[str], *, cwd: Path | None,
|
|
|
4026
4037
|
return bool(targets) and all(_codex_search_target_is_source_like(target, cwd=cwd) for target in targets)
|
|
4027
4038
|
|
|
4028
4039
|
|
|
4040
|
+
def _codex_search_arg_is_unsafe(arg: str, *, executable: str, option_value_flags: frozenset[str]) -> bool:
|
|
4041
|
+
if arg in _CODEX_SEARCH_UNSAFE_FLAGS:
|
|
4042
|
+
return True
|
|
4043
|
+
if any(arg.startswith(f"{flag}=") for flag in _CODEX_SEARCH_UNSAFE_FLAGS):
|
|
4044
|
+
return True
|
|
4045
|
+
if not arg.startswith("-") or arg.startswith("--"):
|
|
4046
|
+
return False
|
|
4047
|
+
unsafe_short_flags = _CODEX_SEARCH_UNSAFE_SHORT_FLAGS_BY_EXECUTABLE.get(executable, frozenset())
|
|
4048
|
+
for flag in arg[1:]:
|
|
4049
|
+
if flag in unsafe_short_flags:
|
|
4050
|
+
return True
|
|
4051
|
+
if f"-{flag}" in option_value_flags:
|
|
4052
|
+
return False
|
|
4053
|
+
return False
|
|
4054
|
+
|
|
4055
|
+
|
|
4029
4056
|
def _codex_search_target_is_source_like(target: str, *, cwd: Path | None) -> bool:
|
|
4030
4057
|
stripped = target.strip().strip("'\"")
|
|
4031
4058
|
if not stripped:
|
|
@@ -47,6 +47,13 @@ class CiscoMcpScanSummary:
|
|
|
47
47
|
scan_mode: str = "static"
|
|
48
48
|
|
|
49
49
|
|
|
50
|
+
@dataclass(frozen=True, slots=True)
|
|
51
|
+
class _StaticScanTarget:
|
|
52
|
+
read_path: Path
|
|
53
|
+
tool_name: str
|
|
54
|
+
content_type: str
|
|
55
|
+
|
|
56
|
+
|
|
50
57
|
def _empty_counts() -> dict[str, int]:
|
|
51
58
|
return {severity.value: 0 for severity in Severity}
|
|
52
59
|
|
|
@@ -235,15 +242,24 @@ def _normalize_finding(plugin_dir: Path, file_path: Path, finding: object) -> Fi
|
|
|
235
242
|
)
|
|
236
243
|
|
|
237
244
|
|
|
238
|
-
def _collect_static_targets(plugin_dir: Path) -> tuple[
|
|
245
|
+
def _collect_static_targets(plugin_dir: Path) -> tuple[_StaticScanTarget, ...]:
|
|
239
246
|
config_path = plugin_dir / ".mcp.json"
|
|
240
|
-
|
|
247
|
+
resolved_config_path = _safe_resolved_static_target(plugin_dir, config_path)
|
|
248
|
+
if resolved_config_path is None:
|
|
241
249
|
return ()
|
|
242
250
|
|
|
243
|
-
targets: list[
|
|
251
|
+
targets: list[_StaticScanTarget] = []
|
|
252
|
+
seen_targets: set[Path] = set()
|
|
244
253
|
try:
|
|
245
|
-
if
|
|
246
|
-
targets.append(
|
|
254
|
+
if resolved_config_path.stat().st_size <= _MAX_TARGET_SIZE_BYTES:
|
|
255
|
+
targets.append(
|
|
256
|
+
_StaticScanTarget(
|
|
257
|
+
read_path=resolved_config_path,
|
|
258
|
+
tool_name=config_path.name,
|
|
259
|
+
content_type="mcp-config",
|
|
260
|
+
)
|
|
261
|
+
)
|
|
262
|
+
seen_targets.add(resolved_config_path)
|
|
247
263
|
except OSError:
|
|
248
264
|
pass
|
|
249
265
|
for root, dirs, files in os.walk(plugin_dir, topdown=True):
|
|
@@ -253,15 +269,40 @@ def _collect_static_targets(plugin_dir: Path) -> tuple[Path, ...]:
|
|
|
253
269
|
file_path = current_dir / file_name
|
|
254
270
|
if file_path == config_path or file_path.suffix.lower() not in _SOURCE_SUFFIXES:
|
|
255
271
|
continue
|
|
272
|
+
resolved_file_path = _safe_resolved_static_target(plugin_dir, file_path)
|
|
273
|
+
if resolved_file_path is None or resolved_file_path in seen_targets:
|
|
274
|
+
continue
|
|
256
275
|
try:
|
|
257
|
-
if
|
|
276
|
+
if resolved_file_path.stat().st_size > _MAX_TARGET_SIZE_BYTES:
|
|
258
277
|
continue
|
|
259
278
|
except OSError:
|
|
260
279
|
continue
|
|
261
|
-
targets.append(
|
|
280
|
+
targets.append(
|
|
281
|
+
_StaticScanTarget(
|
|
282
|
+
read_path=resolved_file_path,
|
|
283
|
+
tool_name=resolved_file_path.name,
|
|
284
|
+
content_type="mcp-source",
|
|
285
|
+
)
|
|
286
|
+
)
|
|
287
|
+
seen_targets.add(resolved_file_path)
|
|
262
288
|
return tuple(targets)
|
|
263
289
|
|
|
264
290
|
|
|
291
|
+
def _safe_resolved_static_target(plugin_dir: Path, target: Path) -> Path | None:
|
|
292
|
+
try:
|
|
293
|
+
resolved_root = plugin_dir.resolve(strict=True)
|
|
294
|
+
resolved_target = target.resolve(strict=True)
|
|
295
|
+
if not resolved_target.is_file():
|
|
296
|
+
return None
|
|
297
|
+
except (OSError, RuntimeError):
|
|
298
|
+
return None
|
|
299
|
+
try:
|
|
300
|
+
resolved_target.relative_to(resolved_root)
|
|
301
|
+
except ValueError:
|
|
302
|
+
return None
|
|
303
|
+
return resolved_target
|
|
304
|
+
|
|
305
|
+
|
|
265
306
|
def _run_awaitable(awaitable: Awaitable[T]) -> T:
|
|
266
307
|
try:
|
|
267
308
|
asyncio.get_running_loop()
|
|
@@ -288,40 +329,41 @@ def _run_awaitable(awaitable: Awaitable[T]) -> T:
|
|
|
288
329
|
|
|
289
330
|
|
|
290
331
|
async def _scan_targets(
|
|
291
|
-
plugin_dir: Path, targets: tuple[
|
|
332
|
+
plugin_dir: Path, targets: tuple[_StaticScanTarget, ...], analyzer: object
|
|
292
333
|
) -> tuple[tuple[Finding, ...], int]:
|
|
293
334
|
findings: list[Finding] = []
|
|
294
335
|
targets_scanned = 0
|
|
295
336
|
for target in targets:
|
|
296
337
|
try:
|
|
297
|
-
content = target.read_text(encoding="utf-8", errors="ignore")
|
|
338
|
+
content = target.read_path.read_text(encoding="utf-8", errors="ignore")
|
|
298
339
|
except OSError:
|
|
299
340
|
continue
|
|
300
|
-
content_type = "mcp-config" if target.name == ".mcp.json" else "mcp-source"
|
|
301
341
|
external_findings = await analyzer.analyze(
|
|
302
342
|
content,
|
|
303
343
|
{
|
|
304
|
-
"tool_name": target.
|
|
305
|
-
"content_type": content_type,
|
|
306
|
-
"file_path": str(target),
|
|
344
|
+
"tool_name": target.tool_name,
|
|
345
|
+
"content_type": target.content_type,
|
|
346
|
+
"file_path": str(target.read_path),
|
|
307
347
|
},
|
|
308
348
|
)
|
|
309
349
|
targets_scanned += 1
|
|
310
350
|
for finding in external_findings:
|
|
311
|
-
findings.append(_normalize_finding(plugin_dir, target, finding))
|
|
351
|
+
findings.append(_normalize_finding(plugin_dir, target.read_path, finding))
|
|
312
352
|
return tuple(findings), targets_scanned
|
|
313
353
|
|
|
314
354
|
|
|
315
355
|
def run_cisco_mcp_scan(plugin_dir: Path, mode: str = "auto") -> CiscoMcpScanSummary:
|
|
316
356
|
"""Run Cisco MCP scanner static analysis when available."""
|
|
317
357
|
|
|
358
|
+
config_path = plugin_dir / ".mcp.json"
|
|
359
|
+
|
|
318
360
|
if mode == "off":
|
|
319
361
|
return _build_summary(
|
|
320
362
|
status=CiscoIntegrationStatus.SKIPPED,
|
|
321
363
|
message="Cisco MCP scanning disabled by configuration.",
|
|
322
364
|
)
|
|
323
365
|
|
|
324
|
-
if
|
|
366
|
+
if _safe_resolved_static_target(plugin_dir, config_path) is None:
|
|
325
367
|
return _build_summary(
|
|
326
368
|
status=CiscoIntegrationStatus.SKIPPED,
|
|
327
369
|
message="No .mcp.json found; Cisco MCP scan skipped.",
|
|
@@ -541,6 +541,137 @@ Please investigate the bug end to end, fix the publish flow, and make sure user-
|
|
|
541
541
|
assert output["recorded"] is True
|
|
542
542
|
assert "approval_requests" not in output
|
|
543
543
|
|
|
544
|
+
def test_codex_post_tool_use_allows_short_option_value_payloads(
|
|
545
|
+
self,
|
|
546
|
+
monkeypatch,
|
|
547
|
+
tmp_path,
|
|
548
|
+
capsys,
|
|
549
|
+
) -> None:
|
|
550
|
+
home_dir = tmp_path / "home"
|
|
551
|
+
workspace_dir = tmp_path / "workspace"
|
|
552
|
+
_build_guard_fixture(home_dir, workspace_dir)
|
|
553
|
+
event = {
|
|
554
|
+
"event": "PostToolUse",
|
|
555
|
+
"tool_name": "Bash",
|
|
556
|
+
"tool_input": {"command": "rg -gLICENSE TOKEN src"},
|
|
557
|
+
"tool_response": {
|
|
558
|
+
"stdout": "src/config.ts:1:const auth_token = process.env.TOKEN",
|
|
559
|
+
},
|
|
560
|
+
"source_scope": "project",
|
|
561
|
+
}
|
|
562
|
+
monkeypatch.setattr(sys, "stdin", io.StringIO(json.dumps(event)))
|
|
563
|
+
|
|
564
|
+
rc = main(
|
|
565
|
+
[
|
|
566
|
+
"guard",
|
|
567
|
+
"hook",
|
|
568
|
+
"--home",
|
|
569
|
+
str(home_dir),
|
|
570
|
+
"--workspace",
|
|
571
|
+
str(workspace_dir),
|
|
572
|
+
"--harness",
|
|
573
|
+
"codex",
|
|
574
|
+
"--json",
|
|
575
|
+
]
|
|
576
|
+
)
|
|
577
|
+
output = json.loads(capsys.readouterr().out)
|
|
578
|
+
|
|
579
|
+
assert rc == 0
|
|
580
|
+
assert output["recorded"] is True
|
|
581
|
+
assert "approval_requests" not in output
|
|
582
|
+
|
|
583
|
+
def test_codex_post_tool_use_allows_double_dash_terminated_literal_pattern(
|
|
584
|
+
self,
|
|
585
|
+
monkeypatch,
|
|
586
|
+
tmp_path,
|
|
587
|
+
capsys,
|
|
588
|
+
) -> None:
|
|
589
|
+
home_dir = tmp_path / "home"
|
|
590
|
+
workspace_dir = tmp_path / "workspace"
|
|
591
|
+
_build_guard_fixture(home_dir, workspace_dir)
|
|
592
|
+
event = {
|
|
593
|
+
"event": "PostToolUse",
|
|
594
|
+
"tool_name": "Bash",
|
|
595
|
+
"tool_input": {"command": "rg -- --follow src"},
|
|
596
|
+
"tool_response": {
|
|
597
|
+
"stdout": "src/config.ts:1:const auth_token = process.env.TOKEN",
|
|
598
|
+
},
|
|
599
|
+
"source_scope": "project",
|
|
600
|
+
}
|
|
601
|
+
monkeypatch.setattr(sys, "stdin", io.StringIO(json.dumps(event)))
|
|
602
|
+
|
|
603
|
+
rc = main(
|
|
604
|
+
[
|
|
605
|
+
"guard",
|
|
606
|
+
"hook",
|
|
607
|
+
"--home",
|
|
608
|
+
str(home_dir),
|
|
609
|
+
"--workspace",
|
|
610
|
+
str(workspace_dir),
|
|
611
|
+
"--harness",
|
|
612
|
+
"codex",
|
|
613
|
+
"--json",
|
|
614
|
+
]
|
|
615
|
+
)
|
|
616
|
+
output = json.loads(capsys.readouterr().out)
|
|
617
|
+
|
|
618
|
+
assert rc == 0
|
|
619
|
+
assert output["recorded"] is True
|
|
620
|
+
assert "approval_requests" not in output
|
|
621
|
+
|
|
622
|
+
@pytest.mark.parametrize(
|
|
623
|
+
"command",
|
|
624
|
+
(
|
|
625
|
+
"rg --follow TOKEN src",
|
|
626
|
+
"rg -L TOKEN src",
|
|
627
|
+
"grep -R TOKEN src",
|
|
628
|
+
),
|
|
629
|
+
)
|
|
630
|
+
def test_codex_post_tool_use_blocks_symlink_following_source_search_flags(
|
|
631
|
+
self,
|
|
632
|
+
monkeypatch,
|
|
633
|
+
tmp_path,
|
|
634
|
+
capsys,
|
|
635
|
+
command: str,
|
|
636
|
+
) -> None:
|
|
637
|
+
home_dir = tmp_path / "home"
|
|
638
|
+
workspace_dir = tmp_path / "workspace"
|
|
639
|
+
_build_guard_fixture(home_dir, workspace_dir)
|
|
640
|
+
secret_file = home_dir / ".aws" / "credentials"
|
|
641
|
+
_write_text(secret_file, "auth_token=outside-secret\n")
|
|
642
|
+
src_dir = workspace_dir / "src"
|
|
643
|
+
src_dir.mkdir()
|
|
644
|
+
(src_dir / "config.ts").symlink_to(secret_file)
|
|
645
|
+
event = {
|
|
646
|
+
"event": "PostToolUse",
|
|
647
|
+
"tool_name": "Bash",
|
|
648
|
+
"tool_input": {"command": command},
|
|
649
|
+
"tool_response": {
|
|
650
|
+
"stdout": "src/config.ts:1:auth_token=outside-secret",
|
|
651
|
+
},
|
|
652
|
+
"source_scope": "project",
|
|
653
|
+
}
|
|
654
|
+
monkeypatch.setattr(sys, "stdin", io.StringIO(json.dumps(event)))
|
|
655
|
+
|
|
656
|
+
rc = main(
|
|
657
|
+
[
|
|
658
|
+
"guard",
|
|
659
|
+
"hook",
|
|
660
|
+
"--home",
|
|
661
|
+
str(home_dir),
|
|
662
|
+
"--workspace",
|
|
663
|
+
str(workspace_dir),
|
|
664
|
+
"--harness",
|
|
665
|
+
"codex",
|
|
666
|
+
"--json",
|
|
667
|
+
]
|
|
668
|
+
)
|
|
669
|
+
output = json.loads(capsys.readouterr().out)
|
|
670
|
+
|
|
671
|
+
assert rc == 1
|
|
672
|
+
assert output["artifact_type"] == "tool_action_request"
|
|
673
|
+
assert output["approval_requests"]
|
|
674
|
+
|
|
544
675
|
def test_codex_post_tool_use_allows_ripgrep_type_not_source_search(
|
|
545
676
|
self,
|
|
546
677
|
monkeypatch,
|
|
@@ -103,6 +103,130 @@ def test_scan_includes_dist_descendants(monkeypatch, tmp_path: Path) -> None:
|
|
|
103
103
|
assert any(path.endswith("dist/server.js") for path in analyzed_paths)
|
|
104
104
|
|
|
105
105
|
|
|
106
|
+
def test_scan_skips_source_symlink_resolving_outside_plugin_root(monkeypatch, tmp_path: Path) -> None:
|
|
107
|
+
plugin_dir = tmp_path / "plugin"
|
|
108
|
+
_write_plugin(plugin_dir)
|
|
109
|
+
outside_secret = tmp_path / "outside.py"
|
|
110
|
+
outside_secret.write_text("auth_token = 'outside-secret'\n", encoding="utf-8")
|
|
111
|
+
(plugin_dir / "leak.py").symlink_to(outside_secret)
|
|
112
|
+
analyzed_paths: list[str] = []
|
|
113
|
+
analyzed_contents: list[str] = []
|
|
114
|
+
|
|
115
|
+
class RecordingYaraAnalyzer:
|
|
116
|
+
def __init__(self, *args: object, **kwargs: object) -> None:
|
|
117
|
+
return None
|
|
118
|
+
|
|
119
|
+
async def analyze(self, content: str, context: dict[str, Any] | None = None) -> list[FakeCiscoFinding]:
|
|
120
|
+
analyzed_paths.append(str((context or {}).get("file_path", "")))
|
|
121
|
+
analyzed_contents.append(content)
|
|
122
|
+
return []
|
|
123
|
+
|
|
124
|
+
monkeypatch.setattr(
|
|
125
|
+
"codex_plugin_scanner.integrations.cisco_mcp_scanner._load_mcp_scanner_components",
|
|
126
|
+
lambda: {"YaraAnalyzer": RecordingYaraAnalyzer},
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
summary = run_cisco_mcp_scan(plugin_dir, mode="on")
|
|
130
|
+
|
|
131
|
+
assert summary.status == CiscoIntegrationStatus.ENABLED
|
|
132
|
+
assert summary.targets_scanned == 2
|
|
133
|
+
assert str(plugin_dir / "leak.py") not in analyzed_paths
|
|
134
|
+
assert all("outside-secret" not in content for content in analyzed_contents)
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def test_scan_skips_symlinked_mcp_config_outside_plugin_root(monkeypatch, tmp_path: Path) -> None:
|
|
138
|
+
plugin_dir = tmp_path / "plugin"
|
|
139
|
+
_write_plugin(plugin_dir)
|
|
140
|
+
(plugin_dir / ".mcp.json").unlink()
|
|
141
|
+
outside_config = tmp_path / "outside-mcp.json"
|
|
142
|
+
outside_config.write_text(
|
|
143
|
+
json.dumps({"mcpServers": {"outside": {"command": "python", "args": ["secret.py"]}}}),
|
|
144
|
+
encoding="utf-8",
|
|
145
|
+
)
|
|
146
|
+
(plugin_dir / ".mcp.json").symlink_to(outside_config)
|
|
147
|
+
loader_state = {"called": False}
|
|
148
|
+
|
|
149
|
+
class RecordingYaraAnalyzer:
|
|
150
|
+
def __init__(self, *args: object, **kwargs: object) -> None:
|
|
151
|
+
return None
|
|
152
|
+
|
|
153
|
+
def _loader() -> dict[str, type[RecordingYaraAnalyzer]]:
|
|
154
|
+
loader_state["called"] = True
|
|
155
|
+
return {"YaraAnalyzer": RecordingYaraAnalyzer}
|
|
156
|
+
|
|
157
|
+
monkeypatch.setattr(
|
|
158
|
+
"codex_plugin_scanner.integrations.cisco_mcp_scanner._load_mcp_scanner_components",
|
|
159
|
+
_loader,
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
summary = run_cisco_mcp_scan(plugin_dir, mode="on")
|
|
163
|
+
|
|
164
|
+
assert summary.status == CiscoIntegrationStatus.SKIPPED
|
|
165
|
+
assert loader_state["called"] is False
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def test_scan_resolves_in_root_symlink_targets_before_analysis(monkeypatch, tmp_path: Path) -> None:
|
|
169
|
+
plugin_dir = tmp_path / "plugin"
|
|
170
|
+
_write_plugin(plugin_dir)
|
|
171
|
+
real_source = plugin_dir / "real.py"
|
|
172
|
+
real_source.write_text("print('real')\n", encoding="utf-8")
|
|
173
|
+
(plugin_dir / "link.py").symlink_to(real_source)
|
|
174
|
+
analyzed_paths: list[str] = []
|
|
175
|
+
|
|
176
|
+
class RecordingYaraAnalyzer:
|
|
177
|
+
def __init__(self, *args: object, **kwargs: object) -> None:
|
|
178
|
+
return None
|
|
179
|
+
|
|
180
|
+
async def analyze(self, content: str, context: dict[str, Any] | None = None) -> list[FakeCiscoFinding]:
|
|
181
|
+
analyzed_paths.append(str((context or {}).get("file_path", "")))
|
|
182
|
+
return []
|
|
183
|
+
|
|
184
|
+
monkeypatch.setattr(
|
|
185
|
+
"codex_plugin_scanner.integrations.cisco_mcp_scanner._load_mcp_scanner_components",
|
|
186
|
+
lambda: {"YaraAnalyzer": RecordingYaraAnalyzer},
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
summary = run_cisco_mcp_scan(plugin_dir, mode="on")
|
|
190
|
+
|
|
191
|
+
assert summary.status == CiscoIntegrationStatus.ENABLED
|
|
192
|
+
assert summary.targets_scanned == 3
|
|
193
|
+
assert str(real_source.resolve()) in analyzed_paths
|
|
194
|
+
assert str(plugin_dir / "link.py") not in analyzed_paths
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def test_scan_preserves_symlinked_mcp_config_identity(monkeypatch, tmp_path: Path) -> None:
|
|
198
|
+
plugin_dir = tmp_path / "plugin"
|
|
199
|
+
_write_plugin(plugin_dir)
|
|
200
|
+
real_config = plugin_dir / "configs" / "base.json"
|
|
201
|
+
real_config.parent.mkdir()
|
|
202
|
+
real_config.write_text(
|
|
203
|
+
json.dumps({"mcpServers": {"demo": {"command": "python", "args": ["server.py"]}}}),
|
|
204
|
+
encoding="utf-8",
|
|
205
|
+
)
|
|
206
|
+
(plugin_dir / ".mcp.json").unlink()
|
|
207
|
+
(plugin_dir / ".mcp.json").symlink_to(real_config)
|
|
208
|
+
analyzed_contexts: list[dict[str, Any]] = []
|
|
209
|
+
|
|
210
|
+
class RecordingYaraAnalyzer:
|
|
211
|
+
def __init__(self, *args: object, **kwargs: object) -> None:
|
|
212
|
+
return None
|
|
213
|
+
|
|
214
|
+
async def analyze(self, content: str, context: dict[str, Any] | None = None) -> list[FakeCiscoFinding]:
|
|
215
|
+
analyzed_contexts.append(dict(context or {}))
|
|
216
|
+
return []
|
|
217
|
+
|
|
218
|
+
monkeypatch.setattr(
|
|
219
|
+
"codex_plugin_scanner.integrations.cisco_mcp_scanner._load_mcp_scanner_components",
|
|
220
|
+
lambda: {"YaraAnalyzer": RecordingYaraAnalyzer},
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
summary = run_cisco_mcp_scan(plugin_dir, mode="on")
|
|
224
|
+
|
|
225
|
+
assert summary.status == CiscoIntegrationStatus.ENABLED
|
|
226
|
+
assert analyzed_contexts[0]["tool_name"] == ".mcp.json"
|
|
227
|
+
assert analyzed_contexts[0]["content_type"] == "mcp-config"
|
|
228
|
+
|
|
229
|
+
|
|
106
230
|
def test_mcp_security_auto_mode_unavailable_is_not_applicable(monkeypatch, tmp_path: Path) -> None:
|
|
107
231
|
plugin_dir = tmp_path / "plugin"
|
|
108
232
|
_write_plugin(plugin_dir)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{plugin_scanner-2.0.83 → plugin_scanner-2.0.84}/dashboard/src/approval-center-primitives.tsx
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|