@jaguilar87/gaia-ops 4.4.0 → 4.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (371) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +12 -3
  3. package/ARCHITECTURE.md +9 -8
  4. package/CHANGELOG.md +34 -0
  5. package/README.md +43 -11
  6. package/agents/terraform-architect.md +1 -1
  7. package/bin/README.md +2 -2
  8. package/bin/gaia-doctor.js +18 -5
  9. package/bin/gaia-history.js +0 -1
  10. package/bin/gaia-metrics.js +2 -2
  11. package/bin/gaia-scan.py +23 -1
  12. package/bin/gaia-update.js +346 -54
  13. package/bin/pre-publish-validate.js +33 -10
  14. package/commands/gaia.md +37 -0
  15. package/config/README.md +3 -9
  16. package/config/context-contracts.json +47 -15
  17. package/config/surface-routing.json +9 -1
  18. package/dist/gaia-ops/.claude-plugin/plugin.json +22 -0
  19. package/dist/gaia-ops/agents/cloud-troubleshooter.md +73 -0
  20. package/dist/gaia-ops/agents/devops-developer.md +57 -0
  21. package/dist/gaia-ops/agents/gaia-system.md +58 -0
  22. package/dist/gaia-ops/agents/gitops-operator.md +60 -0
  23. package/dist/gaia-ops/agents/speckit-planner.md +71 -0
  24. package/dist/gaia-ops/agents/terraform-architect.md +60 -0
  25. package/dist/gaia-ops/commands/gaia.md +37 -0
  26. package/dist/gaia-ops/config/README.md +58 -0
  27. package/dist/gaia-ops/config/cloud/aws.json +140 -0
  28. package/dist/gaia-ops/config/cloud/gcp.json +145 -0
  29. package/dist/gaia-ops/config/context-contracts.json +131 -0
  30. package/dist/gaia-ops/config/git_standards.json +72 -0
  31. package/dist/gaia-ops/config/surface-routing.json +197 -0
  32. package/dist/gaia-ops/config/universal-rules.json +10 -0
  33. package/dist/gaia-ops/hooks/adapters/__init__.py +52 -0
  34. package/dist/gaia-ops/hooks/adapters/base.py +219 -0
  35. package/dist/gaia-ops/hooks/adapters/channel.py +17 -0
  36. package/dist/gaia-ops/hooks/adapters/claude_code.py +1477 -0
  37. package/dist/gaia-ops/hooks/adapters/types.py +194 -0
  38. package/dist/gaia-ops/hooks/adapters/utils.py +25 -0
  39. package/dist/gaia-ops/hooks/hooks.json +126 -0
  40. package/dist/gaia-ops/hooks/modules/__init__.py +15 -0
  41. package/dist/gaia-ops/hooks/modules/agents/__init__.py +29 -0
  42. package/dist/gaia-ops/hooks/modules/agents/contract_validator.py +647 -0
  43. package/dist/gaia-ops/hooks/modules/agents/response_contract.py +496 -0
  44. package/dist/gaia-ops/hooks/modules/agents/skill_injection_verifier.py +124 -0
  45. package/dist/gaia-ops/hooks/modules/agents/task_info_builder.py +74 -0
  46. package/dist/gaia-ops/hooks/modules/agents/transcript_analyzer.py +458 -0
  47. package/dist/gaia-ops/hooks/modules/agents/transcript_reader.py +152 -0
  48. package/dist/gaia-ops/hooks/modules/audit/__init__.py +28 -0
  49. package/dist/gaia-ops/hooks/modules/audit/event_detector.py +168 -0
  50. package/dist/gaia-ops/hooks/modules/audit/logger.py +131 -0
  51. package/dist/gaia-ops/hooks/modules/audit/metrics.py +134 -0
  52. package/dist/gaia-ops/hooks/modules/audit/workflow_auditor.py +576 -0
  53. package/dist/gaia-ops/hooks/modules/audit/workflow_recorder.py +296 -0
  54. package/dist/gaia-ops/hooks/modules/context/__init__.py +11 -0
  55. package/dist/gaia-ops/hooks/modules/context/anchor_tracker.py +317 -0
  56. package/dist/gaia-ops/hooks/modules/context/compact_context_builder.py +215 -0
  57. package/dist/gaia-ops/hooks/modules/context/context_cache.py +129 -0
  58. package/dist/gaia-ops/hooks/modules/context/context_freshness.py +145 -0
  59. package/dist/gaia-ops/hooks/modules/context/context_injector.py +427 -0
  60. package/dist/gaia-ops/hooks/modules/context/context_writer.py +518 -0
  61. package/dist/gaia-ops/hooks/modules/context/contracts_loader.py +161 -0
  62. package/dist/gaia-ops/hooks/modules/core/__init__.py +40 -0
  63. package/dist/gaia-ops/hooks/modules/core/hook_entry.py +78 -0
  64. package/dist/gaia-ops/hooks/modules/core/paths.py +160 -0
  65. package/dist/gaia-ops/hooks/modules/core/plugin_mode.py +149 -0
  66. package/dist/gaia-ops/hooks/modules/core/plugin_setup.py +558 -0
  67. package/dist/gaia-ops/hooks/modules/core/state.py +179 -0
  68. package/dist/gaia-ops/hooks/modules/core/stdin.py +24 -0
  69. package/dist/gaia-ops/hooks/modules/events/__init__.py +1 -0
  70. package/dist/gaia-ops/hooks/modules/events/event_writer.py +210 -0
  71. package/dist/gaia-ops/hooks/modules/identity/__init__.py +0 -0
  72. package/dist/gaia-ops/hooks/modules/identity/identity_provider.py +21 -0
  73. package/dist/gaia-ops/hooks/modules/identity/ops_identity.py +34 -0
  74. package/dist/gaia-ops/hooks/modules/identity/security_identity.py +10 -0
  75. package/dist/gaia-ops/hooks/modules/memory/__init__.py +8 -0
  76. package/dist/gaia-ops/hooks/modules/memory/episode_writer.py +227 -0
  77. package/dist/gaia-ops/hooks/modules/orchestrator/__init__.py +1 -0
  78. package/dist/gaia-ops/hooks/modules/orchestrator/delegate_mode.py +128 -0
  79. package/dist/gaia-ops/hooks/modules/scanning/__init__.py +8 -0
  80. package/dist/gaia-ops/hooks/modules/scanning/scan_trigger.py +84 -0
  81. package/dist/gaia-ops/hooks/modules/security/__init__.py +89 -0
  82. package/dist/gaia-ops/hooks/modules/security/approval_cleanup.py +87 -0
  83. package/dist/gaia-ops/hooks/modules/security/approval_constants.py +23 -0
  84. package/dist/gaia-ops/hooks/modules/security/approval_grants.py +912 -0
  85. package/dist/gaia-ops/hooks/modules/security/approval_messages.py +71 -0
  86. package/dist/gaia-ops/hooks/modules/security/approval_scopes.py +153 -0
  87. package/dist/gaia-ops/hooks/modules/security/blocked_commands.py +584 -0
  88. package/dist/gaia-ops/hooks/modules/security/blocked_message_formatter.py +86 -0
  89. package/dist/gaia-ops/hooks/modules/security/command_semantics.py +130 -0
  90. package/dist/gaia-ops/hooks/modules/security/gitops_validator.py +179 -0
  91. package/dist/gaia-ops/hooks/modules/security/mutative_verbs.py +850 -0
  92. package/dist/gaia-ops/hooks/modules/security/prompt_validator.py +40 -0
  93. package/dist/gaia-ops/hooks/modules/security/tiers.py +196 -0
  94. package/dist/gaia-ops/hooks/modules/session/__init__.py +10 -0
  95. package/dist/gaia-ops/hooks/modules/session/session_context_writer.py +100 -0
  96. package/dist/gaia-ops/hooks/modules/session/session_event_injector.py +158 -0
  97. package/dist/gaia-ops/hooks/modules/session/session_manager.py +31 -0
  98. package/dist/gaia-ops/hooks/modules/tools/__init__.py +25 -0
  99. package/dist/gaia-ops/hooks/modules/tools/bash_validator.py +708 -0
  100. package/dist/gaia-ops/hooks/modules/tools/cloud_pipe_validator.py +181 -0
  101. package/dist/gaia-ops/hooks/modules/tools/hook_response.py +55 -0
  102. package/dist/gaia-ops/hooks/modules/tools/shell_parser.py +227 -0
  103. package/dist/gaia-ops/hooks/modules/tools/task_validator.py +283 -0
  104. package/dist/gaia-ops/hooks/modules/validation/__init__.py +23 -0
  105. package/dist/gaia-ops/hooks/modules/validation/commit_validator.py +380 -0
  106. package/dist/gaia-ops/hooks/post_compact.py +43 -0
  107. package/dist/gaia-ops/hooks/post_tool_use.py +54 -0
  108. package/dist/gaia-ops/hooks/pre_tool_use.py +383 -0
  109. package/dist/gaia-ops/hooks/session_start.py +69 -0
  110. package/dist/gaia-ops/hooks/stop_hook.py +69 -0
  111. package/dist/gaia-ops/hooks/subagent_start.py +71 -0
  112. package/dist/gaia-ops/hooks/subagent_stop.py +288 -0
  113. package/dist/gaia-ops/hooks/task_completed.py +70 -0
  114. package/dist/gaia-ops/hooks/user_prompt_submit.py +177 -0
  115. package/dist/gaia-ops/settings.json +72 -0
  116. package/dist/gaia-ops/skills/README.md +109 -0
  117. package/dist/gaia-ops/skills/agent-protocol/SKILL.md +105 -0
  118. package/dist/gaia-ops/skills/agent-protocol/examples.md +170 -0
  119. package/dist/gaia-ops/skills/agent-response/SKILL.md +53 -0
  120. package/dist/gaia-ops/skills/approval/SKILL.md +85 -0
  121. package/dist/gaia-ops/skills/approval/examples.md +140 -0
  122. package/dist/gaia-ops/skills/approval/reference.md +57 -0
  123. package/dist/gaia-ops/skills/command-execution/SKILL.md +64 -0
  124. package/dist/gaia-ops/skills/command-execution/reference.md +83 -0
  125. package/dist/gaia-ops/skills/context-updater/SKILL.md +76 -0
  126. package/dist/gaia-ops/skills/context-updater/examples.md +71 -0
  127. package/dist/gaia-ops/skills/developer-patterns/SKILL.md +93 -0
  128. package/dist/gaia-ops/skills/developer-patterns/reference.md +112 -0
  129. package/dist/gaia-ops/skills/execution/SKILL.md +66 -0
  130. package/dist/gaia-ops/skills/fast-queries/SKILL.md +47 -0
  131. package/dist/gaia-ops/skills/gaia-patterns/SKILL.md +92 -0
  132. package/dist/gaia-ops/skills/gaia-patterns/reference.md +22 -0
  133. package/dist/gaia-ops/skills/git-conventions/SKILL.md +48 -0
  134. package/dist/gaia-ops/skills/gitops-patterns/SKILL.md +73 -0
  135. package/dist/gaia-ops/skills/gitops-patterns/reference.md +183 -0
  136. package/dist/gaia-ops/skills/investigation/SKILL.md +77 -0
  137. package/dist/gaia-ops/skills/orchestrator-approval/SKILL.md +64 -0
  138. package/dist/gaia-ops/skills/reference.md +134 -0
  139. package/dist/gaia-ops/skills/security-tiers/SKILL.md +61 -0
  140. package/dist/gaia-ops/skills/security-tiers/destructive-commands-reference.md +623 -0
  141. package/dist/gaia-ops/skills/security-tiers/reference.md +39 -0
  142. package/dist/gaia-ops/skills/skill-creation/SKILL.md +119 -0
  143. package/dist/gaia-ops/skills/specification/SKILL.md +186 -0
  144. package/dist/gaia-ops/skills/speckit-workflow/SKILL.md +165 -0
  145. package/dist/gaia-ops/skills/speckit-workflow/reference.md +117 -0
  146. package/dist/gaia-ops/skills/terraform-patterns/SKILL.md +63 -0
  147. package/dist/gaia-ops/skills/terraform-patterns/reference.md +93 -0
  148. package/dist/gaia-ops/speckit/README.md +516 -0
  149. package/dist/gaia-ops/speckit/scripts/.gitkeep +0 -0
  150. package/dist/gaia-ops/speckit/templates/adr-template.md +118 -0
  151. package/dist/gaia-ops/speckit/templates/agent-file-template.md +23 -0
  152. package/dist/gaia-ops/speckit/templates/plan-template.md +227 -0
  153. package/dist/gaia-ops/speckit/templates/spec-template.md +140 -0
  154. package/dist/gaia-ops/speckit/templates/tasks-template.md +257 -0
  155. package/dist/gaia-ops/tools/context/README.md +132 -0
  156. package/dist/gaia-ops/tools/context/__init__.py +42 -0
  157. package/dist/gaia-ops/tools/context/_paths.py +20 -0
  158. package/dist/gaia-ops/tools/context/context_provider.py +476 -0
  159. package/dist/gaia-ops/tools/context/context_section_reader.py +330 -0
  160. package/dist/gaia-ops/tools/context/deep_merge.py +159 -0
  161. package/dist/gaia-ops/tools/context/pending_updates.py +760 -0
  162. package/dist/gaia-ops/tools/context/surface_router.py +278 -0
  163. package/dist/gaia-ops/tools/fast-queries/README.md +65 -0
  164. package/dist/gaia-ops/tools/fast-queries/__init__.py +30 -0
  165. package/dist/gaia-ops/tools/fast-queries/appservices/quicktriage_devops_developer.sh +75 -0
  166. package/dist/gaia-ops/tools/fast-queries/cloud/aws/quicktriage_aws_troubleshooter.sh +32 -0
  167. package/dist/gaia-ops/tools/fast-queries/cloud/gcp/quicktriage_gcp_troubleshooter.sh +88 -0
  168. package/dist/gaia-ops/tools/fast-queries/gitops/quicktriage_gitops_operator.sh +48 -0
  169. package/dist/gaia-ops/tools/fast-queries/run_triage.sh +59 -0
  170. package/dist/gaia-ops/tools/fast-queries/terraform/quicktriage_terraform_architect.sh +80 -0
  171. package/dist/gaia-ops/tools/gaia_simulator/__init__.py +33 -0
  172. package/dist/gaia-ops/tools/gaia_simulator/cli.py +354 -0
  173. package/dist/gaia-ops/tools/gaia_simulator/extractor.py +457 -0
  174. package/dist/gaia-ops/tools/gaia_simulator/reporter.py +258 -0
  175. package/dist/gaia-ops/tools/gaia_simulator/routing_simulator.py +334 -0
  176. package/dist/gaia-ops/tools/gaia_simulator/runner.py +539 -0
  177. package/dist/gaia-ops/tools/gaia_simulator/skills_mapper.py +262 -0
  178. package/dist/gaia-ops/tools/memory/README.md +0 -0
  179. package/dist/gaia-ops/tools/memory/__init__.py +20 -0
  180. package/dist/gaia-ops/tools/memory/episodic.py +1196 -0
  181. package/dist/gaia-ops/tools/persist_transcript_analysis.py +85 -0
  182. package/dist/gaia-ops/tools/review/__init__.py +1 -0
  183. package/dist/gaia-ops/tools/review/review_engine.py +157 -0
  184. package/dist/gaia-ops/tools/scan/__init__.py +35 -0
  185. package/dist/gaia-ops/tools/scan/config.py +247 -0
  186. package/dist/gaia-ops/tools/scan/merge.py +212 -0
  187. package/dist/gaia-ops/tools/scan/orchestrator.py +549 -0
  188. package/dist/gaia-ops/tools/scan/registry.py +127 -0
  189. package/dist/gaia-ops/tools/scan/scanners/__init__.py +18 -0
  190. package/dist/gaia-ops/tools/scan/scanners/base.py +137 -0
  191. package/dist/gaia-ops/tools/scan/scanners/environment.py +324 -0
  192. package/dist/gaia-ops/tools/scan/scanners/git.py +570 -0
  193. package/dist/gaia-ops/tools/scan/scanners/infrastructure.py +875 -0
  194. package/dist/gaia-ops/tools/scan/scanners/orchestration.py +600 -0
  195. package/dist/gaia-ops/tools/scan/scanners/stack.py +1085 -0
  196. package/dist/gaia-ops/tools/scan/scanners/tools.py +260 -0
  197. package/dist/gaia-ops/tools/scan/setup.py +753 -0
  198. package/dist/gaia-ops/tools/scan/tests/__init__.py +1 -0
  199. package/dist/gaia-ops/tools/scan/tests/conftest.py +796 -0
  200. package/dist/gaia-ops/tools/scan/tests/test_environment.py +323 -0
  201. package/dist/gaia-ops/tools/scan/tests/test_git.py +419 -0
  202. package/dist/gaia-ops/tools/scan/tests/test_infrastructure.py +382 -0
  203. package/dist/gaia-ops/tools/scan/tests/test_integration.py +920 -0
  204. package/dist/gaia-ops/tools/scan/tests/test_merge.py +269 -0
  205. package/dist/gaia-ops/tools/scan/tests/test_orchestration.py +304 -0
  206. package/dist/gaia-ops/tools/scan/tests/test_stack.py +604 -0
  207. package/dist/gaia-ops/tools/scan/tests/test_tools.py +349 -0
  208. package/dist/gaia-ops/tools/scan/ui.py +624 -0
  209. package/dist/gaia-ops/tools/scan/verify.py +266 -0
  210. package/dist/gaia-ops/tools/scan/walk.py +118 -0
  211. package/dist/gaia-ops/tools/scan/workspace.py +85 -0
  212. package/dist/gaia-ops/tools/validation/README.md +244 -0
  213. package/dist/gaia-ops/tools/validation/__init__.py +17 -0
  214. package/dist/gaia-ops/tools/validation/approval_gate.py +321 -0
  215. package/dist/gaia-ops/tools/validation/validate_skills.py +189 -0
  216. package/dist/gaia-security/.claude-plugin/plugin.json +22 -0
  217. package/dist/gaia-security/config/universal-rules.json +10 -0
  218. package/dist/gaia-security/hooks/adapters/__init__.py +52 -0
  219. package/dist/gaia-security/hooks/adapters/base.py +219 -0
  220. package/dist/gaia-security/hooks/adapters/channel.py +17 -0
  221. package/dist/gaia-security/hooks/adapters/claude_code.py +1477 -0
  222. package/dist/gaia-security/hooks/adapters/types.py +194 -0
  223. package/dist/gaia-security/hooks/adapters/utils.py +25 -0
  224. package/dist/gaia-security/hooks/hooks.json +57 -0
  225. package/dist/gaia-security/hooks/modules/__init__.py +15 -0
  226. package/dist/gaia-security/hooks/modules/agents/__init__.py +29 -0
  227. package/dist/gaia-security/hooks/modules/agents/contract_validator.py +647 -0
  228. package/dist/gaia-security/hooks/modules/agents/response_contract.py +496 -0
  229. package/dist/gaia-security/hooks/modules/agents/skill_injection_verifier.py +124 -0
  230. package/dist/gaia-security/hooks/modules/agents/task_info_builder.py +74 -0
  231. package/dist/gaia-security/hooks/modules/agents/transcript_analyzer.py +458 -0
  232. package/dist/gaia-security/hooks/modules/agents/transcript_reader.py +152 -0
  233. package/dist/gaia-security/hooks/modules/audit/__init__.py +28 -0
  234. package/dist/gaia-security/hooks/modules/audit/event_detector.py +168 -0
  235. package/dist/gaia-security/hooks/modules/audit/logger.py +131 -0
  236. package/dist/gaia-security/hooks/modules/audit/metrics.py +134 -0
  237. package/dist/gaia-security/hooks/modules/audit/workflow_auditor.py +576 -0
  238. package/dist/gaia-security/hooks/modules/audit/workflow_recorder.py +296 -0
  239. package/dist/gaia-security/hooks/modules/context/__init__.py +11 -0
  240. package/dist/gaia-security/hooks/modules/context/anchor_tracker.py +317 -0
  241. package/dist/gaia-security/hooks/modules/context/compact_context_builder.py +215 -0
  242. package/dist/gaia-security/hooks/modules/context/context_cache.py +129 -0
  243. package/dist/gaia-security/hooks/modules/context/context_freshness.py +145 -0
  244. package/dist/gaia-security/hooks/modules/context/context_injector.py +427 -0
  245. package/dist/gaia-security/hooks/modules/context/context_writer.py +518 -0
  246. package/dist/gaia-security/hooks/modules/context/contracts_loader.py +161 -0
  247. package/dist/gaia-security/hooks/modules/core/__init__.py +40 -0
  248. package/dist/gaia-security/hooks/modules/core/hook_entry.py +78 -0
  249. package/dist/gaia-security/hooks/modules/core/paths.py +160 -0
  250. package/dist/gaia-security/hooks/modules/core/plugin_mode.py +149 -0
  251. package/dist/gaia-security/hooks/modules/core/plugin_setup.py +558 -0
  252. package/dist/gaia-security/hooks/modules/core/state.py +179 -0
  253. package/dist/gaia-security/hooks/modules/core/stdin.py +24 -0
  254. package/dist/gaia-security/hooks/modules/events/__init__.py +1 -0
  255. package/dist/gaia-security/hooks/modules/events/event_writer.py +210 -0
  256. package/dist/gaia-security/hooks/modules/identity/__init__.py +0 -0
  257. package/dist/gaia-security/hooks/modules/identity/identity_provider.py +21 -0
  258. package/dist/gaia-security/hooks/modules/identity/ops_identity.py +34 -0
  259. package/dist/gaia-security/hooks/modules/identity/security_identity.py +10 -0
  260. package/dist/gaia-security/hooks/modules/memory/__init__.py +8 -0
  261. package/dist/gaia-security/hooks/modules/memory/episode_writer.py +227 -0
  262. package/dist/gaia-security/hooks/modules/orchestrator/__init__.py +1 -0
  263. package/dist/gaia-security/hooks/modules/orchestrator/delegate_mode.py +128 -0
  264. package/dist/gaia-security/hooks/modules/scanning/__init__.py +8 -0
  265. package/dist/gaia-security/hooks/modules/scanning/scan_trigger.py +84 -0
  266. package/dist/gaia-security/hooks/modules/security/__init__.py +89 -0
  267. package/dist/gaia-security/hooks/modules/security/approval_cleanup.py +87 -0
  268. package/dist/gaia-security/hooks/modules/security/approval_constants.py +23 -0
  269. package/dist/gaia-security/hooks/modules/security/approval_grants.py +912 -0
  270. package/dist/gaia-security/hooks/modules/security/approval_messages.py +71 -0
  271. package/dist/gaia-security/hooks/modules/security/approval_scopes.py +153 -0
  272. package/dist/gaia-security/hooks/modules/security/blocked_commands.py +584 -0
  273. package/dist/gaia-security/hooks/modules/security/blocked_message_formatter.py +86 -0
  274. package/dist/gaia-security/hooks/modules/security/command_semantics.py +130 -0
  275. package/dist/gaia-security/hooks/modules/security/gitops_validator.py +179 -0
  276. package/dist/gaia-security/hooks/modules/security/mutative_verbs.py +850 -0
  277. package/dist/gaia-security/hooks/modules/security/prompt_validator.py +40 -0
  278. package/dist/gaia-security/hooks/modules/security/tiers.py +196 -0
  279. package/dist/gaia-security/hooks/modules/session/__init__.py +10 -0
  280. package/dist/gaia-security/hooks/modules/session/session_context_writer.py +100 -0
  281. package/dist/gaia-security/hooks/modules/session/session_event_injector.py +158 -0
  282. package/dist/gaia-security/hooks/modules/session/session_manager.py +31 -0
  283. package/dist/gaia-security/hooks/modules/tools/__init__.py +25 -0
  284. package/dist/gaia-security/hooks/modules/tools/bash_validator.py +708 -0
  285. package/dist/gaia-security/hooks/modules/tools/cloud_pipe_validator.py +181 -0
  286. package/dist/gaia-security/hooks/modules/tools/hook_response.py +55 -0
  287. package/dist/gaia-security/hooks/modules/tools/shell_parser.py +227 -0
  288. package/dist/gaia-security/hooks/modules/tools/task_validator.py +283 -0
  289. package/dist/gaia-security/hooks/modules/validation/__init__.py +23 -0
  290. package/dist/gaia-security/hooks/modules/validation/commit_validator.py +380 -0
  291. package/dist/gaia-security/hooks/post_tool_use.py +54 -0
  292. package/dist/gaia-security/hooks/pre_tool_use.py +383 -0
  293. package/dist/gaia-security/hooks/session_start.py +69 -0
  294. package/dist/gaia-security/hooks/stop_hook.py +69 -0
  295. package/dist/gaia-security/hooks/user_prompt_submit.py +177 -0
  296. package/dist/gaia-security/settings.json +58 -0
  297. package/git-hooks/commit-msg +41 -0
  298. package/hooks/README.md +8 -6
  299. package/hooks/adapters/channel.py +0 -25
  300. package/hooks/adapters/claude_code.py +364 -125
  301. package/hooks/elicitation_result.py +132 -0
  302. package/hooks/hooks.json +10 -1
  303. package/hooks/modules/README.md +3 -2
  304. package/hooks/modules/agents/contract_validator.py +3 -51
  305. package/hooks/modules/agents/response_contract.py +4 -8
  306. package/hooks/modules/agents/transcript_reader.py +4 -5
  307. package/hooks/modules/audit/__init__.py +4 -6
  308. package/hooks/modules/audit/event_detector.py +0 -2
  309. package/hooks/modules/audit/metrics.py +108 -187
  310. package/hooks/modules/audit/workflow_auditor.py +0 -4
  311. package/hooks/modules/audit/workflow_recorder.py +0 -5
  312. package/hooks/modules/context/compact_context_builder.py +1 -0
  313. package/hooks/modules/context/context_cache.py +129 -0
  314. package/hooks/modules/context/context_injector.py +18 -40
  315. package/hooks/modules/context/context_writer.py +1 -25
  316. package/hooks/modules/context/contracts_loader.py +7 -10
  317. package/hooks/modules/core/hook_entry.py +1 -0
  318. package/hooks/modules/core/paths.py +12 -13
  319. package/hooks/modules/core/plugin_mode.py +74 -4
  320. package/hooks/modules/core/plugin_setup.py +395 -23
  321. package/hooks/modules/events/__init__.py +1 -0
  322. package/hooks/modules/events/event_writer.py +210 -0
  323. package/hooks/modules/identity/ops_identity.py +18 -27
  324. package/hooks/modules/memory/episode_writer.py +1 -6
  325. package/hooks/modules/orchestrator/__init__.py +1 -0
  326. package/hooks/modules/orchestrator/delegate_mode.py +128 -0
  327. package/hooks/modules/security/__init__.py +2 -4
  328. package/hooks/modules/security/approval_constants.py +5 -1
  329. package/hooks/modules/security/approval_grants.py +189 -6
  330. package/hooks/modules/security/approval_messages.py +9 -21
  331. package/hooks/modules/security/blocked_commands.py +98 -34
  332. package/hooks/modules/security/command_semantics.py +0 -4
  333. package/hooks/modules/security/gitops_validator.py +1 -11
  334. package/hooks/modules/security/mutative_verbs.py +179 -38
  335. package/hooks/modules/security/tiers.py +1 -19
  336. package/hooks/modules/session/session_event_injector.py +1 -25
  337. package/hooks/modules/tools/bash_validator.py +310 -94
  338. package/hooks/modules/tools/shell_parser.py +0 -1
  339. package/hooks/modules/tools/task_validator.py +9 -29
  340. package/hooks/post_tool_use.py +0 -72
  341. package/hooks/pre_tool_use.py +42 -102
  342. package/hooks/session_start.py +4 -2
  343. package/hooks/subagent_start.py +6 -2
  344. package/hooks/subagent_stop.py +1 -13
  345. package/hooks/user_prompt_submit.py +119 -37
  346. package/index.js +1 -1
  347. package/package.json +5 -3
  348. package/skills/README.md +3 -5
  349. package/skills/agent-protocol/SKILL.md +17 -16
  350. package/skills/agent-protocol/examples.md +6 -6
  351. package/skills/agent-response/SKILL.md +11 -14
  352. package/skills/approval/SKILL.md +28 -13
  353. package/skills/approval/reference.md +2 -2
  354. package/skills/execution/SKILL.md +1 -1
  355. package/skills/gaia-patterns/SKILL.md +2 -3
  356. package/skills/orchestrator-approval/SKILL.md +22 -50
  357. package/skills/security-tiers/SKILL.md +1 -1
  358. package/templates/README.md +9 -9
  359. package/templates/managed-settings.template.json +43 -0
  360. package/tools/gaia_simulator/runner.py +34 -1
  361. package/tools/scan/orchestrator.py +13 -0
  362. package/tools/scan/scanners/base.py +8 -0
  363. package/tools/scan/scanners/git.py +78 -0
  364. package/tools/scan/scanners/infrastructure.py +65 -0
  365. package/tools/scan/scanners/stack.py +110 -0
  366. package/tools/scan/setup.py +120 -13
  367. package/tools/scan/workspace.py +85 -0
  368. package/config/context-contracts.aws.json +0 -42
  369. package/config/context-contracts.gcp.json +0 -39
  370. package/skills/project-dispatch/SKILL.md +0 -34
  371. package/templates/settings.template.json +0 -226
@@ -0,0 +1,40 @@
1
+ """Validate and classify resume prompts for security decision-making.
2
+
3
+ Subsystem 1 of the pre_tool_use Task/Agent path.
4
+ Runs FIRST -- if invalid, nothing else loads.
5
+
6
+ Responsibilities:
7
+ - Validates prompt is not empty, not malformed
8
+ - Detects deprecated approval phrases
9
+ - Detects nonce patterns
10
+ - Returns: classification (nonce/malformed_nonce/deprecated/standard)
11
+ """
12
+
13
+ from .approval_constants import (
14
+ NONCE_APPROVAL_PREFIX,
15
+ NONCE_APPROVAL_PATTERN,
16
+ DEPRECATED_APPROVAL_PHRASES,
17
+ )
18
+
19
+
20
+ def classify_resume_prompt(prompt: str) -> str:
21
+ """Classify a resume prompt into one of four categories.
22
+
23
+ Args:
24
+ prompt: The resume prompt string.
25
+
26
+ Returns:
27
+ 'nonce' -- valid nonce approval token present
28
+ 'malformed_nonce' -- APPROVE: prefix present but invalid nonce
29
+ 'deprecated' -- deprecated approval phrase detected
30
+ 'standard' -- normal resume prompt (no approval indicators)
31
+ """
32
+ stripped_prompt = prompt.strip()
33
+ if NONCE_APPROVAL_PATTERN.search(prompt):
34
+ return "nonce"
35
+ if stripped_prompt.startswith(NONCE_APPROVAL_PREFIX):
36
+ return "malformed_nonce"
37
+ prompt_lower = prompt.lower()
38
+ if any(phrase in prompt_lower for phrase in DEPRECATED_APPROVAL_PHRASES):
39
+ return "deprecated"
40
+ return "standard"
@@ -0,0 +1,196 @@
1
+ """
2
+ Security tier definitions and classification.
3
+
4
+ Provides tier metadata for commands after bash_validator has already
5
+ enforced security decisions. The bash_validator is the primary gate;
6
+ this module's classify_command_tier() is used for logging and state
7
+ tracking.
8
+
9
+ Tiers:
10
+ - T0: Read-only operations (safe by elimination)
11
+ - T1: Validation operations (validate, lint, fmt, check) -- local only
12
+ - T2: Simulation operations (plan, diff, dry-run) -- may contact remote APIs
13
+ - T3: State-modifying operations (mutative_verbs.py detection,
14
+ nonce-based approval via approval_grants.py)
15
+ """
16
+ from __future__ import annotations
17
+
18
+ import re
19
+ import logging
20
+ from enum import Enum
21
+ from functools import lru_cache
22
+
23
+ logger = logging.getLogger(__name__)
24
+
25
+
26
+ class SecurityTier(str, Enum):
27
+ """Security tier classification for commands."""
28
+
29
+ T0_READ_ONLY = "T0" # describe, get, show, list operations
30
+ T1_VALIDATION = "T1" # validate, lint, fmt, check (local only)
31
+ T2_DRY_RUN = "T2" # plan, diff, dry-run, template (simulation)
32
+ T3_BLOCKED = "T3" # apply, reconcile, deploy operations (require approval)
33
+
34
+ def __str__(self) -> str:
35
+ return self.value
36
+
37
+ @property
38
+ def requires_approval(self) -> bool:
39
+ """Check if this tier requires user approval."""
40
+ return self == SecurityTier.T3_BLOCKED
41
+
42
+ @property
43
+ def description(self) -> str:
44
+ """Human-readable description of the tier."""
45
+ descriptions = {
46
+ SecurityTier.T0_READ_ONLY: "Read-only operation",
47
+ SecurityTier.T1_VALIDATION: "Validation operation",
48
+ SecurityTier.T2_DRY_RUN: "Dry-run operation",
49
+ SecurityTier.T3_BLOCKED: "State-modifying operation (requires approval)",
50
+ }
51
+ return descriptions.get(self, "Unknown tier")
52
+
53
+
54
+ # T1: Local validation (no remote API calls)
55
+ T1_PATTERNS = [
56
+ r"\bvalidate\b",
57
+ r"\blint\b",
58
+ r"\bcheck\b",
59
+ r"\bfmt\b",
60
+ ]
61
+
62
+ # T2: Simulation (may contact remote APIs, but no state changes)
63
+ T2_PATTERNS = [
64
+ r"\bplan\b",
65
+ r"\btemplate\b",
66
+ r"\bdiff\b",
67
+ ]
68
+
69
+ # Ultra-common commands that should fast-path to T0
70
+ # These are commands that appear in >80% of sessions
71
+ # NOTE: Only include commands that are ALWAYS read-only regardless of flags.
72
+ # "git branch" was removed because it has mutative variants (-D, -m, -M, etc.).
73
+ ULTRA_COMMON_T0_COMMANDS = frozenset({
74
+ "ls", "pwd", "cat", "echo", "git status", "git diff",
75
+ "git log", "kubectl get",
76
+ })
77
+
78
+
79
+ @lru_cache(maxsize=512)
80
+ def _classify_command_tier_cached(
81
+ command: str,
82
+ has_blocked_patterns: bool = False,
83
+ ) -> SecurityTier:
84
+ """
85
+ Classify command into security tier with LRU cache.
86
+
87
+ This is the internal cached implementation. Use classify_command_tier() instead.
88
+ """
89
+ if not command or not command.strip():
90
+ return SecurityTier.T3_BLOCKED
91
+
92
+ command = command.strip()
93
+
94
+ # Fast-path: Ultra-common T0 commands
95
+ words = command.split()
96
+ if len(words) >= 2:
97
+ prefix2 = f"{words[0]} {words[1]}"
98
+ if prefix2 in ULTRA_COMMON_T0_COMMANDS:
99
+ return SecurityTier.T0_READ_ONLY
100
+ if len(words) >= 1:
101
+ if words[0] in ULTRA_COMMON_T0_COMMANDS:
102
+ return SecurityTier.T0_READ_ONLY
103
+
104
+ # Blocked patterns already checked externally
105
+ if has_blocked_patterns:
106
+ return SecurityTier.T3_BLOCKED
107
+
108
+ # Check for dry-run operations (T2)
109
+ if "--dry-run" in command or "--plan-only" in command:
110
+ return SecurityTier.T2_DRY_RUN
111
+
112
+ # Check for simulation operations (T2: plan, diff, template)
113
+ for pattern in T2_PATTERNS:
114
+ if re.search(pattern, command, re.IGNORECASE):
115
+ return SecurityTier.T2_DRY_RUN
116
+
117
+ # Check for local validation operations (T1: validate, lint, fmt, check)
118
+ for pattern in T1_PATTERNS:
119
+ if re.search(pattern, command, re.IGNORECASE):
120
+ return SecurityTier.T1_VALIDATION
121
+
122
+ # Use the mutative verb detector for T3 classification
123
+ from .mutative_verbs import (
124
+ detect_mutative_command,
125
+ CATEGORY_MUTATIVE,
126
+ CATEGORY_READ_ONLY,
127
+ CATEGORY_SIMULATION,
128
+ )
129
+ result = detect_mutative_command(command)
130
+ if result.is_mutative:
131
+ return SecurityTier.T3_BLOCKED
132
+ if result.category == CATEGORY_SIMULATION:
133
+ return SecurityTier.T2_DRY_RUN
134
+ if result.category == CATEGORY_READ_ONLY:
135
+ return SecurityTier.T0_READ_ONLY
136
+
137
+ # Not blocked, not mutative -> safe by elimination (T0)
138
+ return SecurityTier.T0_READ_ONLY
139
+
140
+
141
+ def classify_command_tier(
142
+ command: str,
143
+ *,
144
+ pre_computed_tier: "SecurityTier | None" = None,
145
+ ) -> SecurityTier:
146
+ """
147
+ Classify command into security tier.
148
+
149
+ NOTE: This function is used for tier metadata AFTER the bash_validator has
150
+ already enforced security decisions. The bash_validator's own validation
151
+ order (blocked -> safe -> dangerous verbs -> GitOps -> tier) is the primary
152
+ security gate.
153
+
154
+ If *pre_computed_tier* is provided (e.g. from a ``BashValidationResult``
155
+ that already determined the tier during validation), it is returned
156
+ immediately without re-computing.
157
+
158
+ Classification order (when no pre-computed tier):
159
+ 1. Ultra-common T0 fast-path (ls, git status, etc.)
160
+ 2. Blocked patterns (T3) -- checked against pre-compiled patterns
161
+ 3. Dry-run/simulation (T2) -- --dry-run, plan, diff, template
162
+ 4. Local validation (T1) -- validate, lint, fmt, check
163
+ 5. Mutative verb detector (T3) -- MUTATIVE verbs
164
+ 6. Default T0 for everything else (safe by elimination)
165
+
166
+ Args:
167
+ command: Shell command to classify
168
+ pre_computed_tier: Optional tier already determined by an upstream
169
+ validator. When provided the function returns it directly.
170
+
171
+ Returns:
172
+ SecurityTier classification
173
+ """
174
+ # Fast path: caller already knows the tier (e.g. BashValidationResult).
175
+ if pre_computed_tier is not None:
176
+ return pre_computed_tier
177
+
178
+ if not command or not command.strip():
179
+ return SecurityTier.T3_BLOCKED
180
+
181
+ command = command.strip()
182
+
183
+ # Import here to avoid circular imports
184
+ from .blocked_commands import get_blocked_patterns
185
+ blocked_patterns = get_blocked_patterns()
186
+
187
+ # Check for blocked operations first (T3)
188
+ # This must be done before caching since blocked_patterns come from module state
189
+ has_blocked = False
190
+ for pattern in blocked_patterns:
191
+ if pattern.search(command):
192
+ has_blocked = True
193
+ break
194
+
195
+ # Use cached classification
196
+ return _classify_command_tier_cached(command, has_blocked)
@@ -0,0 +1,10 @@
1
+ """Session management module.
2
+
3
+ Provides:
4
+ - session_manager: Session ID generation and management
5
+ - session_event_injector: Filter and inject session events into agent prompts
6
+
7
+ Note: session_state.py has been absorbed into modules.memory.episode_writer.
8
+ """
9
+
10
+ __all__ = []
@@ -0,0 +1,100 @@
1
+ """
2
+ Session context writer for PostToolUse hook.
3
+
4
+ Manages the active session context file, appending critical events
5
+ (git commits, pushes, etc.) and applying a time-based retention policy.
6
+
7
+ Public API:
8
+ - SessionContextWriter (class with update_context method)
9
+ """
10
+
11
+ import fcntl
12
+ import json
13
+ import logging
14
+ import os
15
+ from datetime import datetime, timedelta
16
+ from pathlib import Path
17
+ from typing import Dict, Any
18
+
19
+ from ..core.paths import get_session_dir
20
+
21
+ logger = logging.getLogger(__name__)
22
+
23
+ # Default retention period for session events
24
+ DEFAULT_RETENTION_HOURS = 24
25
+
26
+
27
+ class SessionContextWriter:
28
+ """Update active session context for critical events.
29
+
30
+ Thread-safe via file locking. Applies a configurable retention
31
+ policy (default 24h, override via SESSION_RETENTION_HOURS env var).
32
+ """
33
+
34
+ def __init__(self, context_path: Path = None):
35
+ """Initialize with optional custom context path.
36
+
37
+ Args:
38
+ context_path: Override path. Defaults to session_dir/context.json.
39
+ """
40
+ self.context_path = context_path or (get_session_dir() / "context.json")
41
+
42
+ def update_context(self, event_data: Dict[str, Any]) -> None:
43
+ """Update active context with event data.
44
+
45
+ Appends the event to the critical_events list, applies retention
46
+ policy, and writes back atomically with file locking.
47
+
48
+ Args:
49
+ event_data: Event dict (must include at least event_type).
50
+ """
51
+ try:
52
+ self.context_path.parent.mkdir(parents=True, exist_ok=True)
53
+
54
+ # File lock to prevent race conditions from parallel tool calls
55
+ lock_path = self.context_path.with_suffix(".lock")
56
+ with open(lock_path, "w") as lock_file:
57
+ fcntl.flock(lock_file.fileno(), fcntl.LOCK_EX)
58
+ try:
59
+ context: Dict[str, Any] = {}
60
+ if self.context_path.exists():
61
+ with open(self.context_path, "r") as f:
62
+ context = json.load(f)
63
+
64
+ if "critical_events" not in context:
65
+ context["critical_events"] = []
66
+
67
+ event_data["timestamp"] = datetime.now().isoformat()
68
+
69
+ context["critical_events"].append(event_data)
70
+
71
+ # Keep only events within retention window
72
+ retention_hours = int(
73
+ os.environ.get(
74
+ "SESSION_RETENTION_HOURS",
75
+ str(DEFAULT_RETENTION_HOURS),
76
+ )
77
+ )
78
+ cutoff = datetime.now() - timedelta(hours=retention_hours)
79
+
80
+ context["critical_events"] = [
81
+ event
82
+ for event in context["critical_events"]
83
+ if event.get("timestamp")
84
+ and datetime.fromisoformat(event["timestamp"]) > cutoff
85
+ ]
86
+
87
+ context["last_modified"] = datetime.now().isoformat()
88
+
89
+ with open(self.context_path, "w") as f:
90
+ json.dump(context, f, indent=2)
91
+ finally:
92
+ fcntl.flock(lock_file.fileno(), fcntl.LOCK_UN)
93
+
94
+ logger.info(
95
+ "Updated context with event: %s",
96
+ event_data.get("event_type", "unknown"),
97
+ )
98
+
99
+ except Exception as e:
100
+ logger.error("Error updating active context: %s", e)
@@ -0,0 +1,158 @@
1
+ """Session event injection for agent context.
2
+
3
+ Subsystem 4 of the pre_tool_use Task/Agent path.
4
+
5
+ Filters events by agent domain and injects them into agent prompts.
6
+ Includes the hardcoded agent-to-event mapping.
7
+ """
8
+ from __future__ import annotations
9
+
10
+ import json
11
+ import logging
12
+ from pathlib import Path
13
+
14
+ logger = logging.getLogger(__name__)
15
+
16
+ # Agent-to-event-type mapping: which events each agent should see
17
+ AGENT_EVENT_FILTERS = {
18
+ "terraform-architect": ["git_commit", "infrastructure_change"],
19
+ "gitops-operator": ["git_commit", "git_push", "infrastructure_change"],
20
+ "devops-developer": ["git_commit", "file_modifications"],
21
+ "cloud-troubleshooter": "*", # All events (needs full history for diagnosis)
22
+ "gaia-system": "*" # All events (workflow analysis)
23
+ }
24
+
25
+
26
+ def filter_events_for_agent(events: list, agent: str) -> list:
27
+ """
28
+ Filter events relevant to agent domain.
29
+
30
+ Args:
31
+ events: List of critical events from session
32
+ agent: Agent type (e.g., "gitops-operator")
33
+
34
+ Returns:
35
+ Filtered list of events relevant to agent
36
+ """
37
+ agent_filter = AGENT_EVENT_FILTERS.get(agent, [])
38
+
39
+ # Return all events for wildcard agents
40
+ if agent_filter == "*":
41
+ return events[-10:] # Last 10 events
42
+
43
+ # Filter by event type and return max 10
44
+ filtered = [
45
+ e for e in events[-20:] # Search last 20
46
+ if e.get("event_type") in agent_filter
47
+ ]
48
+
49
+ return filtered[:10] # Return max 10
50
+
51
+
52
+ def format_events_summary(events: list) -> str:
53
+ """
54
+ Format events as readable summary for agent context.
55
+
56
+ Args:
57
+ events: List of filtered events
58
+
59
+ Returns:
60
+ Formatted markdown string
61
+ """
62
+ if not events:
63
+ return "No recent events"
64
+
65
+ lines = []
66
+
67
+ for event in events:
68
+ etype = event.get("event_type", "")
69
+ ts = event.get("timestamp", "")[:16] # YYYY-MM-DDTHH:MM
70
+
71
+ if etype == "git_commit":
72
+ msg = event.get("commit_message", "")
73
+ hash_val = event.get("commit_hash", "")[:7]
74
+ if hash_val and msg:
75
+ lines.append(f"- [{ts}] Commit {hash_val}: {msg}")
76
+
77
+ elif etype == "git_push":
78
+ branch = event.get("branch", "")
79
+ if branch:
80
+ lines.append(f"- [{ts}] Pushed to {branch}")
81
+
82
+ elif etype == "file_modifications":
83
+ count = event.get("modification_count", 0)
84
+ if count:
85
+ lines.append(f"- [{ts}] Modified {count} files")
86
+
87
+ elif etype == "infrastructure_change":
88
+ cmd = event.get("command", "")
89
+ if cmd:
90
+ lines.append(f"- [{ts}] Infrastructure: {cmd}")
91
+
92
+ return "\n".join(lines) if lines else "No recent events"
93
+
94
+
95
+ def build_session_events(
96
+ parameters: dict,
97
+ project_agents: list,
98
+ ) -> str | None:
99
+ """
100
+ Build session events string for agent context without mutating parameters.
101
+
102
+ Filters events by agent domain to avoid noise.
103
+ Returns the events string suitable for additionalContext injection,
104
+ or None if no events to inject.
105
+
106
+ Args:
107
+ parameters: Task tool parameters (read-only).
108
+ project_agents: List of valid project agent names.
109
+
110
+ Returns:
111
+ Session events string, or None if nothing to inject.
112
+ """
113
+ subagent_type = parameters.get("subagent_type", "")
114
+
115
+ # Only inject for project agents
116
+ if subagent_type not in project_agents:
117
+ logger.debug(f"Skipping session events for non-project agent: {subagent_type}")
118
+ return None
119
+
120
+ # Get session events
121
+ from ..core.paths import get_session_dir
122
+ context_path = get_session_dir() / "context.json"
123
+ if not context_path.exists():
124
+ logger.debug("No session context file found")
125
+ return None
126
+
127
+ try:
128
+ with open(context_path, 'r') as f:
129
+ context = json.load(f)
130
+
131
+ events = context.get("critical_events", [])
132
+ if not events:
133
+ logger.debug("No critical events in session")
134
+ return None
135
+
136
+ # Filter by agent domain
137
+ filtered = filter_events_for_agent(events, subagent_type)
138
+
139
+ if not filtered:
140
+ logger.debug(f"No relevant events for {subagent_type}")
141
+ return None
142
+
143
+ # Format events summary
144
+ events_summary = format_events_summary(filtered)
145
+
146
+ events_string = (
147
+ "# Recent Session Events (Auto-Injected, Last 24h)\n"
148
+ f"{events_summary}"
149
+ )
150
+ logger.info(f"Session events built for {subagent_type} ({len(filtered)} events)")
151
+
152
+ return events_string
153
+
154
+ except Exception as e:
155
+ logger.warning(f"Failed to build session events: {e}")
156
+ return None
157
+
158
+
@@ -0,0 +1,31 @@
1
+ """
2
+ Session ID generation and retrieval.
3
+
4
+ Provides:
5
+ - get_or_create_session_id(): Get existing session ID or create new one
6
+ """
7
+
8
+ import hashlib
9
+ import logging
10
+ import os
11
+ from datetime import datetime
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+
16
+ def get_or_create_session_id() -> str:
17
+ """Get existing session ID or create new one.
18
+
19
+ Checks the CLAUDE_SESSION_ID env var first. If absent, generates a
20
+ new session ID from the current time and PID, stores it in the env var,
21
+ and returns it.
22
+ """
23
+ session_id = os.environ.get("CLAUDE_SESSION_ID")
24
+ if not session_id:
25
+ timestamp = datetime.now().strftime("%H%M%S")
26
+ hash_input = f"{timestamp}-{os.getpid()}"
27
+ session_hash = hashlib.sha256(hash_input.encode()).hexdigest()[:8]
28
+ session_id = f"session-{timestamp}-{session_hash}"
29
+ os.environ["CLAUDE_SESSION_ID"] = session_id
30
+ logger.debug(f"Generated new session_id: {session_id}")
31
+ return session_id
@@ -0,0 +1,25 @@
1
+ """
2
+ Tools module - Tool-specific validators.
3
+
4
+ Provides:
5
+ - bash_validator: Bash command validation
6
+ - task_validator: Task tool validation with context enforcement
7
+ - shell_parser: Shell command parsing (pipes, chains, etc.)
8
+ """
9
+
10
+ from .shell_parser import ShellCommandParser, get_shell_parser, parse_command
11
+ from .bash_validator import BashValidator, validate_bash_command
12
+ from .task_validator import TaskValidator, validate_task_invocation
13
+
14
+ __all__ = [
15
+ # Shell parser
16
+ "ShellCommandParser",
17
+ "get_shell_parser",
18
+ "parse_command",
19
+ # Bash validator
20
+ "BashValidator",
21
+ "validate_bash_command",
22
+ # Task validator
23
+ "TaskValidator",
24
+ "validate_task_invocation",
25
+ ]