plugin-scanner 2.0.72__tar.gz → 2.0.74__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.
Files changed (333) hide show
  1. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/PKG-INFO +5 -5
  2. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/dashboard/pnpm-lock.yaml +4 -4
  3. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/dashboard/src/approval-center-layout.tsx +119 -37
  4. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/dashboard/src/approval-center-primitives.tsx +3 -2
  5. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/dashboard/src/settings-workspace.tsx +97 -22
  6. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/docker-requirements.txt +324 -181
  7. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/pyproject.toml +15 -5
  8. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/pyproject.toml.bak +15 -5
  9. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/adapters/copilot.py +10 -4
  10. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/cli/commands.py +22 -4
  11. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/cli/render.py +34 -2
  12. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/config.py +8 -0
  13. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/daemon/manager.py +0 -6
  14. plugin_scanner-2.0.74/src/codex_plugin_scanner/guard/daemon/static/assets/guard-dashboard.js +9 -0
  15. plugin_scanner-2.0.74/src/codex_plugin_scanner/guard/daemon/static/assets/index.css +1 -0
  16. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/risk.py +4 -1
  17. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/runtime/secret_file_requests.py +176 -24
  18. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/version.py +1 -1
  19. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_cisco_install_surfaces.py +26 -3
  20. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_guard_config_paths.py +24 -0
  21. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_guard_copilot_adapter.py +6 -9
  22. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_guard_daemon_manager.py +2 -2
  23. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_guard_render.py +65 -0
  24. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_guard_risk.py +258 -0
  25. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_guard_runtime.py +84 -3
  26. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/uv.lock +405 -187
  27. plugin_scanner-2.0.72/src/codex_plugin_scanner/guard/daemon/static/assets/guard-dashboard.js +0 -9
  28. plugin_scanner-2.0.72/src/codex_plugin_scanner/guard/daemon/static/assets/index.css +0 -1
  29. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/.clusterfuzzlite/Dockerfile +0 -0
  30. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/.clusterfuzzlite/build.sh +0 -0
  31. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/.clusterfuzzlite/project.yaml +0 -0
  32. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/.clusterfuzzlite/requirements-atheris.txt +0 -0
  33. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/.dockerignore +0 -0
  34. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/.github/CODEOWNERS +0 -0
  35. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/.github/ISSUE_TEMPLATE/bug-report.yml +0 -0
  36. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  37. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/.github/ISSUE_TEMPLATE/feature-request.yml +0 -0
  38. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/.github/dependabot.yml +0 -0
  39. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/.github/workflows/ci.yml +0 -0
  40. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/.github/workflows/codeql.yml +0 -0
  41. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/.github/workflows/dependabot-uv-lock.yml +0 -0
  42. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/.github/workflows/fuzz.yml +0 -0
  43. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/.github/workflows/harness-smoke.yml +0 -0
  44. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/.github/workflows/publish.yml +0 -0
  45. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/.github/workflows/scorecard.yml +0 -0
  46. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/.gitignore +0 -0
  47. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/.pre-commit-hooks.yaml +0 -0
  48. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/CONTRIBUTING.md +0 -0
  49. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/Dockerfile +0 -0
  50. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/LICENSE +0 -0
  51. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/README.md +0 -0
  52. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/SECURITY.md +0 -0
  53. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/dashboard/index.html +0 -0
  54. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/dashboard/package.json +0 -0
  55. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/dashboard/public/apple-touch-icon.png +0 -0
  56. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/dashboard/public/brand/Logo_Icon_Dark.png +0 -0
  57. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/dashboard/public/brand/Logo_Whole.png +0 -0
  58. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/dashboard/public/favicon-16x16.png +0 -0
  59. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/dashboard/public/favicon-32x32.png +0 -0
  60. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/dashboard/public/favicon.ico +0 -0
  61. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/dashboard/src/app.tsx +0 -0
  62. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/dashboard/src/approval-center-utils.ts +0 -0
  63. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/dashboard/src/fleet-workspace.tsx +0 -0
  64. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/dashboard/src/guard-api.ts +0 -0
  65. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/dashboard/src/guard-demo.ts +0 -0
  66. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/dashboard/src/guard-types.ts +0 -0
  67. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/dashboard/src/main.tsx +0 -0
  68. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/dashboard/src/receipts-workspace.tsx +0 -0
  69. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/dashboard/src/runtime-overview.tsx +0 -0
  70. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/dashboard/src/styles.css +0 -0
  71. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/dashboard/src/vite-env.d.ts +0 -0
  72. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/dashboard/tsconfig.json +0 -0
  73. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/dashboard/vite.config.ts +0 -0
  74. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/docs/guard/approval-audit.md +0 -0
  75. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/docs/guard/architecture.md +0 -0
  76. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/docs/guard/get-started.md +0 -0
  77. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/docs/guard/harness-support.md +0 -0
  78. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/docs/guard/local-vs-cloud.md +0 -0
  79. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/docs/guard/testing-matrix.md +0 -0
  80. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/docs/trust/mcp-trust-draft.md +0 -0
  81. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/docs/trust/plugin-trust-draft.md +0 -0
  82. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/docs/trust/skill-trust-local.md +0 -0
  83. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/fuzzers/manifest_fuzzer.py +0 -0
  84. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/requirements.txt +0 -0
  85. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/schemas/plugin-quality.v1.json +0 -0
  86. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/schemas/scan-result.v1.json +0 -0
  87. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/schemas/verify-result.v1.json +0 -0
  88. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/__init__.py +0 -0
  89. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/action_runner.py +0 -0
  90. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/argparse_utils.py +0 -0
  91. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/checks/__init__.py +0 -0
  92. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/checks/best_practices.py +0 -0
  93. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/checks/claude.py +0 -0
  94. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/checks/code_quality.py +0 -0
  95. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/checks/ecosystem_common.py +0 -0
  96. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/checks/gemini.py +0 -0
  97. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/checks/manifest.py +0 -0
  98. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/checks/manifest_support.py +0 -0
  99. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/checks/marketplace.py +0 -0
  100. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/checks/mcp_security.py +0 -0
  101. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/checks/opencode.py +0 -0
  102. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/checks/operational_security.py +0 -0
  103. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/checks/security.py +0 -0
  104. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/checks/skill_security.py +0 -0
  105. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/cli.py +0 -0
  106. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/cli_ui.py +0 -0
  107. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/config.py +0 -0
  108. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/ecosystems/__init__.py +0 -0
  109. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/ecosystems/base.py +0 -0
  110. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/ecosystems/claude.py +0 -0
  111. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/ecosystems/codex.py +0 -0
  112. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/ecosystems/detect.py +0 -0
  113. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/ecosystems/gemini.py +0 -0
  114. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/ecosystems/opencode.py +0 -0
  115. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/ecosystems/registry.py +0 -0
  116. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/ecosystems/types.py +0 -0
  117. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/github_reporting.py +0 -0
  118. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/__init__.py +0 -0
  119. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/adapters/__init__.py +0 -0
  120. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/adapters/antigravity.py +0 -0
  121. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/adapters/base.py +0 -0
  122. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/adapters/claude_code.py +0 -0
  123. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/adapters/codex.py +0 -0
  124. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/adapters/cursor.py +0 -0
  125. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/adapters/gemini.py +0 -0
  126. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/adapters/hermes.py +0 -0
  127. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/adapters/mcp_servers.py +0 -0
  128. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/adapters/opencode.py +0 -0
  129. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/adapters/opencode_artifacts.py +0 -0
  130. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/approvals.py +0 -0
  131. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/bridge/__init__.py +0 -0
  132. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/capabilities.py +0 -0
  133. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/cli/__init__.py +0 -0
  134. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/cli/approval_commands.py +0 -0
  135. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/cli/bootstrap.py +0 -0
  136. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/cli/connect_flow.py +0 -0
  137. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/cli/install_commands.py +0 -0
  138. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/cli/product.py +0 -0
  139. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/cli/prompt.py +0 -0
  140. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/cli/update_commands.py +0 -0
  141. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/codex_config.py +0 -0
  142. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/consumer/__init__.py +0 -0
  143. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/consumer/service.py +0 -0
  144. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/daemon/__init__.py +0 -0
  145. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/daemon/client.py +0 -0
  146. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/daemon/server.py +0 -0
  147. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/daemon/static/apple-touch-icon.png +0 -0
  148. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/daemon/static/brand/Logo_Icon_Dark.png +0 -0
  149. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/daemon/static/brand/Logo_Whole.png +0 -0
  150. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/daemon/static/favicon-16x16.png +0 -0
  151. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/daemon/static/favicon-32x32.png +0 -0
  152. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/daemon/static/favicon.ico +0 -0
  153. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/daemon/static/index.html +0 -0
  154. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/edge_events.py +0 -0
  155. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/incident.py +0 -0
  156. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/launcher.py +0 -0
  157. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/mcp_tool_calls.py +0 -0
  158. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/models.py +0 -0
  159. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/policy/__init__.py +0 -0
  160. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/policy/engine.py +0 -0
  161. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/protect.py +0 -0
  162. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/proxy/__init__.py +0 -0
  163. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/proxy/remote.py +0 -0
  164. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/proxy/runtime_mcp.py +0 -0
  165. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/proxy/stdio.py +0 -0
  166. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/receipts/__init__.py +0 -0
  167. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/receipts/manager.py +0 -0
  168. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/runtime/__init__.py +0 -0
  169. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/runtime/runner.py +0 -0
  170. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/runtime/surface_server.py +0 -0
  171. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/schemas/__init__.py +0 -0
  172. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/schemas/consumer_mode.py +0 -0
  173. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/schemas/guard_event_v1.py +0 -0
  174. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/schemas/surface_server.py +0 -0
  175. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/shims.py +0 -0
  176. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/store.py +0 -0
  177. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/store_approvals.py +0 -0
  178. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/store_connect.py +0 -0
  179. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/guard/types.py +0 -0
  180. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/integrations/__init__.py +0 -0
  181. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/integrations/cisco_mcp_scanner.py +0 -0
  182. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/integrations/cisco_skill_scanner.py +0 -0
  183. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/lint_fixes.py +0 -0
  184. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/marketplace_support.py +0 -0
  185. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/models.py +0 -0
  186. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/path_support.py +0 -0
  187. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/policy.py +0 -0
  188. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/quality_artifact.py +0 -0
  189. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/repo_detect.py +0 -0
  190. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/reporting.py +0 -0
  191. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/rules/__init__.py +0 -0
  192. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/rules/registry.py +0 -0
  193. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/rules/specs.py +0 -0
  194. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/scanner.py +0 -0
  195. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/submission.py +0 -0
  196. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/suppressions.py +0 -0
  197. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/trust_domain_scoring.py +0 -0
  198. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/trust_helpers.py +0 -0
  199. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/trust_mcp_scoring.py +0 -0
  200. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/trust_models.py +0 -0
  201. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/trust_plugin_scoring.py +0 -0
  202. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/trust_scoring.py +0 -0
  203. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/trust_skill_scoring.py +0 -0
  204. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/trust_specs.py +0 -0
  205. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/src/codex_plugin_scanner/verification.py +0 -0
  206. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/__init__.py +0 -0
  207. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/conftest.py +0 -0
  208. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/__init__.py +0 -0
  209. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/bad-plugin/.codex-plugin/plugin.json +0 -0
  210. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/bad-plugin/.mcp.json +0 -0
  211. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/bad-plugin/secrets.js +0 -0
  212. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/claude-plugin-good/.claude-plugin/plugin.json +0 -0
  213. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/claude-plugin-good/LICENSE +0 -0
  214. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/claude-plugin-good/README.md +0 -0
  215. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/claude-plugin-good/SECURITY.md +0 -0
  216. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/claude-plugin-good/hooks/hooks.json +0 -0
  217. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/claude-plugin-good/skills/example/SKILL.md +0 -0
  218. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/code-quality-bad/evil.js +0 -0
  219. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/code-quality-bad/inject.js +0 -0
  220. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/gemini-extension-good/GEMINI.md +0 -0
  221. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/gemini-extension-good/LICENSE +0 -0
  222. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/gemini-extension-good/README.md +0 -0
  223. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/gemini-extension-good/SECURITY.md +0 -0
  224. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/gemini-extension-good/commands/hello.toml +0 -0
  225. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/gemini-extension-good/gemini-extension.json +0 -0
  226. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/good-plugin/.codex-plugin/plugin.json +0 -0
  227. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/good-plugin/.codexignore +0 -0
  228. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/good-plugin/LICENSE +0 -0
  229. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/good-plugin/README.md +0 -0
  230. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/good-plugin/SECURITY.md +0 -0
  231. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/good-plugin/assets/icon.svg +0 -0
  232. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/good-plugin/assets/logo.svg +0 -0
  233. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/good-plugin/assets/screenshot.svg +0 -0
  234. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/good-plugin/skills/example/SKILL.md +0 -0
  235. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/guard-codex-malicious-mcp/.codex/config.toml +0 -0
  236. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/hermes-plugin-evil/config.yaml +0 -0
  237. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/hermes-plugin-evil/mcp_servers.json +0 -0
  238. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/hermes-plugin-evil/skills/security/malicious/SKILL.md +0 -0
  239. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/hermes-plugin-evil/skills/stealth/sneaky/SKILL.md +0 -0
  240. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/hermes-plugin-evil/skills/stealth/sneaky/references/api-setup.md +0 -0
  241. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/hermes-plugin-evil/skills/stealth/sneaky/scripts/deploy.sh +0 -0
  242. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/hermes-plugin-evil/skills/utils/benign/SKILL.md +0 -0
  243. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/malformed-json/.codex-plugin/plugin.json +0 -0
  244. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/malicious-skill-plugin/.codex-plugin/plugin.json +0 -0
  245. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/malicious-skill-plugin/.codexignore +0 -0
  246. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/malicious-skill-plugin/LICENSE +0 -0
  247. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/malicious-skill-plugin/README.md +0 -0
  248. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/malicious-skill-plugin/SECURITY.md +0 -0
  249. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/malicious-skill-plugin/skills/leaky-skill/SKILL.md +0 -0
  250. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/mcp-canary-server.py +0 -0
  251. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/minimal-plugin/.codex-plugin/plugin.json +0 -0
  252. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/missing-fields/.codex-plugin/plugin.json +0 -0
  253. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/mit-license/LICENSE +0 -0
  254. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/multi-ecosystem-repo/codex-plugin/.codex-plugin/plugin.json +0 -0
  255. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/multi-ecosystem-repo/codex-plugin/LICENSE +0 -0
  256. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/multi-ecosystem-repo/codex-plugin/README.md +0 -0
  257. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/multi-ecosystem-repo/codex-plugin/SECURITY.md +0 -0
  258. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/multi-ecosystem-repo/gemini-ext/README.md +0 -0
  259. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/multi-ecosystem-repo/gemini-ext/gemini-extension.json +0 -0
  260. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/multi-plugin-repo/.agents/plugins/marketplace.json +0 -0
  261. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/.codex-plugin/plugin.json +0 -0
  262. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/.codexignore +0 -0
  263. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/LICENSE +0 -0
  264. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/README.md +0 -0
  265. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/SECURITY.md +0 -0
  266. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/skills/example/SKILL.md +0 -0
  267. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/multi-plugin-repo/plugins/beta-plugin/.codex-plugin/plugin.json +0 -0
  268. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/multi-plugin-repo/plugins/beta-plugin/skills/example/SKILL.md +0 -0
  269. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/no-version/.codex-plugin/plugin.json +0 -0
  270. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/opencode-good/.opencode/commands/hello.md +0 -0
  271. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/opencode-good/.opencode/plugins/example.ts +0 -0
  272. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/opencode-good/LICENSE +0 -0
  273. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/opencode-good/README.md +0 -0
  274. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/opencode-good/SECURITY.md +0 -0
  275. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/opencode-good/opencode.jsonc +0 -0
  276. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/skills-missing-dir/.codex-plugin/plugin.json +0 -0
  277. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/skills-no-frontmatter/.codex-plugin/plugin.json +0 -0
  278. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/skills-no-frontmatter/skills/bad-skill/SKILL.md +0 -0
  279. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/with-marketplace/.codex-plugin/plugin.json +0 -0
  280. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/with-marketplace/marketplace-broken.json +0 -0
  281. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/fixtures/with-marketplace/marketplace.json +0 -0
  282. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test-trust-scoring.py +0 -0
  283. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test-trust-specs.py +0 -0
  284. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_action_runner.py +0 -0
  285. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_best_practices.py +0 -0
  286. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_cli.py +0 -0
  287. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_code_quality.py +0 -0
  288. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_config.py +0 -0
  289. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_coverage_remaining.py +0 -0
  290. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_ecosystems.py +0 -0
  291. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_edge_cases.py +0 -0
  292. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_final_coverage.py +0 -0
  293. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_guard_approvals.py +0 -0
  294. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_guard_bootstrap.py +0 -0
  295. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_guard_capabilities.py +0 -0
  296. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_guard_claude_adapter.py +0 -0
  297. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_guard_cli.py +0 -0
  298. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_guard_codex_e2e.py +0 -0
  299. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_guard_codex_install.py +0 -0
  300. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_guard_codex_proxy.py +0 -0
  301. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_guard_connect_flow.py +0 -0
  302. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_guard_consumer_mode.py +0 -0
  303. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_guard_copilot_proxy.py +0 -0
  304. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_guard_event_schema_v1.py +0 -0
  305. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_guard_events.py +0 -0
  306. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_guard_launch_env.py +0 -0
  307. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_guard_opencode_proxy.py +0 -0
  308. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_guard_product_flow.py +0 -0
  309. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_guard_protect.py +0 -0
  310. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_guard_store_migrations.py +0 -0
  311. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_guard_surface_server.py +0 -0
  312. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_guard_verdicts.py +0 -0
  313. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_hermes_adapter.py +0 -0
  314. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_integration.py +0 -0
  315. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_lint_fixes.py +0 -0
  316. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_live_cisco_smoke.py +0 -0
  317. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_manifest.py +0 -0
  318. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_marketplace.py +0 -0
  319. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_mcp_security.py +0 -0
  320. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_operational_security.py +0 -0
  321. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_policy.py +0 -0
  322. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_quality_artifact.py +0 -0
  323. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_rule_registry.py +0 -0
  324. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_scanner.py +0 -0
  325. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_schema_contracts.py +0 -0
  326. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_security.py +0 -0
  327. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_security_ops.py +0 -0
  328. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_skill_security.py +0 -0
  329. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_submission.py +0 -0
  330. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_trust_scoring.py +0 -0
  331. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_trust_specs.py +0 -0
  332. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_verification.py +0 -0
  333. {plugin_scanner-2.0.72 → plugin_scanner-2.0.74}/tests/test_versioning.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: plugin-scanner
3
- Version: 2.0.72
3
+ Version: 2.0.74
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
@@ -21,15 +21,15 @@ Classifier: Programming Language :: Python :: 3.13
21
21
  Classifier: Topic :: Security
22
22
  Classifier: Topic :: Software Development :: Quality Assurance
23
23
  Requires-Python: >=3.10
24
- Requires-Dist: cisco-ai-skill-scanner~=2.0.8
25
- Requires-Dist: cryptography>=46.0.0
24
+ Requires-Dist: cisco-ai-skill-scanner~=2.0.9
25
+ Requires-Dist: cryptography>=47.0.0
26
26
  Requires-Dist: rich>=13.0
27
27
  Requires-Dist: tomli>=2.0; python_version < '3.11'
28
28
  Provides-Extra: cisco
29
- Requires-Dist: cisco-ai-mcp-scanner~=4.5; (python_version >= '3.11') and extra == 'cisco'
29
+ Requires-Dist: cisco-ai-mcp-scanner~=4.6; (python_version >= '3.11') and extra == 'cisco'
30
30
  Provides-Extra: dev
31
31
  Requires-Dist: build>=1.2.2; extra == 'dev'
32
- Requires-Dist: jsonschema>=4.26.0; extra == 'dev'
32
+ Requires-Dist: jsonschema>=4.23.0; extra == 'dev'
33
33
  Requires-Dist: pytest-cov>=7.1.0; extra == 'dev'
34
34
  Requires-Dist: pytest>=9.0.3; extra == 'dev'
35
35
  Requires-Dist: pyyaml>=6.0.3; extra == 'dev'
@@ -724,8 +724,8 @@ packages:
724
724
  resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==}
725
725
  engines: {node: '>=12'}
726
726
 
727
- postcss@8.5.9:
728
- resolution: {integrity: sha512-7a70Nsot+EMX9fFU3064K/kdHWZqGVY+BADLyXc8Dfv+mTLLVl6JzJpPaCZ2kQL9gIJvKXSLMHhqdRRjwQeFtw==}
727
+ postcss@8.5.12:
728
+ resolution: {integrity: sha512-W62t/Se6rA0Az3DfCL0AqJwXuKwBeYg6nOaIgzP+xZ7N5BFCI7DYi1qs6ygUYT6rvfi6t9k65UMLJC+PHZpDAA==}
729
729
  engines: {node: ^10 || ^12 || >=14}
730
730
 
731
731
  react-dom@19.2.5:
@@ -1372,7 +1372,7 @@ snapshots:
1372
1372
 
1373
1373
  picomatch@4.0.4: {}
1374
1374
 
1375
- postcss@8.5.9:
1375
+ postcss@8.5.12:
1376
1376
  dependencies:
1377
1377
  nanoid: 3.3.11
1378
1378
  picocolors: 1.1.1
@@ -1450,7 +1450,7 @@ snapshots:
1450
1450
  esbuild: 0.27.7
1451
1451
  fdir: 6.5.0(picomatch@4.0.4)
1452
1452
  picomatch: 4.0.4
1453
- postcss: 8.5.9
1453
+ postcss: 8.5.12
1454
1454
  rollup: 4.60.1
1455
1455
  tinyglobby: 0.2.16
1456
1456
  optionalDependencies:
@@ -1,5 +1,12 @@
1
1
  import type { ReactNode } from "react";
2
2
  import { useState, useEffect, useCallback, useMemo, type ChangeEvent } from "react";
3
+ import {
4
+ HiMiniClipboard,
5
+ HiMiniClipboardDocumentCheck,
6
+ HiMiniExclamationTriangle,
7
+ HiMiniNoSymbol,
8
+ HiMiniArrowTopRightOnSquare,
9
+ } from "react-icons/hi2";
3
10
  import {
4
11
  ShellHeader,
5
12
  ShellSidebar,
@@ -603,6 +610,7 @@ function RuleBuilder(props: {
603
610
  allowLabel={allowLabel}
604
611
  previewText={previewText}
605
612
  submitting={props.submitting}
613
+ isBlocked={props.item.policy_action === "block"}
606
614
  onAllow={() => props.onResolve("allow")}
607
615
  onBlock={() => props.onResolve("block")}
608
616
  />
@@ -614,10 +622,13 @@ function RuleBuilder(props: {
614
622
  <BlockedActionCard item={props.item} />
615
623
  <div className="space-y-4">
616
624
  <div>
617
- <SectionLabel>Trust level</SectionLabel>
625
+ <SectionLabel>Approval scope</SectionLabel>
618
626
  <p className="mt-2 text-sm leading-6 text-brand-dark/75">
619
627
  {buildRecommendation(props.item)}
620
628
  </p>
629
+ <p className="mt-1 text-xs text-muted-foreground">
630
+ Start with the narrowest scope. Broader trust is harder to undo.
631
+ </p>
621
632
  </div>
622
633
  <fieldset className="space-y-3">
623
634
  <legend className="sr-only">Approval scope</legend>
@@ -635,19 +646,24 @@ function RuleBuilder(props: {
635
646
  </div>
636
647
  <details>
637
648
  <summary className="cursor-pointer select-none py-1 font-mono text-[11px] font-semibold uppercase tracking-[0.2em] text-muted-foreground transition-colors hover:text-brand-dark/70 [&::-webkit-details-marker]:hidden">
638
- Advanced trust levels
649
+ Broader approval scopes
639
650
  </summary>
640
- <div className="mt-2 grid gap-2 sm:grid-cols-3 xl:grid-cols-1">
641
- {props.broadScopeOptions.map((option) => (
642
- <ScopeOption
643
- key={option.value}
644
- value={option.value}
645
- label={option.label}
646
- description={option.description}
647
- checked={props.scope === option.value}
648
- onChange={() => props.onScopeChange(option.value)}
649
- />
650
- ))}
651
+ <div className="mt-2 rounded-[1rem] border border-amber-200/60 bg-amber-50/50 p-2 dark:border-amber-500/20 dark:bg-amber-900/10">
652
+ <p className="mb-2 px-1 text-[11px] font-medium text-amber-700 dark:text-amber-400">
653
+ Broader scopes apply across more sessions. Use only when the narrower options are not enough.
654
+ </p>
655
+ <div className="grid gap-2 sm:grid-cols-3 xl:grid-cols-1">
656
+ {props.broadScopeOptions.map((option) => (
657
+ <ScopeOption
658
+ key={option.value}
659
+ value={option.value}
660
+ label={option.label}
661
+ description={option.description}
662
+ checked={props.scope === option.value}
663
+ onChange={() => props.onScopeChange(option.value)}
664
+ />
665
+ ))}
666
+ </div>
651
667
  </div>
652
668
  </details>
653
669
  </fieldset>
@@ -677,6 +693,7 @@ function DecisionActionPanel(props: {
677
693
  allowLabel: string;
678
694
  previewText: string;
679
695
  submitting: "allow" | "block" | null;
696
+ isBlocked: boolean;
680
697
  onAllow: () => void;
681
698
  onBlock: () => void;
682
699
  }) {
@@ -687,11 +704,11 @@ function DecisionActionPanel(props: {
687
704
  {props.previewText}
688
705
  </p>
689
706
  <div className="mt-4 grid gap-2">
690
- <ActionButton onClick={props.onAllow} disabled={props.submitting !== null}>
691
- {props.submitting === "allow" ? "Saving…" : props.allowLabel}
707
+ <ActionButton variant="success" onClick={props.onAllow} disabled={props.submitting !== null}>
708
+ {props.submitting === "allow" ? "Saving…" : (props.isBlocked ? "Allow — override block" : props.allowLabel)}
692
709
  </ActionButton>
693
710
  <ActionButton variant="danger" onClick={props.onBlock} disabled={props.submitting !== null}>
694
- {props.submitting === "block" ? "Saving…" : "Keep blocked"}
711
+ {props.submitting === "block" ? "Saving…" : (props.isBlocked ? "Keep blocked" : "Block this action")}
695
712
  </ActionButton>
696
713
  </div>
697
714
  <p className="mt-3 text-xs leading-5 text-muted-foreground">
@@ -734,32 +751,97 @@ function DecisionSteps(props: { activeStep: number }) {
734
751
  );
735
752
  }
736
753
 
754
+ function CopyCommandButton(props: { command: string }) {
755
+ const [copied, setCopied] = useState(false);
756
+
757
+ const handleCopy = useCallback(() => {
758
+ void navigator.clipboard?.writeText(props.command)?.then(() => {
759
+ setCopied(true);
760
+ const timer = setTimeout(() => setCopied(false), 2000);
761
+ return timer;
762
+ });
763
+ }, [props.command]);
764
+
765
+ return (
766
+ <button
767
+ type="button"
768
+ onClick={handleCopy}
769
+ aria-label="Copy command to clipboard"
770
+ className="inline-flex items-center gap-1.5 rounded-full border border-white/20 bg-white/10 px-2.5 py-1 font-mono text-[10px] font-semibold uppercase tracking-[0.18em] text-white/70 transition-colors hover:bg-white/20 hover:text-white"
771
+ >
772
+ {copied ? (
773
+ <HiMiniClipboardDocumentCheck className="h-3.5 w-3.5" aria-hidden="true" />
774
+ ) : (
775
+ <HiMiniClipboard className="h-3.5 w-3.5" aria-hidden="true" />
776
+ )}
777
+ {copied ? "Copied" : "Copy"}
778
+ </button>
779
+ );
780
+ }
781
+
737
782
  function BlockedActionCard(props: { item: GuardApprovalRequest }) {
738
783
  const launchText = actionLaunchText(props.item);
784
+ const isBlocked = props.item.policy_action === "block";
785
+ const bannerBg = isBlocked
786
+ ? "bg-gradient-to-r from-brand-purple/90 to-brand-purple/75"
787
+ : "bg-gradient-to-r from-brand-blue/85 to-brand-dark/80";
788
+ const bannerLabel = isBlocked ? "Blocked" : "Paused for review";
789
+ const bannerIcon = isBlocked ? HiMiniNoSymbol : HiMiniExclamationTriangle;
790
+ const BannerIcon = bannerIcon;
791
+
739
792
  return (
740
- <div className="rounded-[1.65rem] border border-brand-blue/15 bg-white/70 p-4 shadow-[inset_0_1px_0_rgba(255,255,255,0.85)]">
741
- <div className="flex flex-wrap items-center justify-between gap-2">
742
- <SectionLabel>What was stopped</SectionLabel>
743
- <Badge tone="warning">{artifactTypeLabel(props.item.artifact_type)}</Badge>
793
+ <div className="overflow-hidden rounded-[1.65rem] border border-brand-blue/15 bg-white/70 shadow-[inset_0_1px_0_rgba(255,255,255,0.85)]">
794
+ <div className={`flex items-center gap-2 px-4 py-2.5 ${bannerBg}`}>
795
+ <BannerIcon className="h-3.5 w-3.5 shrink-0 text-white" aria-hidden="true" />
796
+ <span className="font-mono text-[11px] font-semibold uppercase tracking-[0.2em] text-white">
797
+ {bannerLabel}
798
+ </span>
799
+ {props.item.approval_url ? (
800
+ <a
801
+ href={props.item.approval_url}
802
+ target="_blank"
803
+ rel="noreferrer"
804
+ className="ml-auto inline-flex items-center gap-1 font-mono text-[10px] font-semibold uppercase tracking-[0.18em] text-white/80 transition-colors hover:text-white"
805
+ >
806
+ Approval link
807
+ <HiMiniArrowTopRightOnSquare className="h-3 w-3" aria-hidden="true" />
808
+ </a>
809
+ ) : null}
744
810
  </div>
745
- <h4 className="mt-2 text-xl font-semibold tracking-tight text-brand-dark">
746
- {actionDisplayTitle(props.item)}
747
- </h4>
748
- <p className="mt-2 text-sm leading-6 text-brand-dark/70">
749
- {harnessDisplayName(props.item.harness)} paused this because {buildQueueSummary(props.item).toLowerCase()}.
750
- </p>
751
- <div className="mt-4 rounded-[1.25rem] bg-[#090d1a] p-1 shadow-[0_14px_35px_rgba(9,13,26,0.18)]">
752
- <div className="flex items-center gap-1.5 border-b border-white/10 px-3 py-2">
753
- <span className="h-2.5 w-2.5 rounded-full bg-brand-purple" />
754
- <span className="h-2.5 w-2.5 rounded-full bg-brand-blue" />
755
- <span className="h-2.5 w-2.5 rounded-full bg-brand-green" />
756
- <span className="ml-2 font-mono text-[10px] uppercase tracking-[0.22em] text-white/45">
757
- Command or tool details
758
- </span>
811
+ <div className="p-4">
812
+ <div className="flex flex-wrap items-center justify-between gap-2">
813
+ <SectionLabel>What was stopped</SectionLabel>
814
+ <Badge tone="warning">{artifactTypeLabel(props.item.artifact_type)}</Badge>
815
+ </div>
816
+ <h4 className="mt-2 text-xl font-semibold tracking-tight text-brand-dark">
817
+ {actionDisplayTitle(props.item)}
818
+ </h4>
819
+ <p className="mt-2 text-sm leading-6 text-brand-dark/70">
820
+ {harnessDisplayName(props.item.harness)} paused this because {buildQueueSummary(props.item).toLowerCase()}.
821
+ </p>
822
+ <div className="mt-4 rounded-[1.25rem] bg-[#090d1a] p-1 shadow-[0_14px_35px_rgba(9,13,26,0.18)]">
823
+ <div className="flex items-center gap-1.5 border-b border-white/10 px-3 py-2">
824
+ <span className="h-2.5 w-2.5 rounded-full bg-brand-purple" />
825
+ <span className="h-2.5 w-2.5 rounded-full bg-brand-blue" />
826
+ <span className="h-2.5 w-2.5 rounded-full bg-brand-green" />
827
+ <span className="ml-2 font-mono text-[10px] uppercase tracking-[0.22em] text-white/45">
828
+ Stopped command
829
+ </span>
830
+ <span className="ml-auto">
831
+ <CopyCommandButton command={launchText} />
832
+ </span>
833
+ </div>
834
+ <pre className="overflow-x-auto whitespace-pre-wrap break-words px-3 py-3 font-mono text-sm leading-6 text-white">
835
+ {launchText}
836
+ </pre>
759
837
  </div>
760
- <pre className="overflow-x-auto whitespace-pre-wrap break-words px-3 py-3 font-mono text-sm leading-6 text-white">
761
- {launchText}
762
- </pre>
838
+ {isBlocked && (
839
+ <div className="mt-3 rounded-[1rem] border border-brand-purple/20 bg-brand-purple/[0.05] px-3 py-2.5">
840
+ <p className="text-sm leading-6 text-brand-purple">
841
+ HOL Guard blocked this based on a saved decision. If this is a false positive, choose <span className="font-semibold">Allow</span> below and pick how broadly to remember the override.
842
+ </p>
843
+ </div>
844
+ )}
763
845
  </div>
764
846
  </div>
765
847
  );
@@ -282,7 +282,7 @@ export function ActionButton(props: {
282
282
  children: ReactNode;
283
283
  onClick?: () => void;
284
284
  href?: string;
285
- variant?: "primary" | "secondary" | "danger" | "outline" | "ghost";
285
+ variant?: "primary" | "secondary" | "danger" | "outline" | "ghost" | "success";
286
286
  disabled?: boolean;
287
287
  }) {
288
288
  const className = actionButtonClass(props.variant);
@@ -460,13 +460,14 @@ function tagToneClass(tone: "blue" | "green" | "purple" | "slate" | "red" | unde
460
460
  return "border-transparent bg-blue-500/10 text-blue-700";
461
461
  }
462
462
 
463
- function actionButtonClass(variant: "primary" | "secondary" | "danger" | "outline" | "ghost" | undefined): string {
463
+ function actionButtonClass(variant: "primary" | "secondary" | "danger" | "outline" | "ghost" | "success" | undefined): string {
464
464
  const base = "inline-flex items-center justify-center rounded-lg text-sm font-semibold ring-offset-background transition-[color,background-color,border-color,opacity,transform,box-shadow] duration-150 active:scale-[0.98] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-blue/40 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 min-w-0";
465
465
  const sizeDefault = "min-h-11 h-auto px-4 py-2";
466
466
  if (variant === "outline") return `${base} ${sizeDefault} border border-slate-200 bg-white hover:bg-slate-50 hover:border-slate-300 text-slate-900`;
467
467
  if (variant === "secondary") return `${base} ${sizeDefault} border border-slate-200 bg-white hover:bg-slate-50 hover:border-slate-300 text-slate-900`;
468
468
  if (variant === "ghost") return `${base} ${sizeDefault} hover:bg-slate-100 hover:text-slate-900`;
469
469
  if (variant === "danger") return `${base} ${sizeDefault} bg-brand-purple text-white shadow-lg shadow-brand-blue/10 hover:bg-brand-purple/90 hover:shadow-brand-blue/20`;
470
+ if (variant === "success") return `${base} ${sizeDefault} bg-[#059669] text-white shadow-lg shadow-emerald-500/15 hover:bg-[#047857] hover:shadow-emerald-500/20`;
470
471
  return `${base} ${sizeDefault} bg-brand-blue text-white shadow-lg shadow-brand-blue/20 hover:bg-brand-blue/90 hover:shadow-brand-blue/30`;
471
472
  }
472
473
 
@@ -1,4 +1,10 @@
1
1
  import { useCallback, useEffect, useState, type ChangeEvent } from "react";
2
+ import {
3
+ HiMiniShieldCheck,
4
+ HiMiniLockClosed,
5
+ HiMiniCog6Tooth,
6
+ HiMiniCheckCircle,
7
+ } from "react-icons/hi2";
2
8
 
3
9
  import {
4
10
  ActionButton,
@@ -34,17 +40,26 @@ const securityLevels = [
34
40
  {
35
41
  value: "balanced",
36
42
  label: "Balanced",
37
- description: "Ask before secret access, hidden execution, exfiltration, and destructive actions."
43
+ description: "Ask before secret access, hidden execution, exfiltration, and destructive actions.",
44
+ icon: HiMiniShieldCheck,
45
+ protects: ["Secret file access", "Credential sharing", "Destructive shell commands", "Hidden scripts"],
46
+ tone: "blue" as const,
38
47
  },
39
48
  {
40
49
  value: "strict",
41
50
  label: "Strict",
42
- description: "Ask more often, including new network destinations."
51
+ description: "Ask more often, including new network destinations.",
52
+ icon: HiMiniLockClosed,
53
+ protects: ["Everything in Balanced", "New network destinations"],
54
+ tone: "purple" as const,
43
55
  },
44
56
  {
45
57
  value: "custom",
46
58
  label: "Custom",
47
- description: "Use the exact choices below for this machine and connected apps."
59
+ description: "Use the exact choices below for this machine and connected apps.",
60
+ icon: HiMiniCog6Tooth,
61
+ protects: [],
62
+ tone: "slate" as const,
48
63
  }
49
64
  ] as const;
50
65
 
@@ -306,22 +321,58 @@ export function SettingsWorkspace() {
306
321
  <div className="space-y-6">
307
322
  <div className="rounded-[1.75rem] border border-slate-200/70 bg-white/80 p-5 shadow-sm">
308
323
  <SectionLabel>Security level</SectionLabel>
324
+ <p className="mt-2 text-sm leading-6 text-muted-foreground">
325
+ Pick a level to set up all risk choices at once. Switch to Custom only when you need to override individual behaviors.
326
+ </p>
309
327
  <div className="mt-4 grid gap-3 md:grid-cols-3">
310
- {securityLevels.map((level) => (
311
- <button
312
- key={level.value}
313
- type="button"
314
- onClick={() => handleSecurityLevelChange(level.value)}
315
- className={`min-h-32 rounded-[1.5rem] border p-4 text-left transition-all duration-150 ${
316
- draft.security_level === level.value
317
- ? "border-brand-blue/35 bg-brand-blue/[0.07] shadow-[0_12px_32px_rgba(85,153,254,0.14)]"
318
- : "border-transparent bg-surface-1/80 hover:bg-white"
319
- }`}
320
- >
321
- <span className="text-base font-semibold text-brand-dark">{level.label}</span>
322
- <span className="mt-2 block text-sm leading-6 text-muted-foreground">{level.description}</span>
323
- </button>
324
- ))}
328
+ {securityLevels.map((level) => {
329
+ const LevelIcon = level.icon;
330
+ const isSelected = draft.security_level === level.value;
331
+ const iconColorClass =
332
+ level.tone === "blue" ? "text-brand-blue" :
333
+ level.tone === "purple" ? "text-brand-purple" :
334
+ "text-slate-500";
335
+ const iconBgClass =
336
+ level.tone === "blue" ? "bg-brand-blue/10" :
337
+ level.tone === "purple" ? "bg-brand-purple/10" :
338
+ "bg-slate-100";
339
+ const selectedBorderClass =
340
+ level.tone === "blue" ? "border-brand-blue/35 bg-brand-blue/[0.07] shadow-[0_12px_32px_rgba(85,153,254,0.14)]" :
341
+ level.tone === "purple" ? "border-brand-purple/35 bg-brand-purple/[0.06] shadow-[0_12px_32px_rgba(181,108,255,0.12)]" :
342
+ "border-slate-300 bg-slate-50 shadow-sm";
343
+ return (
344
+ <button
345
+ key={level.value}
346
+ type="button"
347
+ onClick={() => handleSecurityLevelChange(level.value)}
348
+ aria-pressed={isSelected}
349
+ className={`relative min-h-36 rounded-[1.5rem] border p-4 text-left transition-all duration-150 ${
350
+ isSelected ? selectedBorderClass : "border-transparent bg-surface-1/80 hover:bg-white"
351
+ }`}
352
+ >
353
+ {isSelected && (
354
+ <span className="absolute right-3 top-3 flex h-5 w-5 items-center justify-center rounded-full bg-[#059669]">
355
+ <HiMiniCheckCircle className="h-4 w-4 text-white" aria-hidden="true" />
356
+ </span>
357
+ )}
358
+ <span className={`inline-flex h-8 w-8 items-center justify-center rounded-lg ${iconBgClass}`}>
359
+ <LevelIcon className={`h-4 w-4 ${iconColorClass}`} aria-hidden="true" />
360
+ </span>
361
+ <span className="mt-3 block text-base font-semibold text-brand-dark">{level.label}</span>
362
+ <span className="mt-1.5 block text-sm leading-6 text-muted-foreground">{level.description}</span>
363
+ {level.protects.length > 0 && (
364
+ <ul className="mt-3 space-y-1">
365
+ {level.protects.map((item) => (
366
+ <li key={item} className="flex items-center gap-1.5 text-[11px] font-medium text-brand-dark/60">
367
+ <span className={`h-1 w-1 shrink-0 rounded-full ${iconColorClass}`} />
368
+ {item}
369
+ </li>
370
+ ))}
371
+ </ul>
372
+ )}
373
+ </button>
374
+ );
375
+ })}
325
376
  </div>
326
377
  </div>
327
378
 
@@ -351,8 +402,28 @@ export function SettingsWorkspace() {
351
402
  </div>
352
403
 
353
404
  <div className="rounded-[1.75rem] border border-slate-200/70 bg-white/80 p-5 shadow-sm">
354
- <SectionLabel>Risk choices</SectionLabel>
355
- <div className="mt-4 divide-y divide-slate-200/70 overflow-hidden rounded-[1.35rem] border border-slate-200/70 bg-white">
405
+ <div className="flex flex-wrap items-center justify-between gap-3">
406
+ <SectionLabel>Risk choices</SectionLabel>
407
+ {draft.security_level !== "custom" ? (
408
+ <span className="inline-flex items-center gap-1.5 rounded-full border border-slate-200 bg-slate-50 px-3 py-1 font-mono text-[10px] font-semibold uppercase tracking-[0.18em] text-slate-500">
409
+ <HiMiniLockClosed className="h-3 w-3" aria-hidden="true" />
410
+ Managed by {draft.security_level === "balanced" ? "Balanced" : "Strict"}
411
+ </span>
412
+ ) : (
413
+ <span className="inline-flex items-center gap-1.5 rounded-full border border-brand-blue/25 bg-brand-blue/[0.06] px-3 py-1 font-mono text-[10px] font-semibold uppercase tracking-[0.18em] text-brand-blue">
414
+ <HiMiniCog6Tooth className="h-3 w-3" aria-hidden="true" />
415
+ Custom overrides active
416
+ </span>
417
+ )}
418
+ </div>
419
+ {draft.security_level !== "custom" && (
420
+ <div className="mt-3 flex items-center justify-between gap-3 rounded-[1rem] border border-slate-200/60 bg-slate-50/80 px-4 py-3">
421
+ <p className="text-sm text-brand-dark/65">
422
+ All risk behaviors are set by the <span className="font-semibold">{draft.security_level === "balanced" ? "Balanced" : "Strict"}</span> level. Select <span className="font-semibold">Custom</span> above to override individual choices.
423
+ </p>
424
+ </div>
425
+ )}
426
+ <div className={`mt-4 divide-y divide-slate-200/70 overflow-hidden rounded-[1.35rem] border border-slate-200/70 bg-white ${draft.security_level !== "custom" ? "opacity-60" : ""}`}>
356
427
  {riskControls.map((risk) => (
357
428
  <div key={risk.key} className="grid gap-3 px-4 py-4 md:grid-cols-[minmax(0,1fr)_220px] md:items-center">
358
429
  <div>
@@ -364,6 +435,7 @@ export function SettingsWorkspace() {
364
435
  value={draft.risk_actions[risk.key] ?? "require-reapproval"}
365
436
  options={actionOptions}
366
437
  onChange={handleRiskActionChange(risk.key)}
438
+ disabled={draft.security_level !== "custom"}
367
439
  />
368
440
  </div>
369
441
  ))}
@@ -372,7 +444,7 @@ export function SettingsWorkspace() {
372
444
 
373
445
  <div className="rounded-[1.75rem] border border-slate-200/70 bg-white/80 p-5 shadow-sm">
374
446
  <SectionLabel>Codex override</SectionLabel>
375
- <div className="mt-4 grid gap-4 md:grid-cols-[minmax(0,1fr)_260px] md:items-center">
447
+ <div className={`mt-4 grid gap-4 md:grid-cols-[minmax(0,1fr)_260px] md:items-center ${draft.security_level !== "custom" ? "opacity-60" : ""}`}>
376
448
  <div>
377
449
  <p className="text-sm font-semibold text-brand-dark">Codex reading local secret files</p>
378
450
  <p className="mt-1 text-sm leading-6 text-muted-foreground">
@@ -384,6 +456,7 @@ export function SettingsWorkspace() {
384
456
  value={draft.harness_risk_actions.codex?.local_secret_read ?? draft.risk_actions.local_secret_read ?? "require-reapproval"}
385
457
  options={actionOptions}
386
458
  onChange={handleCodexSecretReadChange}
459
+ disabled={draft.security_level !== "custom"}
387
460
  />
388
461
  </div>
389
462
  </div>
@@ -448,6 +521,7 @@ function SettingSelect(props: {
448
521
  value: string;
449
522
  options: Array<{ value: string; label: string }>;
450
523
  onChange: (event: ChangeEvent<HTMLSelectElement>) => void;
524
+ disabled?: boolean;
451
525
  }) {
452
526
  return (
453
527
  <label className="block">
@@ -455,7 +529,8 @@ function SettingSelect(props: {
455
529
  <select
456
530
  value={props.value}
457
531
  onChange={props.onChange}
458
- className="mt-2 min-h-11 w-full rounded-full border border-slate-200 bg-white px-4 text-sm font-medium text-brand-dark transition-colors duration-150 focus:border-brand-blue focus:outline-none focus:ring-2 focus:ring-brand-blue/20"
532
+ disabled={props.disabled}
533
+ className="mt-2 min-h-11 w-full rounded-full border border-slate-200 bg-white px-4 text-sm font-medium text-brand-dark transition-colors duration-150 focus:border-brand-blue focus:outline-none focus:ring-2 focus:ring-brand-blue/20 disabled:cursor-not-allowed disabled:opacity-60"
459
534
  >
460
535
  {props.options.map((option) => (
461
536
  <option key={option.value} value={option.value}>{option.label}</option>