@trac3er/oh-my-god 2.0.0 → 2.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 (243) hide show
  1. package/.claude-plugin/marketplace.json +8 -8
  2. package/.claude-plugin/plugin.json +5 -4
  3. package/.claude-plugin/scripts/uninstall.sh +74 -3
  4. package/.claude-plugin/scripts/update.sh +78 -3
  5. package/.coveragerc +26 -0
  6. package/.mcp.json +4 -4
  7. package/CHANGELOG.md +14 -0
  8. package/CODE_OF_CONDUCT.md +27 -0
  9. package/CONTRIBUTING.md +62 -0
  10. package/OMG-setup.sh +1201 -355
  11. package/README.md +77 -56
  12. package/SECURITY.md +25 -0
  13. package/agents/__init__.py +1 -0
  14. package/agents/model_roles.py +196 -0
  15. package/agents/omg-architect-mode.md +3 -5
  16. package/agents/omg-backend-engineer.md +3 -5
  17. package/agents/omg-database-engineer.md +3 -5
  18. package/agents/omg-frontend-designer.md +4 -5
  19. package/agents/omg-implement-mode.md +4 -5
  20. package/agents/omg-infra-engineer.md +3 -5
  21. package/agents/omg-research-mode.md +4 -6
  22. package/agents/omg-security-auditor.md +3 -5
  23. package/agents/omg-testing-engineer.md +3 -5
  24. package/build/lib/yaml.py +321 -0
  25. package/commands/OMG:ai-commit.md +101 -14
  26. package/commands/OMG:arch.md +302 -19
  27. package/commands/OMG:ccg.md +12 -7
  28. package/commands/OMG:compat.md +25 -17
  29. package/commands/OMG:cost.md +173 -13
  30. package/commands/OMG:crazy.md +1 -1
  31. package/commands/OMG:create-agent.md +170 -20
  32. package/commands/OMG:deps.md +235 -17
  33. package/commands/OMG:domain-init.md +1 -1
  34. package/commands/OMG:escalate.md +41 -12
  35. package/commands/OMG:health-check.md +37 -13
  36. package/commands/OMG:init.md +122 -14
  37. package/commands/OMG:project-init.md +1 -1
  38. package/commands/OMG:session-branch.md +76 -9
  39. package/commands/OMG:session-fork.md +42 -5
  40. package/commands/OMG:session-merge.md +124 -8
  41. package/commands/OMG:setup.md +69 -12
  42. package/commands/OMG:stats.md +215 -14
  43. package/commands/OMG:teams.md +19 -10
  44. package/config/lsp_languages.yaml +8 -0
  45. package/hooks/__init__.py +0 -0
  46. package/hooks/_agent_registry.py +423 -0
  47. package/hooks/_analytics.py +291 -0
  48. package/hooks/_budget.py +31 -0
  49. package/hooks/_common.py +569 -0
  50. package/hooks/_compression_optimizer.py +119 -0
  51. package/hooks/_cost_ledger.py +176 -0
  52. package/hooks/_learnings.py +126 -0
  53. package/hooks/_memory.py +103 -0
  54. package/hooks/_protected_context.py +150 -0
  55. package/hooks/_token_counter.py +221 -0
  56. package/hooks/branch_manager.py +236 -0
  57. package/hooks/budget_governor.py +232 -0
  58. package/hooks/circuit-breaker.py +270 -0
  59. package/hooks/compression_feedback.py +254 -0
  60. package/hooks/config-guard.py +216 -0
  61. package/hooks/context_pressure.py +53 -0
  62. package/hooks/credential_store.py +1020 -0
  63. package/hooks/fetch-rate-limits.py +212 -0
  64. package/hooks/firewall.py +48 -0
  65. package/hooks/hashline-formatter-bridge.py +224 -0
  66. package/hooks/hashline-injector.py +273 -0
  67. package/hooks/hashline-validator.py +216 -0
  68. package/hooks/idle-detector.py +95 -0
  69. package/hooks/intentgate-keyword-detector.py +188 -0
  70. package/hooks/magic-keyword-router.py +195 -0
  71. package/hooks/policy_engine.py +505 -0
  72. package/hooks/post-tool-failure.py +19 -0
  73. package/hooks/post-write.py +219 -0
  74. package/hooks/post_write.py +46 -0
  75. package/hooks/pre-compact.py +398 -0
  76. package/hooks/pre-tool-inject.py +98 -0
  77. package/hooks/prompt-enhancer.py +672 -0
  78. package/hooks/quality-runner.py +191 -0
  79. package/hooks/query.py +512 -0
  80. package/hooks/secret-guard.py +61 -0
  81. package/hooks/secret_audit.py +144 -0
  82. package/hooks/session-end-capture.py +137 -0
  83. package/hooks/session-start.py +277 -0
  84. package/hooks/setup_wizard.py +582 -0
  85. package/hooks/shadow_manager.py +297 -0
  86. package/hooks/state_migration.py +225 -0
  87. package/hooks/stop-gate.py +7 -0
  88. package/hooks/stop_dispatcher.py +945 -0
  89. package/hooks/test-validator.py +361 -0
  90. package/hooks/test_generator_hook.py +123 -0
  91. package/hooks/todo-state-tracker.py +114 -0
  92. package/hooks/tool-ledger.py +149 -0
  93. package/hooks/trust_review.py +585 -0
  94. package/hud/omg-hud.mjs +31 -1
  95. package/lab/__init__.py +1 -0
  96. package/lab/pipeline.py +75 -0
  97. package/lab/policies.py +52 -0
  98. package/package.json +7 -18
  99. package/plugins/README.md +33 -61
  100. package/plugins/advanced/commands/OMG:deep-plan.md +3 -3
  101. package/plugins/advanced/commands/OMG:learn.md +1 -1
  102. package/plugins/advanced/commands/OMG:security-review.md +3 -3
  103. package/plugins/advanced/commands/OMG:ship.md +1 -1
  104. package/plugins/advanced/plugin.json +1 -1
  105. package/plugins/core/plugin.json +8 -3
  106. package/plugins/dephealth/__init__.py +0 -0
  107. package/plugins/dephealth/cve_scanner.py +188 -0
  108. package/plugins/dephealth/license_checker.py +135 -0
  109. package/plugins/dephealth/manifest_detector.py +423 -0
  110. package/plugins/dephealth/vuln_analyzer.py +169 -0
  111. package/plugins/testgen/__init__.py +0 -0
  112. package/plugins/testgen/codamosa_engine.py +402 -0
  113. package/plugins/testgen/edge_case_synthesizer.py +184 -0
  114. package/plugins/testgen/framework_detector.py +271 -0
  115. package/plugins/testgen/skeleton_generator.py +219 -0
  116. package/plugins/viz/__init__.py +0 -0
  117. package/plugins/viz/ast_parser.py +139 -0
  118. package/plugins/viz/diagram_generator.py +192 -0
  119. package/plugins/viz/graph_builder.py +444 -0
  120. package/plugins/viz/native_parsers.py +259 -0
  121. package/plugins/viz/regex_parser.py +112 -0
  122. package/pyproject.toml +81 -0
  123. package/rules/contextual/write-verify.md +2 -2
  124. package/rules/core/00-truth.md +1 -1
  125. package/rules/core/01-surgical.md +1 -1
  126. package/rules/core/02-circuit-breaker.md +2 -2
  127. package/rules/core/03-ensemble.md +3 -3
  128. package/rules/core/04-testing.md +3 -3
  129. package/runtime/__init__.py +32 -0
  130. package/runtime/adapters/__init__.py +13 -0
  131. package/runtime/adapters/claude.py +60 -0
  132. package/runtime/adapters/gpt.py +53 -0
  133. package/runtime/adapters/local.py +53 -0
  134. package/runtime/adoption.py +212 -0
  135. package/runtime/business_workflow.py +220 -0
  136. package/runtime/cli_provider.py +85 -0
  137. package/runtime/compat.py +1299 -0
  138. package/runtime/custom_agent_loader.py +366 -0
  139. package/runtime/dispatcher.py +47 -0
  140. package/runtime/ecosystem.py +371 -0
  141. package/runtime/legacy_compat.py +7 -0
  142. package/runtime/mcp_config_writers.py +115 -0
  143. package/runtime/mcp_lifecycle.py +153 -0
  144. package/runtime/mcp_memory_server.py +135 -0
  145. package/runtime/memory_parsers/__init__.py +0 -0
  146. package/runtime/memory_parsers/chatgpt_parser.py +257 -0
  147. package/runtime/memory_parsers/claude_import.py +107 -0
  148. package/runtime/memory_parsers/export.py +97 -0
  149. package/runtime/memory_parsers/gemini_import.py +91 -0
  150. package/runtime/memory_parsers/kimi_import.py +91 -0
  151. package/runtime/memory_store.py +215 -0
  152. package/runtime/omc_compat.py +7 -0
  153. package/runtime/providers/__init__.py +0 -0
  154. package/runtime/providers/codex_provider.py +112 -0
  155. package/runtime/providers/gemini_provider.py +128 -0
  156. package/runtime/providers/kimi_provider.py +151 -0
  157. package/runtime/providers/opencode_provider.py +144 -0
  158. package/runtime/subagent_dispatcher.py +362 -0
  159. package/runtime/team_router.py +1167 -0
  160. package/runtime/tmux_session_manager.py +169 -0
  161. package/scripts/check-omg-compat-contract-snapshot.py +137 -0
  162. package/scripts/check-omg-contract-snapshot.py +12 -0
  163. package/scripts/check-omg-public-ready.py +193 -0
  164. package/scripts/check-omg-standalone-clean.py +103 -0
  165. package/scripts/legacy_to_omg_migrate.py +29 -0
  166. package/scripts/migrate-legacy.py +464 -0
  167. package/scripts/omc_to_omg_migrate.py +12 -0
  168. package/scripts/omg.py +492 -0
  169. package/scripts/settings-merge.py +283 -0
  170. package/scripts/verify-standalone.sh +8 -4
  171. package/settings.json +126 -29
  172. package/templates/profile.yaml +1 -1
  173. package/tools/__init__.py +2 -0
  174. package/tools/browser_consent.py +289 -0
  175. package/tools/browser_stealth.py +481 -0
  176. package/tools/browser_tool.py +448 -0
  177. package/tools/changelog_generator.py +347 -0
  178. package/tools/commit_splitter.py +746 -0
  179. package/tools/config_discovery.py +151 -0
  180. package/tools/config_merger.py +449 -0
  181. package/tools/dashboard_generator.py +300 -0
  182. package/tools/git_inspector.py +298 -0
  183. package/tools/lsp_client.py +275 -0
  184. package/tools/lsp_discovery.py +231 -0
  185. package/tools/lsp_operations.py +392 -0
  186. package/tools/pr_generator.py +404 -0
  187. package/tools/python_repl.py +656 -0
  188. package/tools/python_sandbox.py +609 -0
  189. package/tools/search_providers/__init__.py +77 -0
  190. package/tools/search_providers/brave.py +115 -0
  191. package/tools/search_providers/exa.py +116 -0
  192. package/tools/search_providers/jina.py +104 -0
  193. package/tools/search_providers/perplexity.py +139 -0
  194. package/tools/search_providers/synthetic.py +74 -0
  195. package/tools/session_snapshot.py +736 -0
  196. package/tools/ssh_manager.py +912 -0
  197. package/tools/theme_engine.py +294 -0
  198. package/tools/theme_selector.py +137 -0
  199. package/tools/web_search.py +622 -0
  200. package/yaml.py +321 -0
  201. package/.claude-plugin/scripts/install.sh +0 -9
  202. package/bun.lock +0 -23
  203. package/bunfig.toml +0 -3
  204. package/hooks/_budget.ts +0 -1
  205. package/hooks/_common.ts +0 -63
  206. package/hooks/circuit-breaker.ts +0 -101
  207. package/hooks/config-guard.ts +0 -4
  208. package/hooks/firewall.ts +0 -20
  209. package/hooks/policy_engine.ts +0 -156
  210. package/hooks/post-tool-failure.ts +0 -22
  211. package/hooks/post-write.ts +0 -4
  212. package/hooks/pre-tool-inject.ts +0 -4
  213. package/hooks/prompt-enhancer.ts +0 -46
  214. package/hooks/quality-runner.ts +0 -24
  215. package/hooks/secret-guard.ts +0 -4
  216. package/hooks/session-end-capture.ts +0 -19
  217. package/hooks/session-start.ts +0 -19
  218. package/hooks/shadow_manager.ts +0 -81
  219. package/hooks/stop-gate.ts +0 -22
  220. package/hooks/stop_dispatcher.ts +0 -147
  221. package/hooks/test-generator-hook.ts +0 -4
  222. package/hooks/tool-ledger.ts +0 -27
  223. package/hooks/trust_review.ts +0 -175
  224. package/lab/pipeline.ts +0 -75
  225. package/lab/policies.ts +0 -68
  226. package/runtime/common.ts +0 -111
  227. package/runtime/compat.ts +0 -174
  228. package/runtime/dispatcher.ts +0 -25
  229. package/runtime/ecosystem.ts +0 -186
  230. package/runtime/provider_bootstrap.ts +0 -99
  231. package/runtime/provider_smoke.ts +0 -34
  232. package/runtime/release_readiness.ts +0 -186
  233. package/runtime/team_router.ts +0 -144
  234. package/scripts/check-omg-compat-contract-snapshot.ts +0 -20
  235. package/scripts/check-omg-standalone-clean.ts +0 -12
  236. package/scripts/check-runtime-clean.ts +0 -94
  237. package/scripts/omg.ts +0 -352
  238. package/scripts/settings-merge.ts +0 -93
  239. package/tools/commit_splitter.ts +0 -23
  240. package/tools/git_inspector.ts +0 -18
  241. package/tools/session_snapshot.ts +0 -47
  242. package/trac3er-oh-my-god-2.0.0.tgz +0 -0
  243. package/tsconfig.json +0 -15
@@ -0,0 +1,259 @@
1
+ """Native toolchain dependency parsers for Go, TypeScript, and Rust.
2
+
3
+ Shells out to `go list -json`, `tsc --listFiles`, and `cargo metadata`
4
+ for higher-accuracy dependency graphs (~95%) compared to regex parsers.
5
+
6
+ Standalone extension — graph_builder.py can optionally import this module.
7
+ Feature-gated behind CODEBASE_VIZ.
8
+
9
+ All subprocess calls use argv lists (never shell=True) with timeout=30.
10
+ All functions handle exceptions gracefully and never raise to the caller.
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ import json
16
+ import shutil
17
+ import subprocess
18
+ from typing import Any
19
+
20
+
21
+ def is_toolchain_available(toolchain: str) -> bool:
22
+ """Check if a toolchain binary is installed and on PATH.
23
+
24
+ Args:
25
+ toolchain: Name of the binary (e.g. ``"go"``, ``"tsc"``, ``"cargo"``).
26
+
27
+ Returns:
28
+ True if the binary is found, False otherwise.
29
+ """
30
+ try:
31
+ return shutil.which(toolchain) is not None
32
+ except Exception:
33
+ return False
34
+
35
+
36
+ def _error_result(language: str, message: str) -> dict[str, Any]:
37
+ """Build a standardised error result dict."""
38
+ return {
39
+ "error": message,
40
+ "accuracy": "N/A",
41
+ "graph": {},
42
+ "language": language,
43
+ }
44
+
45
+
46
+ def _run_subprocess(
47
+ argv: list[str],
48
+ cwd: str,
49
+ ) -> tuple[str | None, str | None]:
50
+ """Run a subprocess safely with timeout.
51
+
52
+ Returns:
53
+ (stdout, None) on success, (None, error_message) on failure.
54
+ """
55
+ try:
56
+ proc = subprocess.run(
57
+ argv,
58
+ capture_output=True,
59
+ text=True,
60
+ cwd=cwd,
61
+ timeout=30,
62
+ )
63
+ except subprocess.TimeoutExpired:
64
+ return None, f"timeout: {argv[0]} timed out after 30s"
65
+ except OSError as exc:
66
+ return None, f"os-error: {exc}"
67
+ except Exception as exc:
68
+ return None, f"unexpected-error: {exc}"
69
+
70
+ if proc.returncode != 0:
71
+ stderr_snippet = (proc.stderr or "").strip()[:200]
72
+ return None, f"{argv[0]} exited with code {proc.returncode}: {stderr_snippet}"
73
+
74
+ return proc.stdout, None
75
+
76
+
77
+ # ---------------------------------------------------------------------------
78
+ # Go: go list -json ./...
79
+ # ---------------------------------------------------------------------------
80
+
81
+ def _parse_concatenated_json(raw: str) -> list[dict[str, Any]]:
82
+ """Parse concatenated JSON objects (go list -json output format).
83
+
84
+ ``go list -json`` emits multiple JSON objects concatenated together,
85
+ not a JSON array. We use ``json.JSONDecoder.raw_decode`` to stream
86
+ through the buffer.
87
+ """
88
+ decoder = json.JSONDecoder()
89
+ objects: list[dict[str, Any]] = []
90
+ idx = 0
91
+ length = len(raw)
92
+
93
+ while idx < length:
94
+ # Skip whitespace
95
+ while idx < length and raw[idx] in " \t\n\r":
96
+ idx += 1
97
+ if idx >= length:
98
+ break
99
+ try:
100
+ obj, end_idx = decoder.raw_decode(raw, idx)
101
+ objects.append(obj)
102
+ idx = end_idx
103
+ except json.JSONDecodeError:
104
+ break
105
+
106
+ return objects
107
+
108
+
109
+ def parse_go_native(project_dir: str) -> dict[str, Any]:
110
+ """Parse Go dependencies using ``go list -json ./...``.
111
+
112
+ Returns an adjacency list keyed by Go import path.
113
+ Accuracy: native-95% when Go toolchain is available.
114
+ """
115
+ try:
116
+ if not is_toolchain_available("go"):
117
+ return _error_result("go", "go toolchain not found")
118
+
119
+ stdout, err = _run_subprocess(
120
+ ["go", "list", "-json", "./..."],
121
+ cwd=project_dir,
122
+ )
123
+ if err is not None:
124
+ return _error_result("go", err)
125
+
126
+ packages = _parse_concatenated_json(stdout or "")
127
+ graph: dict[str, list[str]] = {}
128
+
129
+ for pkg in packages:
130
+ import_path = pkg.get("ImportPath", "")
131
+ imports = pkg.get("Imports") or []
132
+ if import_path:
133
+ graph[import_path] = list(imports)
134
+
135
+ return {
136
+ "graph": graph,
137
+ "accuracy": "native-95%",
138
+ "language": "go",
139
+ }
140
+
141
+ except Exception as exc:
142
+ return _error_result("go", f"unexpected-error: {exc}")
143
+
144
+
145
+ # ---------------------------------------------------------------------------
146
+ # TypeScript: tsc --listFiles --noEmit
147
+ # ---------------------------------------------------------------------------
148
+
149
+ def parse_typescript_native(project_dir: str) -> dict[str, Any]:
150
+ """Parse TypeScript project files using ``tsc --listFiles --noEmit``.
151
+
152
+ Extracts module names from file paths, excluding ``node_modules``.
153
+ Accuracy: native-95% when tsc is available.
154
+ """
155
+ try:
156
+ if not is_toolchain_available("tsc"):
157
+ return _error_result("typescript", "tsc toolchain not found")
158
+
159
+ stdout, err = _run_subprocess(
160
+ ["tsc", "--listFiles", "--noEmit"],
161
+ cwd=project_dir,
162
+ )
163
+ if err is not None:
164
+ return _error_result("typescript", err)
165
+
166
+ graph: dict[str, list[str]] = {}
167
+ lines = (stdout or "").strip().splitlines()
168
+
169
+ for line in lines:
170
+ file_path = line.strip()
171
+ if not file_path:
172
+ continue
173
+ # Skip node_modules and .d.ts declaration files from stdlib
174
+ if "node_modules" in file_path:
175
+ continue
176
+
177
+ # Derive a module name from the file path relative to project_dir
178
+ module_name = _ts_module_name(file_path, project_dir)
179
+ if module_name:
180
+ graph[module_name] = []
181
+
182
+ return {
183
+ "graph": graph,
184
+ "accuracy": "native-95%",
185
+ "language": "typescript",
186
+ }
187
+
188
+ except Exception as exc:
189
+ return _error_result("typescript", f"unexpected-error: {exc}")
190
+
191
+
192
+ def _ts_module_name(file_path: str, project_dir: str) -> str:
193
+ """Derive a TypeScript module name from a file path."""
194
+ try:
195
+ # Normalise paths
196
+ fp = file_path.replace("\\", "/")
197
+ pd = project_dir.rstrip("/").replace("\\", "/") + "/"
198
+
199
+ if fp.startswith(pd):
200
+ rel = fp[len(pd):]
201
+ else:
202
+ rel = fp
203
+
204
+ # Strip extensions
205
+ for ext in (".tsx", ".ts", ".jsx", ".js", ".mjs", ".cjs"):
206
+ if rel.endswith(ext):
207
+ rel = rel[: -len(ext)]
208
+ break
209
+
210
+ # Convert path separators to dots
211
+ return rel.replace("/", ".")
212
+ except Exception:
213
+ return ""
214
+
215
+
216
+ # ---------------------------------------------------------------------------
217
+ # Rust: cargo metadata --format-version=1 --no-deps
218
+ # ---------------------------------------------------------------------------
219
+
220
+ def parse_rust_native(project_dir: str) -> dict[str, Any]:
221
+ """Parse Rust dependencies using ``cargo metadata``.
222
+
223
+ Returns an adjacency list keyed by crate name.
224
+ Accuracy: native-95% when Cargo toolchain is available.
225
+ """
226
+ try:
227
+ if not is_toolchain_available("cargo"):
228
+ return _error_result("rust", "cargo toolchain not found")
229
+
230
+ stdout, err = _run_subprocess(
231
+ ["cargo", "metadata", "--format-version=1", "--no-deps"],
232
+ cwd=project_dir,
233
+ )
234
+ if err is not None:
235
+ return _error_result("rust", err)
236
+
237
+ try:
238
+ metadata = json.loads(stdout or "{}")
239
+ except json.JSONDecodeError as exc:
240
+ return _error_result("rust", f"json-parse-error: {exc}")
241
+
242
+ graph: dict[str, list[str]] = {}
243
+ packages = metadata.get("packages") or []
244
+
245
+ for pkg in packages:
246
+ name = pkg.get("name", "")
247
+ deps = pkg.get("dependencies") or []
248
+ dep_names = [d.get("name", "") for d in deps if d.get("name")]
249
+ if name:
250
+ graph[name] = dep_names
251
+
252
+ return {
253
+ "graph": graph,
254
+ "accuracy": "native-95%",
255
+ "language": "rust",
256
+ }
257
+
258
+ except Exception as exc:
259
+ return _error_result("rust", f"unexpected-error: {exc}")
@@ -0,0 +1,112 @@
1
+ """Regex-based import parsers for JavaScript/TypeScript and Go.
2
+
3
+ These parsers are intentionally lightweight and best-effort.
4
+ """
5
+
6
+ from pathlib import Path
7
+ import re
8
+ from typing import NotRequired, TypedDict, cast
9
+
10
+
11
+ class ParseResult(TypedDict):
12
+ imports: list[str]
13
+ accuracy: str
14
+ language: str
15
+ error: NotRequired[str]
16
+
17
+
18
+ def _read_text_file(file_path: str) -> tuple[str | None, str | None]:
19
+ """Read UTF-8 text safely, returning (text, error)."""
20
+ try:
21
+ raw = Path(file_path).read_bytes()
22
+ except OSError as exc:
23
+ return None, f"file-read-error: {exc}"
24
+
25
+ if b"\x00" in raw:
26
+ return None, "unparseable-file: binary content detected"
27
+
28
+ try:
29
+ return raw.decode("utf-8"), None
30
+ except UnicodeDecodeError as exc:
31
+ return None, f"unparseable-file: {exc}"
32
+
33
+
34
+ def _result(imports: list[str], accuracy: str, language: str, error: str | None) -> ParseResult:
35
+ result: ParseResult = {
36
+ "imports": imports,
37
+ "accuracy": accuracy,
38
+ "language": language,
39
+ }
40
+ if error:
41
+ result["error"] = error
42
+ return result
43
+
44
+
45
+ def _unique(values: list[str]) -> list[str]:
46
+ seen: set[str] = set()
47
+ ordered: list[str] = []
48
+ for value in values:
49
+ if value not in seen:
50
+ seen.add(value)
51
+ ordered.append(value)
52
+ return ordered
53
+
54
+
55
+ def parse_js_imports(file_path: str) -> ParseResult:
56
+ """Parse JS/TS import specifiers from a file via regex (~70% accuracy).
57
+
58
+ Accuracy: ~70% ("regex-70%").
59
+ Known misses: dynamic imports with variables/template literals,
60
+ complex transpiler syntax, and imports hidden in non-UTF8 files.
61
+ """
62
+ text, error = _read_text_file(file_path)
63
+ if text is None:
64
+ return _result([], "regex-70%", "javascript", error)
65
+
66
+ imports: list[str] = []
67
+
68
+ static_import_re = re.compile(
69
+ r"^\s*import\s+(?:[\w*$\s{},]+\s+from\s+)?['\"]([^'\"]+)['\"]",
70
+ re.MULTILINE,
71
+ )
72
+ require_re = re.compile(r"require\s*\(\s*['\"]([^'\"]+)['\"]\s*\)")
73
+ export_from_re = re.compile(
74
+ r"^\s*export\s+\*\s+from\s+['\"]([^'\"]+)['\"]",
75
+ re.MULTILINE,
76
+ )
77
+ dynamic_import_re = re.compile(r"import\s*\(\s*['\"]([^'\"]+)['\"]\s*\)")
78
+
79
+ imports.extend(static_import_re.findall(text))
80
+ imports.extend(require_re.findall(text))
81
+ imports.extend(export_from_re.findall(text))
82
+ imports.extend(dynamic_import_re.findall(text))
83
+
84
+ return _result(_unique(imports), "regex-70%", "javascript", None)
85
+
86
+
87
+ def parse_go_imports(file_path: str) -> ParseResult:
88
+ """Parse Go import paths from a file via regex (~80% accuracy).
89
+
90
+ Accuracy: ~80% ("regex-80%").
91
+ Known misses: imports gated by build tags/conditional file inclusion,
92
+ and non-UTF8 or unparseable files.
93
+ """
94
+ text, error = _read_text_file(file_path)
95
+ if text is None:
96
+ return _result([], "regex-80%", "go", error)
97
+
98
+ imports: list[str] = []
99
+
100
+ single_or_alias_re = re.compile(
101
+ r'^\s*import\s+(?:[A-Za-z_][\w.]*)?\s*"([^"]+)"',
102
+ re.MULTILINE,
103
+ )
104
+ block_re = re.compile(r"import\s*\((.*?)\)", re.DOTALL)
105
+ block_entry_re = re.compile(r'(?:[A-Za-z_][\w.]*)?\s*"([^"]+)"')
106
+
107
+ imports.extend(single_or_alias_re.findall(text))
108
+
109
+ for block in cast(list[str], block_re.findall(text)):
110
+ imports.extend(block_entry_re.findall(block))
111
+
112
+ return _result(_unique(imports), "regex-80%", "go", None)
package/pyproject.toml ADDED
@@ -0,0 +1,81 @@
1
+ [build-system]
2
+ requires = ["setuptools>=65.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "oh-my-god"
7
+ version = "2.0.0b1"
8
+ description = "OMG (Oh My God) — Multi-agent orchestration, intelligent model routing, and durable session state for Claude Code"
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = {text = "MIT"}
12
+ authors = [
13
+ {name = "trac3er00", email = "trac3er00@example.com"}
14
+ ]
15
+ keywords = ["claude", "claude-code", "orchestration", "multi-agent", "ai", "llm", "codex", "gemini"]
16
+ classifiers = [
17
+ "Development Status :: 4 - Beta",
18
+ "Intended Audience :: Developers",
19
+ "License :: OSI Approved :: MIT License",
20
+ "Programming Language :: Python :: 3",
21
+ "Programming Language :: Python :: 3.10",
22
+ "Programming Language :: Python :: 3.11",
23
+ "Programming Language :: Python :: 3.12",
24
+ "Topic :: Software Development :: Libraries :: Python Modules",
25
+ ]
26
+ dependencies = [
27
+ "fastmcp>=2.0",
28
+ ]
29
+
30
+ [project.optional-dependencies]
31
+ test = [
32
+ "pytest>=7.0",
33
+ "pytest-cov>=4.0",
34
+ ]
35
+ mcp = [
36
+ "fastmcp>=2.0",
37
+ ]
38
+
39
+ [project.urls]
40
+ Homepage = "https://github.com/trac3er00/OMG"
41
+ Repository = "https://github.com/trac3er00/OMG.git"
42
+ Issues = "https://github.com/trac3er00/OMG/issues"
43
+
44
+ [tool.setuptools]
45
+ packages = ["hooks", "runtime", "agents", "commands"]
46
+
47
+ [tool.pytest.ini_options]
48
+ testpaths = ["tests"]
49
+ python_files = ["test_*.py"]
50
+ python_classes = ["Test*"]
51
+ python_functions = ["test_*"]
52
+ addopts = [
53
+ "--strict-markers",
54
+ "--cov=.",
55
+ "--cov-report=term-missing",
56
+ "--cov-report=html",
57
+ ]
58
+ markers = [
59
+ "slow: marks tests as slow",
60
+ "integration: marks tests as integration tests",
61
+ "unit: marks tests as unit tests",
62
+ ]
63
+
64
+ [tool.coverage.run]
65
+ source = ["."]
66
+ omit = [
67
+ "tests/*",
68
+ "*/__pycache__/*",
69
+ ".venv/*",
70
+ "setup.py",
71
+ ]
72
+
73
+ [tool.coverage.report]
74
+ exclude_lines = [
75
+ "pragma: no cover",
76
+ "def __repr__",
77
+ "raise AssertionError",
78
+ "raise NotImplementedError",
79
+ "if __name__ == .__main__.:",
80
+ "if TYPE_CHECKING:",
81
+ ]
@@ -3,7 +3,7 @@
3
3
  When any file write or edit operation shows an error, warning, or hook error:
4
4
 
5
5
  1. **NEVER claim success** without reading the file to verify changes are present
6
- 2. **Hook errors from external plugins** (e.g. `security_reminder_hook.ts`) are warnings — the write may have succeeded. READ the file to check.
6
+ 2. **Hook errors from external plugins** (e.g. security_reminder_hook.py) are warnings — the write may have succeeded. READ the file to check.
7
7
  3. **"Error editing file"** means the Edit tool failed. Use an alternative:
8
8
  - Try `Write` tool (creates new file)
9
9
  - Try Bash: `cat > path/to/file << 'EOF'\n[content]\nEOF`
@@ -13,7 +13,7 @@ When any file write or edit operation shows an error, warning, or hook error:
13
13
 
14
14
  ## Common Hook Error Pattern
15
15
  ```
16
- Error: PreToolUse:Write hook error: [bun .../security_reminder_hook.ts]: warning emitted by external hook
16
+ Error: PreToolUse:Write hook error: [python3 .../security_reminder_hook.py]: ⚠️ Security Warning: ...
17
17
  ```
18
18
  This means an external hook emitted a warning. The file write likely succeeded.
19
19
  **Action:** Read the file to verify, then continue. Do NOT retry blindly.
@@ -17,4 +17,4 @@ NEVER claim a state you haven't verified. Period.
17
17
 
18
18
  Forbidden without evidence: "done", "LGTM", "fixed", "works now", "tests passed"
19
19
 
20
- > Enforced: stop-gate.ts checks evidence. tool-ledger.ts logs tool calls.
20
+ > Enforced: stop-gate.py checks evidence. tool-ledger.py logs tool calls.
@@ -16,4 +16,4 @@ For 3+ file changes: create .omg/state/_plan.md + _checklist.md BEFORE coding.
16
16
  Mark [x] immediately as steps complete. Update plan when approach changes.
17
17
  If stuck 2x: STOP. Try different approach or /OMG:escalate.
18
18
 
19
- > Enforced: stop-gate.ts checks diff budget. circuit-breaker.ts catches loops.
19
+ > Enforced: stop-gate.py checks diff budget. circuit-breaker.py catches loops.
@@ -16,7 +16,7 @@ Options:
16
16
  - **Force-Fixer:** Immediately try to fix without understanding root cause
17
17
 
18
18
  ## Auto-Escalation
19
- After 3 failures: circuit-breaker.ts suggests /OMG:escalate with specific context.
19
+ After 3 failures: circuit-breaker.py suggests /OMG:escalate with specific context.
20
20
  After 5 failures: HARD BLOCK. Must escalate or get user input.
21
21
 
22
- > Enforced: circuit-breaker.ts tracks patterns + auto-escalates.
22
+ > Enforced: circuit-breaker.py tracks patterns + auto-escalates.
@@ -13,8 +13,8 @@
13
13
  - Stuck on anything for 3+ attempts → /OMG:escalate to relevant model
14
14
 
15
15
  ## Auto-Detection
16
- prompt-enhancer.ts detects keywords and suggests the right model.
17
- circuit-breaker.ts auto-suggests escalation after failures.
16
+ prompt-enhancer.py detects keywords and suggests the right model.
17
+ circuit-breaker.py auto-suggests escalation after failures.
18
18
 
19
19
  ## Plugins & MCPs
20
20
  - Installed plugins: USE them (they're installed for a reason)
@@ -25,4 +25,4 @@ circuit-breaker.ts auto-suggests escalation after failures.
25
25
  Say: "This touches auth — let me get Codex to check the security."
26
26
  NOT: "Invoking cross-model review protocol for backend analysis."
27
27
 
28
- > Enforced: prompt-enhancer.ts + session-start.ts detect available tools.
28
+ > Enforced: prompt-enhancer.py + session-start.py detect available tools.
@@ -24,7 +24,7 @@ Then write tests for THOSE scenarios.
24
24
 
25
25
  ## Quality Gate
26
26
  Every change runs: format → lint → typecheck (if typed) → test
27
- If quality-gate.json exists, quality-runner.ts enforces this.
27
+ If quality-gate.json exists, quality-runner.py enforces this.
28
28
 
29
- > Enforced: test-generator-hook.ts catches missing coverage follow-up for generated tests.
30
- > quality-runner.ts runs QA commands.
29
+ > Enforced: test-validator.py catches fake/boilerplate tests.
30
+ > quality-runner.py runs QA commands.
@@ -0,0 +1,32 @@
1
+ """Runtime package for OMG."""
2
+
3
+ from .compat import (
4
+ build_compat_gap_report,
5
+ build_omg_gap_report,
6
+ dispatch_compat_skill,
7
+ dispatch_omg_skill,
8
+ get_compat_skill_contract,
9
+ get_omg_skill_contract,
10
+ list_compat_skill_contracts,
11
+ list_compat_skills,
12
+ list_omg_skill_contracts,
13
+ list_omg_skills,
14
+ )
15
+ from .ecosystem import ecosystem_status, list_ecosystem_repos, resolve_ecosystem_selection, sync_ecosystem_repos
16
+
17
+ __all__ = [
18
+ "build_compat_gap_report",
19
+ "build_omg_gap_report",
20
+ "dispatch_compat_skill",
21
+ "dispatch_omg_skill",
22
+ "get_compat_skill_contract",
23
+ "get_omg_skill_contract",
24
+ "list_compat_skill_contracts",
25
+ "list_compat_skills",
26
+ "list_omg_skill_contracts",
27
+ "list_omg_skills",
28
+ "ecosystem_status",
29
+ "list_ecosystem_repos",
30
+ "resolve_ecosystem_selection",
31
+ "sync_ecosystem_repos",
32
+ ]
@@ -0,0 +1,13 @@
1
+ """Runtime adapters for OMG v1."""
2
+
3
+ from .claude import ClaudeAdapter
4
+ from .gpt import GPTAdapter
5
+ from .local import LocalAdapter
6
+
7
+
8
+ def get_adapters():
9
+ return {
10
+ "claude": ClaudeAdapter(),
11
+ "gpt": GPTAdapter(),
12
+ "local": LocalAdapter(),
13
+ }
@@ -0,0 +1,60 @@
1
+ """Claude runtime adapter (v1 stub)."""
2
+ from __future__ import annotations
3
+
4
+ from datetime import datetime, timezone
5
+ from typing import Any
6
+
7
+
8
+ class ClaudeAdapter:
9
+ runtime = "claude"
10
+
11
+ def plan(self, idea: dict[str, Any]) -> dict[str, Any]:
12
+ goal = str(idea.get("goal", "")).strip() or "unspecified-goal"
13
+ return {
14
+ "runtime": self.runtime,
15
+ "phase": "plan",
16
+ "status": "planned",
17
+ "goal": goal,
18
+ "steps": [
19
+ "analyze-goal",
20
+ "generate-plan",
21
+ "emit-checklist",
22
+ ],
23
+ }
24
+
25
+ def execute(self, plan: dict[str, Any]) -> dict[str, Any]:
26
+ return {
27
+ "runtime": self.runtime,
28
+ "phase": "execute",
29
+ "status": "executed",
30
+ "operations": [
31
+ "apply-plan",
32
+ "collect-diff",
33
+ ],
34
+ "errors": [],
35
+ }
36
+
37
+ def verify(self, execution_result: dict[str, Any]) -> dict[str, Any]:
38
+ return {
39
+ "runtime": self.runtime,
40
+ "phase": "verify",
41
+ "status": "verified",
42
+ "ok": True,
43
+ "checks": [
44
+ {"name": "tests", "passed": True},
45
+ {"name": "security", "passed": True},
46
+ ],
47
+ }
48
+
49
+ def collect_evidence(self, verify_result: dict[str, Any]) -> dict[str, Any]:
50
+ return {
51
+ "runtime": self.runtime,
52
+ "phase": "evidence",
53
+ "status": "collected",
54
+ "created_at": datetime.now(timezone.utc).isoformat(),
55
+ "tests": verify_result.get("checks", []),
56
+ "security_scans": [],
57
+ "diff_summary": {},
58
+ "reproducibility": {"seed": "deterministic"},
59
+ "unresolved_risks": [],
60
+ }
@@ -0,0 +1,53 @@
1
+ """GPT runtime adapter (v1 stub)."""
2
+ from __future__ import annotations
3
+
4
+ from datetime import datetime, timezone
5
+ from typing import Any
6
+
7
+
8
+ class GPTAdapter:
9
+ runtime = "gpt"
10
+
11
+ def plan(self, idea: dict[str, Any]) -> dict[str, Any]:
12
+ goal = str(idea.get("goal", "")).strip() or "unspecified-goal"
13
+ return {
14
+ "runtime": self.runtime,
15
+ "phase": "plan",
16
+ "status": "planned",
17
+ "goal": goal,
18
+ "steps": ["analyze-goal", "generate-plan", "emit-checklist"],
19
+ }
20
+
21
+ def execute(self, plan: dict[str, Any]) -> dict[str, Any]:
22
+ return {
23
+ "runtime": self.runtime,
24
+ "phase": "execute",
25
+ "status": "executed",
26
+ "operations": ["apply-plan", "collect-diff"],
27
+ "errors": [],
28
+ }
29
+
30
+ def verify(self, execution_result: dict[str, Any]) -> dict[str, Any]:
31
+ return {
32
+ "runtime": self.runtime,
33
+ "phase": "verify",
34
+ "status": "verified",
35
+ "ok": True,
36
+ "checks": [
37
+ {"name": "tests", "passed": True},
38
+ {"name": "security", "passed": True},
39
+ ],
40
+ }
41
+
42
+ def collect_evidence(self, verify_result: dict[str, Any]) -> dict[str, Any]:
43
+ return {
44
+ "runtime": self.runtime,
45
+ "phase": "evidence",
46
+ "status": "collected",
47
+ "created_at": datetime.now(timezone.utc).isoformat(),
48
+ "tests": verify_result.get("checks", []),
49
+ "security_scans": [],
50
+ "diff_summary": {},
51
+ "reproducibility": {"seed": "deterministic"},
52
+ "unresolved_risks": [],
53
+ }