@jaguilar87/gaia-ops 4.4.0 → 4.7.2

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 (371) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +12 -3
  3. package/ARCHITECTURE.md +9 -8
  4. package/CHANGELOG.md +34 -0
  5. package/README.md +43 -11
  6. package/agents/terraform-architect.md +1 -1
  7. package/bin/README.md +2 -2
  8. package/bin/gaia-doctor.js +18 -5
  9. package/bin/gaia-history.js +0 -1
  10. package/bin/gaia-metrics.js +2 -2
  11. package/bin/gaia-scan.py +23 -1
  12. package/bin/gaia-update.js +346 -54
  13. package/bin/pre-publish-validate.js +33 -10
  14. package/commands/gaia.md +37 -0
  15. package/config/README.md +3 -9
  16. package/config/context-contracts.json +47 -15
  17. package/config/surface-routing.json +9 -1
  18. package/dist/gaia-ops/.claude-plugin/plugin.json +22 -0
  19. package/dist/gaia-ops/agents/cloud-troubleshooter.md +73 -0
  20. package/dist/gaia-ops/agents/devops-developer.md +57 -0
  21. package/dist/gaia-ops/agents/gaia-system.md +58 -0
  22. package/dist/gaia-ops/agents/gitops-operator.md +60 -0
  23. package/dist/gaia-ops/agents/speckit-planner.md +71 -0
  24. package/dist/gaia-ops/agents/terraform-architect.md +60 -0
  25. package/dist/gaia-ops/commands/gaia.md +37 -0
  26. package/dist/gaia-ops/config/README.md +58 -0
  27. package/dist/gaia-ops/config/cloud/aws.json +140 -0
  28. package/dist/gaia-ops/config/cloud/gcp.json +145 -0
  29. package/dist/gaia-ops/config/context-contracts.json +131 -0
  30. package/dist/gaia-ops/config/git_standards.json +72 -0
  31. package/dist/gaia-ops/config/surface-routing.json +197 -0
  32. package/dist/gaia-ops/config/universal-rules.json +10 -0
  33. package/dist/gaia-ops/hooks/adapters/__init__.py +52 -0
  34. package/dist/gaia-ops/hooks/adapters/base.py +219 -0
  35. package/dist/gaia-ops/hooks/adapters/channel.py +17 -0
  36. package/dist/gaia-ops/hooks/adapters/claude_code.py +1477 -0
  37. package/dist/gaia-ops/hooks/adapters/types.py +194 -0
  38. package/dist/gaia-ops/hooks/adapters/utils.py +25 -0
  39. package/dist/gaia-ops/hooks/hooks.json +126 -0
  40. package/dist/gaia-ops/hooks/modules/__init__.py +15 -0
  41. package/dist/gaia-ops/hooks/modules/agents/__init__.py +29 -0
  42. package/dist/gaia-ops/hooks/modules/agents/contract_validator.py +647 -0
  43. package/dist/gaia-ops/hooks/modules/agents/response_contract.py +496 -0
  44. package/dist/gaia-ops/hooks/modules/agents/skill_injection_verifier.py +124 -0
  45. package/dist/gaia-ops/hooks/modules/agents/task_info_builder.py +74 -0
  46. package/dist/gaia-ops/hooks/modules/agents/transcript_analyzer.py +458 -0
  47. package/dist/gaia-ops/hooks/modules/agents/transcript_reader.py +152 -0
  48. package/dist/gaia-ops/hooks/modules/audit/__init__.py +28 -0
  49. package/dist/gaia-ops/hooks/modules/audit/event_detector.py +168 -0
  50. package/dist/gaia-ops/hooks/modules/audit/logger.py +131 -0
  51. package/dist/gaia-ops/hooks/modules/audit/metrics.py +134 -0
  52. package/dist/gaia-ops/hooks/modules/audit/workflow_auditor.py +576 -0
  53. package/dist/gaia-ops/hooks/modules/audit/workflow_recorder.py +296 -0
  54. package/dist/gaia-ops/hooks/modules/context/__init__.py +11 -0
  55. package/dist/gaia-ops/hooks/modules/context/anchor_tracker.py +317 -0
  56. package/dist/gaia-ops/hooks/modules/context/compact_context_builder.py +215 -0
  57. package/dist/gaia-ops/hooks/modules/context/context_cache.py +129 -0
  58. package/dist/gaia-ops/hooks/modules/context/context_freshness.py +145 -0
  59. package/dist/gaia-ops/hooks/modules/context/context_injector.py +427 -0
  60. package/dist/gaia-ops/hooks/modules/context/context_writer.py +518 -0
  61. package/dist/gaia-ops/hooks/modules/context/contracts_loader.py +161 -0
  62. package/dist/gaia-ops/hooks/modules/core/__init__.py +40 -0
  63. package/dist/gaia-ops/hooks/modules/core/hook_entry.py +78 -0
  64. package/dist/gaia-ops/hooks/modules/core/paths.py +160 -0
  65. package/dist/gaia-ops/hooks/modules/core/plugin_mode.py +149 -0
  66. package/dist/gaia-ops/hooks/modules/core/plugin_setup.py +558 -0
  67. package/dist/gaia-ops/hooks/modules/core/state.py +179 -0
  68. package/dist/gaia-ops/hooks/modules/core/stdin.py +24 -0
  69. package/dist/gaia-ops/hooks/modules/events/__init__.py +1 -0
  70. package/dist/gaia-ops/hooks/modules/events/event_writer.py +210 -0
  71. package/dist/gaia-ops/hooks/modules/identity/__init__.py +0 -0
  72. package/dist/gaia-ops/hooks/modules/identity/identity_provider.py +21 -0
  73. package/dist/gaia-ops/hooks/modules/identity/ops_identity.py +34 -0
  74. package/dist/gaia-ops/hooks/modules/identity/security_identity.py +10 -0
  75. package/dist/gaia-ops/hooks/modules/memory/__init__.py +8 -0
  76. package/dist/gaia-ops/hooks/modules/memory/episode_writer.py +227 -0
  77. package/dist/gaia-ops/hooks/modules/orchestrator/__init__.py +1 -0
  78. package/dist/gaia-ops/hooks/modules/orchestrator/delegate_mode.py +128 -0
  79. package/dist/gaia-ops/hooks/modules/scanning/__init__.py +8 -0
  80. package/dist/gaia-ops/hooks/modules/scanning/scan_trigger.py +84 -0
  81. package/dist/gaia-ops/hooks/modules/security/__init__.py +89 -0
  82. package/dist/gaia-ops/hooks/modules/security/approval_cleanup.py +87 -0
  83. package/dist/gaia-ops/hooks/modules/security/approval_constants.py +23 -0
  84. package/dist/gaia-ops/hooks/modules/security/approval_grants.py +912 -0
  85. package/dist/gaia-ops/hooks/modules/security/approval_messages.py +71 -0
  86. package/dist/gaia-ops/hooks/modules/security/approval_scopes.py +153 -0
  87. package/dist/gaia-ops/hooks/modules/security/blocked_commands.py +584 -0
  88. package/dist/gaia-ops/hooks/modules/security/blocked_message_formatter.py +86 -0
  89. package/dist/gaia-ops/hooks/modules/security/command_semantics.py +130 -0
  90. package/dist/gaia-ops/hooks/modules/security/gitops_validator.py +179 -0
  91. package/dist/gaia-ops/hooks/modules/security/mutative_verbs.py +850 -0
  92. package/dist/gaia-ops/hooks/modules/security/prompt_validator.py +40 -0
  93. package/dist/gaia-ops/hooks/modules/security/tiers.py +196 -0
  94. package/dist/gaia-ops/hooks/modules/session/__init__.py +10 -0
  95. package/dist/gaia-ops/hooks/modules/session/session_context_writer.py +100 -0
  96. package/dist/gaia-ops/hooks/modules/session/session_event_injector.py +158 -0
  97. package/dist/gaia-ops/hooks/modules/session/session_manager.py +31 -0
  98. package/dist/gaia-ops/hooks/modules/tools/__init__.py +25 -0
  99. package/dist/gaia-ops/hooks/modules/tools/bash_validator.py +708 -0
  100. package/dist/gaia-ops/hooks/modules/tools/cloud_pipe_validator.py +181 -0
  101. package/dist/gaia-ops/hooks/modules/tools/hook_response.py +55 -0
  102. package/dist/gaia-ops/hooks/modules/tools/shell_parser.py +227 -0
  103. package/dist/gaia-ops/hooks/modules/tools/task_validator.py +283 -0
  104. package/dist/gaia-ops/hooks/modules/validation/__init__.py +23 -0
  105. package/dist/gaia-ops/hooks/modules/validation/commit_validator.py +380 -0
  106. package/dist/gaia-ops/hooks/post_compact.py +43 -0
  107. package/dist/gaia-ops/hooks/post_tool_use.py +54 -0
  108. package/dist/gaia-ops/hooks/pre_tool_use.py +383 -0
  109. package/dist/gaia-ops/hooks/session_start.py +69 -0
  110. package/dist/gaia-ops/hooks/stop_hook.py +69 -0
  111. package/dist/gaia-ops/hooks/subagent_start.py +71 -0
  112. package/dist/gaia-ops/hooks/subagent_stop.py +288 -0
  113. package/dist/gaia-ops/hooks/task_completed.py +70 -0
  114. package/dist/gaia-ops/hooks/user_prompt_submit.py +177 -0
  115. package/dist/gaia-ops/settings.json +72 -0
  116. package/dist/gaia-ops/skills/README.md +109 -0
  117. package/dist/gaia-ops/skills/agent-protocol/SKILL.md +105 -0
  118. package/dist/gaia-ops/skills/agent-protocol/examples.md +170 -0
  119. package/dist/gaia-ops/skills/agent-response/SKILL.md +53 -0
  120. package/dist/gaia-ops/skills/approval/SKILL.md +85 -0
  121. package/dist/gaia-ops/skills/approval/examples.md +140 -0
  122. package/dist/gaia-ops/skills/approval/reference.md +57 -0
  123. package/dist/gaia-ops/skills/command-execution/SKILL.md +64 -0
  124. package/dist/gaia-ops/skills/command-execution/reference.md +83 -0
  125. package/dist/gaia-ops/skills/context-updater/SKILL.md +76 -0
  126. package/dist/gaia-ops/skills/context-updater/examples.md +71 -0
  127. package/dist/gaia-ops/skills/developer-patterns/SKILL.md +93 -0
  128. package/dist/gaia-ops/skills/developer-patterns/reference.md +112 -0
  129. package/dist/gaia-ops/skills/execution/SKILL.md +66 -0
  130. package/dist/gaia-ops/skills/fast-queries/SKILL.md +47 -0
  131. package/dist/gaia-ops/skills/gaia-patterns/SKILL.md +92 -0
  132. package/dist/gaia-ops/skills/gaia-patterns/reference.md +22 -0
  133. package/dist/gaia-ops/skills/git-conventions/SKILL.md +48 -0
  134. package/dist/gaia-ops/skills/gitops-patterns/SKILL.md +73 -0
  135. package/dist/gaia-ops/skills/gitops-patterns/reference.md +183 -0
  136. package/dist/gaia-ops/skills/investigation/SKILL.md +77 -0
  137. package/dist/gaia-ops/skills/orchestrator-approval/SKILL.md +64 -0
  138. package/dist/gaia-ops/skills/reference.md +134 -0
  139. package/dist/gaia-ops/skills/security-tiers/SKILL.md +61 -0
  140. package/dist/gaia-ops/skills/security-tiers/destructive-commands-reference.md +623 -0
  141. package/dist/gaia-ops/skills/security-tiers/reference.md +39 -0
  142. package/dist/gaia-ops/skills/skill-creation/SKILL.md +119 -0
  143. package/dist/gaia-ops/skills/specification/SKILL.md +186 -0
  144. package/dist/gaia-ops/skills/speckit-workflow/SKILL.md +165 -0
  145. package/dist/gaia-ops/skills/speckit-workflow/reference.md +117 -0
  146. package/dist/gaia-ops/skills/terraform-patterns/SKILL.md +63 -0
  147. package/dist/gaia-ops/skills/terraform-patterns/reference.md +93 -0
  148. package/dist/gaia-ops/speckit/README.md +516 -0
  149. package/dist/gaia-ops/speckit/scripts/.gitkeep +0 -0
  150. package/dist/gaia-ops/speckit/templates/adr-template.md +118 -0
  151. package/dist/gaia-ops/speckit/templates/agent-file-template.md +23 -0
  152. package/dist/gaia-ops/speckit/templates/plan-template.md +227 -0
  153. package/dist/gaia-ops/speckit/templates/spec-template.md +140 -0
  154. package/dist/gaia-ops/speckit/templates/tasks-template.md +257 -0
  155. package/dist/gaia-ops/tools/context/README.md +132 -0
  156. package/dist/gaia-ops/tools/context/__init__.py +42 -0
  157. package/dist/gaia-ops/tools/context/_paths.py +20 -0
  158. package/dist/gaia-ops/tools/context/context_provider.py +476 -0
  159. package/dist/gaia-ops/tools/context/context_section_reader.py +330 -0
  160. package/dist/gaia-ops/tools/context/deep_merge.py +159 -0
  161. package/dist/gaia-ops/tools/context/pending_updates.py +760 -0
  162. package/dist/gaia-ops/tools/context/surface_router.py +278 -0
  163. package/dist/gaia-ops/tools/fast-queries/README.md +65 -0
  164. package/dist/gaia-ops/tools/fast-queries/__init__.py +30 -0
  165. package/dist/gaia-ops/tools/fast-queries/appservices/quicktriage_devops_developer.sh +75 -0
  166. package/dist/gaia-ops/tools/fast-queries/cloud/aws/quicktriage_aws_troubleshooter.sh +32 -0
  167. package/dist/gaia-ops/tools/fast-queries/cloud/gcp/quicktriage_gcp_troubleshooter.sh +88 -0
  168. package/dist/gaia-ops/tools/fast-queries/gitops/quicktriage_gitops_operator.sh +48 -0
  169. package/dist/gaia-ops/tools/fast-queries/run_triage.sh +59 -0
  170. package/dist/gaia-ops/tools/fast-queries/terraform/quicktriage_terraform_architect.sh +80 -0
  171. package/dist/gaia-ops/tools/gaia_simulator/__init__.py +33 -0
  172. package/dist/gaia-ops/tools/gaia_simulator/cli.py +354 -0
  173. package/dist/gaia-ops/tools/gaia_simulator/extractor.py +457 -0
  174. package/dist/gaia-ops/tools/gaia_simulator/reporter.py +258 -0
  175. package/dist/gaia-ops/tools/gaia_simulator/routing_simulator.py +334 -0
  176. package/dist/gaia-ops/tools/gaia_simulator/runner.py +539 -0
  177. package/dist/gaia-ops/tools/gaia_simulator/skills_mapper.py +262 -0
  178. package/dist/gaia-ops/tools/memory/README.md +0 -0
  179. package/dist/gaia-ops/tools/memory/__init__.py +20 -0
  180. package/dist/gaia-ops/tools/memory/episodic.py +1196 -0
  181. package/dist/gaia-ops/tools/persist_transcript_analysis.py +85 -0
  182. package/dist/gaia-ops/tools/review/__init__.py +1 -0
  183. package/dist/gaia-ops/tools/review/review_engine.py +157 -0
  184. package/dist/gaia-ops/tools/scan/__init__.py +35 -0
  185. package/dist/gaia-ops/tools/scan/config.py +247 -0
  186. package/dist/gaia-ops/tools/scan/merge.py +212 -0
  187. package/dist/gaia-ops/tools/scan/orchestrator.py +549 -0
  188. package/dist/gaia-ops/tools/scan/registry.py +127 -0
  189. package/dist/gaia-ops/tools/scan/scanners/__init__.py +18 -0
  190. package/dist/gaia-ops/tools/scan/scanners/base.py +137 -0
  191. package/dist/gaia-ops/tools/scan/scanners/environment.py +324 -0
  192. package/dist/gaia-ops/tools/scan/scanners/git.py +570 -0
  193. package/dist/gaia-ops/tools/scan/scanners/infrastructure.py +875 -0
  194. package/dist/gaia-ops/tools/scan/scanners/orchestration.py +600 -0
  195. package/dist/gaia-ops/tools/scan/scanners/stack.py +1085 -0
  196. package/dist/gaia-ops/tools/scan/scanners/tools.py +260 -0
  197. package/dist/gaia-ops/tools/scan/setup.py +753 -0
  198. package/dist/gaia-ops/tools/scan/tests/__init__.py +1 -0
  199. package/dist/gaia-ops/tools/scan/tests/conftest.py +796 -0
  200. package/dist/gaia-ops/tools/scan/tests/test_environment.py +323 -0
  201. package/dist/gaia-ops/tools/scan/tests/test_git.py +419 -0
  202. package/dist/gaia-ops/tools/scan/tests/test_infrastructure.py +382 -0
  203. package/dist/gaia-ops/tools/scan/tests/test_integration.py +920 -0
  204. package/dist/gaia-ops/tools/scan/tests/test_merge.py +269 -0
  205. package/dist/gaia-ops/tools/scan/tests/test_orchestration.py +304 -0
  206. package/dist/gaia-ops/tools/scan/tests/test_stack.py +604 -0
  207. package/dist/gaia-ops/tools/scan/tests/test_tools.py +349 -0
  208. package/dist/gaia-ops/tools/scan/ui.py +624 -0
  209. package/dist/gaia-ops/tools/scan/verify.py +266 -0
  210. package/dist/gaia-ops/tools/scan/walk.py +118 -0
  211. package/dist/gaia-ops/tools/scan/workspace.py +85 -0
  212. package/dist/gaia-ops/tools/validation/README.md +244 -0
  213. package/dist/gaia-ops/tools/validation/__init__.py +17 -0
  214. package/dist/gaia-ops/tools/validation/approval_gate.py +321 -0
  215. package/dist/gaia-ops/tools/validation/validate_skills.py +189 -0
  216. package/dist/gaia-security/.claude-plugin/plugin.json +22 -0
  217. package/dist/gaia-security/config/universal-rules.json +10 -0
  218. package/dist/gaia-security/hooks/adapters/__init__.py +52 -0
  219. package/dist/gaia-security/hooks/adapters/base.py +219 -0
  220. package/dist/gaia-security/hooks/adapters/channel.py +17 -0
  221. package/dist/gaia-security/hooks/adapters/claude_code.py +1477 -0
  222. package/dist/gaia-security/hooks/adapters/types.py +194 -0
  223. package/dist/gaia-security/hooks/adapters/utils.py +25 -0
  224. package/dist/gaia-security/hooks/hooks.json +57 -0
  225. package/dist/gaia-security/hooks/modules/__init__.py +15 -0
  226. package/dist/gaia-security/hooks/modules/agents/__init__.py +29 -0
  227. package/dist/gaia-security/hooks/modules/agents/contract_validator.py +647 -0
  228. package/dist/gaia-security/hooks/modules/agents/response_contract.py +496 -0
  229. package/dist/gaia-security/hooks/modules/agents/skill_injection_verifier.py +124 -0
  230. package/dist/gaia-security/hooks/modules/agents/task_info_builder.py +74 -0
  231. package/dist/gaia-security/hooks/modules/agents/transcript_analyzer.py +458 -0
  232. package/dist/gaia-security/hooks/modules/agents/transcript_reader.py +152 -0
  233. package/dist/gaia-security/hooks/modules/audit/__init__.py +28 -0
  234. package/dist/gaia-security/hooks/modules/audit/event_detector.py +168 -0
  235. package/dist/gaia-security/hooks/modules/audit/logger.py +131 -0
  236. package/dist/gaia-security/hooks/modules/audit/metrics.py +134 -0
  237. package/dist/gaia-security/hooks/modules/audit/workflow_auditor.py +576 -0
  238. package/dist/gaia-security/hooks/modules/audit/workflow_recorder.py +296 -0
  239. package/dist/gaia-security/hooks/modules/context/__init__.py +11 -0
  240. package/dist/gaia-security/hooks/modules/context/anchor_tracker.py +317 -0
  241. package/dist/gaia-security/hooks/modules/context/compact_context_builder.py +215 -0
  242. package/dist/gaia-security/hooks/modules/context/context_cache.py +129 -0
  243. package/dist/gaia-security/hooks/modules/context/context_freshness.py +145 -0
  244. package/dist/gaia-security/hooks/modules/context/context_injector.py +427 -0
  245. package/dist/gaia-security/hooks/modules/context/context_writer.py +518 -0
  246. package/dist/gaia-security/hooks/modules/context/contracts_loader.py +161 -0
  247. package/dist/gaia-security/hooks/modules/core/__init__.py +40 -0
  248. package/dist/gaia-security/hooks/modules/core/hook_entry.py +78 -0
  249. package/dist/gaia-security/hooks/modules/core/paths.py +160 -0
  250. package/dist/gaia-security/hooks/modules/core/plugin_mode.py +149 -0
  251. package/dist/gaia-security/hooks/modules/core/plugin_setup.py +558 -0
  252. package/dist/gaia-security/hooks/modules/core/state.py +179 -0
  253. package/dist/gaia-security/hooks/modules/core/stdin.py +24 -0
  254. package/dist/gaia-security/hooks/modules/events/__init__.py +1 -0
  255. package/dist/gaia-security/hooks/modules/events/event_writer.py +210 -0
  256. package/dist/gaia-security/hooks/modules/identity/__init__.py +0 -0
  257. package/dist/gaia-security/hooks/modules/identity/identity_provider.py +21 -0
  258. package/dist/gaia-security/hooks/modules/identity/ops_identity.py +34 -0
  259. package/dist/gaia-security/hooks/modules/identity/security_identity.py +10 -0
  260. package/dist/gaia-security/hooks/modules/memory/__init__.py +8 -0
  261. package/dist/gaia-security/hooks/modules/memory/episode_writer.py +227 -0
  262. package/dist/gaia-security/hooks/modules/orchestrator/__init__.py +1 -0
  263. package/dist/gaia-security/hooks/modules/orchestrator/delegate_mode.py +128 -0
  264. package/dist/gaia-security/hooks/modules/scanning/__init__.py +8 -0
  265. package/dist/gaia-security/hooks/modules/scanning/scan_trigger.py +84 -0
  266. package/dist/gaia-security/hooks/modules/security/__init__.py +89 -0
  267. package/dist/gaia-security/hooks/modules/security/approval_cleanup.py +87 -0
  268. package/dist/gaia-security/hooks/modules/security/approval_constants.py +23 -0
  269. package/dist/gaia-security/hooks/modules/security/approval_grants.py +912 -0
  270. package/dist/gaia-security/hooks/modules/security/approval_messages.py +71 -0
  271. package/dist/gaia-security/hooks/modules/security/approval_scopes.py +153 -0
  272. package/dist/gaia-security/hooks/modules/security/blocked_commands.py +584 -0
  273. package/dist/gaia-security/hooks/modules/security/blocked_message_formatter.py +86 -0
  274. package/dist/gaia-security/hooks/modules/security/command_semantics.py +130 -0
  275. package/dist/gaia-security/hooks/modules/security/gitops_validator.py +179 -0
  276. package/dist/gaia-security/hooks/modules/security/mutative_verbs.py +850 -0
  277. package/dist/gaia-security/hooks/modules/security/prompt_validator.py +40 -0
  278. package/dist/gaia-security/hooks/modules/security/tiers.py +196 -0
  279. package/dist/gaia-security/hooks/modules/session/__init__.py +10 -0
  280. package/dist/gaia-security/hooks/modules/session/session_context_writer.py +100 -0
  281. package/dist/gaia-security/hooks/modules/session/session_event_injector.py +158 -0
  282. package/dist/gaia-security/hooks/modules/session/session_manager.py +31 -0
  283. package/dist/gaia-security/hooks/modules/tools/__init__.py +25 -0
  284. package/dist/gaia-security/hooks/modules/tools/bash_validator.py +708 -0
  285. package/dist/gaia-security/hooks/modules/tools/cloud_pipe_validator.py +181 -0
  286. package/dist/gaia-security/hooks/modules/tools/hook_response.py +55 -0
  287. package/dist/gaia-security/hooks/modules/tools/shell_parser.py +227 -0
  288. package/dist/gaia-security/hooks/modules/tools/task_validator.py +283 -0
  289. package/dist/gaia-security/hooks/modules/validation/__init__.py +23 -0
  290. package/dist/gaia-security/hooks/modules/validation/commit_validator.py +380 -0
  291. package/dist/gaia-security/hooks/post_tool_use.py +54 -0
  292. package/dist/gaia-security/hooks/pre_tool_use.py +383 -0
  293. package/dist/gaia-security/hooks/session_start.py +69 -0
  294. package/dist/gaia-security/hooks/stop_hook.py +69 -0
  295. package/dist/gaia-security/hooks/user_prompt_submit.py +177 -0
  296. package/dist/gaia-security/settings.json +58 -0
  297. package/git-hooks/commit-msg +41 -0
  298. package/hooks/README.md +8 -6
  299. package/hooks/adapters/channel.py +0 -25
  300. package/hooks/adapters/claude_code.py +364 -125
  301. package/hooks/elicitation_result.py +132 -0
  302. package/hooks/hooks.json +10 -1
  303. package/hooks/modules/README.md +3 -2
  304. package/hooks/modules/agents/contract_validator.py +3 -51
  305. package/hooks/modules/agents/response_contract.py +4 -8
  306. package/hooks/modules/agents/transcript_reader.py +4 -5
  307. package/hooks/modules/audit/__init__.py +4 -6
  308. package/hooks/modules/audit/event_detector.py +0 -2
  309. package/hooks/modules/audit/metrics.py +108 -187
  310. package/hooks/modules/audit/workflow_auditor.py +0 -4
  311. package/hooks/modules/audit/workflow_recorder.py +0 -5
  312. package/hooks/modules/context/compact_context_builder.py +1 -0
  313. package/hooks/modules/context/context_cache.py +129 -0
  314. package/hooks/modules/context/context_injector.py +18 -40
  315. package/hooks/modules/context/context_writer.py +1 -25
  316. package/hooks/modules/context/contracts_loader.py +7 -10
  317. package/hooks/modules/core/hook_entry.py +1 -0
  318. package/hooks/modules/core/paths.py +12 -13
  319. package/hooks/modules/core/plugin_mode.py +74 -4
  320. package/hooks/modules/core/plugin_setup.py +395 -23
  321. package/hooks/modules/events/__init__.py +1 -0
  322. package/hooks/modules/events/event_writer.py +210 -0
  323. package/hooks/modules/identity/ops_identity.py +18 -27
  324. package/hooks/modules/memory/episode_writer.py +1 -6
  325. package/hooks/modules/orchestrator/__init__.py +1 -0
  326. package/hooks/modules/orchestrator/delegate_mode.py +128 -0
  327. package/hooks/modules/security/__init__.py +2 -4
  328. package/hooks/modules/security/approval_constants.py +5 -1
  329. package/hooks/modules/security/approval_grants.py +189 -6
  330. package/hooks/modules/security/approval_messages.py +9 -21
  331. package/hooks/modules/security/blocked_commands.py +98 -34
  332. package/hooks/modules/security/command_semantics.py +0 -4
  333. package/hooks/modules/security/gitops_validator.py +1 -11
  334. package/hooks/modules/security/mutative_verbs.py +179 -38
  335. package/hooks/modules/security/tiers.py +1 -19
  336. package/hooks/modules/session/session_event_injector.py +1 -25
  337. package/hooks/modules/tools/bash_validator.py +310 -94
  338. package/hooks/modules/tools/shell_parser.py +0 -1
  339. package/hooks/modules/tools/task_validator.py +9 -29
  340. package/hooks/post_tool_use.py +0 -72
  341. package/hooks/pre_tool_use.py +42 -102
  342. package/hooks/session_start.py +4 -2
  343. package/hooks/subagent_start.py +6 -2
  344. package/hooks/subagent_stop.py +1 -13
  345. package/hooks/user_prompt_submit.py +119 -37
  346. package/index.js +1 -1
  347. package/package.json +5 -3
  348. package/skills/README.md +3 -5
  349. package/skills/agent-protocol/SKILL.md +17 -16
  350. package/skills/agent-protocol/examples.md +6 -6
  351. package/skills/agent-response/SKILL.md +11 -14
  352. package/skills/approval/SKILL.md +28 -13
  353. package/skills/approval/reference.md +2 -2
  354. package/skills/execution/SKILL.md +1 -1
  355. package/skills/gaia-patterns/SKILL.md +2 -3
  356. package/skills/orchestrator-approval/SKILL.md +22 -50
  357. package/skills/security-tiers/SKILL.md +1 -1
  358. package/templates/README.md +9 -9
  359. package/templates/managed-settings.template.json +43 -0
  360. package/tools/gaia_simulator/runner.py +34 -1
  361. package/tools/scan/orchestrator.py +13 -0
  362. package/tools/scan/scanners/base.py +8 -0
  363. package/tools/scan/scanners/git.py +78 -0
  364. package/tools/scan/scanners/infrastructure.py +65 -0
  365. package/tools/scan/scanners/stack.py +110 -0
  366. package/tools/scan/setup.py +120 -13
  367. package/tools/scan/workspace.py +85 -0
  368. package/config/context-contracts.aws.json +0 -42
  369. package/config/context-contracts.gcp.json +0 -39
  370. package/skills/project-dispatch/SKILL.md +0 -34
  371. package/templates/settings.template.json +0 -226
@@ -0,0 +1,189 @@
1
+ #!/usr/bin/env python3
2
+ import os
3
+ import re
4
+ import yaml
5
+ from pathlib import Path
6
+ from collections import defaultdict
7
+
8
+ def find_skills(base_dirs):
9
+ """Encuentra todas las skills en los directorios base."""
10
+ skills = {}
11
+ for base_dir in base_dirs:
12
+ path = Path(base_dir)
13
+ if not path.exists():
14
+ continue
15
+ for skill_file in path.rglob("SKILL.md"):
16
+ skill_name = skill_file.parent.name
17
+ skills[skill_name] = {
18
+ "path": str(skill_file),
19
+ "content": skill_file.read_text(encoding="utf-8", errors="ignore")
20
+ }
21
+ return skills
22
+
23
+ def validate_skill_format(skills):
24
+ """Valida el formato de cada skill."""
25
+ validation_results = {}
26
+ for name, data in skills.items():
27
+ content = data["content"]
28
+ has_title = bool(re.search(r'^#\s+.+', content, re.MULTILINE))
29
+ validation_results[name] = {
30
+ "has_title": has_title,
31
+ "is_empty": len(content.strip()) == 0,
32
+ "path": data["path"]
33
+ }
34
+ return validation_results
35
+
36
+ def find_agents(base_dirs):
37
+ """Encuentra las definiciones de los agentes."""
38
+ agents = {}
39
+ for base_dir in base_dirs:
40
+ path = Path(base_dir)
41
+ if not path.exists():
42
+ continue
43
+ for agent_file in path.rglob("*.md"):
44
+ if agent_file.name == "README.md":
45
+ continue
46
+ content = agent_file.read_text(encoding="utf-8", errors="ignore")
47
+ # Extraer frontmatter YAML
48
+ match = re.match(r'^---\s*\n(.*?)\n---\s*\n(.*)', content, re.DOTALL)
49
+ if match:
50
+ try:
51
+ frontmatter = yaml.safe_load(match.group(1))
52
+ if isinstance(frontmatter, dict) and "name" in frontmatter:
53
+ agents[frontmatter["name"]] = {
54
+ "path": str(agent_file),
55
+ "skills_declared": frontmatter.get("skills", []),
56
+ "body": match.group(2)
57
+ }
58
+ except yaml.YAMLError:
59
+ pass
60
+ return agents
61
+
62
+ def analyze_injection():
63
+ """Analiza cómo se inyectan las skills (revisando pre_tool_use.py)."""
64
+ hook_path = Path("gaia-ops/hooks/pre_tool_use.py")
65
+ if not hook_path.exists():
66
+ return "No se encontró gaia-ops/hooks/pre_tool_use.py"
67
+
68
+ content = hook_path.read_text(encoding="utf-8", errors="ignore")
69
+ if "skills are injected natively by Claude Code" in content:
70
+ return "Las skills se inyectan de forma nativa por Claude Code a través del campo 'skills:' en el frontmatter del agente (según pre_tool_use.py)."
71
+ return "Mecanismo de inyección en pre_tool_use.py analizado, pero no se encontró la nota estándar sobre inyección nativa."
72
+
73
+ def generate_report(skills, validation, agents, injection_info):
74
+ """Genera el reporte en formato Markdown."""
75
+ report = ["# Reporte de Validación de Skills\n"]
76
+
77
+ report.append("## 1. Análisis de Inyección")
78
+ report.append(f"{injection_info}\n")
79
+
80
+ report.append(f"## 2. Skills Encontradas ({len(skills)})")
81
+ for name, val in validation.items():
82
+ status = "✅ OK" if val["has_title"] and not val["is_empty"] else "❌ PROBLEMA"
83
+ issues = []
84
+ if not val["has_title"]: issues.append("Falta título (# Título)")
85
+ if val["is_empty"]: issues.append("Archivo vacío")
86
+ issue_str = f" - Detalles: {', '.join(issues)}" if issues else ""
87
+ report.append(f"- **{name}** ({val['path']}): {status}{issue_str}")
88
+ report.append("")
89
+
90
+ # Analizar uso de skills
91
+ used_skills = defaultdict(list)
92
+ missing_skills = defaultdict(list)
93
+ body_mentions = defaultdict(list)
94
+
95
+ for agent_name, agent_data in agents.items():
96
+ declared = agent_data["skills_declared"] or []
97
+ body = agent_data["body"]
98
+ for skill in declared:
99
+ if skill in skills:
100
+ used_skills[skill].append(agent_name)
101
+ else:
102
+ missing_skills[agent_name].append(skill)
103
+
104
+ # Check for skills mentioned in the body but not declared
105
+ for skill in skills:
106
+ if skill not in declared and skill in body:
107
+ body_mentions[agent_name].append(skill)
108
+
109
+ report.append("## 3. Uso de Skills por Agentes")
110
+ if not agents:
111
+ report.append("No se encontraron definiciones de agentes con frontmatter YAML válido.\n")
112
+ else:
113
+ for agent_name, agent_data in agents.items():
114
+ declared = agent_data["skills_declared"] or []
115
+ mentions = body_mentions[agent_name]
116
+ mention_str = f" (Menciona en texto sin declarar: {', '.join(mentions)})" if mentions else ""
117
+ report.append(f"- **{agent_name}**: {len(declared)} skills declaradas.{mention_str}")
118
+ report.append("")
119
+
120
+ report.append("## 4. Gaps Identificados")
121
+
122
+ # Skills no utilizadas
123
+ # Consideramos una skill como utilizada si está declarada o si se menciona explícitamente en el cuerpo
124
+ all_used_skills = set(used_skills.keys())
125
+ for mentions in body_mentions.values():
126
+ all_used_skills.update(mentions)
127
+
128
+ unused_skills = set(skills.keys()) - all_used_skills
129
+ if unused_skills:
130
+ report.append("### Skills no utilizadas (Huérfanas)")
131
+ for skill in sorted(unused_skills):
132
+ report.append(f"- {skill}")
133
+ else:
134
+ report.append("### Skills no utilizadas (Huérfanas)")
135
+ report.append("- Ninguna. Todas las skills encontradas están asignadas a al menos un agente.")
136
+ report.append("")
137
+
138
+ # Skills declaradas pero inexistentes
139
+ if missing_skills:
140
+ report.append("### Skills declaradas pero no encontradas (Faltantes)")
141
+ for agent, missing in missing_skills.items():
142
+ for m in missing:
143
+ report.append(f"- El agente **{agent}** declara la skill '{m}', pero no se encontró el archivo SKILL.md correspondiente.")
144
+ else:
145
+ report.append("### Skills declaradas pero no encontradas (Faltantes)")
146
+ report.append("- Ninguna. Todas las skills declaradas por los agentes existen.")
147
+ report.append("")
148
+
149
+ # Skills mencionadas en el texto pero no inyectadas formalmente
150
+ report.append("### Skills mencionadas en el texto pero NO declaradas en 'skills:'")
151
+ if body_mentions:
152
+ for agent, mentions in body_mentions.items():
153
+ for m in mentions:
154
+ report.append(f"- **{agent}** menciona '{m}' en su cuerpo pero no está en la lista de inyección.")
155
+ else:
156
+ report.append("- Ninguna.")
157
+ report.append("")
158
+
159
+ return "\n".join(report)
160
+
161
+ def main():
162
+ skill_dirs = ["gaia-ops/skills", ".claude/skills", "conductor-orchestrator/skills"]
163
+ agent_dirs = ["gaia-ops/agents", ".claude/agents", "conductor-orchestrator/agents"]
164
+
165
+ print("Buscando skills...")
166
+ skills = find_skills(skill_dirs)
167
+
168
+ print("Validando formato...")
169
+ validation = validate_skill_format(skills)
170
+
171
+ print("Buscando agentes...")
172
+ agents = find_agents(agent_dirs)
173
+
174
+ print("Analizando inyección...")
175
+ injection_info = analyze_injection()
176
+
177
+ print("Generando reporte...")
178
+ report = generate_report(skills, validation, agents, injection_info)
179
+
180
+ report_path = Path("gaia-ops/tools/validation/skills_report.md")
181
+ report_path.write_text(report, encoding="utf-8")
182
+ print(f"Reporte generado en {report_path}")
183
+
184
+ # Imprimir el reporte en la salida estándar para que el agente lo pueda devolver
185
+ print("\n" + "="*50 + "\n")
186
+ print(report)
187
+
188
+ if __name__ == "__main__":
189
+ main()
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "gaia-security",
3
+ "version": "4.7.2",
4
+ "description": "Keeps you in the loop only when it matters. Gaia Security analyzes every command and classifies it into risk tiers: read-only queries run freely, simulations and validations pass through, and state-changing operations (create, delete, apply, push) pause for your explicit approval before executing. Irreversible commands like dropping databases or deleting cloud infrastructure are permanently blocked.",
5
+ "author": {
6
+ "name": "jaguilar87"
7
+ },
8
+ "repository": "https://github.com/metraton/gaia-ops",
9
+ "license": "MIT",
10
+ "keywords": [
11
+ "security",
12
+ "devops"
13
+ ],
14
+ "engines": {
15
+ "claude-code": ">=2.1.0"
16
+ },
17
+ "categories": [
18
+ "devops",
19
+ "security",
20
+ "orchestration"
21
+ ]
22
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "rules": {
3
+ "universal": [
4
+ {
5
+ "rule": "Your prompt includes a Project Context section with confirmed project knowledge. Extract relevant data from it BEFORE executing commands."
6
+ }
7
+ ],
8
+ "agent_specific": {}
9
+ }
10
+ }
@@ -0,0 +1,52 @@
1
+ """
2
+ Adapter Layer for Gaia-Ops Hooks.
3
+
4
+ Provides CLI-agnostic normalized types and the abstract HookAdapter interface.
5
+ Business logic modules consume and produce these types; concrete adapters
6
+ translate between these types and CLI-specific JSON protocols.
7
+
8
+ Modules:
9
+ - types: Frozen dataclasses and enums for all hook event/response data
10
+ - base: Abstract HookAdapter interface
11
+ """
12
+
13
+ from .types import (
14
+ HookEventType,
15
+ PermissionDecision,
16
+ DistributionChannel,
17
+ HookEvent,
18
+ ValidationRequest,
19
+ ValidationResult,
20
+ ToolResult,
21
+ AgentCompletion,
22
+ CompletionResult,
23
+ ContextResult,
24
+ BootstrapResult,
25
+ QualityResult,
26
+ VerificationResult,
27
+ HookResponse,
28
+ )
29
+ from .base import HookAdapter
30
+ from .claude_code import ClaudeCodeAdapter
31
+ from .utils import has_stdin_data, warn_if_dual_channel
32
+
33
+ __all__ = [
34
+ "HookEventType",
35
+ "PermissionDecision",
36
+ "DistributionChannel",
37
+ "HookEvent",
38
+ "ValidationRequest",
39
+ "ValidationResult",
40
+ "ToolResult",
41
+ "AgentCompletion",
42
+ "CompletionResult",
43
+ "ContextResult",
44
+ "BootstrapResult",
45
+ "QualityResult",
46
+ "VerificationResult",
47
+ "HookResponse",
48
+ "HookAdapter",
49
+ "ClaudeCodeAdapter",
50
+ "has_stdin_data",
51
+ "warn_if_dual_channel",
52
+ ]
@@ -0,0 +1,219 @@
1
+ """
2
+ Abstract base class defining the adapter contract.
3
+
4
+ Each CLI backend (Claude Code, future CLIs) provides a concrete implementation
5
+ of HookAdapter. Business logic modules interact only with the normalized types;
6
+ they never see raw CLI JSON.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ from abc import ABC, abstractmethod
12
+
13
+ from .types import (
14
+ AgentCompletion,
15
+ BootstrapResult,
16
+ CompletionResult,
17
+ ContextResult,
18
+ DistributionChannel,
19
+ HookEvent,
20
+ HookResponse,
21
+ QualityResult,
22
+ ValidationResult,
23
+ VerificationResult,
24
+ )
25
+
26
+
27
+ class HookAdapter(ABC):
28
+ """Abstract adapter between CLI-specific JSON and normalized types.
29
+
30
+ Invariants (from adapter-interface contract):
31
+ 1. Business logic modules NEVER see HookResponse.
32
+ 2. The adapter NEVER modifies business logic results -- only translates format.
33
+ 3. Adding a new hook event requires ONLY a new adapter method.
34
+ """
35
+
36
+ @abstractmethod
37
+ def parse_event(self, stdin_data: str) -> HookEvent:
38
+ """Parse raw stdin JSON into a normalized HookEvent.
39
+
40
+ Preconditions:
41
+ - stdin_data is a valid JSON string
42
+ - JSON contains at minimum: hook_event_name, session_id
43
+
44
+ Postconditions:
45
+ - Returns HookEvent with event_type set to a valid HookEventType
46
+ - Returns HookEvent with session_id populated
47
+ - payload contains the full raw event data
48
+
49
+ Raises:
50
+ ValueError: If JSON is invalid or event type is unknown.
51
+ """
52
+ ...
53
+
54
+ @abstractmethod
55
+ def format_validation_response(self, result: ValidationResult) -> HookResponse:
56
+ """Format a ValidationResult for CLI consumption.
57
+
58
+ Preconditions:
59
+ - result.allowed is a valid boolean
60
+ - result.reason is a non-empty string
61
+
62
+ Postconditions:
63
+ - HookResponse.output is a valid JSON-serializable dict
64
+ - HookResponse.exit_code is 0 (corrective deny) or 2 (permanent block)
65
+ - If result.allowed is True, output contains permissionDecision: allow
66
+ - If result.allowed is False, output contains permissionDecision: deny
67
+ - If result.modified_input is set, output contains updatedInput
68
+ """
69
+ ...
70
+
71
+ @abstractmethod
72
+ def format_completion_response(self, result: CompletionResult) -> HookResponse:
73
+ """Format a CompletionResult for CLI consumption.
74
+
75
+ Postconditions:
76
+ - HookResponse.output contains contract_valid, anomalies_detected
77
+ - HookResponse.exit_code is always 0
78
+ """
79
+ ...
80
+
81
+ @abstractmethod
82
+ def format_context_response(self, result: ContextResult) -> HookResponse:
83
+ """Format a ContextResult for CLI consumption."""
84
+ ...
85
+
86
+ @abstractmethod
87
+ def format_bootstrap_response(self, result: BootstrapResult) -> HookResponse:
88
+ """Format a BootstrapResult for CLI consumption.
89
+
90
+ Returns session bootstrap status for SessionStart events.
91
+ """
92
+ ...
93
+
94
+ @abstractmethod
95
+ def adapt_session_start(self, raw: dict) -> BootstrapResult:
96
+ """Parse SessionStart event and return bootstrap actions.
97
+
98
+ Preconditions:
99
+ - raw is the HookEvent.payload dict for a SessionStart event
100
+
101
+ Postconditions:
102
+ - Returns BootstrapResult with should_scan and should_refresh set
103
+ based on session_type
104
+ """
105
+ ...
106
+
107
+ # ------------------------------------------------------------------ #
108
+ # P2 event adapters
109
+ # ------------------------------------------------------------------ #
110
+
111
+ @abstractmethod
112
+ def adapt_stop(self, raw: dict) -> QualityResult:
113
+ """Parse Stop event and assess response quality.
114
+
115
+ Preconditions:
116
+ - raw is the HookEvent.payload dict for a Stop event
117
+
118
+ Postconditions:
119
+ - Returns QualityResult with quality assessment
120
+ """
121
+ ...
122
+
123
+ @abstractmethod
124
+ def adapt_task_completed(self, raw: dict) -> VerificationResult:
125
+ """Parse TaskCompleted event and verify completion criteria.
126
+
127
+ Preconditions:
128
+ - raw is the HookEvent.payload dict for a TaskCompleted event
129
+
130
+ Postconditions:
131
+ - Returns VerificationResult with criteria assessment
132
+ """
133
+ ...
134
+
135
+ @abstractmethod
136
+ def adapt_subagent_start(self, raw: dict) -> ContextResult:
137
+ """Parse SubagentStart event and prepare agent context.
138
+
139
+ Preconditions:
140
+ - raw is the HookEvent.payload dict for a SubagentStart event
141
+
142
+ Postconditions:
143
+ - Returns ContextResult with agent-specific context
144
+ """
145
+ ...
146
+
147
+ # ------------------------------------------------------------------ #
148
+ # P2 formatters
149
+ # ------------------------------------------------------------------ #
150
+
151
+ @abstractmethod
152
+ def format_quality_response(self, result: QualityResult) -> HookResponse:
153
+ """Format a QualityResult for CLI consumption."""
154
+ ...
155
+
156
+ @abstractmethod
157
+ def format_verification_response(self, result: VerificationResult) -> HookResponse:
158
+ """Format a VerificationResult for CLI consumption."""
159
+ ...
160
+
161
+ @abstractmethod
162
+ def detect_channel(self) -> DistributionChannel:
163
+ """Detect the distribution channel (NPM or PLUGIN).
164
+
165
+ Checks environment variables and filesystem layout to determine
166
+ how gaia-ops was installed.
167
+ """
168
+ ...
169
+
170
+ # ------------------------------------------------------------------ #
171
+ # Full hook lifecycle adapters (thin-gate pattern)
172
+ # ------------------------------------------------------------------ #
173
+
174
+ @abstractmethod
175
+ def adapt_pre_tool_use(self, event: HookEvent) -> HookResponse:
176
+ """Run all pre-tool-use business logic and return a formatted response.
177
+
178
+ Orchestrates: routing (bash vs task), validation, state management,
179
+ context injection, approval handling, and response formatting.
180
+
181
+ Preconditions:
182
+ - event is a parsed HookEvent with event_type PRE_TOOL_USE
183
+
184
+ Postconditions:
185
+ - Returns HookResponse ready for stdout + sys.exit()
186
+ """
187
+ ...
188
+
189
+ @abstractmethod
190
+ def adapt_post_tool_use(self, event: HookEvent) -> HookResponse:
191
+ """Run all post-tool-use business logic and return a formatted response.
192
+
193
+ Orchestrates: state retrieval, duration computation, audit logging,
194
+ T3 grant confirmation, critical event detection, session context
195
+ writing, and state cleanup.
196
+
197
+ Preconditions:
198
+ - event is a parsed HookEvent with event_type POST_TOOL_USE
199
+
200
+ Postconditions:
201
+ - Returns HookResponse (always exit 0, post-hook never blocks)
202
+ """
203
+ ...
204
+
205
+ @abstractmethod
206
+ def adapt_subagent_stop(self, event: HookEvent) -> HookResponse:
207
+ """Run all subagent-stop business logic and return a formatted response.
208
+
209
+ Orchestrates: contract parsing and validation, approval cleanup,
210
+ context updates, workflow recording, response contract validation,
211
+ anomaly detection, episodic memory, and result assembly.
212
+
213
+ Preconditions:
214
+ - event is a parsed HookEvent with event_type SUBAGENT_STOP
215
+
216
+ Postconditions:
217
+ - Returns HookResponse (exit 0 for success, exit 2 for contract rejection)
218
+ """
219
+ ...
@@ -0,0 +1,17 @@
1
+ """
2
+ Distribution Channel Detection for Gaia-Ops.
3
+
4
+ Utility module that detects whether gaia-ops is running as a Claude Code plugin
5
+ or via npm. Used by entry points to log coexistence warnings and by business
6
+ logic to adapt behavior per channel.
7
+ """
8
+
9
+ import os
10
+ from pathlib import Path
11
+
12
+
13
+ def is_dual_channel_active() -> bool:
14
+ """Check if both plugin and npm installations exist simultaneously."""
15
+ has_plugin = bool(os.environ.get("CLAUDE_PLUGIN_ROOT"))
16
+ has_npm = Path(".claude/hooks").is_symlink()
17
+ return has_plugin and has_npm