plugin-scanner 2.0.70__tar.gz → 2.0.72__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 (331) hide show
  1. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/PKG-INFO +1 -1
  2. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/docs/guard/harness-support.md +14 -0
  3. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/docs/guard/testing-matrix.md +4 -0
  4. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/pyproject.toml +1 -1
  5. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/pyproject.toml.bak +1 -1
  6. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/adapters/copilot.py +1 -1
  7. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/adapters/cursor.py +7 -0
  8. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/adapters/gemini.py +5 -0
  9. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/adapters/opencode.py +5 -0
  10. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/approvals.py +3 -2
  11. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/cli/commands.py +12 -26
  12. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/daemon/server.py +51 -54
  13. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/runtime/runner.py +175 -30
  14. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/version.py +1 -1
  15. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_guard_approvals.py +125 -1
  16. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_guard_claude_adapter.py +8 -2
  17. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_guard_copilot_adapter.py +3 -0
  18. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_guard_launch_env.py +193 -1
  19. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_guard_runtime.py +205 -6
  20. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_guard_surface_server.py +7 -2
  21. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/.clusterfuzzlite/Dockerfile +0 -0
  22. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/.clusterfuzzlite/build.sh +0 -0
  23. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/.clusterfuzzlite/project.yaml +0 -0
  24. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/.clusterfuzzlite/requirements-atheris.txt +0 -0
  25. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/.dockerignore +0 -0
  26. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/.github/CODEOWNERS +0 -0
  27. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/.github/ISSUE_TEMPLATE/bug-report.yml +0 -0
  28. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  29. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/.github/ISSUE_TEMPLATE/feature-request.yml +0 -0
  30. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/.github/dependabot.yml +0 -0
  31. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/.github/workflows/ci.yml +0 -0
  32. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/.github/workflows/codeql.yml +0 -0
  33. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/.github/workflows/dependabot-uv-lock.yml +0 -0
  34. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/.github/workflows/fuzz.yml +0 -0
  35. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/.github/workflows/harness-smoke.yml +0 -0
  36. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/.github/workflows/publish.yml +0 -0
  37. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/.github/workflows/scorecard.yml +0 -0
  38. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/.gitignore +0 -0
  39. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/.pre-commit-hooks.yaml +0 -0
  40. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/CONTRIBUTING.md +0 -0
  41. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/Dockerfile +0 -0
  42. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/LICENSE +0 -0
  43. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/README.md +0 -0
  44. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/SECURITY.md +0 -0
  45. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/dashboard/index.html +0 -0
  46. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/dashboard/package.json +0 -0
  47. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/dashboard/pnpm-lock.yaml +0 -0
  48. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/dashboard/public/apple-touch-icon.png +0 -0
  49. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/dashboard/public/brand/Logo_Icon_Dark.png +0 -0
  50. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/dashboard/public/brand/Logo_Whole.png +0 -0
  51. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/dashboard/public/favicon-16x16.png +0 -0
  52. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/dashboard/public/favicon-32x32.png +0 -0
  53. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/dashboard/public/favicon.ico +0 -0
  54. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/dashboard/src/app.tsx +0 -0
  55. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/dashboard/src/approval-center-layout.tsx +0 -0
  56. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/dashboard/src/approval-center-primitives.tsx +0 -0
  57. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/dashboard/src/approval-center-utils.ts +0 -0
  58. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/dashboard/src/fleet-workspace.tsx +0 -0
  59. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/dashboard/src/guard-api.ts +0 -0
  60. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/dashboard/src/guard-demo.ts +0 -0
  61. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/dashboard/src/guard-types.ts +0 -0
  62. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/dashboard/src/main.tsx +0 -0
  63. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/dashboard/src/receipts-workspace.tsx +0 -0
  64. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/dashboard/src/runtime-overview.tsx +0 -0
  65. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/dashboard/src/settings-workspace.tsx +0 -0
  66. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/dashboard/src/styles.css +0 -0
  67. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/dashboard/src/vite-env.d.ts +0 -0
  68. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/dashboard/tsconfig.json +0 -0
  69. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/dashboard/vite.config.ts +0 -0
  70. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/docker-requirements.txt +0 -0
  71. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/docs/guard/approval-audit.md +0 -0
  72. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/docs/guard/architecture.md +0 -0
  73. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/docs/guard/get-started.md +0 -0
  74. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/docs/guard/local-vs-cloud.md +0 -0
  75. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/docs/trust/mcp-trust-draft.md +0 -0
  76. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/docs/trust/plugin-trust-draft.md +0 -0
  77. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/docs/trust/skill-trust-local.md +0 -0
  78. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/fuzzers/manifest_fuzzer.py +0 -0
  79. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/requirements.txt +0 -0
  80. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/schemas/plugin-quality.v1.json +0 -0
  81. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/schemas/scan-result.v1.json +0 -0
  82. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/schemas/verify-result.v1.json +0 -0
  83. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/__init__.py +0 -0
  84. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/action_runner.py +0 -0
  85. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/argparse_utils.py +0 -0
  86. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/checks/__init__.py +0 -0
  87. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/checks/best_practices.py +0 -0
  88. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/checks/claude.py +0 -0
  89. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/checks/code_quality.py +0 -0
  90. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/checks/ecosystem_common.py +0 -0
  91. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/checks/gemini.py +0 -0
  92. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/checks/manifest.py +0 -0
  93. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/checks/manifest_support.py +0 -0
  94. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/checks/marketplace.py +0 -0
  95. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/checks/mcp_security.py +0 -0
  96. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/checks/opencode.py +0 -0
  97. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/checks/operational_security.py +0 -0
  98. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/checks/security.py +0 -0
  99. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/checks/skill_security.py +0 -0
  100. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/cli.py +0 -0
  101. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/cli_ui.py +0 -0
  102. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/config.py +0 -0
  103. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/ecosystems/__init__.py +0 -0
  104. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/ecosystems/base.py +0 -0
  105. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/ecosystems/claude.py +0 -0
  106. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/ecosystems/codex.py +0 -0
  107. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/ecosystems/detect.py +0 -0
  108. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/ecosystems/gemini.py +0 -0
  109. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/ecosystems/opencode.py +0 -0
  110. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/ecosystems/registry.py +0 -0
  111. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/ecosystems/types.py +0 -0
  112. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/github_reporting.py +0 -0
  113. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/__init__.py +0 -0
  114. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/adapters/__init__.py +0 -0
  115. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/adapters/antigravity.py +0 -0
  116. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/adapters/base.py +0 -0
  117. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/adapters/claude_code.py +0 -0
  118. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/adapters/codex.py +0 -0
  119. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/adapters/hermes.py +0 -0
  120. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/adapters/mcp_servers.py +0 -0
  121. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/adapters/opencode_artifacts.py +0 -0
  122. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/bridge/__init__.py +0 -0
  123. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/capabilities.py +0 -0
  124. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/cli/__init__.py +0 -0
  125. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/cli/approval_commands.py +0 -0
  126. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/cli/bootstrap.py +0 -0
  127. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/cli/connect_flow.py +0 -0
  128. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/cli/install_commands.py +0 -0
  129. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/cli/product.py +0 -0
  130. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/cli/prompt.py +0 -0
  131. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/cli/render.py +0 -0
  132. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/cli/update_commands.py +0 -0
  133. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/codex_config.py +0 -0
  134. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/config.py +0 -0
  135. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/consumer/__init__.py +0 -0
  136. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/consumer/service.py +0 -0
  137. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/daemon/__init__.py +0 -0
  138. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/daemon/client.py +0 -0
  139. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/daemon/manager.py +0 -0
  140. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/daemon/static/apple-touch-icon.png +0 -0
  141. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/daemon/static/assets/guard-dashboard.js +0 -0
  142. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/daemon/static/assets/index.css +0 -0
  143. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/daemon/static/brand/Logo_Icon_Dark.png +0 -0
  144. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/daemon/static/brand/Logo_Whole.png +0 -0
  145. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/daemon/static/favicon-16x16.png +0 -0
  146. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/daemon/static/favicon-32x32.png +0 -0
  147. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/daemon/static/favicon.ico +0 -0
  148. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/daemon/static/index.html +0 -0
  149. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/edge_events.py +0 -0
  150. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/incident.py +0 -0
  151. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/launcher.py +0 -0
  152. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/mcp_tool_calls.py +0 -0
  153. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/models.py +0 -0
  154. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/policy/__init__.py +0 -0
  155. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/policy/engine.py +0 -0
  156. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/protect.py +0 -0
  157. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/proxy/__init__.py +0 -0
  158. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/proxy/remote.py +0 -0
  159. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/proxy/runtime_mcp.py +0 -0
  160. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/proxy/stdio.py +0 -0
  161. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/receipts/__init__.py +0 -0
  162. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/receipts/manager.py +0 -0
  163. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/risk.py +0 -0
  164. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/runtime/__init__.py +0 -0
  165. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/runtime/secret_file_requests.py +0 -0
  166. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/runtime/surface_server.py +0 -0
  167. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/schemas/__init__.py +0 -0
  168. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/schemas/consumer_mode.py +0 -0
  169. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/schemas/guard_event_v1.py +0 -0
  170. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/schemas/surface_server.py +0 -0
  171. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/shims.py +0 -0
  172. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/store.py +0 -0
  173. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/store_approvals.py +0 -0
  174. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/store_connect.py +0 -0
  175. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/guard/types.py +0 -0
  176. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/integrations/__init__.py +0 -0
  177. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/integrations/cisco_mcp_scanner.py +0 -0
  178. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/integrations/cisco_skill_scanner.py +0 -0
  179. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/lint_fixes.py +0 -0
  180. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/marketplace_support.py +0 -0
  181. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/models.py +0 -0
  182. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/path_support.py +0 -0
  183. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/policy.py +0 -0
  184. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/quality_artifact.py +0 -0
  185. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/repo_detect.py +0 -0
  186. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/reporting.py +0 -0
  187. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/rules/__init__.py +0 -0
  188. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/rules/registry.py +0 -0
  189. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/rules/specs.py +0 -0
  190. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/scanner.py +0 -0
  191. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/submission.py +0 -0
  192. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/suppressions.py +0 -0
  193. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/trust_domain_scoring.py +0 -0
  194. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/trust_helpers.py +0 -0
  195. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/trust_mcp_scoring.py +0 -0
  196. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/trust_models.py +0 -0
  197. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/trust_plugin_scoring.py +0 -0
  198. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/trust_scoring.py +0 -0
  199. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/trust_skill_scoring.py +0 -0
  200. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/trust_specs.py +0 -0
  201. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/src/codex_plugin_scanner/verification.py +0 -0
  202. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/__init__.py +0 -0
  203. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/conftest.py +0 -0
  204. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/__init__.py +0 -0
  205. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/bad-plugin/.codex-plugin/plugin.json +0 -0
  206. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/bad-plugin/.mcp.json +0 -0
  207. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/bad-plugin/secrets.js +0 -0
  208. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/claude-plugin-good/.claude-plugin/plugin.json +0 -0
  209. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/claude-plugin-good/LICENSE +0 -0
  210. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/claude-plugin-good/README.md +0 -0
  211. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/claude-plugin-good/SECURITY.md +0 -0
  212. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/claude-plugin-good/hooks/hooks.json +0 -0
  213. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/claude-plugin-good/skills/example/SKILL.md +0 -0
  214. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/code-quality-bad/evil.js +0 -0
  215. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/code-quality-bad/inject.js +0 -0
  216. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/gemini-extension-good/GEMINI.md +0 -0
  217. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/gemini-extension-good/LICENSE +0 -0
  218. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/gemini-extension-good/README.md +0 -0
  219. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/gemini-extension-good/SECURITY.md +0 -0
  220. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/gemini-extension-good/commands/hello.toml +0 -0
  221. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/gemini-extension-good/gemini-extension.json +0 -0
  222. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/good-plugin/.codex-plugin/plugin.json +0 -0
  223. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/good-plugin/.codexignore +0 -0
  224. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/good-plugin/LICENSE +0 -0
  225. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/good-plugin/README.md +0 -0
  226. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/good-plugin/SECURITY.md +0 -0
  227. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/good-plugin/assets/icon.svg +0 -0
  228. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/good-plugin/assets/logo.svg +0 -0
  229. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/good-plugin/assets/screenshot.svg +0 -0
  230. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/good-plugin/skills/example/SKILL.md +0 -0
  231. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/guard-codex-malicious-mcp/.codex/config.toml +0 -0
  232. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/hermes-plugin-evil/config.yaml +0 -0
  233. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/hermes-plugin-evil/mcp_servers.json +0 -0
  234. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/hermes-plugin-evil/skills/security/malicious/SKILL.md +0 -0
  235. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/hermes-plugin-evil/skills/stealth/sneaky/SKILL.md +0 -0
  236. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/hermes-plugin-evil/skills/stealth/sneaky/references/api-setup.md +0 -0
  237. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/hermes-plugin-evil/skills/stealth/sneaky/scripts/deploy.sh +0 -0
  238. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/hermes-plugin-evil/skills/utils/benign/SKILL.md +0 -0
  239. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/malformed-json/.codex-plugin/plugin.json +0 -0
  240. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/malicious-skill-plugin/.codex-plugin/plugin.json +0 -0
  241. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/malicious-skill-plugin/.codexignore +0 -0
  242. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/malicious-skill-plugin/LICENSE +0 -0
  243. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/malicious-skill-plugin/README.md +0 -0
  244. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/malicious-skill-plugin/SECURITY.md +0 -0
  245. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/malicious-skill-plugin/skills/leaky-skill/SKILL.md +0 -0
  246. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/mcp-canary-server.py +0 -0
  247. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/minimal-plugin/.codex-plugin/plugin.json +0 -0
  248. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/missing-fields/.codex-plugin/plugin.json +0 -0
  249. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/mit-license/LICENSE +0 -0
  250. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/multi-ecosystem-repo/codex-plugin/.codex-plugin/plugin.json +0 -0
  251. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/multi-ecosystem-repo/codex-plugin/LICENSE +0 -0
  252. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/multi-ecosystem-repo/codex-plugin/README.md +0 -0
  253. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/multi-ecosystem-repo/codex-plugin/SECURITY.md +0 -0
  254. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/multi-ecosystem-repo/gemini-ext/README.md +0 -0
  255. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/multi-ecosystem-repo/gemini-ext/gemini-extension.json +0 -0
  256. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/multi-plugin-repo/.agents/plugins/marketplace.json +0 -0
  257. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/.codex-plugin/plugin.json +0 -0
  258. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/.codexignore +0 -0
  259. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/LICENSE +0 -0
  260. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/README.md +0 -0
  261. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/SECURITY.md +0 -0
  262. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/skills/example/SKILL.md +0 -0
  263. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/multi-plugin-repo/plugins/beta-plugin/.codex-plugin/plugin.json +0 -0
  264. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/multi-plugin-repo/plugins/beta-plugin/skills/example/SKILL.md +0 -0
  265. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/no-version/.codex-plugin/plugin.json +0 -0
  266. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/opencode-good/.opencode/commands/hello.md +0 -0
  267. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/opencode-good/.opencode/plugins/example.ts +0 -0
  268. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/opencode-good/LICENSE +0 -0
  269. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/opencode-good/README.md +0 -0
  270. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/opencode-good/SECURITY.md +0 -0
  271. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/opencode-good/opencode.jsonc +0 -0
  272. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/skills-missing-dir/.codex-plugin/plugin.json +0 -0
  273. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/skills-no-frontmatter/.codex-plugin/plugin.json +0 -0
  274. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/skills-no-frontmatter/skills/bad-skill/SKILL.md +0 -0
  275. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/with-marketplace/.codex-plugin/plugin.json +0 -0
  276. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/with-marketplace/marketplace-broken.json +0 -0
  277. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/fixtures/with-marketplace/marketplace.json +0 -0
  278. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test-trust-scoring.py +0 -0
  279. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test-trust-specs.py +0 -0
  280. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_action_runner.py +0 -0
  281. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_best_practices.py +0 -0
  282. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_cisco_install_surfaces.py +0 -0
  283. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_cli.py +0 -0
  284. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_code_quality.py +0 -0
  285. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_config.py +0 -0
  286. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_coverage_remaining.py +0 -0
  287. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_ecosystems.py +0 -0
  288. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_edge_cases.py +0 -0
  289. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_final_coverage.py +0 -0
  290. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_guard_bootstrap.py +0 -0
  291. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_guard_capabilities.py +0 -0
  292. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_guard_cli.py +0 -0
  293. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_guard_codex_e2e.py +0 -0
  294. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_guard_codex_install.py +0 -0
  295. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_guard_codex_proxy.py +0 -0
  296. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_guard_config_paths.py +0 -0
  297. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_guard_connect_flow.py +0 -0
  298. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_guard_consumer_mode.py +0 -0
  299. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_guard_copilot_proxy.py +0 -0
  300. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_guard_daemon_manager.py +0 -0
  301. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_guard_event_schema_v1.py +0 -0
  302. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_guard_events.py +0 -0
  303. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_guard_opencode_proxy.py +0 -0
  304. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_guard_product_flow.py +0 -0
  305. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_guard_protect.py +0 -0
  306. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_guard_render.py +0 -0
  307. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_guard_risk.py +0 -0
  308. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_guard_store_migrations.py +0 -0
  309. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_guard_verdicts.py +0 -0
  310. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_hermes_adapter.py +0 -0
  311. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_integration.py +0 -0
  312. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_lint_fixes.py +0 -0
  313. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_live_cisco_smoke.py +0 -0
  314. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_manifest.py +0 -0
  315. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_marketplace.py +0 -0
  316. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_mcp_security.py +0 -0
  317. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_operational_security.py +0 -0
  318. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_policy.py +0 -0
  319. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_quality_artifact.py +0 -0
  320. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_rule_registry.py +0 -0
  321. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_scanner.py +0 -0
  322. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_schema_contracts.py +0 -0
  323. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_security.py +0 -0
  324. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_security_ops.py +0 -0
  325. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_skill_security.py +0 -0
  326. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_submission.py +0 -0
  327. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_trust_scoring.py +0 -0
  328. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_trust_specs.py +0 -0
  329. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_verification.py +0 -0
  330. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/tests/test_versioning.py +0 -0
  331. {plugin_scanner-2.0.70 → plugin_scanner-2.0.72}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: plugin-scanner
3
- Version: 2.0.70
3
+ Version: 2.0.72
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
@@ -8,11 +8,13 @@ Current Guard support in this repo:
8
8
  - parses configured MCP servers
9
9
  - installs Guard-owned Codex `PreToolUse` Bash hooks so native shell commands can be denied before execution even when Codex itself is running in YOLO mode
10
10
  - supports wrapper-mode `guard run codex`
11
+ - wrapper prompt screening now suppresses copied debug and incident context while still escalating risky prompt intent
11
12
  - uses same-chat MCP elicitation for live managed MCP tool approvals in the interactive CLI and Codex App
12
13
  - falls back to the local approval center only for nonresponsive or headless Codex sessions such as `codex exec`
13
14
  - `claude-code`
14
15
  - detects global and project settings, hooks, `.mcp.json`, and workspace agents
15
16
  - supports local hook install and uninstall in `.claude/settings.local.json`
17
+ - has native `UserPromptSubmit` and `PreToolUse` Guard hook coverage
16
18
  - is the best current harness for graceful approval deferral
17
19
  - `copilot`
18
20
  - detects read-only user config in `~/.copilot/config.json` and `~/.copilot/mcp-config.json`
@@ -20,9 +22,11 @@ Current Guard support in this repo:
20
22
  - detects repo-local Copilot CLI hooks from `.github/hooks/*.json`
21
23
  - installs and removes Guard-owned repo hooks in `.github/hooks/hol-guard-copilot.json`
22
24
  - supports wrapper-mode `guard run copilot`
25
+ - has native `userPromptSubmitted`, `preToolUse`, and `postToolUse` hook coverage normalized onto the shared Guard runtime
23
26
  - `cursor`
24
27
  - detects global and project `mcp.json`
25
28
  - supports wrapper-mode management state
29
+ - wrapper prompt screening is covered for benign debug prompts and risky secret-read prompts
26
30
  - leaves native Cursor tool approval in place and focuses Guard on artifact trust
27
31
  - `antigravity`
28
32
  - detects Antigravity user settings, installed extension profiles, and Antigravity-owned MCP and skill roots
@@ -31,6 +35,7 @@ Current Guard support in this repo:
31
35
  - `gemini`
32
36
  - detects `.gemini/settings.json`, local extension manifests, embedded MCP declarations, hooks, and Gemini skill directories
33
37
  - supports wrapper-mode management state
38
+ - wrapper prompt screening is covered for benign debug prompts and risky secret-read prompts
34
39
  - falls back to the local approval center when Guard blocks a launch
35
40
  - `hermes`
36
41
  - detects Hermes skills plus MCP servers from `~/.hermes/config.yaml` and `~/.hermes/mcp_servers.json`
@@ -42,6 +47,7 @@ Current Guard support in this repo:
42
47
  plugin files, and OpenCode-compatible skill directories
43
48
  - supports wrapper-mode management state plus a Guard-owned runtime overlay for native skill approval prompts
44
49
  - supports wrapper-mode `guard run opencode`
50
+ - wrapper prompt screening is covered for benign debug prompts and risky secret-read prompts
45
51
  - keeps managed MCP tools on OpenCode native ask so the user can allow once, allow for the session, or reject inline
46
52
  - blocks newly introduced OpenCode MCP, plugin, and skill artifacts before launch when local Guard policy requires
47
53
  approval
@@ -54,6 +60,14 @@ Approval tiers:
54
60
 
55
61
  The harness adapters are designed to prefer discovery and reversible overlay behavior over invasive config mutation.
56
62
 
63
+ The Guard Surface Server now provides one shared runtime shape across harnesses:
64
+
65
+ - session attach
66
+ - operation start and status updates
67
+ - approval request items
68
+ - approval-center lease and heartbeat tracking
69
+ - resume or completion after approval
70
+
57
71
  Runtime intent protections:
58
72
 
59
73
  - Guard evaluates prompt and tool intent for secret-bearing files beyond `.env`, including SSH, AWS, kubeconfig, Docker, npm, and Python credential files.
@@ -4,6 +4,8 @@ Automated coverage in this phase includes:
4
4
 
5
5
  - Guard CLI behavior tests for detect, scan, run, diff, receipts, install, uninstall, login, and sync
6
6
  - Guard product-flow tests for `hol-guard start`, `hol-guard status`, and launcher shim creation
7
+ - prompt-risk regressions for Codex, Cursor, Gemini, and OpenCode wrapper launches
8
+ - native prompt-hook regressions for Claude Code and Copilot hook events
7
9
  - SQLite persistence through real command execution in temporary homes and workspaces
8
10
  - consumer-mode JSON contract generation against scanner fixtures
9
11
  - local HTTP sync against a live in-process server instead of mocked transport
@@ -20,6 +22,8 @@ Manual verification should include:
20
22
  - `hol-guard detect opencode --json`
21
23
  - `hol-guard install opencode --json`
22
24
  - `hol-guard update --dry-run --json`
25
+ - `hol-guard run cursor --dry-run --default-action allow --json`
26
+ - `hol-guard run gemini --dry-run --default-action allow --json`
23
27
  - `hol-guard run opencode --dry-run --default-action allow --json`
24
28
  - `hol-guard run opencode --default-action require-reapproval --json`
25
29
  - `hol-guard approvals --json`
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "plugin-scanner"
7
- version = "2.0.70"
7
+ version = "2.0.72"
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.70"
7
+ version = "2.0.72"
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"
@@ -25,7 +25,7 @@ from .mcp_servers import (
25
25
  skipped_stdio_server_names,
26
26
  )
27
27
 
28
- _MANAGED_HOOK_EVENTS = ("preToolUse", "postToolUse", "permissionRequest")
28
+ _MANAGED_HOOK_EVENTS = ("userPromptSubmitted", "preToolUse", "postToolUse", "permissionRequest")
29
29
  _DETECTABLE_HOOK_EVENTS = (
30
30
  "sessionStart",
31
31
  "sessionEnd",
@@ -2,6 +2,8 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ from pathlib import Path
6
+
5
7
  from ..models import GuardArtifact, HarnessDetection
6
8
  from .base import HarnessAdapter, HarnessContext, _command_available, _json_payload, _run_command_probe
7
9
 
@@ -25,6 +27,11 @@ class CursorHarnessAdapter(HarnessAdapter):
25
27
  return "project"
26
28
  return "global"
27
29
 
30
+ def policy_path(self, context: HarnessContext) -> Path:
31
+ if context.workspace_dir is not None:
32
+ return context.workspace_dir / ".cursor" / "mcp.json"
33
+ return context.home_dir / ".cursor" / "mcp.json"
34
+
28
35
  def detect(self, context: HarnessContext) -> HarnessDetection:
29
36
  config_paths = [context.home_dir / ".cursor" / "mcp.json"]
30
37
  if context.workspace_dir is not None:
@@ -39,6 +39,11 @@ class GeminiHarnessAdapter(HarnessAdapter):
39
39
  return ()
40
40
  return tuple(str(value) for value in raw_args if isinstance(value, str))
41
41
 
42
+ def policy_path(self, context: HarnessContext) -> Path:
43
+ if context.workspace_dir is not None:
44
+ return context.workspace_dir / ".gemini" / "settings.json"
45
+ return context.home_dir / ".gemini" / "settings.json"
46
+
42
47
  def detect(self, context: HarnessContext) -> HarnessDetection:
43
48
  artifacts: list[GuardArtifact] = []
44
49
  found_paths: list[str] = []
@@ -97,6 +97,11 @@ class OpenCodeHarnessAdapter(HarnessAdapter):
97
97
  return "project"
98
98
  return "global"
99
99
 
100
+ def policy_path(self, context: HarnessContext) -> Path:
101
+ if context.workspace_dir is not None:
102
+ return context.workspace_dir / "opencode.json"
103
+ return context.home_dir / ".config" / "opencode" / "opencode.json"
104
+
100
105
  def detect(self, context: HarnessContext) -> HarnessDetection:
101
106
  artifacts = []
102
107
  found_paths: list[str] = []
@@ -119,7 +119,7 @@ def apply_approval_resolution(
119
119
  if scope == "publisher" and not isinstance(request.get("publisher"), str):
120
120
  raise ValueError(f"Approval request {request_id} has no publisher scope to approve.")
121
121
  decision = PolicyDecision(
122
- harness=str(request["harness"]),
122
+ harness="*" if scope == "global" else str(request["harness"]),
123
123
  scope=scope,
124
124
  action="allow" if action == "allow" else "block",
125
125
  artifact_id=str(request["artifact_id"]) if scope == "artifact" else None,
@@ -130,8 +130,9 @@ def apply_approval_resolution(
130
130
  )
131
131
  store.upsert_policy(decision, now or _now())
132
132
  resolved_at = now or _now()
133
+ resolution_harness = None if scope == "global" else str(request["harness"])
133
134
  resolved_ids = store.resolve_matching_approval_requests(
134
- harness=str(request["harness"]),
135
+ harness=resolution_harness,
135
136
  scope=scope,
136
137
  artifact_id=str(request["artifact_id"]) if scope == "artifact" else None,
137
138
  workspace=workspace if scope == "workspace" else None,
@@ -1484,14 +1484,6 @@ def run_guard_command(
1484
1484
  artifact=runtime_artifact,
1485
1485
  artifact_hash=runtime_artifact_hash,
1486
1486
  )
1487
- if _should_allow_claude_user_prompt_submit_without_output(
1488
- args,
1489
- event_name=event_name,
1490
- policy_action=policy_action,
1491
- artifact=runtime_artifact,
1492
- output_stream=output_stream,
1493
- ):
1494
- return 0
1495
1487
  if _should_emit_copilot_hook_response(args):
1496
1488
  _emit_copilot_hook_response(
1497
1489
  policy_action=policy_action,
@@ -1866,23 +1858,6 @@ def _should_emit_prequeue_native_hook_response(
1866
1858
  return output_stream is not None
1867
1859
 
1868
1860
 
1869
- def _should_allow_claude_user_prompt_submit_without_output(
1870
- args: argparse.Namespace,
1871
- *,
1872
- event_name: str,
1873
- policy_action: str,
1874
- artifact: GuardArtifact,
1875
- output_stream: TextIO | None,
1876
- ) -> bool:
1877
- return (
1878
- _canonical_harness_name(args.harness) == "claude-code"
1879
- and event_name == "UserPromptSubmit"
1880
- and policy_action == "require-reapproval"
1881
- and not _prompt_requires_hard_block(artifact)
1882
- and (not getattr(args, "json", False) or output_stream is not None)
1883
- )
1884
-
1885
-
1886
1861
  def _emit_claude_permission_request_passthrough(*, output_stream: TextIO | None = None) -> None:
1887
1862
  if output_stream is not None:
1888
1863
  output_stream.write("")
@@ -3070,6 +3045,8 @@ def _emit_native_hook_response(
3070
3045
  "hookEventName": event_name,
3071
3046
  "additionalContext": additional_context,
3072
3047
  }
3048
+ elif _canonical_harness_name(harness) in {"claude-code", "codex"}:
3049
+ payload["hookSpecificOutput"] = {"hookEventName": event_name}
3073
3050
  if payload:
3074
3051
  _write_json_line(payload, output_stream=output_stream)
3075
3052
  return
@@ -3432,11 +3409,20 @@ def _optional_string(value: object | None) -> str | None:
3432
3409
  return None
3433
3410
 
3434
3411
 
3412
+ _HOOK_EVENT_NAME_MAP = {
3413
+ "userpromptsubmitted": "UserPromptSubmit",
3414
+ "pretooluse": "PreToolUse",
3415
+ "posttooluse": "PostToolUse",
3416
+ "permissionrequest": "PermissionRequest",
3417
+ }
3418
+
3419
+
3435
3420
  def _hook_event_name(payload: dict[str, object]) -> str | None:
3436
3421
  for key in ("event", "hook_event_name", "hookEventName", "hook_name"):
3437
3422
  value = payload.get(key)
3438
3423
  if isinstance(value, str) and value.strip():
3439
- return value.strip()
3424
+ normalized = value.strip()
3425
+ return _HOOK_EVENT_NAME_MAP.get(normalized.lower(), normalized)
3440
3426
  return None
3441
3427
 
3442
3428
 
@@ -26,6 +26,7 @@ from ..store import GuardStore
26
26
  from .manager import (
27
27
  GUARD_DAEMON_COMPATIBILITY_VERSION,
28
28
  clear_guard_daemon_state,
29
+ load_guard_daemon_auth_token,
29
30
  write_guard_daemon_state,
30
31
  )
31
32
 
@@ -59,18 +60,19 @@ class _GuardDaemonHandler(BaseHTTPRequestHandler):
59
60
  _MAX_BODY_BYTES = 1_000_000
60
61
 
61
62
  def do_OPTIONS(self) -> None:
62
- parsed = urlparse(self.path)
63
- if parsed.path in {"/v1/connect/complete", "/v1/connect/state"}:
64
- origin = self._normalize_origin(self.headers.get("Origin"))
65
- if origin is None:
66
- self._write_empty(status=400)
67
- return
68
- self._write_empty(
69
- status=200,
70
- extra_headers=self._cors_headers(origin, allow_methods="GET, POST, OPTIONS"),
71
- )
63
+ origin = self._normalize_origin(self.headers.get("Origin"))
64
+ if origin is None:
65
+ self._write_empty(status=400)
66
+ return
67
+ if not self._origin_is_allowed():
68
+ self._write_empty(status=403)
72
69
  return
73
- self._write_empty(status=404)
70
+ self._write_empty(
71
+ status=200,
72
+ extra_headers=self._cors_headers(
73
+ origin, allow_methods="GET, POST, OPTIONS", allow_headers="Content-Type, X-Guard-Token"
74
+ ),
75
+ )
74
76
 
75
77
  def do_GET(self) -> None:
76
78
  store = self.server.store # type: ignore[attr-defined]
@@ -205,11 +207,19 @@ class _GuardDaemonHandler(BaseHTTPRequestHandler):
205
207
  if parsed.path != "/v1/connect/complete" and not self._origin_is_allowed():
206
208
  self._write_json({"error": "forbidden_origin"}, status=403)
207
209
  return
210
+ path_parts = [part for part in parsed.path.split("/") if part]
211
+ if self._requires_header_token(parsed.path, path_parts) and not self._header_token_is_valid():
212
+ origin = self._normalize_origin(self.headers.get("Origin"))
213
+ self._write_json(
214
+ {"error": "unauthorized"},
215
+ status=401,
216
+ extra_headers=self._cors_headers(origin) if origin is not None else None,
217
+ )
218
+ return
208
219
  payload, body_error = self._load_request_body()
209
220
  if body_error is not None:
210
221
  self._write_json({"error": body_error}, status=400)
211
222
  return
212
- path_parts = [part for part in parsed.path.split("/") if part]
213
223
  if parsed.path == "/v1/initialize":
214
224
  self._handle_initialize(payload)
215
225
  return
@@ -217,78 +227,42 @@ class _GuardDaemonHandler(BaseHTTPRequestHandler):
217
227
  self._handle_claude_hook(payload, parsed.query)
218
228
  return
219
229
  if parsed.path == "/v1/clients/attach":
220
- if not self._header_token_is_valid():
221
- self._write_json({"error": "unauthorized"}, status=401)
222
- return
223
230
  self._handle_client_attach(payload)
224
231
  return
225
232
  if parsed.path == "/v1/clients/heartbeat":
226
- if not self._header_token_is_valid():
227
- self._write_json({"error": "unauthorized"}, status=401)
228
- return
229
233
  self._handle_client_heartbeat(payload)
230
234
  return
231
235
  if parsed.path == "/v1/sessions/start":
232
- if not self._header_token_is_valid():
233
- self._write_json({"error": "unauthorized"}, status=401)
234
- return
235
236
  self._handle_session_start(payload)
236
237
  return
237
238
  if parsed.path == "/v1/operations/start":
238
- if not self._header_token_is_valid():
239
- self._write_json({"error": "unauthorized"}, status=401)
240
- return
241
239
  self._handle_operation_start(payload)
242
240
  return
243
241
  if parsed.path == "/v1/connect/requests":
244
- if not self._header_token_is_valid():
245
- self._write_json({"error": "unauthorized"}, status=401)
246
- return
247
242
  self._handle_connect_request_create(payload)
248
243
  return
249
244
  if parsed.path == "/v1/connect/complete":
250
245
  self._handle_connect_complete(payload)
251
246
  return
252
247
  if parsed.path == "/v1/connect/result":
253
- if not self._header_token_is_valid():
254
- self._write_json({"error": "unauthorized"}, status=401)
255
- return
256
248
  self._handle_connect_result_update(payload)
257
249
  return
258
250
  if parsed.path == "/v1/operations/block":
259
- if not self._header_token_is_valid():
260
- self._write_json({"error": "unauthorized"}, status=401)
261
- return
262
251
  self._handle_operation_block(payload)
263
252
  return
264
253
  if len(path_parts) == 4 and path_parts[:2] == ["v1", "operations"] and path_parts[3] == "items":
265
- if not self._header_token_is_valid():
266
- self._write_json({"error": "unauthorized"}, status=401)
267
- return
268
254
  self._handle_operation_item(path_parts[2], payload)
269
255
  return
270
256
  if len(path_parts) == 4 and path_parts[:2] == ["v1", "operations"] and path_parts[3] == "status":
271
- if not self._header_token_is_valid():
272
- self._write_json({"error": "unauthorized"}, status=401)
273
- return
274
257
  self._handle_operation_status(path_parts[2], payload)
275
258
  return
276
259
  if parsed.path == "/v1/policy/decisions":
277
- if not self._header_token_is_valid():
278
- self._write_json({"error": "unauthorized"}, status=401)
279
- return
280
260
  self._handle_policy_upsert(payload)
281
261
  return
282
262
  if parsed.path == "/v1/policy/clear":
283
- if not self._header_token_is_valid():
284
- self._write_json({"error": "unauthorized"}, status=401)
285
- return
286
263
  self._handle_policy_clear(payload)
287
264
  return
288
265
  if parsed.path == "/v1/settings":
289
- if not self._header_token_is_valid():
290
- self._write_json({"error": "unauthorized"}, status=401)
291
- return
292
266
  self._handle_settings_update(payload)
293
267
  return
294
268
  request_id, action, matched = self._resolve_request_action(path_parts, payload)
@@ -296,9 +270,6 @@ class _GuardDaemonHandler(BaseHTTPRequestHandler):
296
270
  self.send_response(404)
297
271
  self.end_headers()
298
272
  return
299
- if not self._header_token_is_valid():
300
- self._write_json({"error": "unauthorized"}, status=401)
301
- return
302
273
  if action is None:
303
274
  self._write_json({"resolved": False, "error": "missing_required_fields"}, status=400)
304
275
  return
@@ -868,11 +839,16 @@ class _GuardDaemonHandler(BaseHTTPRequestHandler):
868
839
  return f"{parsed.scheme}://{host}{port_suffix}"
869
840
 
870
841
  @staticmethod
871
- def _cors_headers(origin: str, *, allow_methods: str = "POST, OPTIONS") -> dict[str, str]:
842
+ def _cors_headers(
843
+ origin: str,
844
+ *,
845
+ allow_methods: str = "POST, OPTIONS",
846
+ allow_headers: str = "Content-Type, X-Guard-Token",
847
+ ) -> dict[str, str]:
872
848
  return {
873
849
  "Access-Control-Allow-Origin": origin,
874
850
  "Access-Control-Allow-Methods": allow_methods,
875
- "Access-Control-Allow-Headers": "Content-Type",
851
+ "Access-Control-Allow-Headers": allow_headers,
876
852
  "Vary": "Origin",
877
853
  }
878
854
 
@@ -959,6 +935,27 @@ class _GuardDaemonHandler(BaseHTTPRequestHandler):
959
935
  return path_parts[1], action.strip(), True
960
936
  return None, None, False
961
937
 
938
+ @staticmethod
939
+ def _requires_header_token(path: str, path_parts: list[str]) -> bool:
940
+ if path in {
941
+ "/v1/clients/attach",
942
+ "/v1/clients/heartbeat",
943
+ "/v1/sessions/start",
944
+ "/v1/operations/start",
945
+ "/v1/connect/requests",
946
+ "/v1/connect/result",
947
+ "/v1/operations/block",
948
+ "/v1/policy/decisions",
949
+ "/v1/policy/clear",
950
+ "/v1/settings",
951
+ }:
952
+ return True
953
+ if len(path_parts) == 4 and path_parts[:2] == ["v1", "operations"] and path_parts[3] in {"items", "status"}:
954
+ return True
955
+ if len(path_parts) == 4 and path_parts[:2] == ["v1", "requests"] and path_parts[3] in {"approve", "block"}:
956
+ return True
957
+ return len(path_parts) == 3 and path_parts[0] == "approvals" and path_parts[2] == "decision"
958
+
962
959
  def _write_json(
963
960
  self,
964
961
  payload: dict[str, Any],
@@ -1080,7 +1077,7 @@ class GuardDaemonServer:
1080
1077
  self._server = _GuardDaemonHttpServer((host, port), _GuardDaemonHandler)
1081
1078
  self._server.store = store
1082
1079
  self._server.runtime = GuardSurfaceRuntime(store)
1083
- self._server.auth_token = uuid.uuid4().hex
1080
+ self._server.auth_token = load_guard_daemon_auth_token(store.guard_home) or uuid.uuid4().hex
1084
1081
  self._server.runtime_host = host
1085
1082
  self._server.runtime_session_id = uuid.uuid4().hex
1086
1083
  self._server.runtime_started_at = _now()