@jaguilar87/gaia 5.0.0-rc.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 (621) 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 +1298 -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 +111 -0
  16. package/agents/gaia-planner.md +53 -0
  17. package/agents/gaia-system.md +71 -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 +651 -0
  26. package/bin/cli/history.py +305 -0
  27. package/bin/cli/memory.py +483 -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 +919 -0
  45. package/bin/pre-publish-validate.js +610 -0
  46. package/bin/python-detect.js +60 -0
  47. package/bin/validate-sandbox.sh +601 -0
  48. package/commands/README.md +64 -0
  49. package/commands/gaia.md +37 -0
  50. package/commands/scan-project.md +67 -0
  51. package/config/README.md +71 -0
  52. package/config/cloud/aws.json +134 -0
  53. package/config/cloud/gcp.json +139 -0
  54. package/config/context-contracts.json +158 -0
  55. package/config/crons-schema.md +81 -0
  56. package/config/git_standards.json +72 -0
  57. package/config/surface-routing.json +417 -0
  58. package/config/universal-rules.json +102 -0
  59. package/dist/gaia-ops/.claude-plugin/plugin.json +24 -0
  60. package/dist/gaia-ops/README.md +80 -0
  61. package/dist/gaia-ops/agents/cloud-troubleshooter.md +73 -0
  62. package/dist/gaia-ops/agents/developer.md +65 -0
  63. package/dist/gaia-ops/agents/gaia-operator.md +64 -0
  64. package/dist/gaia-ops/agents/gaia-orchestrator.md +111 -0
  65. package/dist/gaia-ops/agents/gaia-planner.md +53 -0
  66. package/dist/gaia-ops/agents/gaia-system.md +71 -0
  67. package/dist/gaia-ops/agents/gitops-operator.md +61 -0
  68. package/dist/gaia-ops/agents/terraform-architect.md +63 -0
  69. package/dist/gaia-ops/commands/gaia.md +37 -0
  70. package/dist/gaia-ops/config/README.md +71 -0
  71. package/dist/gaia-ops/config/cloud/aws.json +134 -0
  72. package/dist/gaia-ops/config/cloud/gcp.json +139 -0
  73. package/dist/gaia-ops/config/context-contracts.json +158 -0
  74. package/dist/gaia-ops/config/crons-schema.md +81 -0
  75. package/dist/gaia-ops/config/git_standards.json +72 -0
  76. package/dist/gaia-ops/config/surface-routing.json +417 -0
  77. package/dist/gaia-ops/config/universal-rules.json +102 -0
  78. package/dist/gaia-ops/hooks/adapters/__init__.py +52 -0
  79. package/dist/gaia-ops/hooks/adapters/base.py +219 -0
  80. package/dist/gaia-ops/hooks/adapters/channel.py +17 -0
  81. package/dist/gaia-ops/hooks/adapters/claude_code.py +1890 -0
  82. package/dist/gaia-ops/hooks/adapters/types.py +194 -0
  83. package/dist/gaia-ops/hooks/adapters/utils.py +25 -0
  84. package/dist/gaia-ops/hooks/hooks.json +192 -0
  85. package/dist/gaia-ops/hooks/modules/__init__.py +15 -0
  86. package/dist/gaia-ops/hooks/modules/agents/__init__.py +29 -0
  87. package/dist/gaia-ops/hooks/modules/agents/contract_validator.py +647 -0
  88. package/dist/gaia-ops/hooks/modules/agents/response_contract.py +496 -0
  89. package/dist/gaia-ops/hooks/modules/agents/skill_injection_verifier.py +120 -0
  90. package/dist/gaia-ops/hooks/modules/agents/state_tracker.py +267 -0
  91. package/dist/gaia-ops/hooks/modules/agents/task_info_builder.py +74 -0
  92. package/dist/gaia-ops/hooks/modules/agents/transcript_analyzer.py +458 -0
  93. package/dist/gaia-ops/hooks/modules/agents/transcript_reader.py +152 -0
  94. package/dist/gaia-ops/hooks/modules/audit/__init__.py +28 -0
  95. package/dist/gaia-ops/hooks/modules/audit/event_detector.py +168 -0
  96. package/dist/gaia-ops/hooks/modules/audit/logger.py +131 -0
  97. package/dist/gaia-ops/hooks/modules/audit/metrics.py +134 -0
  98. package/dist/gaia-ops/hooks/modules/audit/workflow_auditor.py +611 -0
  99. package/dist/gaia-ops/hooks/modules/audit/workflow_recorder.py +296 -0
  100. package/dist/gaia-ops/hooks/modules/context/__init__.py +11 -0
  101. package/dist/gaia-ops/hooks/modules/context/agentic_loop_detector.py +165 -0
  102. package/dist/gaia-ops/hooks/modules/context/anchor_tracker.py +317 -0
  103. package/dist/gaia-ops/hooks/modules/context/compact_context_builder.py +218 -0
  104. package/dist/gaia-ops/hooks/modules/context/context_freshness.py +145 -0
  105. package/dist/gaia-ops/hooks/modules/context/context_injector.py +558 -0
  106. package/dist/gaia-ops/hooks/modules/context/context_writer.py +530 -0
  107. package/dist/gaia-ops/hooks/modules/context/contracts_loader.py +161 -0
  108. package/dist/gaia-ops/hooks/modules/core/__init__.py +40 -0
  109. package/dist/gaia-ops/hooks/modules/core/hook_entry.py +78 -0
  110. package/dist/gaia-ops/hooks/modules/core/paths.py +160 -0
  111. package/dist/gaia-ops/hooks/modules/core/plugin_mode.py +149 -0
  112. package/dist/gaia-ops/hooks/modules/core/plugin_setup.py +577 -0
  113. package/dist/gaia-ops/hooks/modules/core/state.py +179 -0
  114. package/dist/gaia-ops/hooks/modules/core/stdin.py +24 -0
  115. package/dist/gaia-ops/hooks/modules/events/__init__.py +1 -0
  116. package/dist/gaia-ops/hooks/modules/events/event_writer.py +210 -0
  117. package/dist/gaia-ops/hooks/modules/memory/__init__.py +8 -0
  118. package/dist/gaia-ops/hooks/modules/memory/episode_writer.py +216 -0
  119. package/dist/gaia-ops/hooks/modules/orchestrator/__init__.py +1 -0
  120. package/dist/gaia-ops/hooks/modules/orchestrator/delegate_mode.py +122 -0
  121. package/dist/gaia-ops/hooks/modules/scanning/__init__.py +8 -0
  122. package/dist/gaia-ops/hooks/modules/scanning/scan_trigger.py +84 -0
  123. package/dist/gaia-ops/hooks/modules/security/__init__.py +120 -0
  124. package/dist/gaia-ops/hooks/modules/security/approval_cleanup.py +87 -0
  125. package/dist/gaia-ops/hooks/modules/security/approval_constants.py +23 -0
  126. package/dist/gaia-ops/hooks/modules/security/approval_grants.py +1638 -0
  127. package/dist/gaia-ops/hooks/modules/security/approval_messages.py +71 -0
  128. package/dist/gaia-ops/hooks/modules/security/approval_scopes.py +222 -0
  129. package/dist/gaia-ops/hooks/modules/security/blocked_commands.py +595 -0
  130. package/dist/gaia-ops/hooks/modules/security/blocked_message_formatter.py +87 -0
  131. package/dist/gaia-ops/hooks/modules/security/command_semantics.py +181 -0
  132. package/dist/gaia-ops/hooks/modules/security/composition_rules.py +547 -0
  133. package/dist/gaia-ops/hooks/modules/security/flag_classifiers.py +873 -0
  134. package/dist/gaia-ops/hooks/modules/security/gitops_validator.py +179 -0
  135. package/dist/gaia-ops/hooks/modules/security/mutative_verbs.py +1131 -0
  136. package/dist/gaia-ops/hooks/modules/security/network_hosts.py +481 -0
  137. package/dist/gaia-ops/hooks/modules/security/prompt_validator.py +40 -0
  138. package/dist/gaia-ops/hooks/modules/security/shell_unwrapper.py +165 -0
  139. package/dist/gaia-ops/hooks/modules/security/tiers.py +196 -0
  140. package/dist/gaia-ops/hooks/modules/session/__init__.py +10 -0
  141. package/dist/gaia-ops/hooks/modules/session/pending_scanner.py +174 -0
  142. package/dist/gaia-ops/hooks/modules/session/session_context_writer.py +100 -0
  143. package/dist/gaia-ops/hooks/modules/session/session_event_injector.py +160 -0
  144. package/dist/gaia-ops/hooks/modules/session/session_manager.py +31 -0
  145. package/dist/gaia-ops/hooks/modules/session/session_registry.py +333 -0
  146. package/dist/gaia-ops/hooks/modules/tools/__init__.py +29 -0
  147. package/dist/gaia-ops/hooks/modules/tools/bash_validator.py +1008 -0
  148. package/dist/gaia-ops/hooks/modules/tools/cloud_pipe_validator.py +231 -0
  149. package/dist/gaia-ops/hooks/modules/tools/hook_response.py +55 -0
  150. package/dist/gaia-ops/hooks/modules/tools/shell_parser.py +227 -0
  151. package/dist/gaia-ops/hooks/modules/tools/stage_decomposer.py +315 -0
  152. package/dist/gaia-ops/hooks/modules/tools/task_validator.py +294 -0
  153. package/dist/gaia-ops/hooks/modules/validation/__init__.py +23 -0
  154. package/dist/gaia-ops/hooks/modules/validation/commit_validator.py +380 -0
  155. package/dist/gaia-ops/hooks/post_compact.py +43 -0
  156. package/dist/gaia-ops/hooks/post_tool_use.py +54 -0
  157. package/dist/gaia-ops/hooks/pre_compact.py +60 -0
  158. package/dist/gaia-ops/hooks/pre_tool_use.py +413 -0
  159. package/dist/gaia-ops/hooks/session_end_hook.py +77 -0
  160. package/dist/gaia-ops/hooks/session_start.py +81 -0
  161. package/dist/gaia-ops/hooks/stop_hook.py +70 -0
  162. package/dist/gaia-ops/hooks/subagent_start.py +71 -0
  163. package/dist/gaia-ops/hooks/subagent_stop.py +295 -0
  164. package/dist/gaia-ops/hooks/task_completed.py +70 -0
  165. package/dist/gaia-ops/hooks/user_prompt_submit.py +246 -0
  166. package/dist/gaia-ops/settings.json +72 -0
  167. package/dist/gaia-ops/skills/README.md +158 -0
  168. package/dist/gaia-ops/skills/agent-creation/SKILL.md +87 -0
  169. package/dist/gaia-ops/skills/agent-creation/examples.md +170 -0
  170. package/dist/gaia-ops/skills/agent-creation/reference.md +191 -0
  171. package/dist/gaia-ops/skills/agent-protocol/SKILL.md +93 -0
  172. package/dist/gaia-ops/skills/agent-protocol/examples.md +223 -0
  173. package/dist/gaia-ops/skills/agent-response/SKILL.md +69 -0
  174. package/dist/gaia-ops/skills/agentic-loop/SKILL.md +80 -0
  175. package/dist/gaia-ops/skills/agentic-loop/reference.md +378 -0
  176. package/dist/gaia-ops/skills/blog-writing/SKILL.md +98 -0
  177. package/dist/gaia-ops/skills/blog-writing/reference.md +130 -0
  178. package/dist/gaia-ops/skills/brief-spec/SKILL.md +185 -0
  179. package/dist/gaia-ops/skills/command-execution/SKILL.md +64 -0
  180. package/dist/gaia-ops/skills/command-execution/reference.md +83 -0
  181. package/dist/gaia-ops/skills/context-updater/SKILL.md +87 -0
  182. package/dist/gaia-ops/skills/context-updater/examples.md +71 -0
  183. package/dist/gaia-ops/skills/developer-patterns/SKILL.md +50 -0
  184. package/dist/gaia-ops/skills/developer-patterns/reference.md +112 -0
  185. package/dist/gaia-ops/skills/execution/SKILL.md +99 -0
  186. package/dist/gaia-ops/skills/fast-queries/SKILL.md +43 -0
  187. package/dist/gaia-ops/skills/gaia-compact/SKILL.md +74 -0
  188. package/dist/gaia-ops/skills/gaia-patterns/SKILL.md +108 -0
  189. package/dist/gaia-ops/skills/gaia-patterns/reference.md +395 -0
  190. package/dist/gaia-ops/skills/gaia-planner/SKILL.md +37 -0
  191. package/dist/gaia-ops/skills/gaia-planner/reference.md +107 -0
  192. package/dist/gaia-ops/skills/gaia-release/SKILL.md +85 -0
  193. package/dist/gaia-ops/skills/gaia-release/reference.md +92 -0
  194. package/dist/gaia-ops/skills/gaia-self-check/SKILL.md +114 -0
  195. package/dist/gaia-ops/skills/gaia-self-check/reference.md +453 -0
  196. package/dist/gaia-ops/skills/gaia-verify/SKILL.md +77 -0
  197. package/dist/gaia-ops/skills/gaia-verify/reference.md +80 -0
  198. package/dist/gaia-ops/skills/git-conventions/SKILL.md +47 -0
  199. package/dist/gaia-ops/skills/gitops-patterns/SKILL.md +60 -0
  200. package/dist/gaia-ops/skills/gitops-patterns/reference.md +183 -0
  201. package/dist/gaia-ops/skills/gmail-policy/SKILL.md +200 -0
  202. package/dist/gaia-ops/skills/gmail-policy/reference.md +150 -0
  203. package/dist/gaia-ops/skills/gmail-triage/SKILL.md +100 -0
  204. package/dist/gaia-ops/skills/gws-setup/SKILL.md +99 -0
  205. package/dist/gaia-ops/skills/gws-setup/reference.md +73 -0
  206. package/dist/gaia-ops/skills/investigation/SKILL.md +100 -0
  207. package/dist/gaia-ops/skills/memory-curation/SKILL.md +83 -0
  208. package/dist/gaia-ops/skills/memory-search/SKILL.md +88 -0
  209. package/dist/gaia-ops/skills/orchestrator-approval/SKILL.md +160 -0
  210. package/dist/gaia-ops/skills/orchestrator-approval/reference.md +174 -0
  211. package/dist/gaia-ops/skills/pending-approvals/SKILL.md +72 -0
  212. package/dist/gaia-ops/skills/pending-approvals/reference.md +214 -0
  213. package/dist/gaia-ops/skills/readme-writing/SKILL.md +71 -0
  214. package/dist/gaia-ops/skills/readme-writing/reference.md +188 -0
  215. package/dist/gaia-ops/skills/reference.md +135 -0
  216. package/dist/gaia-ops/skills/request-approval/SKILL.md +140 -0
  217. package/dist/gaia-ops/skills/request-approval/examples.md +140 -0
  218. package/dist/gaia-ops/skills/request-approval/reference.md +57 -0
  219. package/dist/gaia-ops/skills/schedule-task/SKILL.md +64 -0
  220. package/dist/gaia-ops/skills/schedule-task/reference.md +233 -0
  221. package/dist/gaia-ops/skills/security-tiers/SKILL.md +141 -0
  222. package/dist/gaia-ops/skills/security-tiers/destructive-commands-reference.md +623 -0
  223. package/dist/gaia-ops/skills/security-tiers/reference.md +39 -0
  224. package/dist/gaia-ops/skills/session-reflection/SKILL.md +69 -0
  225. package/dist/gaia-ops/skills/skill-creation/SKILL.md +92 -0
  226. package/dist/gaia-ops/skills/skill-creation/reference.md +29 -0
  227. package/dist/gaia-ops/skills/terraform-patterns/SKILL.md +89 -0
  228. package/dist/gaia-ops/skills/terraform-patterns/reference.md +93 -0
  229. package/dist/gaia-ops/tools/__init__.py +9 -0
  230. package/dist/gaia-ops/tools/agentic-loop/decide-status.py +210 -0
  231. package/dist/gaia-ops/tools/agentic-loop/parse-metric.py +106 -0
  232. package/dist/gaia-ops/tools/agentic-loop/record-iteration.py +221 -0
  233. package/dist/gaia-ops/tools/context/README.md +132 -0
  234. package/dist/gaia-ops/tools/context/__init__.py +42 -0
  235. package/dist/gaia-ops/tools/context/_paths.py +20 -0
  236. package/dist/gaia-ops/tools/context/context_provider.py +721 -0
  237. package/dist/gaia-ops/tools/context/context_section_reader.py +342 -0
  238. package/dist/gaia-ops/tools/context/deep_merge.py +159 -0
  239. package/dist/gaia-ops/tools/context/pending_updates.py +760 -0
  240. package/dist/gaia-ops/tools/context/surface_router.py +278 -0
  241. package/dist/gaia-ops/tools/fast-queries/README.md +65 -0
  242. package/dist/gaia-ops/tools/fast-queries/__init__.py +30 -0
  243. package/dist/gaia-ops/tools/fast-queries/appservices/quicktriage_devops_developer.sh +75 -0
  244. package/dist/gaia-ops/tools/fast-queries/cloud/aws/quicktriage_aws_troubleshooter.sh +32 -0
  245. package/dist/gaia-ops/tools/fast-queries/cloud/gcp/quicktriage_gcp_troubleshooter.sh +88 -0
  246. package/dist/gaia-ops/tools/fast-queries/gitops/quicktriage_gitops_operator.sh +48 -0
  247. package/dist/gaia-ops/tools/fast-queries/run_triage.sh +59 -0
  248. package/dist/gaia-ops/tools/fast-queries/terraform/quicktriage_terraform_architect.sh +80 -0
  249. package/dist/gaia-ops/tools/gaia_simulator/__init__.py +33 -0
  250. package/dist/gaia-ops/tools/gaia_simulator/cli.py +354 -0
  251. package/dist/gaia-ops/tools/gaia_simulator/extractor.py +457 -0
  252. package/dist/gaia-ops/tools/gaia_simulator/reporter.py +258 -0
  253. package/dist/gaia-ops/tools/gaia_simulator/routing_simulator.py +334 -0
  254. package/dist/gaia-ops/tools/gaia_simulator/runner.py +539 -0
  255. package/dist/gaia-ops/tools/gaia_simulator/skills_mapper.py +264 -0
  256. package/dist/gaia-ops/tools/memory/README.md +0 -0
  257. package/dist/gaia-ops/tools/memory/__init__.py +20 -0
  258. package/dist/gaia-ops/tools/memory/backfill_fts5.py +107 -0
  259. package/dist/gaia-ops/tools/memory/conflict_detector.py +295 -0
  260. package/dist/gaia-ops/tools/memory/episodic.py +1210 -0
  261. package/dist/gaia-ops/tools/memory/git_invalidator.py +262 -0
  262. package/dist/gaia-ops/tools/memory/paths.py +102 -0
  263. package/dist/gaia-ops/tools/memory/scoring.py +193 -0
  264. package/dist/gaia-ops/tools/memory/search_store.py +375 -0
  265. package/dist/gaia-ops/tools/persist_transcript_analysis.py +85 -0
  266. package/dist/gaia-ops/tools/review/__init__.py +1 -0
  267. package/dist/gaia-ops/tools/review/review_engine.py +157 -0
  268. package/dist/gaia-ops/tools/scan/__init__.py +35 -0
  269. package/dist/gaia-ops/tools/scan/config.py +247 -0
  270. package/dist/gaia-ops/tools/scan/merge.py +212 -0
  271. package/dist/gaia-ops/tools/scan/orchestrator.py +549 -0
  272. package/dist/gaia-ops/tools/scan/registry.py +127 -0
  273. package/dist/gaia-ops/tools/scan/scanners/__init__.py +18 -0
  274. package/dist/gaia-ops/tools/scan/scanners/base.py +137 -0
  275. package/dist/gaia-ops/tools/scan/scanners/environment.py +349 -0
  276. package/dist/gaia-ops/tools/scan/scanners/git.py +570 -0
  277. package/dist/gaia-ops/tools/scan/scanners/infrastructure.py +875 -0
  278. package/dist/gaia-ops/tools/scan/scanners/orchestration.py +600 -0
  279. package/dist/gaia-ops/tools/scan/scanners/stack.py +1085 -0
  280. package/dist/gaia-ops/tools/scan/scanners/tools.py +260 -0
  281. package/dist/gaia-ops/tools/scan/setup.py +686 -0
  282. package/dist/gaia-ops/tools/scan/tests/__init__.py +1 -0
  283. package/dist/gaia-ops/tools/scan/tests/conftest.py +796 -0
  284. package/dist/gaia-ops/tools/scan/tests/test_environment.py +323 -0
  285. package/dist/gaia-ops/tools/scan/tests/test_git.py +419 -0
  286. package/dist/gaia-ops/tools/scan/tests/test_infrastructure.py +382 -0
  287. package/dist/gaia-ops/tools/scan/tests/test_integration.py +920 -0
  288. package/dist/gaia-ops/tools/scan/tests/test_merge.py +269 -0
  289. package/dist/gaia-ops/tools/scan/tests/test_orchestration.py +304 -0
  290. package/dist/gaia-ops/tools/scan/tests/test_stack.py +604 -0
  291. package/dist/gaia-ops/tools/scan/tests/test_tools.py +349 -0
  292. package/dist/gaia-ops/tools/scan/ui.py +624 -0
  293. package/dist/gaia-ops/tools/scan/verify.py +270 -0
  294. package/dist/gaia-ops/tools/scan/walk.py +118 -0
  295. package/dist/gaia-ops/tools/scan/workspace.py +85 -0
  296. package/dist/gaia-ops/tools/validation/README.md +244 -0
  297. package/dist/gaia-ops/tools/validation/__init__.py +17 -0
  298. package/dist/gaia-ops/tools/validation/approval_gate.py +321 -0
  299. package/dist/gaia-ops/tools/validation/validate_skills.py +189 -0
  300. package/dist/gaia-security/.claude-plugin/plugin.json +24 -0
  301. package/dist/gaia-security/README.md +90 -0
  302. package/dist/gaia-security/config/universal-rules.json +102 -0
  303. package/dist/gaia-security/hooks/adapters/__init__.py +52 -0
  304. package/dist/gaia-security/hooks/adapters/base.py +219 -0
  305. package/dist/gaia-security/hooks/adapters/channel.py +17 -0
  306. package/dist/gaia-security/hooks/adapters/claude_code.py +1890 -0
  307. package/dist/gaia-security/hooks/adapters/types.py +194 -0
  308. package/dist/gaia-security/hooks/adapters/utils.py +25 -0
  309. package/dist/gaia-security/hooks/hooks.json +113 -0
  310. package/dist/gaia-security/hooks/modules/__init__.py +15 -0
  311. package/dist/gaia-security/hooks/modules/agents/__init__.py +29 -0
  312. package/dist/gaia-security/hooks/modules/agents/contract_validator.py +647 -0
  313. package/dist/gaia-security/hooks/modules/agents/response_contract.py +496 -0
  314. package/dist/gaia-security/hooks/modules/agents/skill_injection_verifier.py +120 -0
  315. package/dist/gaia-security/hooks/modules/agents/state_tracker.py +267 -0
  316. package/dist/gaia-security/hooks/modules/agents/task_info_builder.py +74 -0
  317. package/dist/gaia-security/hooks/modules/agents/transcript_analyzer.py +458 -0
  318. package/dist/gaia-security/hooks/modules/agents/transcript_reader.py +152 -0
  319. package/dist/gaia-security/hooks/modules/audit/__init__.py +28 -0
  320. package/dist/gaia-security/hooks/modules/audit/event_detector.py +168 -0
  321. package/dist/gaia-security/hooks/modules/audit/logger.py +131 -0
  322. package/dist/gaia-security/hooks/modules/audit/metrics.py +134 -0
  323. package/dist/gaia-security/hooks/modules/audit/workflow_auditor.py +611 -0
  324. package/dist/gaia-security/hooks/modules/audit/workflow_recorder.py +296 -0
  325. package/dist/gaia-security/hooks/modules/context/__init__.py +11 -0
  326. package/dist/gaia-security/hooks/modules/context/agentic_loop_detector.py +165 -0
  327. package/dist/gaia-security/hooks/modules/context/anchor_tracker.py +317 -0
  328. package/dist/gaia-security/hooks/modules/context/compact_context_builder.py +218 -0
  329. package/dist/gaia-security/hooks/modules/context/context_freshness.py +145 -0
  330. package/dist/gaia-security/hooks/modules/context/context_injector.py +558 -0
  331. package/dist/gaia-security/hooks/modules/context/context_writer.py +530 -0
  332. package/dist/gaia-security/hooks/modules/context/contracts_loader.py +161 -0
  333. package/dist/gaia-security/hooks/modules/core/__init__.py +40 -0
  334. package/dist/gaia-security/hooks/modules/core/hook_entry.py +78 -0
  335. package/dist/gaia-security/hooks/modules/core/paths.py +160 -0
  336. package/dist/gaia-security/hooks/modules/core/plugin_mode.py +149 -0
  337. package/dist/gaia-security/hooks/modules/core/plugin_setup.py +577 -0
  338. package/dist/gaia-security/hooks/modules/core/state.py +179 -0
  339. package/dist/gaia-security/hooks/modules/core/stdin.py +24 -0
  340. package/dist/gaia-security/hooks/modules/events/__init__.py +1 -0
  341. package/dist/gaia-security/hooks/modules/events/event_writer.py +210 -0
  342. package/dist/gaia-security/hooks/modules/memory/__init__.py +8 -0
  343. package/dist/gaia-security/hooks/modules/memory/episode_writer.py +216 -0
  344. package/dist/gaia-security/hooks/modules/orchestrator/__init__.py +1 -0
  345. package/dist/gaia-security/hooks/modules/orchestrator/delegate_mode.py +122 -0
  346. package/dist/gaia-security/hooks/modules/scanning/__init__.py +8 -0
  347. package/dist/gaia-security/hooks/modules/scanning/scan_trigger.py +84 -0
  348. package/dist/gaia-security/hooks/modules/security/__init__.py +120 -0
  349. package/dist/gaia-security/hooks/modules/security/approval_cleanup.py +87 -0
  350. package/dist/gaia-security/hooks/modules/security/approval_constants.py +23 -0
  351. package/dist/gaia-security/hooks/modules/security/approval_grants.py +1638 -0
  352. package/dist/gaia-security/hooks/modules/security/approval_messages.py +71 -0
  353. package/dist/gaia-security/hooks/modules/security/approval_scopes.py +222 -0
  354. package/dist/gaia-security/hooks/modules/security/blocked_commands.py +595 -0
  355. package/dist/gaia-security/hooks/modules/security/blocked_message_formatter.py +87 -0
  356. package/dist/gaia-security/hooks/modules/security/command_semantics.py +181 -0
  357. package/dist/gaia-security/hooks/modules/security/composition_rules.py +547 -0
  358. package/dist/gaia-security/hooks/modules/security/flag_classifiers.py +873 -0
  359. package/dist/gaia-security/hooks/modules/security/gitops_validator.py +179 -0
  360. package/dist/gaia-security/hooks/modules/security/mutative_verbs.py +1131 -0
  361. package/dist/gaia-security/hooks/modules/security/network_hosts.py +481 -0
  362. package/dist/gaia-security/hooks/modules/security/prompt_validator.py +40 -0
  363. package/dist/gaia-security/hooks/modules/security/shell_unwrapper.py +165 -0
  364. package/dist/gaia-security/hooks/modules/security/tiers.py +196 -0
  365. package/dist/gaia-security/hooks/modules/session/__init__.py +10 -0
  366. package/dist/gaia-security/hooks/modules/session/pending_scanner.py +174 -0
  367. package/dist/gaia-security/hooks/modules/session/session_context_writer.py +100 -0
  368. package/dist/gaia-security/hooks/modules/session/session_event_injector.py +160 -0
  369. package/dist/gaia-security/hooks/modules/session/session_manager.py +31 -0
  370. package/dist/gaia-security/hooks/modules/session/session_registry.py +333 -0
  371. package/dist/gaia-security/hooks/modules/tools/__init__.py +29 -0
  372. package/dist/gaia-security/hooks/modules/tools/bash_validator.py +1008 -0
  373. package/dist/gaia-security/hooks/modules/tools/cloud_pipe_validator.py +231 -0
  374. package/dist/gaia-security/hooks/modules/tools/hook_response.py +55 -0
  375. package/dist/gaia-security/hooks/modules/tools/shell_parser.py +227 -0
  376. package/dist/gaia-security/hooks/modules/tools/stage_decomposer.py +315 -0
  377. package/dist/gaia-security/hooks/modules/tools/task_validator.py +294 -0
  378. package/dist/gaia-security/hooks/modules/validation/__init__.py +23 -0
  379. package/dist/gaia-security/hooks/modules/validation/commit_validator.py +380 -0
  380. package/dist/gaia-security/hooks/post_tool_use.py +54 -0
  381. package/dist/gaia-security/hooks/pre_tool_use.py +413 -0
  382. package/dist/gaia-security/hooks/session_end_hook.py +77 -0
  383. package/dist/gaia-security/hooks/session_start.py +81 -0
  384. package/dist/gaia-security/hooks/stop_hook.py +70 -0
  385. package/dist/gaia-security/hooks/user_prompt_submit.py +246 -0
  386. package/dist/gaia-security/settings.json +58 -0
  387. package/git-hooks/commit-msg +41 -0
  388. package/hooks/README.md +100 -0
  389. package/hooks/adapters/__init__.py +52 -0
  390. package/hooks/adapters/base.py +219 -0
  391. package/hooks/adapters/channel.py +17 -0
  392. package/hooks/adapters/claude_code.py +1890 -0
  393. package/hooks/adapters/types.py +194 -0
  394. package/hooks/adapters/utils.py +25 -0
  395. package/hooks/elicitation_result.py +179 -0
  396. package/hooks/hooks.json +84 -0
  397. package/hooks/modules/README.md +189 -0
  398. package/hooks/modules/__init__.py +15 -0
  399. package/hooks/modules/agents/__init__.py +29 -0
  400. package/hooks/modules/agents/contract_validator.py +647 -0
  401. package/hooks/modules/agents/response_contract.py +496 -0
  402. package/hooks/modules/agents/skill_injection_verifier.py +120 -0
  403. package/hooks/modules/agents/state_tracker.py +267 -0
  404. package/hooks/modules/agents/task_info_builder.py +74 -0
  405. package/hooks/modules/agents/transcript_analyzer.py +458 -0
  406. package/hooks/modules/agents/transcript_reader.py +152 -0
  407. package/hooks/modules/audit/__init__.py +28 -0
  408. package/hooks/modules/audit/event_detector.py +168 -0
  409. package/hooks/modules/audit/logger.py +131 -0
  410. package/hooks/modules/audit/metrics.py +134 -0
  411. package/hooks/modules/audit/workflow_auditor.py +611 -0
  412. package/hooks/modules/audit/workflow_recorder.py +296 -0
  413. package/hooks/modules/context/__init__.py +11 -0
  414. package/hooks/modules/context/agentic_loop_detector.py +165 -0
  415. package/hooks/modules/context/anchor_tracker.py +317 -0
  416. package/hooks/modules/context/compact_context_builder.py +218 -0
  417. package/hooks/modules/context/context_freshness.py +145 -0
  418. package/hooks/modules/context/context_injector.py +558 -0
  419. package/hooks/modules/context/context_writer.py +530 -0
  420. package/hooks/modules/context/contracts_loader.py +161 -0
  421. package/hooks/modules/core/__init__.py +40 -0
  422. package/hooks/modules/core/hook_entry.py +78 -0
  423. package/hooks/modules/core/paths.py +160 -0
  424. package/hooks/modules/core/plugin_mode.py +149 -0
  425. package/hooks/modules/core/plugin_setup.py +577 -0
  426. package/hooks/modules/core/state.py +179 -0
  427. package/hooks/modules/core/stdin.py +24 -0
  428. package/hooks/modules/events/__init__.py +1 -0
  429. package/hooks/modules/events/event_writer.py +210 -0
  430. package/hooks/modules/evidence/__init__.py +34 -0
  431. package/hooks/modules/evidence/assertions.py +137 -0
  432. package/hooks/modules/evidence/index_writer.py +57 -0
  433. package/hooks/modules/evidence/loader.py +126 -0
  434. package/hooks/modules/evidence/runner.py +241 -0
  435. package/hooks/modules/memory/__init__.py +8 -0
  436. package/hooks/modules/memory/episode_writer.py +216 -0
  437. package/hooks/modules/orchestrator/__init__.py +1 -0
  438. package/hooks/modules/orchestrator/delegate_mode.py +122 -0
  439. package/hooks/modules/scanning/__init__.py +8 -0
  440. package/hooks/modules/scanning/scan_trigger.py +84 -0
  441. package/hooks/modules/security/__init__.py +120 -0
  442. package/hooks/modules/security/approval_cleanup.py +87 -0
  443. package/hooks/modules/security/approval_constants.py +23 -0
  444. package/hooks/modules/security/approval_grants.py +1638 -0
  445. package/hooks/modules/security/approval_messages.py +71 -0
  446. package/hooks/modules/security/approval_scopes.py +222 -0
  447. package/hooks/modules/security/blocked_commands.py +595 -0
  448. package/hooks/modules/security/blocked_message_formatter.py +87 -0
  449. package/hooks/modules/security/command_semantics.py +181 -0
  450. package/hooks/modules/security/composition_rules.py +547 -0
  451. package/hooks/modules/security/flag_classifiers.py +873 -0
  452. package/hooks/modules/security/gitops_validator.py +179 -0
  453. package/hooks/modules/security/mutative_verbs.py +1131 -0
  454. package/hooks/modules/security/network_hosts.py +481 -0
  455. package/hooks/modules/security/prompt_validator.py +40 -0
  456. package/hooks/modules/security/shell_unwrapper.py +165 -0
  457. package/hooks/modules/security/tiers.py +196 -0
  458. package/hooks/modules/session/__init__.py +10 -0
  459. package/hooks/modules/session/pending_scanner.py +174 -0
  460. package/hooks/modules/session/session_context_writer.py +100 -0
  461. package/hooks/modules/session/session_event_injector.py +160 -0
  462. package/hooks/modules/session/session_manager.py +31 -0
  463. package/hooks/modules/session/session_registry.py +333 -0
  464. package/hooks/modules/tools/__init__.py +29 -0
  465. package/hooks/modules/tools/bash_validator.py +1008 -0
  466. package/hooks/modules/tools/cloud_pipe_validator.py +231 -0
  467. package/hooks/modules/tools/hook_response.py +55 -0
  468. package/hooks/modules/tools/shell_parser.py +227 -0
  469. package/hooks/modules/tools/stage_decomposer.py +315 -0
  470. package/hooks/modules/tools/task_validator.py +294 -0
  471. package/hooks/modules/validation/__init__.py +23 -0
  472. package/hooks/modules/validation/commit_validator.py +380 -0
  473. package/hooks/post_compact.py +43 -0
  474. package/hooks/post_tool_use.py +54 -0
  475. package/hooks/pre_compact.py +60 -0
  476. package/hooks/pre_tool_use.py +413 -0
  477. package/hooks/session_end_hook.py +77 -0
  478. package/hooks/session_start.py +81 -0
  479. package/hooks/stop_hook.py +70 -0
  480. package/hooks/subagent_start.py +71 -0
  481. package/hooks/subagent_stop.py +295 -0
  482. package/hooks/task_completed.py +70 -0
  483. package/hooks/user_prompt_submit.py +246 -0
  484. package/index.js +83 -0
  485. package/package.json +103 -0
  486. package/pyproject.toml +32 -0
  487. package/skills/README.md +158 -0
  488. package/skills/agent-creation/SKILL.md +87 -0
  489. package/skills/agent-creation/examples.md +170 -0
  490. package/skills/agent-creation/reference.md +191 -0
  491. package/skills/agent-protocol/SKILL.md +93 -0
  492. package/skills/agent-protocol/examples.md +223 -0
  493. package/skills/agent-response/SKILL.md +69 -0
  494. package/skills/agentic-loop/SKILL.md +80 -0
  495. package/skills/agentic-loop/reference.md +378 -0
  496. package/skills/blog-writing/SKILL.md +98 -0
  497. package/skills/blog-writing/reference.md +130 -0
  498. package/skills/brief-spec/SKILL.md +185 -0
  499. package/skills/command-execution/SKILL.md +64 -0
  500. package/skills/command-execution/reference.md +83 -0
  501. package/skills/context-updater/SKILL.md +87 -0
  502. package/skills/context-updater/examples.md +71 -0
  503. package/skills/developer-patterns/SKILL.md +50 -0
  504. package/skills/developer-patterns/reference.md +112 -0
  505. package/skills/execution/SKILL.md +99 -0
  506. package/skills/fast-queries/SKILL.md +43 -0
  507. package/skills/gaia-compact/SKILL.md +74 -0
  508. package/skills/gaia-patterns/SKILL.md +108 -0
  509. package/skills/gaia-patterns/reference.md +395 -0
  510. package/skills/gaia-planner/SKILL.md +37 -0
  511. package/skills/gaia-planner/reference.md +107 -0
  512. package/skills/gaia-release/SKILL.md +85 -0
  513. package/skills/gaia-release/reference.md +92 -0
  514. package/skills/gaia-self-check/SKILL.md +114 -0
  515. package/skills/gaia-self-check/reference.md +453 -0
  516. package/skills/gaia-verify/SKILL.md +77 -0
  517. package/skills/gaia-verify/reference.md +80 -0
  518. package/skills/git-conventions/SKILL.md +47 -0
  519. package/skills/gitops-patterns/SKILL.md +60 -0
  520. package/skills/gitops-patterns/reference.md +183 -0
  521. package/skills/gmail-policy/SKILL.md +200 -0
  522. package/skills/gmail-policy/reference.md +150 -0
  523. package/skills/gmail-triage/SKILL.md +100 -0
  524. package/skills/gws-setup/SKILL.md +99 -0
  525. package/skills/gws-setup/reference.md +73 -0
  526. package/skills/investigation/SKILL.md +100 -0
  527. package/skills/memory-curation/SKILL.md +83 -0
  528. package/skills/memory-search/SKILL.md +88 -0
  529. package/skills/orchestrator-approval/SKILL.md +160 -0
  530. package/skills/orchestrator-approval/reference.md +174 -0
  531. package/skills/pending-approvals/SKILL.md +72 -0
  532. package/skills/pending-approvals/reference.md +214 -0
  533. package/skills/readme-writing/SKILL.md +71 -0
  534. package/skills/readme-writing/reference.md +188 -0
  535. package/skills/reference.md +135 -0
  536. package/skills/request-approval/SKILL.md +140 -0
  537. package/skills/request-approval/examples.md +140 -0
  538. package/skills/request-approval/reference.md +57 -0
  539. package/skills/schedule-task/SKILL.md +64 -0
  540. package/skills/schedule-task/reference.md +233 -0
  541. package/skills/security-tiers/SKILL.md +141 -0
  542. package/skills/security-tiers/destructive-commands-reference.md +623 -0
  543. package/skills/security-tiers/reference.md +39 -0
  544. package/skills/session-reflection/SKILL.md +69 -0
  545. package/skills/skill-creation/SKILL.md +92 -0
  546. package/skills/skill-creation/reference.md +29 -0
  547. package/skills/terraform-patterns/SKILL.md +89 -0
  548. package/skills/terraform-patterns/reference.md +93 -0
  549. package/templates/README.md +69 -0
  550. package/templates/managed-settings.template.json +43 -0
  551. package/tools/__init__.py +9 -0
  552. package/tools/agentic-loop/decide-status.py +210 -0
  553. package/tools/agentic-loop/parse-metric.py +106 -0
  554. package/tools/agentic-loop/record-iteration.py +221 -0
  555. package/tools/context/README.md +132 -0
  556. package/tools/context/__init__.py +42 -0
  557. package/tools/context/_paths.py +20 -0
  558. package/tools/context/context_provider.py +721 -0
  559. package/tools/context/context_section_reader.py +342 -0
  560. package/tools/context/deep_merge.py +159 -0
  561. package/tools/context/pending_updates.py +760 -0
  562. package/tools/context/surface_router.py +278 -0
  563. package/tools/fast-queries/README.md +65 -0
  564. package/tools/fast-queries/__init__.py +30 -0
  565. package/tools/fast-queries/appservices/quicktriage_devops_developer.sh +75 -0
  566. package/tools/fast-queries/cloud/aws/quicktriage_aws_troubleshooter.sh +32 -0
  567. package/tools/fast-queries/cloud/gcp/quicktriage_gcp_troubleshooter.sh +88 -0
  568. package/tools/fast-queries/gitops/quicktriage_gitops_operator.sh +48 -0
  569. package/tools/fast-queries/run_triage.sh +59 -0
  570. package/tools/fast-queries/terraform/quicktriage_terraform_architect.sh +80 -0
  571. package/tools/gaia_simulator/__init__.py +33 -0
  572. package/tools/gaia_simulator/cli.py +354 -0
  573. package/tools/gaia_simulator/extractor.py +457 -0
  574. package/tools/gaia_simulator/reporter.py +258 -0
  575. package/tools/gaia_simulator/routing_simulator.py +334 -0
  576. package/tools/gaia_simulator/runner.py +539 -0
  577. package/tools/gaia_simulator/skills_mapper.py +264 -0
  578. package/tools/memory/README.md +0 -0
  579. package/tools/memory/__init__.py +20 -0
  580. package/tools/memory/backfill_fts5.py +107 -0
  581. package/tools/memory/conflict_detector.py +295 -0
  582. package/tools/memory/episodic.py +1210 -0
  583. package/tools/memory/git_invalidator.py +262 -0
  584. package/tools/memory/paths.py +102 -0
  585. package/tools/memory/scoring.py +193 -0
  586. package/tools/memory/search_store.py +375 -0
  587. package/tools/persist_transcript_analysis.py +85 -0
  588. package/tools/review/__init__.py +1 -0
  589. package/tools/review/review_engine.py +157 -0
  590. package/tools/scan/__init__.py +35 -0
  591. package/tools/scan/config.py +247 -0
  592. package/tools/scan/merge.py +212 -0
  593. package/tools/scan/orchestrator.py +549 -0
  594. package/tools/scan/registry.py +127 -0
  595. package/tools/scan/scanners/__init__.py +18 -0
  596. package/tools/scan/scanners/base.py +137 -0
  597. package/tools/scan/scanners/environment.py +349 -0
  598. package/tools/scan/scanners/git.py +570 -0
  599. package/tools/scan/scanners/infrastructure.py +875 -0
  600. package/tools/scan/scanners/orchestration.py +600 -0
  601. package/tools/scan/scanners/stack.py +1085 -0
  602. package/tools/scan/scanners/tools.py +260 -0
  603. package/tools/scan/setup.py +686 -0
  604. package/tools/scan/tests/__init__.py +1 -0
  605. package/tools/scan/tests/conftest.py +796 -0
  606. package/tools/scan/tests/test_environment.py +323 -0
  607. package/tools/scan/tests/test_git.py +419 -0
  608. package/tools/scan/tests/test_infrastructure.py +382 -0
  609. package/tools/scan/tests/test_integration.py +920 -0
  610. package/tools/scan/tests/test_merge.py +269 -0
  611. package/tools/scan/tests/test_orchestration.py +304 -0
  612. package/tools/scan/tests/test_stack.py +604 -0
  613. package/tools/scan/tests/test_tools.py +349 -0
  614. package/tools/scan/ui.py +624 -0
  615. package/tools/scan/verify.py +270 -0
  616. package/tools/scan/walk.py +118 -0
  617. package/tools/scan/workspace.py +85 -0
  618. package/tools/validation/README.md +244 -0
  619. package/tools/validation/__init__.py +17 -0
  620. package/tools/validation/approval_gate.py +321 -0
  621. package/tools/validation/validate_skills.py +189 -0
@@ -0,0 +1,246 @@
1
+ #!/usr/bin/env python3
2
+ """UserPromptSubmit hook — injects routing recommendations, first-run welcome, and agentic-loop resume context."""
3
+
4
+ import sys
5
+ import json
6
+ import logging
7
+ from datetime import datetime
8
+ from pathlib import Path
9
+
10
+ sys.path.insert(0, str(Path(__file__).parent))
11
+
12
+ from modules.core.paths import get_logs_dir
13
+ from modules.core.stdin import has_stdin_data
14
+ from modules.core.plugin_setup import run_first_time_setup
15
+ from modules.core.plugin_mode import get_plugin_mode
16
+
17
+ # Configure logging — file only, no stderr
18
+ _log_file = get_logs_dir() / f"hooks-{datetime.now().strftime('%Y-%m-%d')}.log"
19
+ logging.basicConfig(
20
+ level=logging.INFO,
21
+ format='%(asctime)s [user_prompt_submit] %(name)s - %(levelname)s - %(message)s',
22
+ handlers=[logging.FileHandler(_log_file)],
23
+ )
24
+ logger = logging.getLogger(__name__)
25
+
26
+
27
+ def _extract_user_prompt(raw_input: str) -> str:
28
+ """Extract user prompt text from stdin event.
29
+
30
+ The UserPromptSubmit event is JSON with the user's message.
31
+ Try known field names; return empty string if extraction fails.
32
+ """
33
+ try:
34
+ event = json.loads(raw_input)
35
+ # Try known field names from Claude Code hook events
36
+ for field in ("user_message", "prompt", "message", "content"):
37
+ if field in event and isinstance(event[field], str):
38
+ return event[field]
39
+ # Check nested hookEventInput
40
+ hook_input = event.get("hookEventInput", {})
41
+ if isinstance(hook_input, dict):
42
+ for field in ("user_message", "prompt", "message", "content"):
43
+ if field in hook_input and isinstance(hook_input[field], str):
44
+ return hook_input[field]
45
+ except (json.JSONDecodeError, TypeError, AttributeError):
46
+ pass
47
+ return ""
48
+
49
+
50
+ def _build_routing_recommendation(prompt_text: str) -> str:
51
+ """Run surface classification and format as a routing recommendation block.
52
+
53
+ Returns empty string if classification fails or produces no active surfaces.
54
+ This is advisory — never raises exceptions.
55
+ """
56
+ try:
57
+ # Import surface_router from tools/context
58
+ tools_dir = Path(__file__).resolve().parent.parent / "tools" / "context"
59
+ if str(tools_dir) not in sys.path:
60
+ sys.path.insert(0, str(tools_dir))
61
+
62
+ from surface_router import classify_surfaces
63
+
64
+ routing = classify_surfaces(prompt_text)
65
+
66
+ active_surfaces = routing.get("active_surfaces", [])
67
+ if not active_surfaces:
68
+ logger.info("Surface routing: no active surfaces for prompt")
69
+ return ""
70
+
71
+ agents = routing.get("recommended_agents", [])
72
+ dispatch_mode = routing.get("dispatch_mode", "single_surface")
73
+ confidence = routing.get("confidence", 0.0)
74
+ matched_signals = routing.get("matched_signals", {})
75
+
76
+ # Flatten matched signals into a single list for display
77
+ all_signals = []
78
+ for surface_signals in matched_signals.values():
79
+ all_signals.extend(surface_signals)
80
+
81
+ lines = [
82
+ "\n\n## Surface Routing Recommendation",
83
+ f"- Recommended agents: {agents}",
84
+ f"- Dispatch mode: {dispatch_mode}",
85
+ f"- Confidence: {confidence}",
86
+ f"- Matched signals: {json.dumps(all_signals)}",
87
+ ]
88
+
89
+ logger.info(
90
+ "Surface routing: agents=%s mode=%s confidence=%.2f signals=%s",
91
+ agents, dispatch_mode, confidence, all_signals,
92
+ )
93
+ return "\n".join(lines)
94
+
95
+ except Exception as e:
96
+ logger.warning("Surface routing failed (advisory, skipping): %s", e)
97
+ return ""
98
+
99
+
100
+ def _build_welcome(mode: str) -> str:
101
+ """Build first-run welcome message for the user.
102
+
103
+ This message is injected as additionalContext so Claude receives it,
104
+ not the user directly. The framing explains WHY the user needs to
105
+ know — Claude should naturally relay it because it is actionable
106
+ and the user cannot use the plugin fully without restarting.
107
+ """
108
+ plugin_name = f"GAIA {'Ops' if mode == 'ops' else 'Security'}"
109
+
110
+ return (
111
+ f"{plugin_name} was just installed for the first time in this project. "
112
+ f"The plugin detected the installation and configured security permissions, "
113
+ f"but these permissions only take effect after restarting Claude Code. "
114
+ f"Until the user closes this session and reopens Claude Code, "
115
+ f"{plugin_name} cannot protect their commands — destructive operations "
116
+ f"will not be blocked and mutative operations will not require approval. "
117
+ f"The user needs to know this because they just installed {plugin_name} "
118
+ f"expecting it to work, but it will not be active until they restart. "
119
+ f"Tell the user that {plugin_name} is installed, that they need to close "
120
+ f"and reopen Claude Code to activate it, and that until they do, "
121
+ f"security protections are not active."
122
+ )
123
+
124
+
125
+ def _build_pending_context() -> str:
126
+ """Scan for pending approvals and format as actionable context.
127
+
128
+ Returns an [ACTIONABLE]-framed summary if pending approvals exist,
129
+ or empty string if none found. Includes cross-session fallback:
130
+ scans current session first, then all sessions if empty.
131
+
132
+ Fully fail-safe — never raises exceptions.
133
+ """
134
+ try:
135
+ from modules.session.pending_scanner import scan_pending_approvals, format_pending_summary
136
+ from modules.core.paths import get_plugin_data_dir
137
+ from modules.core.state import get_session_id
138
+
139
+ approvals_dir = get_plugin_data_dir() / "cache" / "approvals"
140
+ session_id = get_session_id()
141
+
142
+ # Current session first
143
+ pendings = scan_pending_approvals(
144
+ approvals_dir, session_id=session_id, current_session_id=session_id
145
+ )
146
+
147
+ # Cross-session fallback: scan all sessions if current has none.
148
+ # exclude_live_sessions=True prevents pendings from parallel live
149
+ # sessions from appearing as "[session anterior]" injections.
150
+ if not pendings:
151
+ pendings = scan_pending_approvals(
152
+ approvals_dir,
153
+ current_session_id=session_id,
154
+ exclude_live_sessions=True,
155
+ )
156
+
157
+ if not pendings:
158
+ return ""
159
+
160
+ summary = format_pending_summary(pendings)
161
+ logger.info("Pending context: %d approvals found", len(pendings))
162
+ return (
163
+ "[ACTIONABLE] Pending approvals require your attention before "
164
+ "routing this request.\n\n" + summary
165
+ )
166
+ except Exception as e:
167
+ logger.debug("Pending context scan skipped (non-fatal): %s", e)
168
+ return ""
169
+
170
+
171
+ if __name__ == "__main__":
172
+ if not has_stdin_data():
173
+ sys.exit(0)
174
+
175
+ try:
176
+ raw_input = sys.stdin.read()
177
+
178
+ # Check first-run BEFORE setup (SessionStart does setup with
179
+ # mark_done=False so the marker doesn't exist yet on first run).
180
+ from modules.core.plugin_setup import is_first_run, mark_initialized
181
+ first_run = is_first_run()
182
+
183
+ # Ensure registry + permissions exist (idempotent, no mark).
184
+ setup_msg = run_first_time_setup(mark_done=False)
185
+ mode = get_plugin_mode()
186
+
187
+ # Build additionalContext: welcome + agentic-loop + routing.
188
+ # Identity now lives in agents/gaia-orchestrator.md (agent definition).
189
+ context_parts = []
190
+
191
+ # First-time welcome: the marker does not exist yet because
192
+ # neither SessionStart nor this call marked it.
193
+ if first_run:
194
+ welcome = _build_welcome(mode)
195
+ context_parts.append(welcome)
196
+ mark_initialized() # Mark AFTER building the welcome
197
+ logger.info("First-run welcome prepended for %s mode", mode)
198
+
199
+ # Detect active agentic-loop and inject resume context (ops mode only).
200
+ # Lightweight: checks file existence + small JSON read, fully fail-safe.
201
+ if mode == "ops":
202
+ try:
203
+ from modules.context.agentic_loop_detector import build_resume_context
204
+ loop_context = build_resume_context()
205
+ if loop_context:
206
+ context_parts.append(loop_context)
207
+ logger.info("Agentic loop resume context injected")
208
+ except Exception as e:
209
+ logger.debug("Agentic loop detection skipped (non-fatal): %s", e)
210
+
211
+ # Inject pending approval context (ops mode only, before routing).
212
+ if mode == "ops":
213
+ pending_block = _build_pending_context()
214
+ if pending_block:
215
+ context_parts.append(pending_block)
216
+ logger.info("Pending approval context injected")
217
+
218
+ # Append deterministic surface routing recommendation (ops mode only)
219
+ if mode == "ops":
220
+ prompt_text = _extract_user_prompt(raw_input)
221
+
222
+ # NOTE: Approval activation moved to ElicitationResult hook.
223
+ # AskUserQuestion responses trigger ElicitationResult, not
224
+ # UserPromptSubmit, so approval detection lives there now.
225
+
226
+ if prompt_text:
227
+ routing_block = _build_routing_recommendation(prompt_text)
228
+ if routing_block:
229
+ context_parts.append(routing_block)
230
+ else:
231
+ logger.info("Could not extract user prompt from stdin, skipping routing")
232
+
233
+ additional_context = "\n\n".join(context_parts)
234
+ logger.info("Context injected: %s mode (%d chars)", mode, len(additional_context))
235
+
236
+ print(json.dumps({
237
+ "hookSpecificOutput": {
238
+ "hookEventName": "UserPromptSubmit",
239
+ "additionalContext": additional_context,
240
+ }
241
+ }))
242
+ sys.exit(0)
243
+
244
+ except Exception as e:
245
+ logger.error("Error in user_prompt_submit: %s", e, exc_info=True)
246
+ sys.exit(0)
@@ -0,0 +1,58 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(*)",
5
+ "Read",
6
+ "Glob",
7
+ "Grep",
8
+ "BashOutput",
9
+ "KillShell"
10
+ ],
11
+ "deny": [
12
+ "Bash(aws ec2 delete-vpc:*)",
13
+ "Bash(aws ec2 delete-subnet:*)",
14
+ "Bash(aws ec2 delete-internet-gateway:*)",
15
+ "Bash(aws ec2 delete-route-table:*)",
16
+ "Bash(aws ec2 delete-route:*)",
17
+ "Bash(aws rds delete-db-instance:*)",
18
+ "Bash(aws rds delete-db-cluster:*)",
19
+ "Bash(aws dynamodb delete-table:*)",
20
+ "Bash(aws s3 rb:*)",
21
+ "Bash(aws s3api delete-bucket:*)",
22
+ "Bash(aws elasticache delete-cache-cluster:*)",
23
+ "Bash(aws elasticache delete-replication-group:*)",
24
+ "Bash(aws eks delete-cluster:*)",
25
+ "Bash(gcloud projects delete:*)",
26
+ "Bash(gcloud container clusters delete:*)",
27
+ "Bash(gcloud sql instances delete:*)",
28
+ "Bash(gcloud sql databases delete:*)",
29
+ "Bash(gcloud services disable:*)",
30
+ "Bash(gsutil rb:*)",
31
+ "Bash(gsutil rm -r:*)",
32
+ "Bash(kubectl delete namespace:*)",
33
+ "Bash(kubectl delete node:*)",
34
+ "Bash(kubectl delete cluster:*)",
35
+ "Bash(kubectl delete pv:*)",
36
+ "Bash(kubectl delete persistentvolume:*)",
37
+ "Bash(kubectl delete pvc:*)",
38
+ "Bash(kubectl delete persistentvolumeclaim:*)",
39
+ "Bash(kubectl delete crd:*)",
40
+ "Bash(kubectl delete customresourcedefinition:*)",
41
+ "Bash(kubectl delete mutatingwebhookconfiguration:*)",
42
+ "Bash(kubectl delete validatingwebhookconfiguration:*)",
43
+ "Bash(kubectl drain:*)",
44
+ "Bash(git push --force:*)",
45
+ "Bash(git push -f:*)",
46
+ "Bash(git push origin --force:*)",
47
+ "Bash(git push origin -f:*)",
48
+ "Bash(dd:*)",
49
+ "Bash(fdisk:*)",
50
+ "Bash(mkfs:*)",
51
+ "Bash(mkfs.ext4:*)",
52
+ "Bash(mkfs.ext3:*)",
53
+ "Bash(mkfs.fat:*)",
54
+ "Bash(mkfs.ntfs:*)"
55
+ ],
56
+ "ask": []
57
+ }
58
+ }
@@ -0,0 +1,41 @@
1
+ #!/bin/sh
2
+ #
3
+ # commit-msg hook: strip Claude Code attribution footers from commit messages.
4
+ #
5
+ # This hook runs at the git level, catching ALL commits regardless of whether
6
+ # they originate from Claude Code's Bash tool, a subagent, or the user's terminal.
7
+ #
8
+ # Patterns match those in hooks/modules/tools/bash_validator.py _strip_claude_footers()
9
+ # to maintain a single source of truth for what constitutes a forbidden footer.
10
+ #
11
+ # Installation:
12
+ # cp git-hooks/commit-msg .git/hooks/commit-msg
13
+ # chmod +x .git/hooks/commit-msg
14
+ #
15
+ # Or via gaia-init (automatic).
16
+
17
+ COMMIT_MSG_FILE="$1"
18
+
19
+ if [ ! -f "${COMMIT_MSG_FILE}" ]; then
20
+ exit 0
21
+ fi
22
+
23
+ # Create a temp file for the cleaned message
24
+ TEMP_FILE=$(mktemp)
25
+ trap 'rm -f "${TEMP_FILE}"' EXIT
26
+
27
+ # Read the commit message and strip forbidden footer lines:
28
+ # - Co-Authored-By: containing "Claude" (any case)
29
+ # - "Generated with Claude Code" or "[Claude Code]" (any case)
30
+ # - Emoji-prefixed "Generated with" lines
31
+ sed -E \
32
+ -e '/^[[:space:]]*[Cc][Oo]-[Aa][Uu][Tt][Hh][Oo][Rr][Ee][Dd]-[Bb][Yy]:.*[Cc][Ll][Aa][Uu][Dd][Ee]/d' \
33
+ -e '/^[[:space:]]*[Gg][Ee][Nn][Ee][Rr][Aa][Tt][Ee][Dd] [Ww][Ii][Tt][Hh].*[Cc][Ll][Aa][Uu][Dd][Ee] [Cc][Oo][Dd][Ee]/d' \
34
+ -e '/^[[:space:]]*..?[[:space:]]*[Gg][Ee][Nn][Ee][Rr][Aa][Tt][Ee][Dd] [Ww][Ii][Tt][Hh]/d' \
35
+ "${COMMIT_MSG_FILE}" > "${TEMP_FILE}"
36
+
37
+ # Remove trailing blank lines (collapse to single trailing newline)
38
+ # This prevents empty trailers after stripping
39
+ sed -e :a -e '/^\n*$/{$d;N;ba' -e '}' "${TEMP_FILE}" > "${COMMIT_MSG_FILE}"
40
+
41
+ exit 0
@@ -0,0 +1,100 @@
1
+ # Hooks
2
+
3
+ Hooks are the event-driven spine of Gaia. Every significant moment in a Claude Code session — a prompt arriving, a tool being called, an agent completing — has a corresponding hook file in this directory. The hooks are not optional middleware; they are the security gate, the context injector, the audit system, and the memory writer. Remove them, and Gaia becomes a collection of agent definitions with no enforcement.
4
+
5
+ Each hook is a Python script that reads a JSON event from stdin, processes it, and writes a JSON response to stdout. Claude Code calls these scripts synchronously before or after each tool execution, which means the hook can allow, modify, or block the operation. The hook cannot do complex async work — it runs inline, in the critical path, so every module it calls must complete quickly.
6
+
7
+ The hooks form a pipeline. A prompt enters at `user_prompt_submit.py`, gets routed to an agent, triggers `pre_tool_use.py` before each tool call, generates audit records in `post_tool_use.py`, and closes out in `subagent_stop.py` when the agent finishes. The event handler hooks (`session_start.py`, `stop_hook.py`, `subagent_start.py`, `task_completed.py`) fire at lifecycle transitions and carry lighter responsibilities.
8
+
9
+ ## Cuándo se activa
10
+
11
+ ```
12
+ User sends prompt
13
+ |
14
+ [user_prompt_submit.py] <- fires on UserPromptSubmit event
15
+ | Builds orchestrator identity via ops_identity.py
16
+ | Injects surface routing recommendation (deterministic, from surface-routing.json)
17
+ | Skills loaded on-demand: agent-response
18
+ v
19
+ Orchestrator dispatches agent (Task/Agent tool call)
20
+ |
21
+ [pre_tool_use.py] <- fires on PreToolUse for: Bash, Task, Agent, SendMessage, Write, Edit
22
+ | Bash calls: security gate (blocked_commands, mutative_verbs, cloud_pipe_validator)
23
+ | Task/Agent calls: context injection from context-contracts.json
24
+ | Write/Edit calls: protected path validation (_is_protected())
25
+ v
26
+ ALLOWED / BLOCKED / ask dialog (T3)
27
+ |
28
+ Tool executes
29
+ |
30
+ [post_tool_use.py] <- fires on PostToolUse for: Bash, AskUserQuestion
31
+ | Audits result, logs to .claude/logs/
32
+ v
33
+ [subagent_stop.py] <- fires on SubagentStop for all agents
34
+ | Validates json:contract format
35
+ | Records workflow metrics
36
+ | Writes to episodic memory
37
+ v
38
+ [subagent_start.py] <- fires on SubagentStart for all agents
39
+ | Can inject additional context (e.g. persisted memory output)
40
+ ```
41
+
42
+ ## Entry point -> adapter -> module
43
+
44
+ Every hook entry point is thin by design. The entry point reads stdin, calls the adapter, and writes stdout. All logic lives in the adapter and module layers.
45
+
46
+ ```
47
+ hooks/pre_tool_use.py <- Entry point: stdin/stdout glue only
48
+ -> adapters/claude_code.py <- Adapter: parses event, dispatches to modules
49
+ -> modules/security/ <- blocked_commands, mutative_verbs, cloud_pipe_validator
50
+ -> modules/context/ <- context_injector, contracts_loader
51
+ -> modules/agents/ <- contract_validator, skill_injection
52
+ -> modules/validation/ <- commit_validator
53
+ -> modules/audit/ <- logger, metrics
54
+ ```
55
+
56
+ To add a new behavior to an existing hook: write a module in `modules/<package>/`, import it in the adapter, and call it from the relevant adapter method. Modules receive parsed context as arguments and return results. They never read stdin or write stdout directly.
57
+
58
+ To add a new hook entry point: create `hooks/<event_name>.py`, register it in `build/gaia-ops.manifest.json` under `hooks.entries` and `hooks.matchers`, then write the adapter method. The entry point pattern is always the same: read stdin JSON, call adapter, print response.
59
+
60
+ ## Qué hay aquí
61
+
62
+ ```
63
+ hooks/
64
+ ├── user_prompt_submit.py # Identity injection (UserPromptSubmit event)
65
+ ├── pre_tool_use.py # Security gate + context injection (PreToolUse)
66
+ ├── post_tool_use.py # Audit logging (PostToolUse)
67
+ ├── subagent_stop.py # Contract validation + memory (SubagentStop)
68
+ ├── subagent_start.py # Subagent start — additional context injection
69
+ ├── session_start.py # Session start event handler
70
+ ├── stop_hook.py # Stop event handler
71
+ ├── task_completed.py # Task completed event handler
72
+ ├── pre_compact.py # Pre-compaction event handler
73
+ ├── post_compact.py # Post-compaction event handler
74
+ ├── hooks.json # Plugin-channel hook configuration
75
+ ├── adapters/ # Adapter layer — event parsing and module dispatch
76
+ └── modules/ # Module layer — security, context, validation, audit logic
77
+ ```
78
+
79
+ ## Convenciones
80
+
81
+ **Security tiers enforced by pre_tool_use:**
82
+
83
+ | Tier | Operation Type | Approval | Hook action |
84
+ |------|----------------|----------|-------------|
85
+ | T0 | Read-only (get, list) | No | Allow immediately |
86
+ | T1 | Local validation (validate, lint) | No | Allow immediately |
87
+ | T2 | Simulation (plan, diff) | No | Allow immediately |
88
+ | T3 | Execution (apply, delete) | Yes — native `ask` dialog | Pause, request approval |
89
+ | T3-blocked | Irreversible (delete-vpc, drop db) | Permanently blocked | Exit 2 (hard block) |
90
+
91
+ **Protected paths** (blocked regardless of permissionMode):
92
+ - `.claude/hooks/` — hooks cannot be modified by any agent
93
+ - `.claude/settings.json` and `.claude/settings.local.json` — settings cannot be modified by any agent
94
+
95
+ ## Ver también
96
+
97
+ - [`build/gaia-ops.manifest.json`](../build/gaia-ops.manifest.json) — hook registration and matchers
98
+ - [`config/surface-routing.json`](../config/surface-routing.json) — read by `user_prompt_submit.py`
99
+ - [`config/context-contracts.json`](../config/context-contracts.json) — read by `pre_tool_use.py` for context injection
100
+ - [`skills/security-tiers/SKILL.md`](../skills/security-tiers/SKILL.md) — tier classification that agents use; hook enforces the same tiers
@@ -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
+ ]