plugin-scanner 2.0.171__tar.gz → 2.0.173__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.171 → plugin_scanner-2.0.173}/PKG-INFO +3 -1
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/README.md +2 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/pyproject.toml +1 -1
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/pyproject.toml.bak +1 -1
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/adapters/hermes.py +20 -2
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/adapters/openclaw.py +20 -2
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/cli/commands.py +50 -0
- plugin_scanner-2.0.173/src/codex_plugin_scanner/guard/inventory_cisco.py +184 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/inventory_contract.py +169 -2
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/version.py +1 -1
- plugin_scanner-2.0.173/tests/test_guard_inventory_cisco.py +228 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_inventory_contract.py +63 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_runtime.py +82 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_hermes_adapter.py +46 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_openclaw_adapter.py +46 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/.clusterfuzzlite/Dockerfile +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/.clusterfuzzlite/build.sh +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/.clusterfuzzlite/project.yaml +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/.clusterfuzzlite/requirements-atheris.txt +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/.dockerignore +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/.github/CODEOWNERS +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/.github/ISSUE_TEMPLATE/bug-report.yml +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/.github/ISSUE_TEMPLATE/feature-request.yml +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/.github/dependabot.yml +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/.github/workflows/ci.yml +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/.github/workflows/codeql.yml +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/.github/workflows/dependabot-uv-lock.yml +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/.github/workflows/fuzz.yml +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/.github/workflows/harness-smoke.yml +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/.github/workflows/publish.yml +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/.github/workflows/scorecard.yml +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/.gitignore +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/.pre-commit-hooks.yaml +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/CONTRIBUTING.md +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/Dockerfile +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/LICENSE +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/SECURITY.md +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/dashboard/index.html +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/dashboard/package.json +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/dashboard/pnpm-lock.yaml +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/dashboard/public/apple-touch-icon.png +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/dashboard/public/brand/Logo_Icon_Dark.png +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/dashboard/public/brand/Logo_Whole.png +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/dashboard/public/favicon-16x16.png +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/dashboard/public/favicon-32x32.png +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/dashboard/public/favicon.ico +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/dashboard/src/app.tsx +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/dashboard/src/approval-center-layout.test.ts +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/dashboard/src/approval-center-layout.tsx +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/dashboard/src/approval-center-mobile.test.ts +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/dashboard/src/approval-center-primitives.tsx +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/dashboard/src/approval-center-review-cards.tsx +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/dashboard/src/approval-center-utils.ts +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/dashboard/src/data-flow-evidence-card.tsx +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/dashboard/src/fleet-workspace.tsx +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/dashboard/src/guard-api.test.ts +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/dashboard/src/guard-api.ts +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/dashboard/src/guard-demo.ts +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/dashboard/src/guard-types.ts +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/dashboard/src/home-dashboard.test.ts +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/dashboard/src/home-dashboard.tsx +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/dashboard/src/main.tsx +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/dashboard/src/queue-chip-filter.tsx +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/dashboard/src/queue-state.test.ts +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/dashboard/src/queue-state.ts +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/dashboard/src/receipts-workspace.test.ts +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/dashboard/src/receipts-workspace.tsx +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/dashboard/src/risk-signal-cards.test.ts +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/dashboard/src/risk-signal-cards.tsx +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/dashboard/src/runtime-overview.test.ts +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/dashboard/src/runtime-overview.tsx +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/dashboard/src/scanner-evidence-badge.tsx +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/dashboard/src/settings-workspace.test.ts +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/dashboard/src/settings-workspace.tsx +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/dashboard/src/styles.css +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/dashboard/src/vite-env.d.ts +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/dashboard/src/watched-app-card.tsx +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/dashboard/tsconfig.json +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/dashboard/vite.config.ts +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/docker-requirements.txt +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/docs/guard/approval-audit.md +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/docs/guard/architecture.md +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/docs/guard/get-started.md +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/docs/guard/harness-support.md +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/docs/guard/local-vs-cloud.md +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/docs/guard/release-checklist.md +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/docs/guard/release-notes.md +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/docs/guard/smoke-tests.md +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/docs/guard/testing-matrix.md +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/docs/trust/mcp-trust-draft.md +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/docs/trust/plugin-trust-draft.md +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/docs/trust/skill-trust-local.md +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/fuzzers/manifest_fuzzer.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/requirements.txt +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/schemas/plugin-quality.v1.json +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/schemas/scan-result.v1.json +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/schemas/verify-result.v1.json +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/__init__.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/action_runner.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/argparse_utils.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/checks/__init__.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/checks/best_practices.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/checks/claude.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/checks/code_quality.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/checks/ecosystem_common.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/checks/gemini.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/checks/manifest.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/checks/manifest_support.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/checks/marketplace.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/checks/mcp_security.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/checks/opencode.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/checks/operational_security.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/checks/security.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/checks/skill_security.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/cli.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/cli_ui.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/config.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/ecosystems/__init__.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/ecosystems/base.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/ecosystems/claude.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/ecosystems/codex.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/ecosystems/detect.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/ecosystems/gemini.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/ecosystems/opencode.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/ecosystems/registry.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/ecosystems/types.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/github_reporting.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/__init__.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/access_graph_events.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/adapters/__init__.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/adapters/antigravity.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/adapters/base.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/adapters/claude_code.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/adapters/cloud_identity.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/adapters/codex.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/adapters/contracts.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/adapters/copilot.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/adapters/cursor.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/adapters/gemini.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/adapters/mcp_servers.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/adapters/openclaw_config.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/adapters/openclaw_support.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/adapters/opencode.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/adapters/opencode_artifacts.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/advisory_model.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/approvals.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/bridge/__init__.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/capabilities.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/cli/__init__.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/cli/approval_commands.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/cli/bootstrap.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/cli/connect_flow.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/cli/install_commands.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/cli/product.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/cli/prompt.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/cli/render.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/cli/update_commands.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/codex_config.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/config.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/consumer/__init__.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/consumer/service.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/daemon/__init__.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/daemon/client.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/daemon/manager.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/daemon/server.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/daemon/static/apple-touch-icon.png +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/daemon/static/assets/guard-dashboard.js +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/daemon/static/assets/index.css +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/daemon/static/brand/Logo_Icon_Dark.png +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/daemon/static/brand/Logo_Whole.png +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/daemon/static/favicon-16x16.png +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/daemon/static/favicon-32x32.png +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/daemon/static/favicon.ico +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/daemon/static/index.html +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/edge_events.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/incident.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/insights.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/launcher.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/mcp_tool_calls.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/models.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/policy/__init__.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/policy/engine.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/protect.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/proxy/__init__.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/proxy/remote.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/proxy/runtime_mcp.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/proxy/stdio.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/receipts/__init__.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/receipts/manager.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/redaction.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/risk.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/runtime/__init__.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/runtime/action_identity.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/runtime/actions.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/runtime/advisory_escalation.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/runtime/advisory_matchers.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/runtime/cisco_evidence.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/runtime/cisco_preflight.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/runtime/composition_rules.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/runtime/data_flow.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/runtime/data_flow_rules.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/runtime/data_flow_variables.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/runtime/decisions.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/runtime/detectors.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/runtime/false_positive_rules.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/runtime/mcp_protection.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/runtime/persistence_rules.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/runtime/prompt_injection.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/runtime/runner.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/runtime/safe_decode.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/runtime/sandbox.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/runtime/scanner_cache.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/runtime/secret_file_requests.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/runtime/secret_sensitivity.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/runtime/secret_sources.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/runtime/shell_commands.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/runtime/signals.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/runtime/skill_protection.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/runtime/supply_chain.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/runtime/surface_server.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/runtime/temp_files.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/runtime/threat_intel.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/schemas/__init__.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/schemas/consumer_mode.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/schemas/guard_event_v1.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/schemas/surface_server.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/shims.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/store.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/store_approvals.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/store_connect.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/store_evidence.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/store_threat_intel.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/types.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/integrations/__init__.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/integrations/cisco_mcp_scanner.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/integrations/cisco_skill_scanner.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/lint_fixes.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/marketplace_support.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/models.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/path_support.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/policy.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/quality_artifact.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/repo_detect.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/reporting.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/rules/__init__.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/rules/registry.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/rules/specs.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/scanner.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/submission.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/suppressions.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/trust_domain_scoring.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/trust_helpers.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/trust_mcp_scoring.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/trust_models.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/trust_plugin_scoring.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/trust_scoring.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/trust_skill_scoring.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/trust_specs.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/verification.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/__init__.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/conftest.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/__init__.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/bad-plugin/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/bad-plugin/.mcp.json +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/bad-plugin/secrets.js +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/claude-plugin-good/.claude-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/claude-plugin-good/LICENSE +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/claude-plugin-good/README.md +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/claude-plugin-good/SECURITY.md +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/claude-plugin-good/hooks/hooks.json +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/claude-plugin-good/skills/example/SKILL.md +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/code-quality-bad/evil.js +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/code-quality-bad/inject.js +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/gemini-extension-good/GEMINI.md +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/gemini-extension-good/LICENSE +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/gemini-extension-good/README.md +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/gemini-extension-good/SECURITY.md +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/gemini-extension-good/commands/hello.toml +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/gemini-extension-good/gemini-extension.json +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/good-plugin/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/good-plugin/.codexignore +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/good-plugin/LICENSE +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/good-plugin/README.md +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/good-plugin/SECURITY.md +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/good-plugin/assets/icon.svg +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/good-plugin/assets/logo.svg +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/good-plugin/assets/screenshot.svg +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/good-plugin/skills/example/SKILL.md +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/guard-codex-malicious-mcp/.codex/config.toml +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/guard-red-team/README.md +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/guard-red-team/benign-docs-fake-token.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/guard-red-team/benign-health-endpoint.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/guard-red-team/benign-nvmrc-fake-creds.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/guard-red-team/benign-source-search.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/guard-red-team/canary-exfil-encoded.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/guard-red-team/canary-exfil.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/guard-red-team/expected-decisions.json +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/guard-red-team/malicious-dockerfile.txt +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/guard-red-team/malicious-encoded-shell-exfil.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/guard-red-team/malicious-github-action.yml +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/guard-red-team/malicious-mcp-delete.md +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/guard-red-team/malicious-mcp-secret-read.md +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/guard-red-team/malicious-mcp-skill-exfil.md +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/guard-red-team/malicious-npm-postinstall.js +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/guard-red-team/malicious-prompt-env-read.md +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/guard-red-team/malicious-prompt-guard-bypass.md +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/guard-red-team/malicious-prompt-npmrc-read.md +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/guard-red-team/malicious-python-setup.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/guard-red-team/smoke-evidence-template.json +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/hermes-plugin-evil/config.yaml +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/hermes-plugin-evil/mcp_servers.json +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/hermes-plugin-evil/skills/security/malicious/SKILL.md +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/hermes-plugin-evil/skills/stealth/sneaky/SKILL.md +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/hermes-plugin-evil/skills/stealth/sneaky/references/api-setup.md +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/hermes-plugin-evil/skills/stealth/sneaky/scripts/deploy.sh +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/hermes-plugin-evil/skills/utils/benign/SKILL.md +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/malformed-json/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/malicious-skill-plugin/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/malicious-skill-plugin/.codexignore +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/malicious-skill-plugin/LICENSE +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/malicious-skill-plugin/README.md +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/malicious-skill-plugin/SECURITY.md +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/malicious-skill-plugin/skills/leaky-skill/SKILL.md +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/mcp-canary-server.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/minimal-plugin/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/missing-fields/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/mit-license/LICENSE +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/multi-ecosystem-repo/codex-plugin/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/multi-ecosystem-repo/codex-plugin/LICENSE +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/multi-ecosystem-repo/codex-plugin/README.md +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/multi-ecosystem-repo/codex-plugin/SECURITY.md +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/multi-ecosystem-repo/gemini-ext/README.md +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/multi-ecosystem-repo/gemini-ext/gemini-extension.json +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/multi-plugin-repo/.agents/plugins/marketplace.json +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/.codexignore +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/LICENSE +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/README.md +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/SECURITY.md +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/skills/example/SKILL.md +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/multi-plugin-repo/plugins/beta-plugin/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/multi-plugin-repo/plugins/beta-plugin/skills/example/SKILL.md +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/no-version/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/opencode-good/.opencode/commands/hello.md +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/opencode-good/.opencode/plugins/example.ts +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/opencode-good/LICENSE +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/opencode-good/README.md +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/opencode-good/SECURITY.md +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/opencode-good/opencode.jsonc +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/skills-missing-dir/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/skills-no-frontmatter/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/skills-no-frontmatter/skills/bad-skill/SKILL.md +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/supply-chain/benign-npm-package.json +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/supply-chain/benign-pnpm-package.json +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/supply-chain/benign-pyproject.toml +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/supply-chain/malicious-Dockerfile +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/supply-chain/malicious-action.yml +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/supply-chain/malicious-npm-package.json +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/supply-chain/malicious-setup.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/with-marketplace/.codex-plugin/plugin.json +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/with-marketplace/marketplace-broken.json +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/fixtures/with-marketplace/marketplace.json +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test-trust-scoring.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test-trust-specs.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_action_runner.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_best_practices.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_cisco_install_surfaces.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_cli.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_code_quality.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_config.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_coverage_remaining.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_ecosystems.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_edge_cases.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_final_coverage.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_access_graph.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_action_identity.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_advisory_escalation.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_approval_continuity.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_approval_copy_commands.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_approval_store_dedup.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_approval_store_scale.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_approvals.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_bootstrap.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_bypass_detector.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_canary_fixtures.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_capabilities.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_cisco_evidence.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_cisco_runtime_cli.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_claude_adapter.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_cli.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_cloud_local_sync.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_codex_e2e.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_codex_install.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_codex_proxy.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_config_paths.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_connect_flow.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_consumer_mode.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_copilot_adapter.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_copilot_proxy.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_daemon_cli.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_daemon_manager.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_daemon_perf.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_daemon_registry.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_daemon_repair_perf.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_daemon_wake.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_data_flow.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_decision_propagation.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_detector_fp.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_event_schema_v1.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_events.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_evidence_store.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_harness_contracts.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_harness_setup.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_harness_smoke.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_insights.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_launch_env.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_mcp_detectors.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_mcp_protection.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_opencode_proxy.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_policy_dedup.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_product_flow.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_prompt_injection.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_protect.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_queue_api_contract.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_queue_contract.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_red_team.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_red_team_e2e.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_redaction.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_render.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_resolution_copy.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_risk.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_runtime_action_harnesses.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_runtime_actions.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_runtime_decisions.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_runtime_detectors.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_runtime_signals.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_safe_decode.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_sandbox.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_settings_presets.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_skill_protection.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_store_migrations.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_supply_chain.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_surface_server.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_threat_intel.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_verdicts.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_guard_web_recovery.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_integration.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_lint_fixes.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_live_cisco_smoke.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_manifest.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_marketplace.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_mcp_security.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_operational_security.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_policy.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_quality_artifact.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_rule_registry.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_scanner.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_schema_contracts.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_security.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_security_ops.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_skill_security.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_submission.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_trust_scoring.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_trust_specs.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_verification.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/tests/test_versioning.py +0 -0
- {plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/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.173
|
|
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
|
|
@@ -275,6 +275,8 @@ pip install "plugin-scanner[cisco]"
|
|
|
275
275
|
|
|
276
276
|
On Guard surfaces, the Cisco extra adds optional offline evidence to `hol-guard scan`, `hol-guard preflight`, and `hol-guard explain <path>`. Use `--cisco-mode {auto,on,off}` to control that consumer-mode evidence path for local artifact scans. `hol-guard run` and Guard runtime prompt/file-read protection remain native Guard behavior in this pass.
|
|
277
277
|
|
|
278
|
+
Guard inventory snapshots can also carry Cisco MCP and skill-scanner status when a Hermes or OpenClaw inventory run explicitly enables those scanners. The Cloud evidence model records scanner source, status, redacted finding text, duration, mapped artifact ID, and risk component metadata without storing raw local paths or secrets.
|
|
279
|
+
|
|
278
280
|
Guard does not add Cisco AIBOM runtime integration in this pass. If AIBOM support returns later, it should stay on evidence or export surfaces rather than Guard blocking or approval logic.
|
|
279
281
|
|
|
280
282
|
### Cisco package status
|
|
@@ -235,6 +235,8 @@ pip install "plugin-scanner[cisco]"
|
|
|
235
235
|
|
|
236
236
|
On Guard surfaces, the Cisco extra adds optional offline evidence to `hol-guard scan`, `hol-guard preflight`, and `hol-guard explain <path>`. Use `--cisco-mode {auto,on,off}` to control that consumer-mode evidence path for local artifact scans. `hol-guard run` and Guard runtime prompt/file-read protection remain native Guard behavior in this pass.
|
|
237
237
|
|
|
238
|
+
Guard inventory snapshots can also carry Cisco MCP and skill-scanner status when a Hermes or OpenClaw inventory run explicitly enables those scanners. The Cloud evidence model records scanner source, status, redacted finding text, duration, mapped artifact ID, and risk component metadata without storing raw local paths or secrets.
|
|
239
|
+
|
|
238
240
|
Guard does not add Cisco AIBOM runtime integration in this pass. If AIBOM support returns later, it should stay on evidence or export surfaces rather than Guard blocking or approval logic.
|
|
239
241
|
|
|
240
242
|
### Cisco package status
|
|
@@ -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.173"
|
|
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.173"
|
|
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.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/adapters/hermes.py
RENAMED
|
@@ -13,6 +13,7 @@ import re
|
|
|
13
13
|
import sys
|
|
14
14
|
from pathlib import Path
|
|
15
15
|
|
|
16
|
+
from ..inventory_cisco import run_cisco_inventory_scans
|
|
16
17
|
from ..inventory_contract import GuardAgentInventorySnapshot, inventory_snapshot_from_detection
|
|
17
18
|
from ..models import GuardArtifact, HarnessDetection
|
|
18
19
|
from ..shims import install_guard_shim, remove_guard_shim
|
|
@@ -247,12 +248,29 @@ class HermesHarnessAdapter(HarnessAdapter):
|
|
|
247
248
|
config_paths=tuple(found_paths),
|
|
248
249
|
)
|
|
249
250
|
|
|
250
|
-
def inventory_snapshot(
|
|
251
|
+
def inventory_snapshot(
|
|
252
|
+
self,
|
|
253
|
+
context: HarnessContext,
|
|
254
|
+
*,
|
|
255
|
+
generated_at: str,
|
|
256
|
+
cisco_mcp_scan: str = "off",
|
|
257
|
+
cisco_skill_scan: str = "off",
|
|
258
|
+
cisco_timeout_seconds: float | None = None,
|
|
259
|
+
) -> GuardAgentInventorySnapshot:
|
|
260
|
+
detection = self.detect(context)
|
|
251
261
|
return inventory_snapshot_from_detection(
|
|
252
|
-
|
|
262
|
+
detection,
|
|
253
263
|
generated_at=generated_at,
|
|
254
264
|
home_dir=context.home_dir,
|
|
255
265
|
workspace_dir=context.workspace_dir,
|
|
266
|
+
cisco_runs=run_cisco_inventory_scans(
|
|
267
|
+
harness=self.harness,
|
|
268
|
+
context=context,
|
|
269
|
+
detection=detection,
|
|
270
|
+
mcp_mode=cisco_mcp_scan,
|
|
271
|
+
skill_mode=cisco_skill_scan,
|
|
272
|
+
timeout_seconds=cisco_timeout_seconds,
|
|
273
|
+
),
|
|
256
274
|
)
|
|
257
275
|
|
|
258
276
|
# ------------------------------------------------------------------
|
|
@@ -5,6 +5,7 @@ from __future__ import annotations
|
|
|
5
5
|
import json
|
|
6
6
|
from pathlib import Path
|
|
7
7
|
|
|
8
|
+
from ..inventory_cisco import run_cisco_inventory_scans
|
|
8
9
|
from ..inventory_contract import GuardAgentInventorySnapshot, inventory_snapshot_from_detection
|
|
9
10
|
from ..models import GuardArtifact, HarnessDetection
|
|
10
11
|
from ..shims import install_guard_shim, remove_guard_shim
|
|
@@ -65,12 +66,29 @@ class OpenClawHarnessAdapter(HarnessAdapter):
|
|
|
65
66
|
artifacts=tuple(artifacts),
|
|
66
67
|
)
|
|
67
68
|
|
|
68
|
-
def inventory_snapshot(
|
|
69
|
+
def inventory_snapshot(
|
|
70
|
+
self,
|
|
71
|
+
context: HarnessContext,
|
|
72
|
+
*,
|
|
73
|
+
generated_at: str,
|
|
74
|
+
cisco_mcp_scan: str = "off",
|
|
75
|
+
cisco_skill_scan: str = "off",
|
|
76
|
+
cisco_timeout_seconds: float | None = None,
|
|
77
|
+
) -> GuardAgentInventorySnapshot:
|
|
78
|
+
detection = self.detect(context)
|
|
69
79
|
return inventory_snapshot_from_detection(
|
|
70
|
-
|
|
80
|
+
detection,
|
|
71
81
|
generated_at=generated_at,
|
|
72
82
|
home_dir=context.home_dir,
|
|
73
83
|
workspace_dir=context.workspace_dir,
|
|
84
|
+
cisco_runs=run_cisco_inventory_scans(
|
|
85
|
+
harness=self.harness,
|
|
86
|
+
context=context,
|
|
87
|
+
detection=detection,
|
|
88
|
+
mcp_mode=cisco_mcp_scan,
|
|
89
|
+
skill_mode=cisco_skill_scan,
|
|
90
|
+
timeout_seconds=cisco_timeout_seconds,
|
|
91
|
+
),
|
|
74
92
|
)
|
|
75
93
|
|
|
76
94
|
def install(self, context: HarnessContext) -> dict[str, object]:
|
{plugin_scanner-2.0.171 → plugin_scanner-2.0.173}/src/codex_plugin_scanner/guard/cli/commands.py
RENAMED
|
@@ -5170,6 +5170,9 @@ def _codex_command_is_read_only_source_inspection(command_text: str, *, cwd: Pat
|
|
|
5170
5170
|
return False
|
|
5171
5171
|
if _codex_command_has_unquoted_glob_metachar(command):
|
|
5172
5172
|
return False
|
|
5173
|
+
chained_segments = _split_codex_safe_read_only_chain(command)
|
|
5174
|
+
if chained_segments is not None:
|
|
5175
|
+
return all(_codex_command_is_read_only_source_inspection(segment, cwd=cwd) for segment in chained_segments)
|
|
5173
5176
|
segments = _split_codex_safe_read_only_pipeline(command)
|
|
5174
5177
|
if segments is None:
|
|
5175
5178
|
return _codex_command_is_read_only_source_search(command, cwd=cwd) or _codex_command_is_read_only_source_view(
|
|
@@ -5186,6 +5189,53 @@ def _codex_command_is_read_only_source_inspection(command_text: str, *, cwd: Pat
|
|
|
5186
5189
|
return all(_codex_command_is_bounded_read_only_filter(segment) for segment in filter_segments)
|
|
5187
5190
|
|
|
5188
5191
|
|
|
5192
|
+
def _split_codex_safe_read_only_chain(command: str) -> list[str] | None:
|
|
5193
|
+
segments: list[str] = []
|
|
5194
|
+
start = 0
|
|
5195
|
+
quote: str | None = None
|
|
5196
|
+
escaped = False
|
|
5197
|
+
found_chain = False
|
|
5198
|
+
index = 0
|
|
5199
|
+
while index < len(command):
|
|
5200
|
+
char = command[index]
|
|
5201
|
+
if escaped:
|
|
5202
|
+
escaped = False
|
|
5203
|
+
index += 1
|
|
5204
|
+
continue
|
|
5205
|
+
if char == "\\":
|
|
5206
|
+
escaped = True
|
|
5207
|
+
index += 1
|
|
5208
|
+
continue
|
|
5209
|
+
if quote is not None:
|
|
5210
|
+
if char == quote:
|
|
5211
|
+
quote = None
|
|
5212
|
+
index += 1
|
|
5213
|
+
continue
|
|
5214
|
+
if char in {"'", '"'}:
|
|
5215
|
+
quote = char
|
|
5216
|
+
index += 1
|
|
5217
|
+
continue
|
|
5218
|
+
if command.startswith("&&", index):
|
|
5219
|
+
segment = command[start:index].strip()
|
|
5220
|
+
if not segment:
|
|
5221
|
+
return None
|
|
5222
|
+
segments.append(segment)
|
|
5223
|
+
found_chain = True
|
|
5224
|
+
index += 2
|
|
5225
|
+
start = index
|
|
5226
|
+
continue
|
|
5227
|
+
if command.startswith("||", index) or char in {";", "&"}:
|
|
5228
|
+
return None
|
|
5229
|
+
index += 1
|
|
5230
|
+
if quote is not None or escaped or not found_chain:
|
|
5231
|
+
return None
|
|
5232
|
+
segment = command[start:].strip()
|
|
5233
|
+
if not segment:
|
|
5234
|
+
return None
|
|
5235
|
+
segments.append(segment)
|
|
5236
|
+
return segments if len(segments) > 1 else None
|
|
5237
|
+
|
|
5238
|
+
|
|
5189
5239
|
def _codex_command_has_unquoted_glob_metachar(command: str) -> bool:
|
|
5190
5240
|
quote: str | None = None
|
|
5191
5241
|
escaped = False
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"""Cisco scanner bridge for Guard inventory snapshots."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import time
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from typing import Literal
|
|
9
|
+
|
|
10
|
+
from ..integrations.cisco_mcp_scanner import run_cisco_mcp_scan
|
|
11
|
+
from ..integrations.cisco_skill_scanner import run_cisco_skill_scan
|
|
12
|
+
from ..models import Finding
|
|
13
|
+
from .adapters.base import HarnessContext
|
|
14
|
+
|
|
15
|
+
CiscoInventorySource = Literal["cisco-mcp-scanner", "cisco-skill-scanner"]
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@dataclass(frozen=True, slots=True)
|
|
19
|
+
class CiscoInventoryRun:
|
|
20
|
+
source: CiscoInventorySource
|
|
21
|
+
status: str
|
|
22
|
+
message: str
|
|
23
|
+
findings: tuple[Finding, ...]
|
|
24
|
+
duration_ms: int
|
|
25
|
+
metadata: dict[str, object]
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def run_cisco_inventory_scans(
|
|
29
|
+
*,
|
|
30
|
+
harness: str,
|
|
31
|
+
context: HarnessContext,
|
|
32
|
+
detection: object,
|
|
33
|
+
mcp_mode: str = "off",
|
|
34
|
+
skill_mode: str = "off",
|
|
35
|
+
timeout_seconds: float | None = None,
|
|
36
|
+
) -> tuple[CiscoInventoryRun, ...]:
|
|
37
|
+
runs: list[CiscoInventoryRun] = []
|
|
38
|
+
if mcp_mode != "off":
|
|
39
|
+
runs.append(_run_mcp_inventory_scan(context=context, mode=mcp_mode, timeout_seconds=timeout_seconds))
|
|
40
|
+
if skill_mode != "off":
|
|
41
|
+
runs.append(
|
|
42
|
+
_run_skill_inventory_scan(
|
|
43
|
+
harness=harness,
|
|
44
|
+
context=context,
|
|
45
|
+
detection=detection,
|
|
46
|
+
mode=skill_mode,
|
|
47
|
+
timeout_seconds=timeout_seconds,
|
|
48
|
+
)
|
|
49
|
+
)
|
|
50
|
+
return tuple(runs)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def _run_mcp_inventory_scan(
|
|
54
|
+
*,
|
|
55
|
+
context: HarnessContext,
|
|
56
|
+
mode: str,
|
|
57
|
+
timeout_seconds: float | None,
|
|
58
|
+
) -> CiscoInventoryRun:
|
|
59
|
+
root = _mcp_scan_root(context)
|
|
60
|
+
if root is None:
|
|
61
|
+
return CiscoInventoryRun(
|
|
62
|
+
source="cisco-mcp-scanner",
|
|
63
|
+
status="skipped",
|
|
64
|
+
message="No .mcp.json found; Cisco MCP inventory scan skipped.",
|
|
65
|
+
findings=(),
|
|
66
|
+
duration_ms=0,
|
|
67
|
+
metadata={"target": "missing", "targetsScanned": 0, "mode": mode},
|
|
68
|
+
)
|
|
69
|
+
started = time.perf_counter()
|
|
70
|
+
summary = run_cisco_mcp_scan(root, mode=mode, timeout_seconds=timeout_seconds)
|
|
71
|
+
duration_ms = int((time.perf_counter() - started) * 1000)
|
|
72
|
+
return CiscoInventoryRun(
|
|
73
|
+
source="cisco-mcp-scanner",
|
|
74
|
+
status=str(summary.status.value),
|
|
75
|
+
message=summary.message,
|
|
76
|
+
findings=summary.findings,
|
|
77
|
+
duration_ms=duration_ms,
|
|
78
|
+
metadata={
|
|
79
|
+
"target": root.name,
|
|
80
|
+
"targetsScanned": summary.targets_scanned,
|
|
81
|
+
"totalFindings": summary.total_findings,
|
|
82
|
+
"findingsBySeverity": summary.findings_by_severity,
|
|
83
|
+
"analyzersUsed": summary.analyzers_used,
|
|
84
|
+
"scanMode": summary.scan_mode,
|
|
85
|
+
"mode": mode,
|
|
86
|
+
},
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def _run_skill_inventory_scan(
|
|
91
|
+
*,
|
|
92
|
+
harness: str,
|
|
93
|
+
context: HarnessContext,
|
|
94
|
+
detection: object,
|
|
95
|
+
mode: str,
|
|
96
|
+
timeout_seconds: float | None,
|
|
97
|
+
) -> CiscoInventoryRun:
|
|
98
|
+
root = _skill_scan_root(harness=harness, context=context, detection=detection)
|
|
99
|
+
if root is None:
|
|
100
|
+
return CiscoInventoryRun(
|
|
101
|
+
source="cisco-skill-scanner",
|
|
102
|
+
status="skipped",
|
|
103
|
+
message="No skill directory found; Cisco skill inventory scan skipped.",
|
|
104
|
+
findings=(),
|
|
105
|
+
duration_ms=0,
|
|
106
|
+
metadata={"target": "missing", "skillsScanned": 0, "mode": mode},
|
|
107
|
+
)
|
|
108
|
+
started = time.perf_counter()
|
|
109
|
+
summary = run_cisco_skill_scan(root, mode=mode, timeout_seconds=timeout_seconds)
|
|
110
|
+
duration_ms = int((time.perf_counter() - started) * 1000)
|
|
111
|
+
return CiscoInventoryRun(
|
|
112
|
+
source="cisco-skill-scanner",
|
|
113
|
+
status=str(summary.status.value),
|
|
114
|
+
message=summary.message,
|
|
115
|
+
findings=summary.findings,
|
|
116
|
+
duration_ms=duration_ms,
|
|
117
|
+
metadata={
|
|
118
|
+
"target": root.name,
|
|
119
|
+
"skillsScanned": summary.skills_scanned,
|
|
120
|
+
"skillsSkipped": summary.skills_skipped,
|
|
121
|
+
"totalFindings": summary.total_findings,
|
|
122
|
+
"findingsBySeverity": summary.findings_by_severity,
|
|
123
|
+
"analyzersUsed": summary.analyzers_used,
|
|
124
|
+
"policyName": summary.policy_name,
|
|
125
|
+
"mode": mode,
|
|
126
|
+
},
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def _mcp_scan_root(context: HarnessContext) -> Path | None:
|
|
131
|
+
candidates = []
|
|
132
|
+
if context.workspace_dir is not None:
|
|
133
|
+
candidates.append(context.workspace_dir)
|
|
134
|
+
candidates.append(context.home_dir)
|
|
135
|
+
for candidate in candidates:
|
|
136
|
+
if (candidate / ".mcp.json").is_file():
|
|
137
|
+
return candidate
|
|
138
|
+
return None
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def _skill_scan_root(*, harness: str, context: HarnessContext, detection: object) -> Path | None:
|
|
142
|
+
if harness == "hermes":
|
|
143
|
+
hermes_skills = context.home_dir / ".hermes" / "skills"
|
|
144
|
+
if hermes_skills.is_dir():
|
|
145
|
+
return hermes_skills
|
|
146
|
+
artifacts = tuple(getattr(detection, "artifacts", ()))
|
|
147
|
+
for artifact in artifacts:
|
|
148
|
+
artifact_type = str(getattr(artifact, "artifact_type", ""))
|
|
149
|
+
if artifact_type not in {"skill", "skill_file"}:
|
|
150
|
+
continue
|
|
151
|
+
metadata = getattr(artifact, "metadata", {})
|
|
152
|
+
if isinstance(metadata, dict):
|
|
153
|
+
skill_root = metadata.get("skill_root")
|
|
154
|
+
if isinstance(skill_root, str):
|
|
155
|
+
root = Path(skill_root)
|
|
156
|
+
if root.is_dir():
|
|
157
|
+
return root
|
|
158
|
+
config_path = getattr(artifact, "config_path", None)
|
|
159
|
+
if not isinstance(config_path, str):
|
|
160
|
+
continue
|
|
161
|
+
skill_path = Path(config_path)
|
|
162
|
+
root = _nearest_skills_root(skill_path)
|
|
163
|
+
if root is not None and root.is_dir():
|
|
164
|
+
return root
|
|
165
|
+
root = _nearest_skill_dir(skill_path)
|
|
166
|
+
if root is not None and root.is_dir():
|
|
167
|
+
return root
|
|
168
|
+
return None
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
def _nearest_skills_root(path: Path) -> Path | None:
|
|
172
|
+
for parent in path.parents:
|
|
173
|
+
if parent.name == "skills":
|
|
174
|
+
return parent
|
|
175
|
+
return None
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def _nearest_skill_dir(path: Path) -> Path | None:
|
|
179
|
+
if path.name == "SKILL.md":
|
|
180
|
+
return path.parent
|
|
181
|
+
for parent in path.parents:
|
|
182
|
+
if (parent / "SKILL.md").is_file():
|
|
183
|
+
return parent
|
|
184
|
+
return None
|
|
@@ -64,6 +64,7 @@ _SENSITIVE_KEY_RE = re.compile(
|
|
|
64
64
|
r"(auth|authorization|bearer|token|secret|password|credential|api[^a-z0-9]?key)",
|
|
65
65
|
re.IGNORECASE,
|
|
66
66
|
)
|
|
67
|
+
_SENSITIVE_VALUE_RE = re.compile(r"(?i)(gh[pousr]_[a-z0-9_]+|sk-[a-z0-9_-]+|guard_live_[a-z0-9_-]+|bearer\s+\S+)")
|
|
67
68
|
_WHITESPACE_RE = re.compile(r"\s+")
|
|
68
69
|
_MCP_READ_RE = re.compile(
|
|
69
70
|
r"(?<![a-z0-9])(read|reads|reading|search|searches|list|lists)(?![a-z0-9])",
|
|
@@ -217,6 +218,7 @@ def inventory_snapshot_from_detection(
|
|
|
217
218
|
home_dir: Path,
|
|
218
219
|
workspace_dir: Path | None = None,
|
|
219
220
|
runtime_version: str | None = None,
|
|
221
|
+
cisco_runs: tuple[object, ...] = (),
|
|
220
222
|
) -> GuardAgentInventorySnapshot:
|
|
221
223
|
harness = str(getattr(detection, "harness", "unknown"))
|
|
222
224
|
artifacts = tuple(getattr(detection, "artifacts", ()))
|
|
@@ -231,7 +233,7 @@ def inventory_snapshot_from_detection(
|
|
|
231
233
|
items.append(item)
|
|
232
234
|
items.extend(_mcp_tool_items_from_artifact(harness, artifact, item))
|
|
233
235
|
config_paths = tuple(dict.fromkeys(str(path) for path in getattr(detection, "config_paths", ())))
|
|
234
|
-
|
|
236
|
+
config_sources = tuple(
|
|
235
237
|
GuardInventorySource(
|
|
236
238
|
source_id=f"{harness}:config:{fingerprint_text(redact_local_path(path, home_dir=home_dir))[:12]}",
|
|
237
239
|
source_type="config",
|
|
@@ -241,11 +243,19 @@ def inventory_snapshot_from_detection(
|
|
|
241
243
|
)
|
|
242
244
|
for path in config_paths
|
|
243
245
|
)
|
|
246
|
+
cisco_findings = _cisco_inventory_findings(
|
|
247
|
+
cisco_runs,
|
|
248
|
+
items=tuple(items),
|
|
249
|
+
home_dir=home_dir,
|
|
250
|
+
workspace_dir=workspace_dir,
|
|
251
|
+
)
|
|
252
|
+
sources = (*config_sources, *_cisco_inventory_sources(cisco_runs))
|
|
244
253
|
snapshot_hash = fingerprint_mapping(
|
|
245
254
|
{
|
|
246
255
|
"agent_type": harness,
|
|
247
256
|
"generated_at": generated_at,
|
|
248
257
|
"item_ids": [item.item_id for item in items],
|
|
258
|
+
"finding_ids": [finding.finding_id for finding in cisco_findings],
|
|
249
259
|
}
|
|
250
260
|
)
|
|
251
261
|
return GuardAgentInventorySnapshot(
|
|
@@ -255,10 +265,11 @@ def inventory_snapshot_from_detection(
|
|
|
255
265
|
generated_at=generated_at,
|
|
256
266
|
runtime_version=runtime_version,
|
|
257
267
|
items=tuple(items),
|
|
268
|
+
findings=cisco_findings,
|
|
258
269
|
sources=sources,
|
|
259
270
|
redaction_report={
|
|
260
271
|
"rawSecretsIncluded": False,
|
|
261
|
-
"redactedFields": ("headers", "env", "url", "paths"),
|
|
272
|
+
"redactedFields": ("headers", "env", "url", "paths", "ciscoFindingText"),
|
|
262
273
|
},
|
|
263
274
|
)
|
|
264
275
|
|
|
@@ -542,6 +553,162 @@ def _risk_level_for_capabilities(capabilities: tuple[InventoryCapability, ...])
|
|
|
542
553
|
return "info"
|
|
543
554
|
|
|
544
555
|
|
|
556
|
+
def _cisco_inventory_findings(
|
|
557
|
+
cisco_runs: tuple[object, ...],
|
|
558
|
+
*,
|
|
559
|
+
items: tuple[GuardAgentInventoryItem, ...],
|
|
560
|
+
home_dir: Path,
|
|
561
|
+
workspace_dir: Path | None,
|
|
562
|
+
) -> tuple[GuardAgentInventoryFinding, ...]:
|
|
563
|
+
findings: list[GuardAgentInventoryFinding] = []
|
|
564
|
+
seen: set[str] = set()
|
|
565
|
+
for run in cisco_runs:
|
|
566
|
+
source = _cisco_source(run)
|
|
567
|
+
if source is None:
|
|
568
|
+
continue
|
|
569
|
+
run_status = str(getattr(run, "status", "unknown"))
|
|
570
|
+
run_message = _safe_finding_text(
|
|
571
|
+
str(getattr(run, "message", "")),
|
|
572
|
+
home_dir=home_dir,
|
|
573
|
+
workspace_dir=workspace_dir,
|
|
574
|
+
)
|
|
575
|
+
duration_ms = getattr(run, "duration_ms", None)
|
|
576
|
+
for raw_finding in tuple(getattr(run, "findings", ()) or ()):
|
|
577
|
+
rule_id = str(getattr(raw_finding, "rule_id", "cisco-finding") or "cisco-finding")
|
|
578
|
+
title = _safe_finding_text(
|
|
579
|
+
str(getattr(raw_finding, "title", "Cisco scanner finding") or "Cisco scanner finding"),
|
|
580
|
+
home_dir=home_dir,
|
|
581
|
+
workspace_dir=workspace_dir,
|
|
582
|
+
)
|
|
583
|
+
file_path = getattr(raw_finding, "file_path", None)
|
|
584
|
+
safe_path = (
|
|
585
|
+
_redact_known_path(str(file_path), home_dir, workspace_dir)
|
|
586
|
+
if isinstance(file_path, str) and file_path
|
|
587
|
+
else None
|
|
588
|
+
)
|
|
589
|
+
line_number = getattr(raw_finding, "line_number", None)
|
|
590
|
+
finding_hash = fingerprint_mapping(
|
|
591
|
+
{
|
|
592
|
+
"source": source,
|
|
593
|
+
"rule_id": rule_id,
|
|
594
|
+
"title": title,
|
|
595
|
+
"path": safe_path,
|
|
596
|
+
"line": line_number if isinstance(line_number, int) else None,
|
|
597
|
+
}
|
|
598
|
+
)
|
|
599
|
+
finding_id = f"{source}:{rule_id}:{finding_hash[:16]}"
|
|
600
|
+
if finding_id in seen:
|
|
601
|
+
continue
|
|
602
|
+
seen.add(finding_id)
|
|
603
|
+
severity = _inventory_severity(getattr(raw_finding, "severity", "info"))
|
|
604
|
+
findings.append(
|
|
605
|
+
GuardAgentInventoryFinding(
|
|
606
|
+
finding_id=finding_id,
|
|
607
|
+
source=source,
|
|
608
|
+
severity=severity,
|
|
609
|
+
confidence="high" if run_status == "enabled" else "unknown",
|
|
610
|
+
title=title,
|
|
611
|
+
artifact_id=_artifact_id_for_cisco_finding(safe_path, items),
|
|
612
|
+
check_id=rule_id,
|
|
613
|
+
summary=_safe_finding_text(
|
|
614
|
+
str(getattr(raw_finding, "description", "") or ""),
|
|
615
|
+
home_dir=home_dir,
|
|
616
|
+
workspace_dir=workspace_dir,
|
|
617
|
+
),
|
|
618
|
+
evidence={
|
|
619
|
+
"scannerStatus": run_status,
|
|
620
|
+
"scannerMessage": run_message,
|
|
621
|
+
"filePath": safe_path,
|
|
622
|
+
"lineNumber": line_number if isinstance(line_number, int) else None,
|
|
623
|
+
"durationMs": duration_ms if isinstance(duration_ms, int) else None,
|
|
624
|
+
"riskComponent": {
|
|
625
|
+
"source": source,
|
|
626
|
+
"severity": severity,
|
|
627
|
+
"confidence": "high" if run_status == "enabled" else "unknown",
|
|
628
|
+
"scoreDelta": _score_delta_for_severity(severity),
|
|
629
|
+
},
|
|
630
|
+
},
|
|
631
|
+
)
|
|
632
|
+
)
|
|
633
|
+
return tuple(findings)
|
|
634
|
+
|
|
635
|
+
|
|
636
|
+
def _cisco_inventory_sources(cisco_runs: tuple[object, ...]) -> tuple[GuardInventorySource, ...]:
|
|
637
|
+
sources: list[GuardInventorySource] = []
|
|
638
|
+
for run in cisco_runs:
|
|
639
|
+
source = _cisco_source(run)
|
|
640
|
+
if source is None:
|
|
641
|
+
continue
|
|
642
|
+
status = str(getattr(run, "status", "unknown"))
|
|
643
|
+
detail = _safe_source_detail(run)
|
|
644
|
+
sources.append(
|
|
645
|
+
GuardInventorySource(
|
|
646
|
+
source_id=f"{source}:{fingerprint_mapping({'status': status, 'detail': detail})[:12]}",
|
|
647
|
+
source_type="scanner",
|
|
648
|
+
status=_source_status_for_cisco_status(status),
|
|
649
|
+
detail=detail,
|
|
650
|
+
)
|
|
651
|
+
)
|
|
652
|
+
return tuple(sources)
|
|
653
|
+
|
|
654
|
+
|
|
655
|
+
def _cisco_source(run: object) -> InventoryFindingSource | None:
|
|
656
|
+
source = str(getattr(run, "source", ""))
|
|
657
|
+
if source in {"cisco-mcp-scanner", "cisco-skill-scanner"}:
|
|
658
|
+
return source
|
|
659
|
+
return None
|
|
660
|
+
|
|
661
|
+
|
|
662
|
+
def _inventory_severity(value: object) -> InventorySeverity:
|
|
663
|
+
severity_value = str(getattr(value, "value", value)).strip().lower()
|
|
664
|
+
if severity_value in {"critical", "high", "medium", "low", "info"}:
|
|
665
|
+
return severity_value
|
|
666
|
+
return "info"
|
|
667
|
+
|
|
668
|
+
|
|
669
|
+
def _score_delta_for_severity(severity: InventorySeverity) -> int:
|
|
670
|
+
return {"critical": -40, "high": -25, "medium": -12, "low": -5, "info": 0}[severity]
|
|
671
|
+
|
|
672
|
+
|
|
673
|
+
def _artifact_id_for_cisco_finding(
|
|
674
|
+
safe_path: str | None,
|
|
675
|
+
items: tuple[GuardAgentInventoryItem, ...],
|
|
676
|
+
) -> str:
|
|
677
|
+
if safe_path is None:
|
|
678
|
+
return "unknown"
|
|
679
|
+
for item in items:
|
|
680
|
+
config_path = item.metadata.get("configPath")
|
|
681
|
+
if isinstance(config_path, str) and (config_path == safe_path or config_path.endswith(safe_path)):
|
|
682
|
+
return item.item_id
|
|
683
|
+
return "unknown"
|
|
684
|
+
|
|
685
|
+
|
|
686
|
+
def _source_status_for_cisco_status(status: str) -> Literal["available", "missing", "failed"]:
|
|
687
|
+
if status == "enabled":
|
|
688
|
+
return "available"
|
|
689
|
+
if status in {"failed", "timed_out"}:
|
|
690
|
+
return "failed"
|
|
691
|
+
return "missing"
|
|
692
|
+
|
|
693
|
+
|
|
694
|
+
def _safe_source_detail(run: object) -> str:
|
|
695
|
+
status = str(getattr(run, "status", "unknown"))
|
|
696
|
+
metadata = getattr(run, "metadata", {})
|
|
697
|
+
finding_count = None
|
|
698
|
+
if isinstance(metadata, dict):
|
|
699
|
+
candidate = metadata.get("totalFindings")
|
|
700
|
+
if isinstance(candidate, int):
|
|
701
|
+
finding_count = candidate
|
|
702
|
+
suffix = f", findings={finding_count}" if finding_count is not None else ""
|
|
703
|
+
return f"status={status}{suffix}"
|
|
704
|
+
|
|
705
|
+
|
|
706
|
+
def _safe_finding_text(value: str, *, home_dir: Path, workspace_dir: Path | None) -> str:
|
|
707
|
+
redacted = _SENSITIVE_VALUE_RE.sub("redacted", value)
|
|
708
|
+
redacted = _redact_command_value(redacted, home_dir, workspace_dir)
|
|
709
|
+
return redacted[:500]
|
|
710
|
+
|
|
711
|
+
|
|
545
712
|
def _agent_type(value: str) -> AgentInventoryType:
|
|
546
713
|
for agent_type in _AGENT_INVENTORY_TYPES:
|
|
547
714
|
if value == agent_type:
|