@jaguilar87/gaia 5.0.0-rc1

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 (609) hide show
  1. package/.claude-plugin/marketplace.json +33 -0
  2. package/.claude-plugin/plugin.json +26 -0
  3. package/ARCHITECTURE.md +335 -0
  4. package/CHANGELOG.md +1212 -0
  5. package/CODE_OF_CONDUCT.md +11 -0
  6. package/CONTRIBUTING.md +146 -0
  7. package/INSTALL.md +436 -0
  8. package/LICENSE +21 -0
  9. package/README.md +222 -0
  10. package/SECURITY.md +47 -0
  11. package/agents/README.md +78 -0
  12. package/agents/cloud-troubleshooter.md +73 -0
  13. package/agents/developer.md +65 -0
  14. package/agents/gaia-operator.md +64 -0
  15. package/agents/gaia-orchestrator.md +237 -0
  16. package/agents/gaia-planner.md +53 -0
  17. package/agents/gaia-system.md +70 -0
  18. package/agents/gitops-operator.md +61 -0
  19. package/agents/terraform-architect.md +63 -0
  20. package/bin/README.md +106 -0
  21. package/bin/cli/__init__.py +1 -0
  22. package/bin/cli/approvals.py +740 -0
  23. package/bin/cli/cleanup.py +562 -0
  24. package/bin/cli/context.py +283 -0
  25. package/bin/cli/doctor.py +628 -0
  26. package/bin/cli/history.py +305 -0
  27. package/bin/cli/memory.py +464 -0
  28. package/bin/cli/metrics.py +1068 -0
  29. package/bin/cli/plans.py +515 -0
  30. package/bin/cli/status.py +302 -0
  31. package/bin/cli/update.py +382 -0
  32. package/bin/gaia +112 -0
  33. package/bin/gaia-cleanup.js +531 -0
  34. package/bin/gaia-doctor.js +635 -0
  35. package/bin/gaia-evidence +126 -0
  36. package/bin/gaia-history.js +251 -0
  37. package/bin/gaia-metrics.js +1278 -0
  38. package/bin/gaia-review.js +269 -0
  39. package/bin/gaia-scan +44 -0
  40. package/bin/gaia-scan.py +589 -0
  41. package/bin/gaia-skills-diagnose.js +929 -0
  42. package/bin/gaia-status.js +278 -0
  43. package/bin/gaia-uninstall.js +111 -0
  44. package/bin/gaia-update.js +816 -0
  45. package/bin/pre-publish-validate.js +610 -0
  46. package/bin/python-detect.js +60 -0
  47. package/commands/README.md +64 -0
  48. package/commands/gaia.md +37 -0
  49. package/commands/scan-project.md +67 -0
  50. package/config/README.md +71 -0
  51. package/config/cloud/aws.json +134 -0
  52. package/config/cloud/gcp.json +139 -0
  53. package/config/context-contracts.json +158 -0
  54. package/config/crons-schema.md +81 -0
  55. package/config/git_standards.json +72 -0
  56. package/config/surface-routing.json +421 -0
  57. package/config/universal-rules.json +102 -0
  58. package/dist/gaia-ops/.claude-plugin/plugin.json +24 -0
  59. package/dist/gaia-ops/README.md +80 -0
  60. package/dist/gaia-ops/agents/cloud-troubleshooter.md +73 -0
  61. package/dist/gaia-ops/agents/developer.md +65 -0
  62. package/dist/gaia-ops/agents/gaia-operator.md +64 -0
  63. package/dist/gaia-ops/agents/gaia-orchestrator.md +237 -0
  64. package/dist/gaia-ops/agents/gaia-planner.md +53 -0
  65. package/dist/gaia-ops/agents/gaia-system.md +70 -0
  66. package/dist/gaia-ops/agents/gitops-operator.md +61 -0
  67. package/dist/gaia-ops/agents/terraform-architect.md +63 -0
  68. package/dist/gaia-ops/commands/gaia.md +37 -0
  69. package/dist/gaia-ops/config/README.md +71 -0
  70. package/dist/gaia-ops/config/cloud/aws.json +134 -0
  71. package/dist/gaia-ops/config/cloud/gcp.json +139 -0
  72. package/dist/gaia-ops/config/context-contracts.json +158 -0
  73. package/dist/gaia-ops/config/crons-schema.md +81 -0
  74. package/dist/gaia-ops/config/git_standards.json +72 -0
  75. package/dist/gaia-ops/config/surface-routing.json +421 -0
  76. package/dist/gaia-ops/config/universal-rules.json +102 -0
  77. package/dist/gaia-ops/hooks/adapters/__init__.py +52 -0
  78. package/dist/gaia-ops/hooks/adapters/base.py +219 -0
  79. package/dist/gaia-ops/hooks/adapters/channel.py +17 -0
  80. package/dist/gaia-ops/hooks/adapters/claude_code.py +1890 -0
  81. package/dist/gaia-ops/hooks/adapters/types.py +194 -0
  82. package/dist/gaia-ops/hooks/adapters/utils.py +25 -0
  83. package/dist/gaia-ops/hooks/hooks.json +163 -0
  84. package/dist/gaia-ops/hooks/modules/__init__.py +15 -0
  85. package/dist/gaia-ops/hooks/modules/agents/__init__.py +29 -0
  86. package/dist/gaia-ops/hooks/modules/agents/contract_validator.py +647 -0
  87. package/dist/gaia-ops/hooks/modules/agents/response_contract.py +496 -0
  88. package/dist/gaia-ops/hooks/modules/agents/skill_injection_verifier.py +120 -0
  89. package/dist/gaia-ops/hooks/modules/agents/state_tracker.py +267 -0
  90. package/dist/gaia-ops/hooks/modules/agents/task_info_builder.py +74 -0
  91. package/dist/gaia-ops/hooks/modules/agents/transcript_analyzer.py +458 -0
  92. package/dist/gaia-ops/hooks/modules/agents/transcript_reader.py +152 -0
  93. package/dist/gaia-ops/hooks/modules/audit/__init__.py +28 -0
  94. package/dist/gaia-ops/hooks/modules/audit/event_detector.py +168 -0
  95. package/dist/gaia-ops/hooks/modules/audit/logger.py +131 -0
  96. package/dist/gaia-ops/hooks/modules/audit/metrics.py +134 -0
  97. package/dist/gaia-ops/hooks/modules/audit/workflow_auditor.py +611 -0
  98. package/dist/gaia-ops/hooks/modules/audit/workflow_recorder.py +296 -0
  99. package/dist/gaia-ops/hooks/modules/context/__init__.py +11 -0
  100. package/dist/gaia-ops/hooks/modules/context/agentic_loop_detector.py +165 -0
  101. package/dist/gaia-ops/hooks/modules/context/anchor_tracker.py +317 -0
  102. package/dist/gaia-ops/hooks/modules/context/compact_context_builder.py +218 -0
  103. package/dist/gaia-ops/hooks/modules/context/context_freshness.py +145 -0
  104. package/dist/gaia-ops/hooks/modules/context/context_injector.py +558 -0
  105. package/dist/gaia-ops/hooks/modules/context/context_writer.py +530 -0
  106. package/dist/gaia-ops/hooks/modules/context/contracts_loader.py +161 -0
  107. package/dist/gaia-ops/hooks/modules/core/__init__.py +40 -0
  108. package/dist/gaia-ops/hooks/modules/core/hook_entry.py +78 -0
  109. package/dist/gaia-ops/hooks/modules/core/paths.py +160 -0
  110. package/dist/gaia-ops/hooks/modules/core/plugin_mode.py +149 -0
  111. package/dist/gaia-ops/hooks/modules/core/plugin_setup.py +577 -0
  112. package/dist/gaia-ops/hooks/modules/core/state.py +179 -0
  113. package/dist/gaia-ops/hooks/modules/core/stdin.py +24 -0
  114. package/dist/gaia-ops/hooks/modules/events/__init__.py +1 -0
  115. package/dist/gaia-ops/hooks/modules/events/event_writer.py +210 -0
  116. package/dist/gaia-ops/hooks/modules/memory/__init__.py +8 -0
  117. package/dist/gaia-ops/hooks/modules/memory/episode_writer.py +216 -0
  118. package/dist/gaia-ops/hooks/modules/orchestrator/__init__.py +1 -0
  119. package/dist/gaia-ops/hooks/modules/orchestrator/delegate_mode.py +122 -0
  120. package/dist/gaia-ops/hooks/modules/scanning/__init__.py +8 -0
  121. package/dist/gaia-ops/hooks/modules/scanning/scan_trigger.py +84 -0
  122. package/dist/gaia-ops/hooks/modules/security/__init__.py +120 -0
  123. package/dist/gaia-ops/hooks/modules/security/approval_cleanup.py +87 -0
  124. package/dist/gaia-ops/hooks/modules/security/approval_constants.py +23 -0
  125. package/dist/gaia-ops/hooks/modules/security/approval_grants.py +1638 -0
  126. package/dist/gaia-ops/hooks/modules/security/approval_messages.py +71 -0
  127. package/dist/gaia-ops/hooks/modules/security/approval_scopes.py +222 -0
  128. package/dist/gaia-ops/hooks/modules/security/blocked_commands.py +595 -0
  129. package/dist/gaia-ops/hooks/modules/security/blocked_message_formatter.py +87 -0
  130. package/dist/gaia-ops/hooks/modules/security/command_semantics.py +181 -0
  131. package/dist/gaia-ops/hooks/modules/security/composition_rules.py +547 -0
  132. package/dist/gaia-ops/hooks/modules/security/flag_classifiers.py +873 -0
  133. package/dist/gaia-ops/hooks/modules/security/gitops_validator.py +179 -0
  134. package/dist/gaia-ops/hooks/modules/security/mutative_verbs.py +1131 -0
  135. package/dist/gaia-ops/hooks/modules/security/network_hosts.py +481 -0
  136. package/dist/gaia-ops/hooks/modules/security/prompt_validator.py +40 -0
  137. package/dist/gaia-ops/hooks/modules/security/shell_unwrapper.py +165 -0
  138. package/dist/gaia-ops/hooks/modules/security/tiers.py +196 -0
  139. package/dist/gaia-ops/hooks/modules/session/__init__.py +10 -0
  140. package/dist/gaia-ops/hooks/modules/session/pending_scanner.py +174 -0
  141. package/dist/gaia-ops/hooks/modules/session/session_context_writer.py +100 -0
  142. package/dist/gaia-ops/hooks/modules/session/session_event_injector.py +160 -0
  143. package/dist/gaia-ops/hooks/modules/session/session_manager.py +31 -0
  144. package/dist/gaia-ops/hooks/modules/session/session_registry.py +232 -0
  145. package/dist/gaia-ops/hooks/modules/tools/__init__.py +29 -0
  146. package/dist/gaia-ops/hooks/modules/tools/bash_validator.py +1008 -0
  147. package/dist/gaia-ops/hooks/modules/tools/cloud_pipe_validator.py +231 -0
  148. package/dist/gaia-ops/hooks/modules/tools/hook_response.py +55 -0
  149. package/dist/gaia-ops/hooks/modules/tools/shell_parser.py +227 -0
  150. package/dist/gaia-ops/hooks/modules/tools/stage_decomposer.py +315 -0
  151. package/dist/gaia-ops/hooks/modules/tools/task_validator.py +294 -0
  152. package/dist/gaia-ops/hooks/modules/validation/__init__.py +23 -0
  153. package/dist/gaia-ops/hooks/modules/validation/commit_validator.py +380 -0
  154. package/dist/gaia-ops/hooks/post_compact.py +43 -0
  155. package/dist/gaia-ops/hooks/post_tool_use.py +54 -0
  156. package/dist/gaia-ops/hooks/pre_compact.py +60 -0
  157. package/dist/gaia-ops/hooks/pre_tool_use.py +413 -0
  158. package/dist/gaia-ops/hooks/session_start.py +81 -0
  159. package/dist/gaia-ops/hooks/stop_hook.py +82 -0
  160. package/dist/gaia-ops/hooks/subagent_start.py +71 -0
  161. package/dist/gaia-ops/hooks/subagent_stop.py +295 -0
  162. package/dist/gaia-ops/hooks/task_completed.py +70 -0
  163. package/dist/gaia-ops/hooks/user_prompt_submit.py +246 -0
  164. package/dist/gaia-ops/settings.json +72 -0
  165. package/dist/gaia-ops/skills/README.md +154 -0
  166. package/dist/gaia-ops/skills/agent-protocol/SKILL.md +93 -0
  167. package/dist/gaia-ops/skills/agent-protocol/examples.md +223 -0
  168. package/dist/gaia-ops/skills/agent-response/SKILL.md +69 -0
  169. package/dist/gaia-ops/skills/agentic-loop/SKILL.md +80 -0
  170. package/dist/gaia-ops/skills/agentic-loop/reference.md +378 -0
  171. package/dist/gaia-ops/skills/blog-writing/SKILL.md +98 -0
  172. package/dist/gaia-ops/skills/blog-writing/reference.md +130 -0
  173. package/dist/gaia-ops/skills/brief-spec/SKILL.md +182 -0
  174. package/dist/gaia-ops/skills/command-execution/SKILL.md +64 -0
  175. package/dist/gaia-ops/skills/command-execution/reference.md +83 -0
  176. package/dist/gaia-ops/skills/context-updater/SKILL.md +87 -0
  177. package/dist/gaia-ops/skills/context-updater/examples.md +71 -0
  178. package/dist/gaia-ops/skills/developer-patterns/SKILL.md +50 -0
  179. package/dist/gaia-ops/skills/developer-patterns/reference.md +112 -0
  180. package/dist/gaia-ops/skills/execution/SKILL.md +99 -0
  181. package/dist/gaia-ops/skills/fast-queries/SKILL.md +43 -0
  182. package/dist/gaia-ops/skills/gaia-compact/SKILL.md +74 -0
  183. package/dist/gaia-ops/skills/gaia-patterns/SKILL.md +108 -0
  184. package/dist/gaia-ops/skills/gaia-patterns/reference.md +395 -0
  185. package/dist/gaia-ops/skills/gaia-planner/SKILL.md +37 -0
  186. package/dist/gaia-ops/skills/gaia-planner/reference.md +107 -0
  187. package/dist/gaia-ops/skills/gaia-release/SKILL.md +82 -0
  188. package/dist/gaia-ops/skills/gaia-release/reference.md +102 -0
  189. package/dist/gaia-ops/skills/gaia-self-check/SKILL.md +114 -0
  190. package/dist/gaia-ops/skills/gaia-self-check/reference.md +453 -0
  191. package/dist/gaia-ops/skills/gaia-verify/SKILL.md +77 -0
  192. package/dist/gaia-ops/skills/gaia-verify/reference.md +80 -0
  193. package/dist/gaia-ops/skills/git-conventions/SKILL.md +47 -0
  194. package/dist/gaia-ops/skills/gitops-patterns/SKILL.md +60 -0
  195. package/dist/gaia-ops/skills/gitops-patterns/reference.md +183 -0
  196. package/dist/gaia-ops/skills/gmail-policy/SKILL.md +200 -0
  197. package/dist/gaia-ops/skills/gmail-policy/reference.md +150 -0
  198. package/dist/gaia-ops/skills/gmail-triage/SKILL.md +100 -0
  199. package/dist/gaia-ops/skills/gws-setup/SKILL.md +99 -0
  200. package/dist/gaia-ops/skills/gws-setup/reference.md +73 -0
  201. package/dist/gaia-ops/skills/investigation/SKILL.md +100 -0
  202. package/dist/gaia-ops/skills/memory-curation/SKILL.md +83 -0
  203. package/dist/gaia-ops/skills/memory-search/SKILL.md +88 -0
  204. package/dist/gaia-ops/skills/orchestrator-approval/SKILL.md +160 -0
  205. package/dist/gaia-ops/skills/orchestrator-approval/reference.md +174 -0
  206. package/dist/gaia-ops/skills/pending-approvals/SKILL.md +72 -0
  207. package/dist/gaia-ops/skills/pending-approvals/reference.md +214 -0
  208. package/dist/gaia-ops/skills/readme-writing/SKILL.md +71 -0
  209. package/dist/gaia-ops/skills/readme-writing/reference.md +188 -0
  210. package/dist/gaia-ops/skills/reference.md +135 -0
  211. package/dist/gaia-ops/skills/request-approval/SKILL.md +140 -0
  212. package/dist/gaia-ops/skills/request-approval/examples.md +140 -0
  213. package/dist/gaia-ops/skills/request-approval/reference.md +57 -0
  214. package/dist/gaia-ops/skills/schedule-task/SKILL.md +64 -0
  215. package/dist/gaia-ops/skills/schedule-task/reference.md +233 -0
  216. package/dist/gaia-ops/skills/security-tiers/SKILL.md +141 -0
  217. package/dist/gaia-ops/skills/security-tiers/destructive-commands-reference.md +623 -0
  218. package/dist/gaia-ops/skills/security-tiers/reference.md +39 -0
  219. package/dist/gaia-ops/skills/skill-creation/SKILL.md +92 -0
  220. package/dist/gaia-ops/skills/skill-creation/reference.md +29 -0
  221. package/dist/gaia-ops/skills/terraform-patterns/SKILL.md +89 -0
  222. package/dist/gaia-ops/skills/terraform-patterns/reference.md +93 -0
  223. package/dist/gaia-ops/tools/__init__.py +9 -0
  224. package/dist/gaia-ops/tools/agentic-loop/decide-status.py +210 -0
  225. package/dist/gaia-ops/tools/agentic-loop/parse-metric.py +106 -0
  226. package/dist/gaia-ops/tools/agentic-loop/record-iteration.py +221 -0
  227. package/dist/gaia-ops/tools/context/README.md +132 -0
  228. package/dist/gaia-ops/tools/context/__init__.py +42 -0
  229. package/dist/gaia-ops/tools/context/_paths.py +20 -0
  230. package/dist/gaia-ops/tools/context/context_provider.py +721 -0
  231. package/dist/gaia-ops/tools/context/context_section_reader.py +342 -0
  232. package/dist/gaia-ops/tools/context/deep_merge.py +159 -0
  233. package/dist/gaia-ops/tools/context/pending_updates.py +760 -0
  234. package/dist/gaia-ops/tools/context/surface_router.py +278 -0
  235. package/dist/gaia-ops/tools/fast-queries/README.md +65 -0
  236. package/dist/gaia-ops/tools/fast-queries/__init__.py +30 -0
  237. package/dist/gaia-ops/tools/fast-queries/appservices/quicktriage_devops_developer.sh +75 -0
  238. package/dist/gaia-ops/tools/fast-queries/cloud/aws/quicktriage_aws_troubleshooter.sh +32 -0
  239. package/dist/gaia-ops/tools/fast-queries/cloud/gcp/quicktriage_gcp_troubleshooter.sh +88 -0
  240. package/dist/gaia-ops/tools/fast-queries/gitops/quicktriage_gitops_operator.sh +48 -0
  241. package/dist/gaia-ops/tools/fast-queries/run_triage.sh +59 -0
  242. package/dist/gaia-ops/tools/fast-queries/terraform/quicktriage_terraform_architect.sh +80 -0
  243. package/dist/gaia-ops/tools/gaia_simulator/__init__.py +33 -0
  244. package/dist/gaia-ops/tools/gaia_simulator/cli.py +354 -0
  245. package/dist/gaia-ops/tools/gaia_simulator/extractor.py +457 -0
  246. package/dist/gaia-ops/tools/gaia_simulator/reporter.py +258 -0
  247. package/dist/gaia-ops/tools/gaia_simulator/routing_simulator.py +334 -0
  248. package/dist/gaia-ops/tools/gaia_simulator/runner.py +539 -0
  249. package/dist/gaia-ops/tools/gaia_simulator/skills_mapper.py +264 -0
  250. package/dist/gaia-ops/tools/memory/README.md +0 -0
  251. package/dist/gaia-ops/tools/memory/__init__.py +20 -0
  252. package/dist/gaia-ops/tools/memory/backfill_fts5.py +107 -0
  253. package/dist/gaia-ops/tools/memory/conflict_detector.py +295 -0
  254. package/dist/gaia-ops/tools/memory/episodic.py +1210 -0
  255. package/dist/gaia-ops/tools/memory/git_invalidator.py +262 -0
  256. package/dist/gaia-ops/tools/memory/paths.py +102 -0
  257. package/dist/gaia-ops/tools/memory/scoring.py +193 -0
  258. package/dist/gaia-ops/tools/memory/search_store.py +360 -0
  259. package/dist/gaia-ops/tools/persist_transcript_analysis.py +85 -0
  260. package/dist/gaia-ops/tools/review/__init__.py +1 -0
  261. package/dist/gaia-ops/tools/review/review_engine.py +157 -0
  262. package/dist/gaia-ops/tools/scan/__init__.py +35 -0
  263. package/dist/gaia-ops/tools/scan/config.py +247 -0
  264. package/dist/gaia-ops/tools/scan/merge.py +212 -0
  265. package/dist/gaia-ops/tools/scan/orchestrator.py +549 -0
  266. package/dist/gaia-ops/tools/scan/registry.py +127 -0
  267. package/dist/gaia-ops/tools/scan/scanners/__init__.py +18 -0
  268. package/dist/gaia-ops/tools/scan/scanners/base.py +137 -0
  269. package/dist/gaia-ops/tools/scan/scanners/environment.py +349 -0
  270. package/dist/gaia-ops/tools/scan/scanners/git.py +570 -0
  271. package/dist/gaia-ops/tools/scan/scanners/infrastructure.py +875 -0
  272. package/dist/gaia-ops/tools/scan/scanners/orchestration.py +600 -0
  273. package/dist/gaia-ops/tools/scan/scanners/stack.py +1085 -0
  274. package/dist/gaia-ops/tools/scan/scanners/tools.py +260 -0
  275. package/dist/gaia-ops/tools/scan/setup.py +686 -0
  276. package/dist/gaia-ops/tools/scan/tests/__init__.py +1 -0
  277. package/dist/gaia-ops/tools/scan/tests/conftest.py +796 -0
  278. package/dist/gaia-ops/tools/scan/tests/test_environment.py +323 -0
  279. package/dist/gaia-ops/tools/scan/tests/test_git.py +419 -0
  280. package/dist/gaia-ops/tools/scan/tests/test_infrastructure.py +382 -0
  281. package/dist/gaia-ops/tools/scan/tests/test_integration.py +920 -0
  282. package/dist/gaia-ops/tools/scan/tests/test_merge.py +269 -0
  283. package/dist/gaia-ops/tools/scan/tests/test_orchestration.py +304 -0
  284. package/dist/gaia-ops/tools/scan/tests/test_stack.py +604 -0
  285. package/dist/gaia-ops/tools/scan/tests/test_tools.py +349 -0
  286. package/dist/gaia-ops/tools/scan/ui.py +624 -0
  287. package/dist/gaia-ops/tools/scan/verify.py +270 -0
  288. package/dist/gaia-ops/tools/scan/walk.py +118 -0
  289. package/dist/gaia-ops/tools/scan/workspace.py +85 -0
  290. package/dist/gaia-ops/tools/validation/README.md +244 -0
  291. package/dist/gaia-ops/tools/validation/__init__.py +17 -0
  292. package/dist/gaia-ops/tools/validation/approval_gate.py +321 -0
  293. package/dist/gaia-ops/tools/validation/validate_skills.py +189 -0
  294. package/dist/gaia-security/.claude-plugin/plugin.json +24 -0
  295. package/dist/gaia-security/README.md +90 -0
  296. package/dist/gaia-security/config/universal-rules.json +102 -0
  297. package/dist/gaia-security/hooks/adapters/__init__.py +52 -0
  298. package/dist/gaia-security/hooks/adapters/base.py +219 -0
  299. package/dist/gaia-security/hooks/adapters/channel.py +17 -0
  300. package/dist/gaia-security/hooks/adapters/claude_code.py +1890 -0
  301. package/dist/gaia-security/hooks/adapters/types.py +194 -0
  302. package/dist/gaia-security/hooks/adapters/utils.py +25 -0
  303. package/dist/gaia-security/hooks/hooks.json +84 -0
  304. package/dist/gaia-security/hooks/modules/__init__.py +15 -0
  305. package/dist/gaia-security/hooks/modules/agents/__init__.py +29 -0
  306. package/dist/gaia-security/hooks/modules/agents/contract_validator.py +647 -0
  307. package/dist/gaia-security/hooks/modules/agents/response_contract.py +496 -0
  308. package/dist/gaia-security/hooks/modules/agents/skill_injection_verifier.py +120 -0
  309. package/dist/gaia-security/hooks/modules/agents/state_tracker.py +267 -0
  310. package/dist/gaia-security/hooks/modules/agents/task_info_builder.py +74 -0
  311. package/dist/gaia-security/hooks/modules/agents/transcript_analyzer.py +458 -0
  312. package/dist/gaia-security/hooks/modules/agents/transcript_reader.py +152 -0
  313. package/dist/gaia-security/hooks/modules/audit/__init__.py +28 -0
  314. package/dist/gaia-security/hooks/modules/audit/event_detector.py +168 -0
  315. package/dist/gaia-security/hooks/modules/audit/logger.py +131 -0
  316. package/dist/gaia-security/hooks/modules/audit/metrics.py +134 -0
  317. package/dist/gaia-security/hooks/modules/audit/workflow_auditor.py +611 -0
  318. package/dist/gaia-security/hooks/modules/audit/workflow_recorder.py +296 -0
  319. package/dist/gaia-security/hooks/modules/context/__init__.py +11 -0
  320. package/dist/gaia-security/hooks/modules/context/agentic_loop_detector.py +165 -0
  321. package/dist/gaia-security/hooks/modules/context/anchor_tracker.py +317 -0
  322. package/dist/gaia-security/hooks/modules/context/compact_context_builder.py +218 -0
  323. package/dist/gaia-security/hooks/modules/context/context_freshness.py +145 -0
  324. package/dist/gaia-security/hooks/modules/context/context_injector.py +558 -0
  325. package/dist/gaia-security/hooks/modules/context/context_writer.py +530 -0
  326. package/dist/gaia-security/hooks/modules/context/contracts_loader.py +161 -0
  327. package/dist/gaia-security/hooks/modules/core/__init__.py +40 -0
  328. package/dist/gaia-security/hooks/modules/core/hook_entry.py +78 -0
  329. package/dist/gaia-security/hooks/modules/core/paths.py +160 -0
  330. package/dist/gaia-security/hooks/modules/core/plugin_mode.py +149 -0
  331. package/dist/gaia-security/hooks/modules/core/plugin_setup.py +577 -0
  332. package/dist/gaia-security/hooks/modules/core/state.py +179 -0
  333. package/dist/gaia-security/hooks/modules/core/stdin.py +24 -0
  334. package/dist/gaia-security/hooks/modules/events/__init__.py +1 -0
  335. package/dist/gaia-security/hooks/modules/events/event_writer.py +210 -0
  336. package/dist/gaia-security/hooks/modules/memory/__init__.py +8 -0
  337. package/dist/gaia-security/hooks/modules/memory/episode_writer.py +216 -0
  338. package/dist/gaia-security/hooks/modules/orchestrator/__init__.py +1 -0
  339. package/dist/gaia-security/hooks/modules/orchestrator/delegate_mode.py +122 -0
  340. package/dist/gaia-security/hooks/modules/scanning/__init__.py +8 -0
  341. package/dist/gaia-security/hooks/modules/scanning/scan_trigger.py +84 -0
  342. package/dist/gaia-security/hooks/modules/security/__init__.py +120 -0
  343. package/dist/gaia-security/hooks/modules/security/approval_cleanup.py +87 -0
  344. package/dist/gaia-security/hooks/modules/security/approval_constants.py +23 -0
  345. package/dist/gaia-security/hooks/modules/security/approval_grants.py +1638 -0
  346. package/dist/gaia-security/hooks/modules/security/approval_messages.py +71 -0
  347. package/dist/gaia-security/hooks/modules/security/approval_scopes.py +222 -0
  348. package/dist/gaia-security/hooks/modules/security/blocked_commands.py +595 -0
  349. package/dist/gaia-security/hooks/modules/security/blocked_message_formatter.py +87 -0
  350. package/dist/gaia-security/hooks/modules/security/command_semantics.py +181 -0
  351. package/dist/gaia-security/hooks/modules/security/composition_rules.py +547 -0
  352. package/dist/gaia-security/hooks/modules/security/flag_classifiers.py +873 -0
  353. package/dist/gaia-security/hooks/modules/security/gitops_validator.py +179 -0
  354. package/dist/gaia-security/hooks/modules/security/mutative_verbs.py +1131 -0
  355. package/dist/gaia-security/hooks/modules/security/network_hosts.py +481 -0
  356. package/dist/gaia-security/hooks/modules/security/prompt_validator.py +40 -0
  357. package/dist/gaia-security/hooks/modules/security/shell_unwrapper.py +165 -0
  358. package/dist/gaia-security/hooks/modules/security/tiers.py +196 -0
  359. package/dist/gaia-security/hooks/modules/session/__init__.py +10 -0
  360. package/dist/gaia-security/hooks/modules/session/pending_scanner.py +174 -0
  361. package/dist/gaia-security/hooks/modules/session/session_context_writer.py +100 -0
  362. package/dist/gaia-security/hooks/modules/session/session_event_injector.py +160 -0
  363. package/dist/gaia-security/hooks/modules/session/session_manager.py +31 -0
  364. package/dist/gaia-security/hooks/modules/session/session_registry.py +232 -0
  365. package/dist/gaia-security/hooks/modules/tools/__init__.py +29 -0
  366. package/dist/gaia-security/hooks/modules/tools/bash_validator.py +1008 -0
  367. package/dist/gaia-security/hooks/modules/tools/cloud_pipe_validator.py +231 -0
  368. package/dist/gaia-security/hooks/modules/tools/hook_response.py +55 -0
  369. package/dist/gaia-security/hooks/modules/tools/shell_parser.py +227 -0
  370. package/dist/gaia-security/hooks/modules/tools/stage_decomposer.py +315 -0
  371. package/dist/gaia-security/hooks/modules/tools/task_validator.py +294 -0
  372. package/dist/gaia-security/hooks/modules/validation/__init__.py +23 -0
  373. package/dist/gaia-security/hooks/modules/validation/commit_validator.py +380 -0
  374. package/dist/gaia-security/hooks/post_tool_use.py +54 -0
  375. package/dist/gaia-security/hooks/pre_tool_use.py +413 -0
  376. package/dist/gaia-security/hooks/session_start.py +81 -0
  377. package/dist/gaia-security/hooks/stop_hook.py +82 -0
  378. package/dist/gaia-security/hooks/user_prompt_submit.py +246 -0
  379. package/dist/gaia-security/settings.json +58 -0
  380. package/git-hooks/commit-msg +41 -0
  381. package/hooks/README.md +100 -0
  382. package/hooks/adapters/__init__.py +52 -0
  383. package/hooks/adapters/base.py +219 -0
  384. package/hooks/adapters/channel.py +17 -0
  385. package/hooks/adapters/claude_code.py +1890 -0
  386. package/hooks/adapters/types.py +194 -0
  387. package/hooks/adapters/utils.py +25 -0
  388. package/hooks/elicitation_result.py +179 -0
  389. package/hooks/hooks.json +84 -0
  390. package/hooks/modules/README.md +189 -0
  391. package/hooks/modules/__init__.py +15 -0
  392. package/hooks/modules/agents/__init__.py +29 -0
  393. package/hooks/modules/agents/contract_validator.py +647 -0
  394. package/hooks/modules/agents/response_contract.py +496 -0
  395. package/hooks/modules/agents/skill_injection_verifier.py +120 -0
  396. package/hooks/modules/agents/state_tracker.py +267 -0
  397. package/hooks/modules/agents/task_info_builder.py +74 -0
  398. package/hooks/modules/agents/transcript_analyzer.py +458 -0
  399. package/hooks/modules/agents/transcript_reader.py +152 -0
  400. package/hooks/modules/audit/__init__.py +28 -0
  401. package/hooks/modules/audit/event_detector.py +168 -0
  402. package/hooks/modules/audit/logger.py +131 -0
  403. package/hooks/modules/audit/metrics.py +134 -0
  404. package/hooks/modules/audit/workflow_auditor.py +611 -0
  405. package/hooks/modules/audit/workflow_recorder.py +296 -0
  406. package/hooks/modules/context/__init__.py +11 -0
  407. package/hooks/modules/context/agentic_loop_detector.py +165 -0
  408. package/hooks/modules/context/anchor_tracker.py +317 -0
  409. package/hooks/modules/context/compact_context_builder.py +218 -0
  410. package/hooks/modules/context/context_freshness.py +145 -0
  411. package/hooks/modules/context/context_injector.py +558 -0
  412. package/hooks/modules/context/context_writer.py +530 -0
  413. package/hooks/modules/context/contracts_loader.py +161 -0
  414. package/hooks/modules/core/__init__.py +40 -0
  415. package/hooks/modules/core/hook_entry.py +78 -0
  416. package/hooks/modules/core/paths.py +160 -0
  417. package/hooks/modules/core/plugin_mode.py +149 -0
  418. package/hooks/modules/core/plugin_setup.py +577 -0
  419. package/hooks/modules/core/state.py +179 -0
  420. package/hooks/modules/core/stdin.py +24 -0
  421. package/hooks/modules/events/__init__.py +1 -0
  422. package/hooks/modules/events/event_writer.py +210 -0
  423. package/hooks/modules/evidence/__init__.py +34 -0
  424. package/hooks/modules/evidence/assertions.py +137 -0
  425. package/hooks/modules/evidence/index_writer.py +57 -0
  426. package/hooks/modules/evidence/loader.py +126 -0
  427. package/hooks/modules/evidence/runner.py +241 -0
  428. package/hooks/modules/memory/__init__.py +8 -0
  429. package/hooks/modules/memory/episode_writer.py +216 -0
  430. package/hooks/modules/orchestrator/__init__.py +1 -0
  431. package/hooks/modules/orchestrator/delegate_mode.py +122 -0
  432. package/hooks/modules/scanning/__init__.py +8 -0
  433. package/hooks/modules/scanning/scan_trigger.py +84 -0
  434. package/hooks/modules/security/__init__.py +120 -0
  435. package/hooks/modules/security/approval_cleanup.py +87 -0
  436. package/hooks/modules/security/approval_constants.py +23 -0
  437. package/hooks/modules/security/approval_grants.py +1638 -0
  438. package/hooks/modules/security/approval_messages.py +71 -0
  439. package/hooks/modules/security/approval_scopes.py +222 -0
  440. package/hooks/modules/security/blocked_commands.py +595 -0
  441. package/hooks/modules/security/blocked_message_formatter.py +87 -0
  442. package/hooks/modules/security/command_semantics.py +181 -0
  443. package/hooks/modules/security/composition_rules.py +547 -0
  444. package/hooks/modules/security/flag_classifiers.py +873 -0
  445. package/hooks/modules/security/gitops_validator.py +179 -0
  446. package/hooks/modules/security/mutative_verbs.py +1131 -0
  447. package/hooks/modules/security/network_hosts.py +481 -0
  448. package/hooks/modules/security/prompt_validator.py +40 -0
  449. package/hooks/modules/security/shell_unwrapper.py +165 -0
  450. package/hooks/modules/security/tiers.py +196 -0
  451. package/hooks/modules/session/__init__.py +10 -0
  452. package/hooks/modules/session/pending_scanner.py +174 -0
  453. package/hooks/modules/session/session_context_writer.py +100 -0
  454. package/hooks/modules/session/session_event_injector.py +160 -0
  455. package/hooks/modules/session/session_manager.py +31 -0
  456. package/hooks/modules/session/session_registry.py +232 -0
  457. package/hooks/modules/tools/__init__.py +29 -0
  458. package/hooks/modules/tools/bash_validator.py +1008 -0
  459. package/hooks/modules/tools/cloud_pipe_validator.py +231 -0
  460. package/hooks/modules/tools/hook_response.py +55 -0
  461. package/hooks/modules/tools/shell_parser.py +227 -0
  462. package/hooks/modules/tools/stage_decomposer.py +315 -0
  463. package/hooks/modules/tools/task_validator.py +294 -0
  464. package/hooks/modules/validation/__init__.py +23 -0
  465. package/hooks/modules/validation/commit_validator.py +380 -0
  466. package/hooks/post_compact.py +43 -0
  467. package/hooks/post_tool_use.py +54 -0
  468. package/hooks/pre_compact.py +60 -0
  469. package/hooks/pre_tool_use.py +413 -0
  470. package/hooks/session_start.py +81 -0
  471. package/hooks/stop_hook.py +82 -0
  472. package/hooks/subagent_start.py +71 -0
  473. package/hooks/subagent_stop.py +295 -0
  474. package/hooks/task_completed.py +70 -0
  475. package/hooks/user_prompt_submit.py +246 -0
  476. package/index.js +83 -0
  477. package/package.json +99 -0
  478. package/pyproject.toml +32 -0
  479. package/skills/README.md +154 -0
  480. package/skills/agent-protocol/SKILL.md +93 -0
  481. package/skills/agent-protocol/examples.md +223 -0
  482. package/skills/agent-response/SKILL.md +69 -0
  483. package/skills/agentic-loop/SKILL.md +80 -0
  484. package/skills/agentic-loop/reference.md +378 -0
  485. package/skills/blog-writing/SKILL.md +98 -0
  486. package/skills/blog-writing/reference.md +130 -0
  487. package/skills/brief-spec/SKILL.md +182 -0
  488. package/skills/command-execution/SKILL.md +64 -0
  489. package/skills/command-execution/reference.md +83 -0
  490. package/skills/context-updater/SKILL.md +87 -0
  491. package/skills/context-updater/examples.md +71 -0
  492. package/skills/developer-patterns/SKILL.md +50 -0
  493. package/skills/developer-patterns/reference.md +112 -0
  494. package/skills/execution/SKILL.md +99 -0
  495. package/skills/fast-queries/SKILL.md +43 -0
  496. package/skills/gaia-compact/SKILL.md +74 -0
  497. package/skills/gaia-patterns/SKILL.md +108 -0
  498. package/skills/gaia-patterns/reference.md +395 -0
  499. package/skills/gaia-planner/SKILL.md +37 -0
  500. package/skills/gaia-planner/reference.md +107 -0
  501. package/skills/gaia-release/SKILL.md +82 -0
  502. package/skills/gaia-release/reference.md +102 -0
  503. package/skills/gaia-self-check/SKILL.md +114 -0
  504. package/skills/gaia-self-check/reference.md +453 -0
  505. package/skills/gaia-verify/SKILL.md +77 -0
  506. package/skills/gaia-verify/reference.md +80 -0
  507. package/skills/git-conventions/SKILL.md +47 -0
  508. package/skills/gitops-patterns/SKILL.md +60 -0
  509. package/skills/gitops-patterns/reference.md +183 -0
  510. package/skills/gmail-policy/SKILL.md +200 -0
  511. package/skills/gmail-policy/reference.md +150 -0
  512. package/skills/gmail-triage/SKILL.md +100 -0
  513. package/skills/gws-setup/SKILL.md +99 -0
  514. package/skills/gws-setup/reference.md +73 -0
  515. package/skills/investigation/SKILL.md +100 -0
  516. package/skills/memory-curation/SKILL.md +83 -0
  517. package/skills/memory-search/SKILL.md +88 -0
  518. package/skills/orchestrator-approval/SKILL.md +160 -0
  519. package/skills/orchestrator-approval/reference.md +174 -0
  520. package/skills/pending-approvals/SKILL.md +72 -0
  521. package/skills/pending-approvals/reference.md +214 -0
  522. package/skills/readme-writing/SKILL.md +71 -0
  523. package/skills/readme-writing/reference.md +188 -0
  524. package/skills/reference.md +135 -0
  525. package/skills/request-approval/SKILL.md +140 -0
  526. package/skills/request-approval/examples.md +140 -0
  527. package/skills/request-approval/reference.md +57 -0
  528. package/skills/schedule-task/SKILL.md +64 -0
  529. package/skills/schedule-task/reference.md +233 -0
  530. package/skills/security-tiers/SKILL.md +141 -0
  531. package/skills/security-tiers/destructive-commands-reference.md +623 -0
  532. package/skills/security-tiers/reference.md +39 -0
  533. package/skills/skill-creation/SKILL.md +92 -0
  534. package/skills/skill-creation/reference.md +29 -0
  535. package/skills/terraform-patterns/SKILL.md +89 -0
  536. package/skills/terraform-patterns/reference.md +93 -0
  537. package/templates/README.md +69 -0
  538. package/templates/managed-settings.template.json +43 -0
  539. package/tools/__init__.py +9 -0
  540. package/tools/agentic-loop/decide-status.py +210 -0
  541. package/tools/agentic-loop/parse-metric.py +106 -0
  542. package/tools/agentic-loop/record-iteration.py +221 -0
  543. package/tools/context/README.md +132 -0
  544. package/tools/context/__init__.py +42 -0
  545. package/tools/context/_paths.py +20 -0
  546. package/tools/context/context_provider.py +721 -0
  547. package/tools/context/context_section_reader.py +342 -0
  548. package/tools/context/deep_merge.py +159 -0
  549. package/tools/context/pending_updates.py +760 -0
  550. package/tools/context/surface_router.py +278 -0
  551. package/tools/fast-queries/README.md +65 -0
  552. package/tools/fast-queries/__init__.py +30 -0
  553. package/tools/fast-queries/appservices/quicktriage_devops_developer.sh +75 -0
  554. package/tools/fast-queries/cloud/aws/quicktriage_aws_troubleshooter.sh +32 -0
  555. package/tools/fast-queries/cloud/gcp/quicktriage_gcp_troubleshooter.sh +88 -0
  556. package/tools/fast-queries/gitops/quicktriage_gitops_operator.sh +48 -0
  557. package/tools/fast-queries/run_triage.sh +59 -0
  558. package/tools/fast-queries/terraform/quicktriage_terraform_architect.sh +80 -0
  559. package/tools/gaia_simulator/__init__.py +33 -0
  560. package/tools/gaia_simulator/cli.py +354 -0
  561. package/tools/gaia_simulator/extractor.py +457 -0
  562. package/tools/gaia_simulator/reporter.py +258 -0
  563. package/tools/gaia_simulator/routing_simulator.py +334 -0
  564. package/tools/gaia_simulator/runner.py +539 -0
  565. package/tools/gaia_simulator/skills_mapper.py +264 -0
  566. package/tools/memory/README.md +0 -0
  567. package/tools/memory/__init__.py +20 -0
  568. package/tools/memory/backfill_fts5.py +107 -0
  569. package/tools/memory/conflict_detector.py +295 -0
  570. package/tools/memory/episodic.py +1210 -0
  571. package/tools/memory/git_invalidator.py +262 -0
  572. package/tools/memory/paths.py +102 -0
  573. package/tools/memory/scoring.py +193 -0
  574. package/tools/memory/search_store.py +360 -0
  575. package/tools/persist_transcript_analysis.py +85 -0
  576. package/tools/review/__init__.py +1 -0
  577. package/tools/review/review_engine.py +157 -0
  578. package/tools/scan/__init__.py +35 -0
  579. package/tools/scan/config.py +247 -0
  580. package/tools/scan/merge.py +212 -0
  581. package/tools/scan/orchestrator.py +549 -0
  582. package/tools/scan/registry.py +127 -0
  583. package/tools/scan/scanners/__init__.py +18 -0
  584. package/tools/scan/scanners/base.py +137 -0
  585. package/tools/scan/scanners/environment.py +349 -0
  586. package/tools/scan/scanners/git.py +570 -0
  587. package/tools/scan/scanners/infrastructure.py +875 -0
  588. package/tools/scan/scanners/orchestration.py +600 -0
  589. package/tools/scan/scanners/stack.py +1085 -0
  590. package/tools/scan/scanners/tools.py +260 -0
  591. package/tools/scan/setup.py +686 -0
  592. package/tools/scan/tests/__init__.py +1 -0
  593. package/tools/scan/tests/conftest.py +796 -0
  594. package/tools/scan/tests/test_environment.py +323 -0
  595. package/tools/scan/tests/test_git.py +419 -0
  596. package/tools/scan/tests/test_infrastructure.py +382 -0
  597. package/tools/scan/tests/test_integration.py +920 -0
  598. package/tools/scan/tests/test_merge.py +269 -0
  599. package/tools/scan/tests/test_orchestration.py +304 -0
  600. package/tools/scan/tests/test_stack.py +604 -0
  601. package/tools/scan/tests/test_tools.py +349 -0
  602. package/tools/scan/ui.py +624 -0
  603. package/tools/scan/verify.py +270 -0
  604. package/tools/scan/walk.py +118 -0
  605. package/tools/scan/workspace.py +85 -0
  606. package/tools/validation/README.md +244 -0
  607. package/tools/validation/__init__.py +17 -0
  608. package/tools/validation/approval_gate.py +321 -0
  609. package/tools/validation/validate_skills.py +189 -0
@@ -0,0 +1,194 @@
1
+ """
2
+ Adapter Normalized Types for Gaia-Ops Hooks.
3
+
4
+ CLI-agnostic frozen dataclasses and enums consumed by business logic modules.
5
+ The adapter layer translates between these types and CLI-specific JSON protocols.
6
+
7
+ No dependencies on any existing gaia-ops module -- this is standalone.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ import enum
13
+ from dataclasses import dataclass, field
14
+ from pathlib import Path
15
+ from typing import Any, Dict, List, Optional
16
+
17
+
18
+ class HookEventType(enum.Enum):
19
+ """All Claude Code hook events as an enumeration."""
20
+
21
+ # P0 - Currently implemented
22
+ PRE_TOOL_USE = "PreToolUse"
23
+ POST_TOOL_USE = "PostToolUse"
24
+ SUBAGENT_STOP = "SubagentStop"
25
+
26
+ # P1
27
+ SESSION_START = "SessionStart"
28
+ USER_PROMPT_SUBMIT = "UserPromptSubmit"
29
+
30
+ # P2
31
+ PERMISSION_REQUEST = "PermissionRequest"
32
+ STOP = "Stop"
33
+ TASK_COMPLETED = "TaskCompleted"
34
+ SUBAGENT_START = "SubagentStart"
35
+
36
+ # P3
37
+ PRE_COMPACT = "PreCompact"
38
+ POST_COMPACT = "PostCompact"
39
+ CONFIG_CHANGE = "ConfigChange"
40
+ SESSION_END = "SessionEnd"
41
+ INSTRUCTIONS_LOADED = "InstructionsLoaded"
42
+ POST_TOOL_USE_FAILURE = "PostToolUseFailure"
43
+
44
+ # P4
45
+ NOTIFICATION = "Notification"
46
+
47
+ # P5 - Additional events
48
+ TEAMMATE_IDLE = "TeammateIdle"
49
+ WORKTREE_CREATE = "WorktreeCreate"
50
+ WORKTREE_REMOVE = "WorktreeRemove"
51
+ PROMPT_SUBMIT = "PromptSubmit" # Deprecated alias for USER_PROMPT_SUBMIT
52
+
53
+
54
+ class PermissionDecision(enum.Enum):
55
+ """Hook permission decision values."""
56
+
57
+ ALLOW = "allow"
58
+ DENY = "deny"
59
+ ASK = "ask"
60
+
61
+
62
+ class DistributionChannel(enum.Enum):
63
+ """How gaia-ops was installed and is being invoked."""
64
+
65
+ NPM = "npm"
66
+ PLUGIN = "plugin"
67
+
68
+
69
+ @dataclass(frozen=True)
70
+ class HookEvent:
71
+ """Normalized hook event, CLI-agnostic.
72
+
73
+ Produced by the adapter's parse_event() method.
74
+ """
75
+
76
+ event_type: HookEventType
77
+ session_id: str
78
+ payload: Dict[str, Any]
79
+ channel: DistributionChannel
80
+ plugin_root: Optional[Path] = None
81
+
82
+
83
+ @dataclass(frozen=True)
84
+ class ValidationRequest:
85
+ """Pre-tool-use validation request extracted from a HookEvent."""
86
+
87
+ tool_name: str
88
+ command: str
89
+ tool_input: Dict[str, Any]
90
+ session_id: str
91
+
92
+
93
+ @dataclass(frozen=True)
94
+ class ValidationResult:
95
+ """CLI-agnostic validation result from business logic.
96
+
97
+ Business logic produces this; the adapter formats it for the CLI.
98
+ """
99
+
100
+ allowed: bool = True
101
+ reason: str = ""
102
+ tier: str = "T0"
103
+ modified_input: Optional[Dict[str, Any]] = None
104
+ suggestions: List[str] = field(default_factory=list)
105
+ nonce: Optional[str] = None
106
+
107
+
108
+ @dataclass(frozen=True)
109
+ class ToolResult:
110
+ """Post-tool-use result data extracted from a HookEvent."""
111
+
112
+ tool_name: str
113
+ command: str
114
+ output: str
115
+ exit_code: int
116
+ session_id: str
117
+
118
+
119
+ @dataclass(frozen=True)
120
+ class AgentCompletion:
121
+ """Subagent completion data extracted from a HookEvent."""
122
+
123
+ agent_type: str
124
+ agent_id: str
125
+ transcript_path: str
126
+ last_message: str
127
+ session_id: str
128
+
129
+
130
+ @dataclass(frozen=True)
131
+ class CompletionResult:
132
+ """Result of processing an agent completion event."""
133
+
134
+ contract_valid: bool = True
135
+ episode_id: Optional[str] = None
136
+ context_updated: bool = False
137
+ anomalies: List[Dict[str, Any]] = field(default_factory=list)
138
+ repair_needed: bool = False
139
+
140
+
141
+ @dataclass(frozen=True)
142
+ class ContextResult:
143
+ """Result of context injection processing."""
144
+
145
+ context_injected: bool = False
146
+ additional_context: Optional[str] = None
147
+ sections_provided: List[str] = field(default_factory=list)
148
+ # Reserved for future adapter use
149
+ prompt_text: str = ""
150
+
151
+
152
+ @dataclass(frozen=True)
153
+ class BootstrapResult:
154
+ """Result of project bootstrap/scanning."""
155
+
156
+ project_scanned: bool = False
157
+ context_path: Optional[Path] = None
158
+ tools_detected: List[str] = field(default_factory=list)
159
+ # P1 fields: SessionStart adapter populates these
160
+ should_scan: bool = False
161
+ should_refresh: bool = False
162
+ session_type: str = "startup"
163
+
164
+
165
+ @dataclass(frozen=True)
166
+ class QualityResult:
167
+ """Result of a Stop event -- whether evidence quality meets threshold."""
168
+
169
+ quality_sufficient: bool = True
170
+ score: float = 1.0
171
+ missing_elements: List[str] = field(default_factory=list)
172
+ recommendation: str = "continue"
173
+
174
+
175
+ @dataclass(frozen=True)
176
+ class VerificationResult:
177
+ """Result of a TaskCompleted event -- whether completion criteria are met."""
178
+
179
+ criteria_met: bool = True
180
+ verified_items: List[str] = field(default_factory=list)
181
+ failed_items: List[str] = field(default_factory=list)
182
+ block_completion: bool = False
183
+
184
+
185
+ @dataclass(frozen=True)
186
+ class HookResponse:
187
+ """CLI-specific hook response. Constructed by adapter, not business logic."""
188
+
189
+ output: Dict[str, Any]
190
+ exit_code: int = 0
191
+
192
+ def to_dict(self) -> Dict[str, Any]:
193
+ """Serialize to a dictionary suitable for JSON output."""
194
+ return {"output": self.output, "exit_code": self.exit_code}
@@ -0,0 +1,25 @@
1
+ """
2
+ Shared utility functions for Gaia-Ops hooks.
3
+
4
+ Centralizes common patterns that were previously copy-pasted across all hook
5
+ entry points (has_stdin_data, dual-channel warnings, etc.).
6
+
7
+ ``has_stdin_data`` is now defined in ``modules.core.stdin`` and re-exported
8
+ here for backward compatibility with existing imports.
9
+ """
10
+
11
+ import logging
12
+
13
+ from modules.core.stdin import has_stdin_data # noqa: F401 -- re-export
14
+
15
+ logger = logging.getLogger(__name__)
16
+
17
+
18
+ def warn_if_dual_channel() -> None:
19
+ """Log a warning if both plugin and npm distribution channels are active."""
20
+ from adapters.channel import is_dual_channel_active
21
+
22
+ if is_dual_channel_active():
23
+ logger.warning(
24
+ "Both plugin and npm channels detected. Plugin channel takes precedence."
25
+ )
@@ -0,0 +1,179 @@
1
+ #!/usr/bin/env python3
2
+ """ElicitationResult hook -- activates T3 approval grants when user approves via AskUserQuestion.
3
+
4
+ This hook fires after the user responds to an AskUserQuestion elicitation.
5
+ It checks if the response indicates approval and, if so, activates all
6
+ pending approval grants for the current session.
7
+
8
+ The hook NEVER blocks (always exits 0). It is purely side-effectful:
9
+ reading the user's answer and activating grants when appropriate.
10
+ """
11
+ from __future__ import annotations
12
+
13
+ import sys
14
+ import json
15
+ import logging
16
+ import os
17
+ from datetime import datetime
18
+ from pathlib import Path
19
+
20
+ sys.path.insert(0, str(Path(__file__).parent))
21
+
22
+ from modules.core.paths import get_logs_dir
23
+ from modules.core.stdin import has_stdin_data
24
+
25
+ # Configure logging -- file only, no stderr
26
+ _log_file = get_logs_dir() / f"hooks-{datetime.now().strftime('%Y-%m-%d')}.log"
27
+ logging.basicConfig(
28
+ level=logging.INFO,
29
+ format='%(asctime)s [elicitation_result] %(name)s - %(levelname)s - %(message)s',
30
+ handlers=[logging.FileHandler(_log_file)],
31
+ )
32
+ logger = logging.getLogger(__name__)
33
+
34
+
35
+ def _extract_response(event: dict) -> str | None:
36
+ """Extract the user's answer from the ElicitationResult event.
37
+
38
+ The exact schema is not fully documented, so we probe multiple
39
+ possible field names defensively.
40
+ """
41
+ # Try top-level fields first
42
+ for field in ("result", "answer", "response", "selected", "value",
43
+ "hookEventInput", "elicitation_result"):
44
+ val = event.get(field)
45
+ if val is None:
46
+ continue
47
+ if isinstance(val, str) and val.strip():
48
+ return val
49
+ if isinstance(val, dict):
50
+ # Nested -- look for answer/selected inside
51
+ for inner in ("answer", "selected", "value", "result", "label"):
52
+ inner_val = val.get(inner)
53
+ if inner_val and isinstance(inner_val, str):
54
+ return inner_val
55
+ # Check for answers dict (AskUserQuestion structured format)
56
+ answers = val.get("answers", {})
57
+ if answers and isinstance(answers, dict):
58
+ first_val = next(iter(answers.values()), None)
59
+ if first_val:
60
+ return str(first_val)
61
+ # Check for options list selection
62
+ options = val.get("options", [])
63
+ if options and isinstance(options, list):
64
+ for opt in options:
65
+ if isinstance(opt, dict) and opt.get("selected"):
66
+ return str(opt.get("label", opt.get("value", "")))
67
+ return None
68
+
69
+
70
+ def _is_approval(response: str) -> bool:
71
+ """Check if the response indicates approval."""
72
+ normalized = response.lower().strip()
73
+ approval_words = ["approve", "approved", "yes", "accept", "confirm", "allow"]
74
+ return any(word in normalized for word in approval_words)
75
+
76
+
77
+ def _activate_grants(session_id: str, response: str = "") -> None:
78
+ """Activate approval grants for this session.
79
+
80
+ When *response* contains a ``[P-<nonce>]`` tag (nonce-labeled approval),
81
+ only the specific grant identified by that nonce is activated. When no
82
+ nonce is present (legacy approvals that predate nonce labeling) the
83
+ function falls back to session-wide activation for backward compatibility.
84
+ """
85
+ from modules.security.approval_grants import (
86
+ activate_grants_for_session,
87
+ activate_pending_approval,
88
+ activate_cross_session_pending,
89
+ extract_nonce_from_label,
90
+ load_pending_by_nonce_prefix,
91
+ get_pending_approvals_for_session,
92
+ )
93
+
94
+ # Try nonce-targeted activation first
95
+ nonce_prefix = extract_nonce_from_label(response) if response else None
96
+ if nonce_prefix:
97
+ logger.info(
98
+ "ElicitationResult: nonce prefix found in response: %s", nonce_prefix,
99
+ )
100
+ pending_data = load_pending_by_nonce_prefix(nonce_prefix)
101
+ if pending_data:
102
+ full_nonce = pending_data.get("nonce", "")
103
+ pending_session = pending_data.get("session_id", "")
104
+ if pending_session == session_id:
105
+ # Same session -- standard targeted activation
106
+ result = activate_pending_approval(
107
+ nonce=full_nonce, session_id=session_id,
108
+ )
109
+ else:
110
+ # Cross-session pending -- approval came from a prior session
111
+ result = activate_cross_session_pending(
112
+ pending_data, session_id=session_id,
113
+ )
114
+ logger.info(
115
+ "ElicitationResult nonce-targeted activation: "
116
+ "nonce=%s success=%s status=%s",
117
+ full_nonce[:12] if full_nonce else nonce_prefix,
118
+ result.success,
119
+ result.status,
120
+ )
121
+ return
122
+ else:
123
+ logger.warning(
124
+ "ElicitationResult: nonce prefix %s not found in pending files, "
125
+ "falling back to session-wide activation",
126
+ nonce_prefix,
127
+ )
128
+
129
+ # Fallback: session-wide activation (backward compat for unlabeled approvals)
130
+ pending = get_pending_approvals_for_session(session_id)
131
+ if not pending:
132
+ logger.info("No pending approvals to activate for session %s", session_id)
133
+ return
134
+
135
+ results = activate_grants_for_session(session_id)
136
+ activated = sum(1 for r in results if r.success)
137
+ logger.info(
138
+ "ElicitationResult activated %d/%d pending approvals for session %s",
139
+ activated, len(results), session_id,
140
+ )
141
+
142
+
143
+ if __name__ == "__main__":
144
+ if not has_stdin_data():
145
+ sys.exit(0)
146
+
147
+ try:
148
+ raw = sys.stdin.read()
149
+ if not raw.strip():
150
+ sys.exit(0)
151
+
152
+ event = json.loads(raw)
153
+
154
+ # Extract session_id from event or environment
155
+ session_id = event.get("session_id") or os.environ.get("CLAUDE_SESSION_ID", "")
156
+
157
+ # Extract user's response
158
+ response = _extract_response(event)
159
+
160
+ if not response:
161
+ logger.info("No extractable response in ElicitationResult event")
162
+ sys.exit(0)
163
+
164
+ logger.info("ElicitationResult response: %s", response[:80])
165
+
166
+ # Check if the response indicates approval
167
+ if _is_approval(response):
168
+ if session_id:
169
+ _activate_grants(session_id, response=response)
170
+ else:
171
+ logger.warning("Approval detected but no session_id available")
172
+ else:
173
+ logger.info("ElicitationResult response is not an approval: %s", response[:40])
174
+
175
+ except Exception as e:
176
+ logger.error("Error in elicitation_result hook: %s", e, exc_info=True)
177
+
178
+ # Never block -- always exit 0
179
+ sys.exit(0)
@@ -0,0 +1,84 @@
1
+ {
2
+ "hooks": {
3
+ "PreToolUse": [
4
+ {
5
+ "matcher": "Bash",
6
+ "hooks": [{"type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/pre_tool_use.py"}]
7
+ },
8
+ {
9
+ "matcher": "Task",
10
+ "hooks": [{"type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/pre_tool_use.py"}]
11
+ },
12
+ {
13
+ "matcher": "Agent",
14
+ "hooks": [{"type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/pre_tool_use.py"}]
15
+ },
16
+ {
17
+ "matcher": "SendMessage",
18
+ "hooks": [{"type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/pre_tool_use.py"}]
19
+ },
20
+ {
21
+ "matcher": "Read|Edit|Write|Glob|Grep|WebSearch|WebFetch|NotebookEdit",
22
+ "hooks": [{"type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/pre_tool_use.py"}]
23
+ }
24
+ ],
25
+ "PostToolUse": [
26
+ {
27
+ "matcher": "Bash",
28
+ "hooks": [{"type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/post_tool_use.py"}]
29
+ },
30
+ {
31
+ "matcher": "AskUserQuestion",
32
+ "hooks": [{"type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/post_tool_use.py"}]
33
+ }
34
+ ],
35
+ "SubagentStop": [
36
+ {
37
+ "matcher": "*",
38
+ "hooks": [{"type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/subagent_stop.py"}]
39
+ }
40
+ ],
41
+ "SessionStart": [
42
+ {
43
+ "matcher": "startup",
44
+ "hooks": [{"type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/session_start.py"}]
45
+ }
46
+ ],
47
+ "Stop": [
48
+ {
49
+ "hooks": [{"type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/stop_hook.py"}]
50
+ }
51
+ ],
52
+ "TaskCompleted": [
53
+ {
54
+ "hooks": [{"type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/task_completed.py"}]
55
+ }
56
+ ],
57
+ "SubagentStart": [
58
+ {
59
+ "matcher": "*",
60
+ "hooks": [{"type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/subagent_start.py"}]
61
+ }
62
+ ],
63
+ "UserPromptSubmit": [
64
+ {
65
+ "hooks": [{"type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/user_prompt_submit.py"}]
66
+ }
67
+ ],
68
+ "PreCompact": [
69
+ {
70
+ "hooks": [{"type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/pre_compact.py"}]
71
+ }
72
+ ],
73
+ "PostCompact": [
74
+ {
75
+ "hooks": [{"type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/post_compact.py"}]
76
+ }
77
+ ],
78
+ "ElicitationResult": [
79
+ {
80
+ "hooks": [{"type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/elicitation_result.py"}]
81
+ }
82
+ ]
83
+ }
84
+ }
@@ -0,0 +1,189 @@
1
+ # Hooks Modular Architecture
2
+
3
+ This directory contains the modular hook system for gaia-ops.
4
+
5
+ ## What is this?
6
+
7
+ A refactored, maintainable architecture for Claude Code hooks. Instead of monolithic 1000+ line files, the logic is split into focused modules that can be tested, maintained, and extended independently.
8
+
9
+ ## Where does this fit?
10
+
11
+ ```
12
+ Claude Code invokes hook
13
+ |
14
+ v
15
+ [session_start.py] --------> [modules/context/context_freshness] -> Staleness check
16
+ | [modules/scanning/scan_trigger] -> Auto-refresh
17
+ v
18
+ [pre_tool_use.py] ---------> [modules/security/*] -> Tier classification
19
+ | [modules/tools/*] -> Bash/Task validation
20
+ v
21
+ Tool executes
22
+ |
23
+ v
24
+ [post_tool_use.py] --------> [modules/audit/*] -> Logging & metrics
25
+ [modules/session/*] -> Session context updates
26
+ [modules/agents/*] -> Anomaly detection
27
+ ```
28
+
29
+ ## Module Structure
30
+
31
+ ```
32
+ modules/
33
+ ├── __init__.py # Package marker
34
+ ├── core/ # Shared utilities
35
+ │ ├── __init__.py
36
+ │ ├── paths.py # find_claude_dir() - single source of truth
37
+ │ └── state.py # Pre/post hook state sharing
38
+
39
+ ├── security/ # Security classification & approval
40
+ │ ├── __init__.py
41
+ │ ├── tiers.py # SecurityTier enum (T0-T3)
42
+ │ ├── blocked_commands.py # Blocked patterns by category
43
+ │ ├── mutative_verbs.py # CLI-agnostic verb detector, nonce-based deny
44
+ │ ├── approval_grants.py # Nonce-based approval grant management
45
+ │ ├── approval_constants.py # Approval system constants
46
+ │ ├── approval_messages.py # Approval denial message formatting
47
+ │ ├── approval_scopes.py # Approval scope definitions
48
+ │ ├── command_semantics.py # Command semantic analysis
49
+ │ └── gitops_validator.py # kubectl/helm/flux validation
50
+
51
+ ├── tools/ # Tool-specific validators
52
+ │ ├── __init__.py
53
+ │ ├── shell_parser.py # Parse compound commands
54
+ │ ├── bash_validator.py # Bash command validation (orchestrates pipeline)
55
+ │ ├── task_validator.py # Task tool validation with context enforcement
56
+ │ ├── cloud_pipe_validator.py # Cloud pipe/redirect/chain check
57
+ │ └── hook_response.py # Standardized hook response formatting
58
+
59
+ ├── context/ # Context management
60
+ │ ├── __init__.py
61
+ │ ├── context_writer.py # Write context updates
62
+ │ └── context_freshness.py # Check staleness for SessionStart
63
+
64
+ ├── scanning/ # Scan triggering
65
+ │ ├── __init__.py
66
+ │ └── scan_trigger.py # Lightweight scan invocation for SessionStart
67
+
68
+ ├── session/ # Session context management
69
+ │ ├── __init__.py
70
+ │ └── session_context_writer.py # Write critical events to session context
71
+
72
+ ├── validation/ # Commit validation
73
+ │ ├── __init__.py
74
+ │ └── commit_validator.py # Conventional Commits enforcement
75
+
76
+ ├── audit/ # Logging and metrics
77
+ │ ├── __init__.py
78
+ │ ├── logger.py # AuditLogger
79
+ │ ├── metrics.py # MetricsCollector + FUNCTIONAL generate_summary
80
+ │ └── event_detector.py # CriticalEventDetector
81
+
82
+ ├── identity/ # Orchestrator identity injection
83
+ │ ├── __init__.py
84
+ │ ├── identity_provider.py # Build identity based on installed plugins
85
+ │ ├── ops_identity.py # Ops mode: minimal identity + on-demand skills
86
+ │ └── security_identity.py # Security-only mode identity
87
+
88
+ └── agents/ # Subagent support
89
+ ├── __init__.py
90
+ └── response_contract.py # Agent response contract validation
91
+ ```
92
+
93
+ ## Key Features
94
+
95
+ ### Orchestrator Gate
96
+ The orchestrator is restricted to four tools:
97
+ - `Agent` -- dispatch work to specialist agents
98
+ - `SendMessage` -- resume a previously spawned agent
99
+ - `AskUserQuestion` -- get clarification or approval from the user
100
+ - `Skill` -- load on-demand procedures
101
+
102
+ This enforces the principle: "Orchestrator delegates, agents execute."
103
+
104
+ ### SendMessage Validation (PreToolUse matcher)
105
+ SendMessage is validated as a PreToolUse event (not a separate hook event):
106
+ - Agent ID format check (must match `/^a[0-9a-f]{5,}$/`)
107
+ - Non-empty message required
108
+ - Grant activation is handled by ElicitationResult hook (user approval via AskUserQuestion)
109
+
110
+ ### Context Enforcement
111
+ Task invocations for project agents inject project-context via `context_provider.py`.
112
+
113
+ ### State Sharing
114
+ Pre-hook saves state to `.claude/.hooks_state.json`, which post-hook reads to get:
115
+ - Security tier assigned
116
+ - Command executed
117
+ - Timestamp for duration calculation
118
+
119
+ ### Functional Metrics
120
+ `generate_summary()` now actually works - reads JSONL metrics files and aggregates:
121
+ - Total executions
122
+ - Success rate
123
+ - Average duration
124
+ - Top command types
125
+ - Tier distribution
126
+
127
+ ## Usage
128
+
129
+ ### Entry Points
130
+
131
+ ```bash
132
+ # Pre-hook (validation)
133
+ python3 pre_tool_use.py --test
134
+
135
+ # Post-hook (audit)
136
+ python3 post_tool_use.py --test
137
+
138
+ # Metrics (use the JS CLI instead)
139
+ npx gaia-metrics
140
+ ```
141
+
142
+ ### Importing Modules
143
+
144
+ ```python
145
+ from modules.security import SecurityTier, classify_command_tier, is_blocked_command
146
+ from modules.security import CATEGORY_MUTATIVE, CATEGORY_READ_ONLY
147
+ from modules.tools import BashValidator
148
+ from modules.audit import generate_summary
149
+
150
+ # Check if command is permanently blocked
151
+ result = is_blocked_command("kubectl delete namespace production")
152
+ print(f"Blocked: {result.blocked}, Reason: {result.reason}")
153
+
154
+ # Classify command tier
155
+ tier = classify_command_tier("kubectl get pods")
156
+ print(f"Tier: {tier}") # SecurityTier.T0
157
+
158
+ # Validate Bash command (full pipeline: blocked -> mutative verbs -> safe by elimination)
159
+ validator = BashValidator()
160
+ result = validator.validate("kubectl get pods")
161
+ print(f"Allowed: {result.allowed}, Tier: {result.tier}")
162
+
163
+ # Get metrics summary
164
+ summary = generate_summary(days=7)
165
+ print(f"Success rate: {summary['success_rate']:.1%}")
166
+ ```
167
+
168
+ ## Architecture Notes
169
+
170
+ The modular architecture maintains full backward compatibility with Claude Code's hook interface (stdin JSON format).
171
+
172
+ All security rules (blocked patterns, mutative verbs, tiers) are hardcoded in the Python modules for performance and simplicity - no external JSON config files needed.
173
+
174
+ ### Validation Order (Defense-in-Depth)
175
+ bash_validator checks commands in this order (short-circuit on first match):
176
+ 0. **Indirect execution detection** — `bash -c`, `eval`, `python -c` etc. → ask or block
177
+ 1. **Blocked commands** (blocked_commands.py) — permanently denied patterns, exit 2
178
+ 2. **Claude footer stripping** — transparent via updatedInput
179
+ 3. **Commit message validation** — conventional commits enforcement
180
+ 4. **Cloud pipe/redirect/chain check** (cloud_pipe_validator.py) — corrective deny
181
+ 5. **Mutative verbs** (mutative_verbs.py) — CLI-agnostic verb detector, native `ask` dialog
182
+ 6. **GitOps validation** (gitops_validator.py) — kubectl/helm/flux policy enforcement
183
+ 7. **Everything else** — SAFE by elimination (auto-approved)
184
+
185
+ ### Tier Classification
186
+ - **T0**: Read-only (get, list, describe, show)
187
+ - **T1**: Local validation (validate, lint, fmt, check)
188
+ - **T2**: Simulation (plan, template, diff, --dry-run)
189
+ - **T3**: State-modifying (apply, delete, push, commit)
@@ -0,0 +1,15 @@
1
+ """
2
+ Gaia-Ops Hooks Modular Architecture
3
+
4
+ This package provides a modular, maintainable hook system for Claude Code.
5
+
6
+ Modules:
7
+ - core: Shared utilities (paths, state, config loading)
8
+ - security: Security tiers, safe commands, blocked patterns
9
+ - tools: Tool-specific validators (Bash, Task)
10
+ - workflow: Phase validation and state tracking
11
+ - audit: Logging, metrics, event detection
12
+ - agents: Subagent metrics and anomaly detection
13
+ """
14
+
15
+ __version__ = "2.0.0"