@trac3er/oh-my-god 1.0.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 (229) hide show
  1. package/.claude-plugin/marketplace.json +36 -0
  2. package/.claude-plugin/plugin.json +23 -0
  3. package/.claude-plugin/scripts/install.sh +49 -0
  4. package/.claude-plugin/scripts/uninstall.sh +80 -0
  5. package/.claude-plugin/scripts/update.sh +84 -0
  6. package/.mcp.json +20 -0
  7. package/LICENSE +21 -0
  8. package/OMG-setup.sh +1093 -0
  9. package/README.md +335 -0
  10. package/THIRD_PARTY_NOTICES.md +24 -0
  11. package/UPSTREAM_DIFF.md +20 -0
  12. package/agents/__init__.py +1 -0
  13. package/agents/_model_roles.yaml +26 -0
  14. package/agents/designer.md +67 -0
  15. package/agents/explore.md +60 -0
  16. package/agents/model_roles.py +196 -0
  17. package/agents/omg-api-builder.md +23 -0
  18. package/agents/omg-architect-mode.md +43 -0
  19. package/agents/omg-architect.md +13 -0
  20. package/agents/omg-backend-engineer.md +43 -0
  21. package/agents/omg-critic.md +16 -0
  22. package/agents/omg-database-engineer.md +43 -0
  23. package/agents/omg-escalation-router.md +17 -0
  24. package/agents/omg-executor.md +12 -0
  25. package/agents/omg-frontend-designer.md +42 -0
  26. package/agents/omg-implement-mode.md +50 -0
  27. package/agents/omg-infra-engineer.md +43 -0
  28. package/agents/omg-qa-tester.md +16 -0
  29. package/agents/omg-research-mode.md +43 -0
  30. package/agents/omg-security-auditor.md +43 -0
  31. package/agents/omg-testing-engineer.md +43 -0
  32. package/agents/plan.md +80 -0
  33. package/agents/quick_task.md +64 -0
  34. package/agents/reviewer.md +83 -0
  35. package/agents/task.md +71 -0
  36. package/commands/OMG:ccg.md +22 -0
  37. package/commands/OMG:compat.md +57 -0
  38. package/commands/OMG:crazy.md +125 -0
  39. package/commands/OMG:domain-init.md +11 -0
  40. package/commands/OMG:escalate.md +52 -0
  41. package/commands/OMG:health-check.md +45 -0
  42. package/commands/OMG:init.md +134 -0
  43. package/commands/OMG:mode.md +44 -0
  44. package/commands/OMG:project-init.md +11 -0
  45. package/commands/OMG:ralph-start.md +43 -0
  46. package/commands/OMG:ralph-stop.md +23 -0
  47. package/commands/OMG:teams.md +39 -0
  48. package/commands/ai-commit.md +113 -0
  49. package/commands/ccg.md +9 -0
  50. package/commands/create-agent.md +183 -0
  51. package/commands/omc-teams.md +9 -0
  52. package/commands/session-branch.md +85 -0
  53. package/commands/session-fork.md +53 -0
  54. package/commands/session-merge.md +134 -0
  55. package/commands/theme.md +44 -0
  56. package/config/lsp_languages.yaml +324 -0
  57. package/config/themes/catppuccin-frappe.yaml +14 -0
  58. package/config/themes/catppuccin-latte.yaml +14 -0
  59. package/config/themes/catppuccin-macchiato.yaml +14 -0
  60. package/config/themes/catppuccin-mocha.yaml +14 -0
  61. package/config/themes/dracula.yaml +14 -0
  62. package/config/themes/gruvbox-dark.yaml +14 -0
  63. package/config/themes/nord.yaml +14 -0
  64. package/config/themes/one-dark.yaml +14 -0
  65. package/config/themes/solarized-dark.yaml +14 -0
  66. package/config/themes/tokyo-night.yaml +14 -0
  67. package/control_plane/__init__.py +2 -0
  68. package/control_plane/openapi.yaml +109 -0
  69. package/control_plane/server.py +107 -0
  70. package/control_plane/service.py +148 -0
  71. package/crates/omg-natives/Cargo.toml +17 -0
  72. package/crates/omg-natives/src/clipboard.rs +5 -0
  73. package/crates/omg-natives/src/glob.rs +15 -0
  74. package/crates/omg-natives/src/grep.rs +15 -0
  75. package/crates/omg-natives/src/highlight.rs +15 -0
  76. package/crates/omg-natives/src/html.rs +14 -0
  77. package/crates/omg-natives/src/image.rs +5 -0
  78. package/crates/omg-natives/src/keys.rs +5 -0
  79. package/crates/omg-natives/src/lib.rs +36 -0
  80. package/crates/omg-natives/src/prof.rs +5 -0
  81. package/crates/omg-natives/src/ps.rs +5 -0
  82. package/crates/omg-natives/src/shell.rs +5 -0
  83. package/crates/omg-natives/src/task.rs +5 -0
  84. package/crates/omg-natives/src/text.rs +14 -0
  85. package/hooks/_agent_registry.py +421 -0
  86. package/hooks/_budget.py +31 -0
  87. package/hooks/_common.py +476 -0
  88. package/hooks/_learnings.py +126 -0
  89. package/hooks/_memory.py +103 -0
  90. package/hooks/circuit-breaker.py +270 -0
  91. package/hooks/config-guard.py +163 -0
  92. package/hooks/context_pressure.py +53 -0
  93. package/hooks/credential_store.py +801 -0
  94. package/hooks/fetch-rate-limits.py +212 -0
  95. package/hooks/firewall.py +48 -0
  96. package/hooks/hashline-formatter-bridge.py +224 -0
  97. package/hooks/hashline-injector.py +273 -0
  98. package/hooks/hashline-validator.py +216 -0
  99. package/hooks/idle-detector.py +95 -0
  100. package/hooks/intentgate-keyword-detector.py +188 -0
  101. package/hooks/magic-keyword-router.py +195 -0
  102. package/hooks/policy_engine.py +310 -0
  103. package/hooks/post-tool-failure.py +19 -0
  104. package/hooks/post-write.py +199 -0
  105. package/hooks/pre-compact.py +204 -0
  106. package/hooks/pre-tool-inject.py +98 -0
  107. package/hooks/prompt-enhancer.py +672 -0
  108. package/hooks/quality-runner.py +191 -0
  109. package/hooks/secret-guard.py +47 -0
  110. package/hooks/session-end-capture.py +137 -0
  111. package/hooks/session-start.py +275 -0
  112. package/hooks/shadow_manager.py +297 -0
  113. package/hooks/state_migration.py +209 -0
  114. package/hooks/stop-gate.py +7 -0
  115. package/hooks/stop_dispatcher.py +929 -0
  116. package/hooks/test-validator.py +138 -0
  117. package/hooks/todo-state-tracker.py +114 -0
  118. package/hooks/tool-ledger.py +126 -0
  119. package/hooks/trust_review.py +524 -0
  120. package/install.sh +9 -0
  121. package/omg_natives/__init__.py +186 -0
  122. package/omg_natives/_bindings.py +165 -0
  123. package/omg_natives/clipboard.py +36 -0
  124. package/omg_natives/glob.py +42 -0
  125. package/omg_natives/grep.py +61 -0
  126. package/omg_natives/highlight.py +54 -0
  127. package/omg_natives/html.py +157 -0
  128. package/omg_natives/image.py +51 -0
  129. package/omg_natives/keys.py +46 -0
  130. package/omg_natives/prof.py +39 -0
  131. package/omg_natives/ps.py +93 -0
  132. package/omg_natives/shell.py +58 -0
  133. package/omg_natives/task.py +41 -0
  134. package/omg_natives/text.py +50 -0
  135. package/package.json +26 -0
  136. package/plugins/README.md +82 -0
  137. package/plugins/advanced/commands/OMG:code-review.md +114 -0
  138. package/plugins/advanced/commands/OMG:deep-plan.md +221 -0
  139. package/plugins/advanced/commands/OMG:handoff.md +115 -0
  140. package/plugins/advanced/commands/OMG:learn.md +110 -0
  141. package/plugins/advanced/commands/OMG:maintainer.md +31 -0
  142. package/plugins/advanced/commands/OMG:ralph-start.md +43 -0
  143. package/plugins/advanced/commands/OMG:ralph-stop.md +23 -0
  144. package/plugins/advanced/commands/OMG:security-review.md +119 -0
  145. package/plugins/advanced/commands/OMG:sequential-thinking.md +20 -0
  146. package/plugins/advanced/commands/OMG:ship.md +46 -0
  147. package/plugins/advanced/plugin.json +96 -0
  148. package/plugins/core/plugin.json +82 -0
  149. package/pytest.ini +5 -0
  150. package/registry/__init__.py +1 -0
  151. package/registry/verify_artifact.py +90 -0
  152. package/rules/contextual/architect-mode.md +9 -0
  153. package/rules/contextual/big-picture.md +20 -0
  154. package/rules/contextual/code-hygiene.md +26 -0
  155. package/rules/contextual/context-management.md +19 -0
  156. package/rules/contextual/context-minimization.md +32 -0
  157. package/rules/contextual/ddd-sdd.md +28 -0
  158. package/rules/contextual/dependency-safety.md +16 -0
  159. package/rules/contextual/doc-check.md +13 -0
  160. package/rules/contextual/implement-mode.md +9 -0
  161. package/rules/contextual/infra-safety.md +14 -0
  162. package/rules/contextual/outside-in.md +13 -0
  163. package/rules/contextual/persistent-mode.md +24 -0
  164. package/rules/contextual/research-mode.md +9 -0
  165. package/rules/contextual/security-domains.md +25 -0
  166. package/rules/contextual/vision-detection.md +27 -0
  167. package/rules/contextual/web-search.md +25 -0
  168. package/rules/contextual/write-verify.md +23 -0
  169. package/rules/core/00-truth.md +20 -0
  170. package/rules/core/01-surgical.md +19 -0
  171. package/rules/core/02-circuit-breaker.md +22 -0
  172. package/rules/core/03-ensemble.md +28 -0
  173. package/rules/core/04-testing.md +30 -0
  174. package/runtime/__init__.py +32 -0
  175. package/runtime/adapters/__init__.py +13 -0
  176. package/runtime/adapters/claude.py +60 -0
  177. package/runtime/adapters/gpt.py +53 -0
  178. package/runtime/adapters/local.py +53 -0
  179. package/runtime/business_workflow.py +220 -0
  180. package/runtime/compat.py +1299 -0
  181. package/runtime/custom_agent_loader.py +366 -0
  182. package/runtime/dispatcher.py +47 -0
  183. package/runtime/ecosystem.py +371 -0
  184. package/runtime/legacy_compat.py +7 -0
  185. package/runtime/omc_compat.py +7 -0
  186. package/runtime/omc_contract_snapshot.json +916 -0
  187. package/runtime/omg_compat_contract_snapshot.json +916 -0
  188. package/runtime/subagent_dispatcher.py +362 -0
  189. package/runtime/team_router.py +838 -0
  190. package/scripts/check-omc-contract-snapshot.py +12 -0
  191. package/scripts/check-omg-compat-contract-snapshot.py +137 -0
  192. package/scripts/check-omg-standalone-clean.py +102 -0
  193. package/scripts/legacy_to_omg_migrate.py +29 -0
  194. package/scripts/migrate-omc.py +464 -0
  195. package/scripts/omc_to_omg_migrate.py +12 -0
  196. package/scripts/omg.py +493 -0
  197. package/scripts/settings-merge.py +224 -0
  198. package/scripts/verify-no-omc.sh +5 -0
  199. package/scripts/verify-standalone.sh +21 -0
  200. package/templates/idea.yml +30 -0
  201. package/templates/policy.yaml +15 -0
  202. package/templates/profile.yaml +25 -0
  203. package/templates/runtime.yaml +12 -0
  204. package/templates/working-memory.md +17 -0
  205. package/tools/__init__.py +2 -0
  206. package/tools/browser_consent.py +289 -0
  207. package/tools/browser_stealth.py +481 -0
  208. package/tools/browser_tool.py +448 -0
  209. package/tools/changelog_generator.py +268 -0
  210. package/tools/commit_splitter.py +361 -0
  211. package/tools/config_discovery.py +151 -0
  212. package/tools/config_merger.py +449 -0
  213. package/tools/git_inspector.py +298 -0
  214. package/tools/lsp_client.py +275 -0
  215. package/tools/lsp_discovery.py +231 -0
  216. package/tools/lsp_operations.py +392 -0
  217. package/tools/python_repl.py +656 -0
  218. package/tools/python_sandbox.py +609 -0
  219. package/tools/search_providers/__init__.py +77 -0
  220. package/tools/search_providers/brave.py +115 -0
  221. package/tools/search_providers/exa.py +116 -0
  222. package/tools/search_providers/jina.py +104 -0
  223. package/tools/search_providers/perplexity.py +139 -0
  224. package/tools/search_providers/synthetic.py +74 -0
  225. package/tools/session_snapshot.py +736 -0
  226. package/tools/ssh_manager.py +912 -0
  227. package/tools/theme_engine.py +294 -0
  228. package/tools/theme_selector.py +137 -0
  229. package/tools/web_search.py +622 -0
@@ -0,0 +1,421 @@
1
+ #!/usr/bin/env python3
2
+ """Agent Registry — Central dispatch table for OMG domain agents.
3
+
4
+ Maps domain keywords to agents with model preferences, skills, and MCP tools.
5
+ """
6
+ import json
7
+ import os
8
+ import shutil
9
+
10
+ # Agent registry: domain → agent config
11
+ AGENT_REGISTRY = {
12
+ 'frontend-designer': {
13
+ 'preferred_model': 'gemini-cli',
14
+ 'task_category': 'visual-engineering',
15
+ 'skills': ['frontend-design', 'frontend-ui-ux'],
16
+ 'trigger_keywords': {'ui', 'ux', 'css', 'layout', 'responsive', 'visual', 'frontend', 'component', 'style', 'design', 'animation', 'color', 'theme'},
17
+ 'mcp_tools': ['puppeteer_screenshot', 'puppeteer_navigate'],
18
+ 'description': 'Frontend/UI specialist. Uses Gemini for visual tasks.',
19
+ 'agent_file': 'agents/omg-frontend-designer.md',
20
+ 'model_version': 'gemini-3.1-pro-preview',
21
+ },
22
+ 'backend-engineer': {
23
+ 'preferred_model': 'codex-cli',
24
+ 'task_category': 'deep',
25
+ 'skills': ['backend-patterns', 'api-design'],
26
+ 'trigger_keywords': {'api', 'server', 'database', 'logic', 'algorithm', 'backend', 'endpoint', 'route', 'middleware', 'service'},
27
+ 'mcp_tools': [],
28
+ 'description': 'Backend/logic specialist. Uses Codex for deep reasoning.',
29
+ 'agent_file': 'agents/omg-backend-engineer.md',
30
+ 'model_version': 'gpt-5.3',
31
+ },
32
+ 'api-builder': {
33
+ 'preferred_model': 'codex-cli',
34
+ 'task_category': 'deep',
35
+ 'skills': ['api-design', 'backend-patterns'],
36
+ 'trigger_keywords': {'openapi', 'swagger', 'rest', 'graphql', 'api-spec', 'schema', 'contract', 'endpoint-design'},
37
+ 'mcp_tools': ['context7_query-docs'],
38
+ 'description': 'API design/build specialist. Contracts, endpoint shape, and versioning.',
39
+ 'agent_file': 'agents/omg-api-builder.md',
40
+ 'model_version': 'gpt-5.3',
41
+ },
42
+ 'security-auditor': {
43
+ 'preferred_model': 'codex-cli',
44
+ 'task_category': 'deep',
45
+ 'skills': ['security-review'],
46
+ 'trigger_keywords': {'auth', 'encrypt', 'cors', 'jwt', 'vulnerability', 'security', 'xss', 'csrf', 'injection', 'secret', 'password', 'token'},
47
+ 'mcp_tools': ['sentry_search_issues', 'sentry_get_issue_details'],
48
+ 'description': 'Security specialist. Uses Codex for deep security analysis.',
49
+ 'agent_file': 'agents/omg-security-auditor.md',
50
+ 'model_version': 'gpt-5.3',
51
+ },
52
+ 'database-engineer': {
53
+ 'preferred_model': 'codex-cli',
54
+ 'task_category': 'unspecified-high',
55
+ 'skills': [],
56
+ 'trigger_keywords': {'sql', 'migration', 'schema', 'query', 'index', 'database', 'postgres', 'mongo', 'redis', 'orm'},
57
+ 'mcp_tools': [],
58
+ 'description': 'Database specialist. Schema design, query optimization, migrations.',
59
+ 'agent_file': 'agents/omg-database-engineer.md',
60
+ 'model_version': 'gpt-5.3',
61
+ },
62
+ 'testing-engineer': {
63
+ 'preferred_model': 'claude',
64
+ 'task_category': 'unspecified-high',
65
+ 'skills': ['python-testing', 'e2e-testing'],
66
+ 'trigger_keywords': {'test', 'spec', 'coverage', 'fixture', 'mock', 'playwright', 'e2e', 'unit', 'integration', 'pytest', 'jest'},
67
+ 'mcp_tools': ['puppeteer_navigate', 'puppeteer_screenshot'],
68
+ 'description': 'Testing specialist. Unit tests, integration tests, E2E with Playwright.',
69
+ 'agent_file': 'agents/omg-testing-engineer.md',
70
+ 'model_version': 'claude-sonnet-4-5',
71
+ },
72
+ 'infra-engineer': {
73
+ 'preferred_model': 'codex-cli',
74
+ 'task_category': 'unspecified-high',
75
+ 'skills': ['docker-patterns'],
76
+ 'trigger_keywords': {'docker', 'ci', 'cd', 'deploy', 'terraform', 'k8s', 'kubernetes', 'nginx', 'pipeline', 'container', 'cloud'},
77
+ 'mcp_tools': [],
78
+ 'description': 'Infrastructure specialist. Docker, CI/CD, deployment, cloud.',
79
+ 'agent_file': 'agents/omg-infra-engineer.md',
80
+ 'model_version': 'gpt-5.3',
81
+ },
82
+ # Cognitive modes
83
+ 'research-mode': {
84
+ 'preferred_model': 'claude',
85
+ 'task_category': None,
86
+ 'subagent_type': 'librarian',
87
+ 'skills': [],
88
+ 'trigger_keywords': {'research', 'find', 'how to', 'explain', 'documentation', 'docs', 'lookup'},
89
+ 'mcp_tools': ['web_search_exa', 'google_search', 'context7_query-docs'],
90
+ 'description': 'Research mode. Web search, docs lookup, library exploration.',
91
+ 'agent_file': 'agents/omg-research-mode.md',
92
+ 'model_version': 'claude-haiku-3-5',
93
+ },
94
+ 'architect-mode': {
95
+ 'preferred_model': 'claude',
96
+ 'task_category': None,
97
+ 'subagent_type': 'oracle',
98
+ 'skills': [],
99
+ 'trigger_keywords': {'architect', 'design', 'plan', 'structure', 'system', 'architecture', 'tradeoff'},
100
+ 'mcp_tools': [],
101
+ 'description': 'Architecture mode. System design, trade-off analysis.',
102
+ 'agent_file': 'agents/omg-architect-mode.md',
103
+ 'model_version': 'claude-sonnet-4-5',
104
+ },
105
+ 'implement-mode': {
106
+ 'preferred_model': 'domain-dependent',
107
+ 'task_category': 'deep',
108
+ 'skills': [],
109
+ 'trigger_keywords': {'implement', 'build', 'create', 'add', 'develop', 'write', 'code'},
110
+ 'mcp_tools': [],
111
+ 'description': 'Implementation mode. Model chosen based on domain of task.',
112
+ 'agent_file': 'agents/omg-implement-mode.md',
113
+ 'model_version': 'claude-sonnet-4-5',
114
+ },
115
+ 'implement-mode': {
116
+ 'preferred_model': 'domain-dependent',
117
+ 'task_category': 'deep',
118
+ 'skills': [],
119
+ 'trigger_keywords': {'implement', 'build', 'create', 'add', 'develop', 'write', 'code'},
120
+ 'mcp_tools': [],
121
+ 'description': 'Implementation mode. Model chosen based on domain of task.',
122
+ 'agent_file': 'agents/omg-implement-mode.md',
123
+ 'model_version': 'claude-sonnet-4-5',
124
+ },
125
+ # Bundled agents (Task 2.3)
126
+ 'explore': {
127
+ 'preferred_model': 'claude',
128
+ 'task_category': 'quick',
129
+ 'skills': [],
130
+ 'trigger_keywords': {'find', 'search', 'grep', 'locate', 'where', 'which', 'lookup', 'explore', 'discover'},
131
+ 'mcp_tools': [],
132
+ 'description': 'Fast codebase search agent. Read-only: grep, glob, file reading, pattern matching.',
133
+ 'agent_file': 'agents/explore.md',
134
+ 'model_version': 'claude-haiku-4-5',
135
+ 'model_role': 'smol',
136
+ 'bundled': True,
137
+ },
138
+ 'plan': {
139
+ 'preferred_model': 'claude',
140
+ 'task_category': 'unspecified-high',
141
+ 'skills': [],
142
+ 'trigger_keywords': {'plan', 'architect', 'design', 'decompose', 'strategy', 'roadmap', 'breakdown', 'structure'},
143
+ 'mcp_tools': [],
144
+ 'description': 'Strategic planning agent. Architecture design, task decomposition, risk analysis.',
145
+ 'agent_file': 'agents/plan.md',
146
+ 'model_version': 'claude-opus-4-5',
147
+ 'model_role': 'slow',
148
+ 'bundled': True,
149
+ },
150
+ 'designer': {
151
+ 'preferred_model': 'gemini-cli',
152
+ 'task_category': 'visual-engineering',
153
+ 'skills': ['frontend-design', 'frontend-ui-ux'],
154
+ 'trigger_keywords': {'component', 'layout', 'accessibility', 'responsive', 'tailwind', 'css', 'aria', 'wcag', 'breakpoint'},
155
+ 'mcp_tools': ['puppeteer_screenshot', 'puppeteer_navigate'],
156
+ 'description': 'UI/UX design agent. Component design, layout, accessibility, responsive design.',
157
+ 'agent_file': 'agents/designer.md',
158
+ 'model_version': 'claude-opus-4-5',
159
+ 'model_role': 'default',
160
+ 'bundled': True,
161
+ },
162
+ 'reviewer': {
163
+ 'preferred_model': 'codex-cli',
164
+ 'task_category': 'deep',
165
+ 'skills': ['security-review'],
166
+ 'trigger_keywords': {'review', 'audit', 'check', 'inspect', 'critique', 'feedback', 'pr', 'pull-request', 'quality'},
167
+ 'mcp_tools': ['sentry_search_issues', 'sentry_get_issue_details'],
168
+ 'description': 'Code review agent. Security, performance, quality, best practices, test coverage.',
169
+ 'agent_file': 'agents/reviewer.md',
170
+ 'model_version': 'claude-opus-4-5',
171
+ 'model_role': 'slow',
172
+ 'bundled': True,
173
+ },
174
+ 'task': {
175
+ 'preferred_model': 'claude',
176
+ 'task_category': 'unspecified-high',
177
+ 'skills': [],
178
+ 'trigger_keywords': {'fix', 'implement', 'feature', 'bug', 'patch', 'update', 'change', 'modify', 'refactor'},
179
+ 'mcp_tools': [],
180
+ 'description': 'General task execution agent. Implement features, fix bugs, write tests.',
181
+ 'agent_file': 'agents/task.md',
182
+ 'model_version': 'claude-opus-4-5',
183
+ 'model_role': 'default',
184
+ 'bundled': True,
185
+ },
186
+ 'quick_task': {
187
+ 'preferred_model': 'claude',
188
+ 'task_category': 'quick',
189
+ 'skills': [],
190
+ 'trigger_keywords': {'typo', 'rename', 'label', 'caption', 'spelling', 'minor', 'small', 'quick', 'simple'},
191
+ 'mcp_tools': [],
192
+ 'description': 'Fast task execution agent. Simple fixes, typo corrections, single-file changes.',
193
+ 'agent_file': 'agents/quick_task.md',
194
+ 'model_version': 'claude-haiku-4-5',
195
+ 'model_role': 'smol',
196
+ 'bundled': True,
197
+ },
198
+ }
199
+
200
+ # ═══════════════════════════════════════════════════════════
201
+ # Intent-to-Agent Routing Table (Magic Keyword Router)
202
+ # Maps LEADER_HINT intents from intentgate-keyword-detector
203
+ # to target agent names. None = halt (no agent dispatch).
204
+ # ═══════════════════════════════════════════════════════════
205
+ INTENT_ROUTING = {
206
+ "INTENT_MAX_EFFORT": "sisyphus", # ultrawork → full-effort agent
207
+ "INTENT_AUTONOMOUS": "sisyphus", # autopilot → autonomous agent
208
+ "INTENT_LOOP": "sisyphus", # ralph → loop agent
209
+ "INTENT_PLAN": "prometheus", # plan this → planning agent
210
+ "INTENT_TEST_DRIVEN": "sisyphus", # tdd → TDD agent
211
+ "INTENT_SEARCH": "librarian", # search → search agent
212
+ "INTENT_STOP": None, # stop → halt (no agent)
213
+ "INTENT_CRAZY": "sisyphus", # crazy → aggressive agent
214
+ # Bundled agent intents (Task 2.3)
215
+ "INTENT_EXPLORE": "explore", # explore/find → fast search agent
216
+ "INTENT_REVIEW": "reviewer", # review/audit → code review agent
217
+ "INTENT_QUICK": "quick_task", # quick/simple → fast task agent
218
+ }
219
+
220
+ # Core agent model preferences. NOT keyword-matched — used by orchestration pipeline only. model_version is informational (not passed to CLI).
221
+ CORE_AGENT_MODELS = {
222
+ 'architect': {
223
+ 'preferred_model': 'codex-cli',
224
+ 'model_version': 'gpt-5.2',
225
+ 'task_category': None,
226
+ 'description': 'System design + planning + delegation routing.',
227
+ 'agent_file': 'agents/omg-architect.md',
228
+ },
229
+ 'critic': {
230
+ 'preferred_model': 'codex-cli',
231
+ 'model_version': 'gpt-5.3',
232
+ 'task_category': None,
233
+ 'description': 'Code review — 3 perspectives, no LGTM allowed.',
234
+ 'agent_file': 'agents/omg-critic.md',
235
+ },
236
+ 'executor': {
237
+ 'preferred_model': 'claude',
238
+ 'model_version': 'claude-sonnet-4-5',
239
+ 'task_category': 'deep',
240
+ 'description': 'Implements code with evidence, auto-escalates when stuck.',
241
+ 'agent_file': 'agents/omg-executor.md',
242
+ },
243
+ 'qa-tester': {
244
+ 'preferred_model': 'claude',
245
+ 'model_version': 'claude-sonnet-4-5',
246
+ 'task_category': 'unspecified-high',
247
+ 'description': 'User-journey test writer — no boilerplate.',
248
+ 'agent_file': 'agents/omg-qa-tester.md',
249
+ },
250
+ 'escalation-router': {
251
+ 'preferred_model': 'claude',
252
+ 'model_version': 'claude-haiku-3-5',
253
+ 'task_category': None,
254
+ 'description': 'Routes problems to Codex/Gemini/CCG based on domain.',
255
+ 'agent_file': 'agents/omg-escalation-router.md',
256
+ },
257
+ }
258
+
259
+ # Cache for model availability (per process)
260
+ _model_cache: dict[str, bool] | None = None
261
+
262
+ def resolve_agent(prompt_keywords: set[str]):
263
+ """Match prompt keywords to best agent. Returns registry entry or None.
264
+
265
+ Scoring: count of matching trigger_keywords. Returns highest-scoring agent.
266
+ Ties broken by order in registry (first wins).
267
+ """
268
+ best_agent = None
269
+ best_score = 0
270
+ for name, config in AGENT_REGISTRY.items():
271
+ triggers_raw = config.get('trigger_keywords', set())
272
+ triggers = triggers_raw if isinstance(triggers_raw, set) else set()
273
+ score = len(prompt_keywords & triggers)
274
+ if score > best_score:
275
+ best_score = score
276
+ best_agent = dict(config)
277
+ best_agent['name'] = name
278
+ return best_agent if best_score > 0 else None
279
+
280
+
281
+ def get_dispatch_params(agent_name: str):
282
+ """Get task() parameters for dispatching this agent.
283
+
284
+ Returns dict with 'category', 'skills', and optionally 'subagent_type'.
285
+ Falls back to claude if preferred model not available.
286
+ """
287
+ config = AGENT_REGISTRY.get(agent_name, {})
288
+ available = detect_available_models()
289
+ preferred = config.get('preferred_model', 'claude')
290
+
291
+ # Resolve model availability
292
+ if preferred == 'gemini-cli' and not available.get('gemini-cli'):
293
+ preferred = 'claude'
294
+ elif preferred == 'codex-cli' and not available.get('codex-cli'):
295
+ preferred = 'claude'
296
+ elif preferred == 'domain-dependent':
297
+ preferred = 'claude'
298
+
299
+ params = {
300
+ 'category': config.get('task_category', 'unspecified-high'),
301
+ 'skills': config.get('skills', []),
302
+ 'preferred_model': preferred,
303
+ 'available_models': available,
304
+ 'model_version': config.get('model_version', 'unknown'),
305
+ }
306
+ if 'subagent_type' in config:
307
+ params['subagent_type'] = config['subagent_type']
308
+ return params
309
+
310
+
311
+ def detect_available_models() -> dict[str, bool]:
312
+ """Check which CLIs are available: codex-cli, gemini-cli.
313
+
314
+ Returns dict: {'claude': True, 'codex-cli': bool, 'gemini-cli': bool}
315
+ Caches result per process.
316
+ """
317
+ global _model_cache
318
+ if _model_cache is not None:
319
+ return _model_cache
320
+
321
+ result = {'claude': True} # Claude is always available
322
+ result['codex-cli'] = shutil.which('codex') is not None
323
+ result['gemini-cli'] = shutil.which('gemini') is not None
324
+ _model_cache = result
325
+ return result
326
+
327
+
328
+ def discover_mcp_tools() -> list[str]:
329
+ """Read MCP config to find available tool names.
330
+
331
+ Checks both project-level .mcp.json and ~/.claude/settings.json for mcpServers keys.
332
+ Returns list of server names (not individual tool names).
333
+ """
334
+ mcp_servers = {}
335
+ project_dir = os.getcwd()
336
+
337
+ # Read from both sources: project .mcp.json and user settings
338
+ for mcp_loc in [
339
+ os.path.join(project_dir, '.mcp.json'),
340
+ os.path.expanduser('~/.claude/settings.json'),
341
+ ]:
342
+ if not os.path.exists(mcp_loc):
343
+ continue
344
+ try:
345
+ with open(mcp_loc) as f:
346
+ config = json.load(f)
347
+ servers = config.get('mcpServers', {})
348
+ mcp_servers.update(servers)
349
+ except (json.JSONDecodeError, OSError, KeyError):
350
+ continue
351
+
352
+ return list(mcp_servers.keys())
353
+
354
+
355
+ # --- Custom Agent Loading (Task 2.4) ---
356
+
357
+
358
+ def load_custom_agents_into_registry(project_dir: str = ".") -> int:
359
+ """Load custom agents from user/project dirs into AGENT_REGISTRY.
360
+
361
+ If OMG_CUSTOM_AGENTS_ENABLED is disabled, does nothing.
362
+ Uses lazy import of runtime.custom_agent_loader to avoid circular deps.
363
+
364
+ Args:
365
+ project_dir: Project directory path.
366
+
367
+ Returns:
368
+ Number of custom agents loaded.
369
+ """
370
+ import sys as _sys
371
+
372
+ # Check feature flag via env var first (fast path)
373
+ env_val = os.environ.get("OMG_CUSTOM_AGENTS_ENABLED", "").lower()
374
+ if env_val in ("0", "false", "no"):
375
+ return 0
376
+
377
+ # If not explicitly enabled via env, check via _common
378
+ if env_val not in ("1", "true", "yes"):
379
+ try:
380
+ from _common import get_feature_flag # pyright: ignore[reportMissingImports]
381
+ if not get_feature_flag("CUSTOM_AGENTS", default=False):
382
+ return 0
383
+ except ImportError:
384
+ return 0 # Can't check flag → disabled
385
+
386
+ # Lazy import custom_agent_loader from runtime/
387
+ _runtime_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'runtime')
388
+ _runtime_dir = os.path.normpath(_runtime_dir)
389
+ if _runtime_dir not in _sys.path:
390
+ _sys.path.insert(0, _runtime_dir)
391
+
392
+ try:
393
+ from custom_agent_loader import load_custom_agents # pyright: ignore[reportMissingImports]
394
+ except ImportError:
395
+ return 0
396
+
397
+ custom_agents = load_custom_agents(project_dir)
398
+ count = 0
399
+
400
+ for agent in custom_agents:
401
+ if not agent.get("validated", False):
402
+ continue # Skip invalid agents
403
+
404
+ name = agent["name"]
405
+ AGENT_REGISTRY[name] = {
406
+ 'preferred_model': 'claude',
407
+ 'task_category': 'unspecified-high',
408
+ 'skills': [],
409
+ 'trigger_keywords': set(),
410
+ 'mcp_tools': [],
411
+ 'description': agent.get('description', ''),
412
+ 'agent_file': agent.get('file', ''),
413
+ 'model_version': 'claude-sonnet-4-5',
414
+ 'model_role': agent.get('model_role'),
415
+ 'source': 'custom',
416
+ 'level': agent.get('level', 'unknown'),
417
+ 'validated': True,
418
+ }
419
+ count += 1
420
+
421
+ return count
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Budget Constants — OMG Context & Prompt Budgets
4
+
5
+ Named constants for token/character budgets across OMG hooks.
6
+ Replaces magic numbers with semantic names for maintainability.
7
+ """
8
+
9
+ # ═══════════════════════════════════════════════════════════
10
+ # Session-start budgets (chars)
11
+ # ═══════════════════════════════════════════════════════════
12
+ BUDGET_SESSION_TOTAL = 2000 # Total context injection budget
13
+ BUDGET_SESSION_IDLE = 200 # When no features active
14
+ BUDGET_PROFILE = 200 # Project profile section
15
+ BUDGET_WORKING_MEMORY = 400 # Working memory section
16
+ BUDGET_HANDOFF = 300 # Handoff section
17
+ BUDGET_MEMORY = 300 # Memory/state section
18
+ BUDGET_FAILURES = 200 # Active failures section
19
+ BUDGET_TOOLS = 100 # Tools inventory section
20
+ BUDGET_PLANNING = 100 # Planning/checklist section
21
+ BUDGET_RALPH = 100 # Ralph/persistent mode section
22
+
23
+ # ═══════════════════════════════════════════════════════════
24
+ # Prompt-enhancer budgets (chars)
25
+ # ═══════════════════════════════════════════════════════════
26
+ BUDGET_PROMPT_TOTAL = 1000 # Total prompt enhancement budget
27
+ BUDGET_INTENT_DISCIPLINE = 200 # Intent classification + discipline
28
+ BUDGET_KNOWLEDGE = 300 # Knowledge retrieval section
29
+ BUDGET_LEARNINGS = 200 # Learnings/patterns section
30
+ BUDGET_AGENT_ROUTING = 200 # Agent routing directives
31
+ BUDGET_MODE = 100 # Mode detection (ulw/crazy/etc)