@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
@@ -1,175 +0,0 @@
1
- import { createHash } from "node:crypto";
2
- import { join } from "node:path";
3
- import { ensureDir, writeJsonFile } from "./_common.ts";
4
-
5
- type RecordShape = Record<string, unknown>;
6
-
7
- function safeRecord(value: unknown): RecordShape {
8
- return value && typeof value === "object" && !Array.isArray(value) ? (value as RecordShape) : {};
9
- }
10
-
11
- function safeList(value: unknown): unknown[] {
12
- return Array.isArray(value) ? value : [];
13
- }
14
-
15
- function collectMcpChanges(oldCfg: RecordShape, newCfg: RecordShape) {
16
- const oldServers = safeRecord(oldCfg.mcpServers);
17
- const newServers = safeRecord(newCfg.mcpServers);
18
- const names = new Set([...Object.keys(oldServers), ...Object.keys(newServers)]);
19
- const changes: RecordShape[] = [];
20
- for (const name of [...names].sort()) {
21
- const before = oldServers[name];
22
- const after = newServers[name];
23
- if (before === undefined) {
24
- changes.push({ type: "added", server: name, new: after });
25
- } else if (after === undefined) {
26
- changes.push({ type: "removed", server: name, old: before });
27
- } else if (JSON.stringify(before) !== JSON.stringify(after)) {
28
- changes.push({ type: "modified", server: name, old: before, new: after });
29
- }
30
- }
31
- return changes;
32
- }
33
-
34
- function countHooks(cfg: RecordShape): number {
35
- const hooks = safeRecord(cfg.hooks);
36
- let total = 0;
37
- for (const entries of Object.values(hooks)) {
38
- for (const entry of safeList(entries)) {
39
- if (entry && typeof entry === "object" && !Array.isArray(entry)) {
40
- const nested = safeList((entry as RecordShape).hooks);
41
- total += nested.length || 1;
42
- } else {
43
- total += 1;
44
- }
45
- }
46
- }
47
- return total;
48
- }
49
-
50
- function collectHookChanges(oldCfg: RecordShape, newCfg: RecordShape) {
51
- const oldHooks = safeRecord(oldCfg.hooks);
52
- const newHooks = safeRecord(newCfg.hooks);
53
- const oldEvents = Object.keys(oldHooks);
54
- const newEvents = Object.keys(newHooks);
55
- return {
56
- old_hook_count: countHooks(oldCfg),
57
- new_hook_count: countHooks(newCfg),
58
- removed_events: oldEvents.filter((event) => !newEvents.includes(event)).sort(),
59
- added_events: newEvents.filter((event) => !oldEvents.includes(event)).sort(),
60
- modified_events: oldEvents
61
- .filter((event) => newEvents.includes(event) && JSON.stringify(oldHooks[event]) !== JSON.stringify(newHooks[event]))
62
- .sort()
63
- };
64
- }
65
-
66
- function collectEnvChanges(oldCfg: RecordShape, newCfg: RecordShape) {
67
- const oldEnv = safeRecord(oldCfg.env);
68
- const newEnv = safeRecord(newCfg.env);
69
- const keys = new Set([...Object.keys(oldEnv), ...Object.keys(newEnv)]);
70
- return [...keys]
71
- .sort()
72
- .flatMap((key) =>
73
- JSON.stringify(oldEnv[key]) === JSON.stringify(newEnv[key]) ? [] : [{ key, old: oldEnv[key], new: newEnv[key] }]
74
- );
75
- }
76
-
77
- function scoreToVerdict(score: number) {
78
- if (score >= 80) {
79
- return { verdict: "deny", risk_level: "critical" };
80
- }
81
- if (score >= 45) {
82
- return { verdict: "ask", risk_level: "high" };
83
- }
84
- if (score >= 20) {
85
- return { verdict: "ask", risk_level: "med" };
86
- }
87
- return { verdict: "allow", risk_level: "low" };
88
- }
89
-
90
- export function reviewConfigChange(filePath: string, oldConfig: RecordShape = {}, newConfig: RecordShape = {}) {
91
- const reasons: string[] = [];
92
- const controls: string[] = [];
93
- let risk_score = 0;
94
-
95
- const oldAllow = new Set(safeList(safeRecord(oldConfig.permissions).allow).map(String));
96
- const newAllow = new Set(safeList(safeRecord(newConfig.permissions).allow).map(String));
97
- for (const pattern of ["Bash(rm:*)", "Bash(sudo:*)", "Bash(curl:*)", "Bash(wget:*)", "Bash(ssh:*)"]) {
98
- if (!oldAllow.has(pattern) && newAllow.has(pattern)) {
99
- risk_score += 80;
100
- reasons.push(`Dangerous allow pattern added: ${pattern}`);
101
- controls.push("manual-trust-review", "deny-by-default");
102
- }
103
- }
104
-
105
- const mcp_changes = collectMcpChanges(oldConfig, newConfig);
106
- for (const change of mcp_changes) {
107
- if (change.type === "added") {
108
- risk_score += 30;
109
- reasons.push(`New MCP server added: ${change.server}`);
110
- controls.push("mcp-endpoint-review");
111
- } else if (change.type === "modified") {
112
- risk_score += 35;
113
- reasons.push(`MCP server modified: ${change.server}`);
114
- controls.push("mcp-diff-review");
115
- }
116
- }
117
-
118
- const hook_changes = collectHookChanges(oldConfig, newConfig);
119
- if (hook_changes.new_hook_count < Math.max(1, hook_changes.old_hook_count - 2)) {
120
- risk_score += 35;
121
- reasons.push(`Hook count reduced significantly (${hook_changes.old_hook_count} -> ${hook_changes.new_hook_count})`);
122
- controls.push("require-hook-audit");
123
- }
124
- if (hook_changes.removed_events.length > 0) {
125
- risk_score += 25;
126
- reasons.push(`Hook events removed: ${hook_changes.removed_events.join(", ")}`);
127
- controls.push("event-removal-review");
128
- }
129
- if (hook_changes.modified_events.length > 0) {
130
- risk_score += 20;
131
- reasons.push(`Hook definitions modified: ${hook_changes.modified_events.join(", ")}`);
132
- controls.push("hook-diff-review");
133
- }
134
-
135
- const env_changes = collectEnvChanges(oldConfig, newConfig);
136
- for (const change of env_changes) {
137
- if (String(change.key).match(/key|token|secret|password|credential/i)) {
138
- risk_score += 20;
139
- reasons.push(`Sensitive environment key modified: ${change.key}`);
140
- controls.push("secret-env-review");
141
- } else {
142
- risk_score += 5;
143
- reasons.push(`Environment key modified: ${change.key}`);
144
- }
145
- }
146
-
147
- return {
148
- ts: new Date().toISOString(),
149
- changed_files: filePath ? [filePath] : [],
150
- mcp_changes,
151
- hook_changes,
152
- env_changes,
153
- risk_score,
154
- ...scoreToVerdict(risk_score),
155
- reasons,
156
- controls: [...new Set(controls)].sort()
157
- };
158
- }
159
-
160
- export function writeTrustManifest(projectDir: string, review: RecordShape): string {
161
- const trustDir = join(projectDir, ".omg", "trust");
162
- ensureDir(trustDir);
163
- const manifestPath = join(trustDir, "manifest.lock.json");
164
- const payload: RecordShape = {
165
- version: "omg-v2-bun",
166
- updated_at: new Date().toISOString(),
167
- last_review: review
168
- };
169
- const digest = createHash("sha256")
170
- .update(JSON.stringify(payload, Object.keys(payload).sort()))
171
- .digest("hex");
172
- payload.signature = digest;
173
- writeJsonFile(manifestPath, payload);
174
- return manifestPath;
175
- }
package/lab/pipeline.ts DELETED
@@ -1,75 +0,0 @@
1
- import { nowIso } from "../runtime/common.ts";
2
- import { validateJobRequest } from "./policies.ts";
3
-
4
- export function runPipeline(job: Record<string, unknown>) {
5
- const validation = validateJobRequest(job);
6
- if (!validation.ok) {
7
- return {
8
- status: "blocked",
9
- stage: "policy",
10
- reason: validation.reason,
11
- published: false,
12
- evaluation_report: null
13
- };
14
- }
15
-
16
- const targetMetric = Number(job.target_metric ?? 0.8);
17
- const simulatedMetric = Number(job.simulated_metric ?? targetMetric);
18
- const passed = simulatedMetric >= targetMetric;
19
-
20
- const stages = [
21
- { name: "data_prepare", status: "ok" },
22
- { name: "synthetic_refine", status: "ok" },
23
- { name: "train_distill", status: "ok" },
24
- { name: "evaluate", status: passed ? "ok" : "fail" },
25
- { name: "regression_test", status: passed ? "ok" : "fail" }
26
- ];
27
-
28
- const evaluation_report = {
29
- created_at: nowIso(),
30
- metric: simulatedMetric,
31
- target_metric: targetMetric,
32
- passed,
33
- notes: String(job.evaluation_notes || "")
34
- };
35
-
36
- if (!passed) {
37
- return {
38
- status: "failed_evaluation",
39
- stage: "evaluate",
40
- stages,
41
- published: false,
42
- evaluation_report
43
- };
44
- }
45
-
46
- return {
47
- status: "ready",
48
- stage: "complete",
49
- stages,
50
- published: false,
51
- evaluation_report
52
- };
53
- }
54
-
55
- export function publishArtifact(result: Record<string, unknown>) {
56
- const report =
57
- result.evaluation_report && typeof result.evaluation_report === "object" && !Array.isArray(result.evaluation_report)
58
- ? (result.evaluation_report as Record<string, unknown>)
59
- : null;
60
-
61
- if (!report || report.passed !== true) {
62
- return {
63
- status: "blocked",
64
- reason: "evaluation report missing or not passed",
65
- published: false
66
- };
67
- }
68
-
69
- return {
70
- ...result,
71
- status: "published",
72
- published: true,
73
- published_at: nowIso()
74
- };
75
- }
package/lab/policies.ts DELETED
@@ -1,68 +0,0 @@
1
- type ValidationResult = {
2
- ok: boolean;
3
- reason: string;
4
- };
5
-
6
- const ALLOWED_LICENSES = new Set(["apache-2.0", "mit", "bsd-3-clause", "cc-by-4.0"]);
7
- const BLOCKED_SOURCE_TOKENS = ["unknown", "leaked", "stolen", "unauthorized", "pirated"];
8
-
9
- function fail(reason: string): ValidationResult {
10
- return { ok: false, reason };
11
- }
12
-
13
- function pass(): ValidationResult {
14
- return { ok: true, reason: "ok" };
15
- }
16
-
17
- export function validateDatasetSource(dataset: Record<string, unknown>): ValidationResult {
18
- const license = String(dataset.license || "").toLowerCase();
19
- const source = String(dataset.source || "").toLowerCase();
20
-
21
- if (!license) {
22
- return fail("dataset license missing");
23
- }
24
- if (!ALLOWED_LICENSES.has(license)) {
25
- return fail(`dataset license not allowed: ${license}`);
26
- }
27
- if (BLOCKED_SOURCE_TOKENS.some((token) => source.includes(token))) {
28
- return fail("dataset source violates policy");
29
- }
30
- return pass();
31
- }
32
-
33
- export function validateModelSource(model: Record<string, unknown>): ValidationResult {
34
- const source = String(model.source || "").toLowerCase();
35
- const allowDistill = Boolean(model.allow_distill);
36
-
37
- if (BLOCKED_SOURCE_TOKENS.some((token) => source.includes(token))) {
38
- return fail("model source violates policy");
39
- }
40
- if (!allowDistill) {
41
- return fail("model source disallows distillation");
42
- }
43
- return pass();
44
- }
45
-
46
- export function validateJobRequest(job: Record<string, unknown>): ValidationResult {
47
- const dataset = job.dataset;
48
- const baseModel = job.base_model;
49
-
50
- if (!dataset || typeof dataset !== "object" || Array.isArray(dataset)) {
51
- return fail("dataset block missing");
52
- }
53
- if (!baseModel || typeof baseModel !== "object" || Array.isArray(baseModel)) {
54
- return fail("base_model block missing");
55
- }
56
-
57
- const datasetResult = validateDatasetSource(dataset as Record<string, unknown>);
58
- if (!datasetResult.ok) {
59
- return datasetResult;
60
- }
61
-
62
- const modelResult = validateModelSource(baseModel as Record<string, unknown>);
63
- if (!modelResult.ok) {
64
- return modelResult;
65
- }
66
-
67
- return pass();
68
- }
package/runtime/common.ts DELETED
@@ -1,111 +0,0 @@
1
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
- import { dirname, resolve, relative } from "node:path";
3
- import { fileURLToPath } from "node:url";
4
-
5
- export const ROOT_DIR = resolve(dirname(fileURLToPath(import.meta.url)), "..");
6
-
7
- export function ensureDir(path: string): void {
8
- mkdirSync(path, { recursive: true });
9
- }
10
-
11
- export function ensureParent(path: string): void {
12
- ensureDir(dirname(path));
13
- }
14
-
15
- export function readJsonFile<T>(path: string, fallback: T): T {
16
- try {
17
- if (!existsSync(path)) {
18
- return fallback;
19
- }
20
- const raw = readFileSync(path, "utf8");
21
- return JSON.parse(raw) as T;
22
- } catch {
23
- return fallback;
24
- }
25
- }
26
-
27
- export function writeJsonFile(path: string, value: unknown): void {
28
- ensureParent(path);
29
- writeFileSync(path, `${JSON.stringify(value, null, 2)}\n`, "utf8");
30
- }
31
-
32
- export function printJson(value: unknown): void {
33
- process.stdout.write(`${JSON.stringify(value, null, 2)}\n`);
34
- }
35
-
36
- export function ensureProjectDir(): string {
37
- return process.env.CLAUDE_PROJECT_DIR || process.cwd();
38
- }
39
-
40
- export function nowIso(): string {
41
- return new Date().toISOString();
42
- }
43
-
44
- export function nowRunId(): string {
45
- return nowIso().replace(/[-:.]/g, "").replace("T", "T").replace("Z", "Z");
46
- }
47
-
48
- export function relativeToProject(projectDir: string, path: string): string {
49
- return relative(projectDir, path) || ".";
50
- }
51
-
52
- type IdeaShape = {
53
- goal: string;
54
- constraints: string[];
55
- acceptance: string[];
56
- risk: Record<string, string[]>;
57
- evidence_required: Record<string, string[]>;
58
- };
59
-
60
- export function parseSimpleIdeaYaml(path: string): IdeaShape {
61
- const idea: IdeaShape = {
62
- goal: "",
63
- constraints: [],
64
- acceptance: [],
65
- risk: { security: [], performance: [], compatibility: [] },
66
- evidence_required: { tests: [], security_scans: [], reproducibility: [], artifacts: [] }
67
- };
68
-
69
- let section = "";
70
- let subsection = "";
71
- const raw = readFileSync(path, "utf8");
72
- for (const line of raw.split(/\r?\n/)) {
73
- const stripped = line.trim();
74
- if (!stripped || stripped.startsWith("#")) {
75
- continue;
76
- }
77
- if (stripped.startsWith("goal:")) {
78
- idea.goal = stripped.slice(5).trim().replace(/^["']|["']$/g, "");
79
- section = "";
80
- subsection = "";
81
- continue;
82
- }
83
- if (["constraints:", "acceptance:", "risk:", "evidence_required:"].includes(stripped)) {
84
- section = stripped.slice(0, -1);
85
- subsection = "";
86
- continue;
87
- }
88
- if ((section === "risk" || section === "evidence_required") && stripped.endsWith(":") && !stripped.startsWith("- ")) {
89
- subsection = stripped.slice(0, -1);
90
- continue;
91
- }
92
- if (stripped.startsWith("- ")) {
93
- const value = stripped.slice(2).trim().replace(/^["']|["']$/g, "");
94
- if (section === "constraints" || section === "acceptance") {
95
- (idea[section] as string[]).push(value);
96
- } else if ((section === "risk" || section === "evidence_required") && subsection) {
97
- idea[section][subsection] ??= [];
98
- idea[section][subsection].push(value);
99
- }
100
- }
101
- }
102
- return idea;
103
- }
104
-
105
- export function unique<T>(items: T[]): T[] {
106
- return [...new Set(items)];
107
- }
108
-
109
- export function normalizeWhitespace(value: string): string {
110
- return value.trim().replace(/\s+/g, " ");
111
- }
package/runtime/compat.ts DELETED
@@ -1,174 +0,0 @@
1
- import { existsSync, readFileSync, writeFileSync } from "node:fs";
2
- import { dirname, join, resolve } from "node:path";
3
- import { ensureDir, ensureParent, nowIso, ROOT_DIR } from "./common.ts";
4
- import { dispatchTeam, executeCcgMode } from "./team_router.ts";
5
-
6
- export const DEFAULT_CONTRACT_SNAPSHOT_PATH = "runtime/omg_compat_contract_snapshot.json";
7
- export const DEFAULT_GAP_REPORT_PATH = ".omg/evidence/omg-compat-gap.json";
8
-
9
- type CompatContract = {
10
- skill: string;
11
- route: string;
12
- maturity: string;
13
- [key: string]: unknown;
14
- };
15
-
16
- function snapshotPath(): string {
17
- return resolve(ROOT_DIR, DEFAULT_CONTRACT_SNAPSHOT_PATH);
18
- }
19
-
20
- function loadContracts(): CompatContract[] {
21
- const raw = JSON.parse(readFileSync(snapshotPath(), "utf8")) as { contracts?: CompatContract[] };
22
- return Array.isArray(raw.contracts) ? raw.contracts : [];
23
- }
24
-
25
- const CONTRACTS = loadContracts();
26
- const CONTRACT_MAP = new Map(CONTRACTS.map((contract) => [contract.skill.toLowerCase(), contract]));
27
- const ALIAS_MAP = new Map<string, string>([
28
- ["team", "omg-teams"],
29
- ["teams", "omg-teams"],
30
- ["release", "release"],
31
- ["ship", "release"],
32
- ["plan", "plan"],
33
- ["ccg", "ccg"]
34
- ]);
35
-
36
- function normalizeSkill(skill: string): string {
37
- const lowered = skill.trim().toLowerCase();
38
- return ALIAS_MAP.get(lowered) || lowered;
39
- }
40
-
41
- export function listCompatSkills(): string[] {
42
- return CONTRACTS.map((contract) => contract.skill).sort();
43
- }
44
-
45
- export function listCompatSkillContracts(): CompatContract[] {
46
- return [...CONTRACTS].sort((left, right) => left.skill.localeCompare(right.skill));
47
- }
48
-
49
- export function getCompatSkillContract(skill: string): CompatContract | null {
50
- return CONTRACT_MAP.get(normalizeSkill(skill)) || null;
51
- }
52
-
53
- export function buildContractSnapshotPayload(options: { includeGeneratedAt?: boolean } = {}) {
54
- const payload: Record<string, unknown> = {
55
- schema: "OmgCompatContractSnapshot",
56
- contract_version: "2.0.0",
57
- count: CONTRACTS.length,
58
- contracts: listCompatSkillContracts()
59
- };
60
- if (options.includeGeneratedAt) {
61
- payload.generated_at = nowIso();
62
- }
63
- return payload;
64
- }
65
-
66
- export function buildCompatGapReport(projectDir?: string) {
67
- const maturity_counts: Record<string, number> = {};
68
- for (const contract of CONTRACTS) {
69
- const maturity = String(contract.maturity || "unknown");
70
- maturity_counts[maturity] = (maturity_counts[maturity] || 0) + 1;
71
- }
72
- return {
73
- schema: "OmgCompatGapReport",
74
- generated_at: nowIso(),
75
- project_dir: projectDir || "",
76
- total_skills: CONTRACTS.length,
77
- maturity_counts,
78
- missing_routes: CONTRACTS.filter((contract) => !contract.route).map((contract) => contract.skill)
79
- };
80
- }
81
-
82
- function writeArtifact(path: string, payload: unknown): string {
83
- ensureParent(path);
84
- writeFileSync(path, `${typeof payload === "string" ? payload : JSON.stringify(payload, null, 2)}\n`, "utf8");
85
- return path;
86
- }
87
-
88
- export function dispatchCompatSkill(input: {
89
- skill: string;
90
- problem?: string;
91
- context?: string;
92
- files?: string[];
93
- expected_outcome?: string;
94
- project_dir?: string;
95
- }) {
96
- const normalized = normalizeSkill(input.skill);
97
- const contract = getCompatSkillContract(normalized);
98
- if (!contract) {
99
- return {
100
- schema: "OmgCompatResult",
101
- status: "error",
102
- message: `Unknown skill: ${input.skill}`,
103
- supported_skills: listCompatSkills()
104
- };
105
- }
106
-
107
- const route = String(contract.route || "");
108
- if (route === "teams") {
109
- return {
110
- schema: "OmgCompatResult",
111
- status: "ok",
112
- skill: normalized,
113
- routed_to: "teams",
114
- route,
115
- result: dispatchTeam({
116
- target: "auto",
117
- problem: input.problem || `compat route for ${normalized}`,
118
- context: input.context || "",
119
- files: input.files || [],
120
- expected_outcome: input.expected_outcome || ""
121
- })
122
- };
123
- }
124
-
125
- if (route === "ccg") {
126
- return {
127
- schema: "OmgCompatResult",
128
- status: "ok",
129
- skill: normalized,
130
- routed_to: "ccg",
131
- route,
132
- result: executeCcgMode({
133
- problem: input.problem || `compat route for ${normalized}`,
134
- context: input.context || "",
135
- files: input.files || []
136
- })
137
- };
138
- }
139
-
140
- if (route === "runtime_ship" || normalized === "release") {
141
- const projectDir = input.project_dir || process.cwd();
142
- const artifact = join(projectDir, ".omg", "evidence", "release-draft.md");
143
- writeArtifact(
144
- artifact,
145
- `# OMG Release Draft\n\n- Skill: \`${normalized}\`\n- Problem: ${input.problem || "n/a"}\n- Generated: ${nowIso()}\n`
146
- );
147
- return {
148
- schema: "OmgCompatResult",
149
- status: "ok",
150
- skill: normalized,
151
- routed_to: "runtime_ship",
152
- route,
153
- artifacts: [artifact]
154
- };
155
- }
156
-
157
- const projectDir = input.project_dir || process.cwd();
158
- const artifact = join(projectDir, ".omg", "evidence", `compat-${normalized}.json`);
159
- writeArtifact(artifact, {
160
- schema: "OmgCompatArtifact",
161
- generated_at: nowIso(),
162
- skill: normalized,
163
- route,
164
- problem: input.problem || ""
165
- });
166
- return {
167
- schema: "OmgCompatResult",
168
- status: "ok",
169
- skill: normalized,
170
- routed_to: route || "native",
171
- route,
172
- artifacts: [artifact]
173
- };
174
- }
@@ -1,25 +0,0 @@
1
- export type RuntimeIdea = Record<string, unknown>;
2
-
3
- export function dispatchRuntime(runtime: string, idea: RuntimeIdea) {
4
- const goal = typeof idea.goal === "string" ? idea.goal : "unspecified";
5
- return {
6
- status: "ok",
7
- schema: "RuntimeDispatchResult",
8
- runtime,
9
- goal,
10
- acceptance: Array.isArray(idea.acceptance) ? idea.acceptance : [],
11
- verification: {
12
- checks: [
13
- {
14
- name: "runtime-contract",
15
- status: "unverified",
16
- command: `omg runtime dispatch --runtime ${runtime}`
17
- }
18
- ]
19
- },
20
- plan: {
21
- route: runtime,
22
- summary: `Dispatch ${runtime} runtime for "${goal}".`
23
- }
24
- };
25
- }