@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.
- package/.claude-plugin/marketplace.json +8 -8
- package/.claude-plugin/plugin.json +5 -4
- package/.claude-plugin/scripts/uninstall.sh +74 -3
- package/.claude-plugin/scripts/update.sh +78 -3
- package/.coveragerc +26 -0
- package/.mcp.json +4 -4
- package/CHANGELOG.md +14 -0
- package/CODE_OF_CONDUCT.md +27 -0
- package/CONTRIBUTING.md +62 -0
- package/OMG-setup.sh +1201 -355
- package/README.md +77 -56
- package/SECURITY.md +25 -0
- package/agents/__init__.py +1 -0
- package/agents/model_roles.py +196 -0
- package/agents/omg-architect-mode.md +3 -5
- package/agents/omg-backend-engineer.md +3 -5
- package/agents/omg-database-engineer.md +3 -5
- package/agents/omg-frontend-designer.md +4 -5
- package/agents/omg-implement-mode.md +4 -5
- package/agents/omg-infra-engineer.md +3 -5
- package/agents/omg-research-mode.md +4 -6
- package/agents/omg-security-auditor.md +3 -5
- package/agents/omg-testing-engineer.md +3 -5
- package/build/lib/yaml.py +321 -0
- package/commands/OMG:ai-commit.md +101 -14
- package/commands/OMG:arch.md +302 -19
- package/commands/OMG:ccg.md +12 -7
- package/commands/OMG:compat.md +25 -17
- package/commands/OMG:cost.md +173 -13
- package/commands/OMG:crazy.md +1 -1
- package/commands/OMG:create-agent.md +170 -20
- package/commands/OMG:deps.md +235 -17
- package/commands/OMG:domain-init.md +1 -1
- package/commands/OMG:escalate.md +41 -12
- package/commands/OMG:health-check.md +37 -13
- package/commands/OMG:init.md +122 -14
- package/commands/OMG:project-init.md +1 -1
- package/commands/OMG:session-branch.md +76 -9
- package/commands/OMG:session-fork.md +42 -5
- package/commands/OMG:session-merge.md +124 -8
- package/commands/OMG:setup.md +69 -12
- package/commands/OMG:stats.md +215 -14
- package/commands/OMG:teams.md +19 -10
- package/config/lsp_languages.yaml +8 -0
- package/hooks/__init__.py +0 -0
- package/hooks/_agent_registry.py +423 -0
- package/hooks/_analytics.py +291 -0
- package/hooks/_budget.py +31 -0
- package/hooks/_common.py +569 -0
- package/hooks/_compression_optimizer.py +119 -0
- package/hooks/_cost_ledger.py +176 -0
- package/hooks/_learnings.py +126 -0
- package/hooks/_memory.py +103 -0
- package/hooks/_protected_context.py +150 -0
- package/hooks/_token_counter.py +221 -0
- package/hooks/branch_manager.py +236 -0
- package/hooks/budget_governor.py +232 -0
- package/hooks/circuit-breaker.py +270 -0
- package/hooks/compression_feedback.py +254 -0
- package/hooks/config-guard.py +216 -0
- package/hooks/context_pressure.py +53 -0
- package/hooks/credential_store.py +1020 -0
- package/hooks/fetch-rate-limits.py +212 -0
- package/hooks/firewall.py +48 -0
- package/hooks/hashline-formatter-bridge.py +224 -0
- package/hooks/hashline-injector.py +273 -0
- package/hooks/hashline-validator.py +216 -0
- package/hooks/idle-detector.py +95 -0
- package/hooks/intentgate-keyword-detector.py +188 -0
- package/hooks/magic-keyword-router.py +195 -0
- package/hooks/policy_engine.py +505 -0
- package/hooks/post-tool-failure.py +19 -0
- package/hooks/post-write.py +219 -0
- package/hooks/post_write.py +46 -0
- package/hooks/pre-compact.py +398 -0
- package/hooks/pre-tool-inject.py +98 -0
- package/hooks/prompt-enhancer.py +672 -0
- package/hooks/quality-runner.py +191 -0
- package/hooks/query.py +512 -0
- package/hooks/secret-guard.py +61 -0
- package/hooks/secret_audit.py +144 -0
- package/hooks/session-end-capture.py +137 -0
- package/hooks/session-start.py +277 -0
- package/hooks/setup_wizard.py +582 -0
- package/hooks/shadow_manager.py +297 -0
- package/hooks/state_migration.py +225 -0
- package/hooks/stop-gate.py +7 -0
- package/hooks/stop_dispatcher.py +945 -0
- package/hooks/test-validator.py +361 -0
- package/hooks/test_generator_hook.py +123 -0
- package/hooks/todo-state-tracker.py +114 -0
- package/hooks/tool-ledger.py +149 -0
- package/hooks/trust_review.py +585 -0
- package/hud/omg-hud.mjs +31 -1
- package/lab/__init__.py +1 -0
- package/lab/pipeline.py +75 -0
- package/lab/policies.py +52 -0
- package/package.json +7 -18
- package/plugins/README.md +33 -61
- package/plugins/advanced/commands/OMG:deep-plan.md +3 -3
- package/plugins/advanced/commands/OMG:learn.md +1 -1
- package/plugins/advanced/commands/OMG:security-review.md +3 -3
- package/plugins/advanced/commands/OMG:ship.md +1 -1
- package/plugins/advanced/plugin.json +1 -1
- package/plugins/core/plugin.json +8 -3
- package/plugins/dephealth/__init__.py +0 -0
- package/plugins/dephealth/cve_scanner.py +188 -0
- package/plugins/dephealth/license_checker.py +135 -0
- package/plugins/dephealth/manifest_detector.py +423 -0
- package/plugins/dephealth/vuln_analyzer.py +169 -0
- package/plugins/testgen/__init__.py +0 -0
- package/plugins/testgen/codamosa_engine.py +402 -0
- package/plugins/testgen/edge_case_synthesizer.py +184 -0
- package/plugins/testgen/framework_detector.py +271 -0
- package/plugins/testgen/skeleton_generator.py +219 -0
- package/plugins/viz/__init__.py +0 -0
- package/plugins/viz/ast_parser.py +139 -0
- package/plugins/viz/diagram_generator.py +192 -0
- package/plugins/viz/graph_builder.py +444 -0
- package/plugins/viz/native_parsers.py +259 -0
- package/plugins/viz/regex_parser.py +112 -0
- package/pyproject.toml +81 -0
- package/rules/contextual/write-verify.md +2 -2
- package/rules/core/00-truth.md +1 -1
- package/rules/core/01-surgical.md +1 -1
- package/rules/core/02-circuit-breaker.md +2 -2
- package/rules/core/03-ensemble.md +3 -3
- package/rules/core/04-testing.md +3 -3
- package/runtime/__init__.py +32 -0
- package/runtime/adapters/__init__.py +13 -0
- package/runtime/adapters/claude.py +60 -0
- package/runtime/adapters/gpt.py +53 -0
- package/runtime/adapters/local.py +53 -0
- package/runtime/adoption.py +212 -0
- package/runtime/business_workflow.py +220 -0
- package/runtime/cli_provider.py +85 -0
- package/runtime/compat.py +1299 -0
- package/runtime/custom_agent_loader.py +366 -0
- package/runtime/dispatcher.py +47 -0
- package/runtime/ecosystem.py +371 -0
- package/runtime/legacy_compat.py +7 -0
- package/runtime/mcp_config_writers.py +115 -0
- package/runtime/mcp_lifecycle.py +153 -0
- package/runtime/mcp_memory_server.py +135 -0
- package/runtime/memory_parsers/__init__.py +0 -0
- package/runtime/memory_parsers/chatgpt_parser.py +257 -0
- package/runtime/memory_parsers/claude_import.py +107 -0
- package/runtime/memory_parsers/export.py +97 -0
- package/runtime/memory_parsers/gemini_import.py +91 -0
- package/runtime/memory_parsers/kimi_import.py +91 -0
- package/runtime/memory_store.py +215 -0
- package/runtime/omc_compat.py +7 -0
- package/runtime/providers/__init__.py +0 -0
- package/runtime/providers/codex_provider.py +112 -0
- package/runtime/providers/gemini_provider.py +128 -0
- package/runtime/providers/kimi_provider.py +151 -0
- package/runtime/providers/opencode_provider.py +144 -0
- package/runtime/subagent_dispatcher.py +362 -0
- package/runtime/team_router.py +1167 -0
- package/runtime/tmux_session_manager.py +169 -0
- package/scripts/check-omg-compat-contract-snapshot.py +137 -0
- package/scripts/check-omg-contract-snapshot.py +12 -0
- package/scripts/check-omg-public-ready.py +193 -0
- package/scripts/check-omg-standalone-clean.py +103 -0
- package/scripts/legacy_to_omg_migrate.py +29 -0
- package/scripts/migrate-legacy.py +464 -0
- package/scripts/omc_to_omg_migrate.py +12 -0
- package/scripts/omg.py +492 -0
- package/scripts/settings-merge.py +283 -0
- package/scripts/verify-standalone.sh +8 -4
- package/settings.json +126 -29
- package/templates/profile.yaml +1 -1
- package/tools/__init__.py +2 -0
- package/tools/browser_consent.py +289 -0
- package/tools/browser_stealth.py +481 -0
- package/tools/browser_tool.py +448 -0
- package/tools/changelog_generator.py +347 -0
- package/tools/commit_splitter.py +746 -0
- package/tools/config_discovery.py +151 -0
- package/tools/config_merger.py +449 -0
- package/tools/dashboard_generator.py +300 -0
- package/tools/git_inspector.py +298 -0
- package/tools/lsp_client.py +275 -0
- package/tools/lsp_discovery.py +231 -0
- package/tools/lsp_operations.py +392 -0
- package/tools/pr_generator.py +404 -0
- package/tools/python_repl.py +656 -0
- package/tools/python_sandbox.py +609 -0
- package/tools/search_providers/__init__.py +77 -0
- package/tools/search_providers/brave.py +115 -0
- package/tools/search_providers/exa.py +116 -0
- package/tools/search_providers/jina.py +104 -0
- package/tools/search_providers/perplexity.py +139 -0
- package/tools/search_providers/synthetic.py +74 -0
- package/tools/session_snapshot.py +736 -0
- package/tools/ssh_manager.py +912 -0
- package/tools/theme_engine.py +294 -0
- package/tools/theme_selector.py +137 -0
- package/tools/web_search.py +622 -0
- package/yaml.py +321 -0
- package/.claude-plugin/scripts/install.sh +0 -9
- package/bun.lock +0 -23
- package/bunfig.toml +0 -3
- package/hooks/_budget.ts +0 -1
- package/hooks/_common.ts +0 -63
- package/hooks/circuit-breaker.ts +0 -101
- package/hooks/config-guard.ts +0 -4
- package/hooks/firewall.ts +0 -20
- package/hooks/policy_engine.ts +0 -156
- package/hooks/post-tool-failure.ts +0 -22
- package/hooks/post-write.ts +0 -4
- package/hooks/pre-tool-inject.ts +0 -4
- package/hooks/prompt-enhancer.ts +0 -46
- package/hooks/quality-runner.ts +0 -24
- package/hooks/secret-guard.ts +0 -4
- package/hooks/session-end-capture.ts +0 -19
- package/hooks/session-start.ts +0 -19
- package/hooks/shadow_manager.ts +0 -81
- package/hooks/stop-gate.ts +0 -22
- package/hooks/stop_dispatcher.ts +0 -147
- package/hooks/test-generator-hook.ts +0 -4
- package/hooks/tool-ledger.ts +0 -27
- package/hooks/trust_review.ts +0 -175
- package/lab/pipeline.ts +0 -75
- package/lab/policies.ts +0 -68
- package/runtime/common.ts +0 -111
- package/runtime/compat.ts +0 -174
- package/runtime/dispatcher.ts +0 -25
- package/runtime/ecosystem.ts +0 -186
- package/runtime/provider_bootstrap.ts +0 -99
- package/runtime/provider_smoke.ts +0 -34
- package/runtime/release_readiness.ts +0 -186
- package/runtime/team_router.ts +0 -144
- package/scripts/check-omg-compat-contract-snapshot.ts +0 -20
- package/scripts/check-omg-standalone-clean.ts +0 -12
- package/scripts/check-runtime-clean.ts +0 -94
- package/scripts/omg.ts +0 -352
- package/scripts/settings-merge.ts +0 -93
- package/tools/commit_splitter.ts +0 -23
- package/tools/git_inspector.ts +0 -18
- package/tools/session_snapshot.ts +0 -47
- package/trac3er-oh-my-god-2.0.0.tgz +0 -0
- package/tsconfig.json +0 -15
package/scripts/omg.py
ADDED
|
@@ -0,0 +1,492 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""OMG 2.0.2 CLI entrypoint.
|
|
3
|
+
|
|
4
|
+
Implements practical command-line flows for:
|
|
5
|
+
- omg ship
|
|
6
|
+
- omg fix --issue
|
|
7
|
+
- omg secure
|
|
8
|
+
- omg maintainer
|
|
9
|
+
- omg trust review
|
|
10
|
+
- omg runtime dispatch
|
|
11
|
+
- omg lab train / omg lab eval
|
|
12
|
+
"""
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
import argparse
|
|
16
|
+
from datetime import datetime, timezone
|
|
17
|
+
import json
|
|
18
|
+
import os
|
|
19
|
+
from pathlib import Path
|
|
20
|
+
import sys
|
|
21
|
+
from typing import Any
|
|
22
|
+
|
|
23
|
+
# --- Path resolution (never relies on CWD) ---
|
|
24
|
+
SCRIPTS_DIR = os.path.dirname(os.path.abspath(__file__))
|
|
25
|
+
ROOT_DIR = Path(SCRIPTS_DIR).resolve().parent
|
|
26
|
+
if str(ROOT_DIR) not in sys.path:
|
|
27
|
+
sys.path.insert(0, str(ROOT_DIR))
|
|
28
|
+
|
|
29
|
+
from hooks.policy_engine import evaluate_bash_command
|
|
30
|
+
from hooks.shadow_manager import create_evidence_pack
|
|
31
|
+
from hooks.trust_review import review_config_change, write_trust_manifest
|
|
32
|
+
from lab.pipeline import publish_artifact, run_pipeline
|
|
33
|
+
from runtime.dispatcher import dispatch_runtime
|
|
34
|
+
from runtime.compat import (
|
|
35
|
+
DEFAULT_CONTRACT_SNAPSHOT_PATH,
|
|
36
|
+
DEFAULT_GAP_REPORT_PATH,
|
|
37
|
+
build_contract_snapshot_payload,
|
|
38
|
+
build_compat_gap_report,
|
|
39
|
+
dispatch_compat_skill,
|
|
40
|
+
get_compat_skill_contract,
|
|
41
|
+
list_compat_skill_contracts,
|
|
42
|
+
list_compat_skills,
|
|
43
|
+
)
|
|
44
|
+
from runtime.adoption import CANONICAL_VERSION
|
|
45
|
+
from runtime.ecosystem import ecosystem_status, list_ecosystem_repos, sync_ecosystem_repos
|
|
46
|
+
from runtime.team_router import TeamDispatchRequest, dispatch_team, execute_ccg_mode, execute_crazy_mode
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def _now_run_id() -> str:
|
|
50
|
+
return datetime.now(timezone.utc).strftime("%Y%m%dT%H%M%S%fZ")
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def _parse_simple_idea_yaml(path: str) -> dict[str, Any]:
|
|
54
|
+
"""Minimal parser for `.omg/idea.yml` template shape."""
|
|
55
|
+
idea: dict[str, Any] = {
|
|
56
|
+
"goal": "",
|
|
57
|
+
"constraints": [],
|
|
58
|
+
"acceptance": [],
|
|
59
|
+
"risk": {"security": [], "performance": [], "compatibility": []},
|
|
60
|
+
"evidence_required": {"tests": [], "security_scans": [], "reproducibility": [], "artifacts": []},
|
|
61
|
+
}
|
|
62
|
+
section: str | None = None
|
|
63
|
+
subsection: str | None = None
|
|
64
|
+
|
|
65
|
+
with open(path, "r", encoding="utf-8") as f:
|
|
66
|
+
for raw in f:
|
|
67
|
+
line = raw.rstrip("\n")
|
|
68
|
+
stripped = line.strip()
|
|
69
|
+
if not stripped or stripped.startswith("#"):
|
|
70
|
+
continue
|
|
71
|
+
|
|
72
|
+
if stripped.startswith("goal:"):
|
|
73
|
+
idea["goal"] = stripped.split(":", 1)[1].strip().strip("\"'")
|
|
74
|
+
section = None
|
|
75
|
+
subsection = None
|
|
76
|
+
continue
|
|
77
|
+
|
|
78
|
+
if stripped in {"constraints:", "acceptance:", "risk:", "evidence_required:"}:
|
|
79
|
+
section = stripped[:-1]
|
|
80
|
+
subsection = None
|
|
81
|
+
continue
|
|
82
|
+
|
|
83
|
+
if section in {"risk", "evidence_required"} and stripped.endswith(":") and not stripped.startswith("- "):
|
|
84
|
+
subsection = stripped[:-1]
|
|
85
|
+
continue
|
|
86
|
+
|
|
87
|
+
if stripped.startswith("- "):
|
|
88
|
+
value = stripped[2:].strip().strip("\"'")
|
|
89
|
+
if section in {"constraints", "acceptance"}:
|
|
90
|
+
idea[section].append(value)
|
|
91
|
+
elif section in {"risk", "evidence_required"} and subsection:
|
|
92
|
+
idea[section].setdefault(subsection, []).append(value)
|
|
93
|
+
|
|
94
|
+
return idea
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def _load_json(path: str) -> dict[str, Any]:
|
|
98
|
+
with open(path, "r", encoding="utf-8") as f:
|
|
99
|
+
data = json.load(f)
|
|
100
|
+
if not isinstance(data, dict):
|
|
101
|
+
raise ValueError(f"Expected object JSON in {path}")
|
|
102
|
+
return data
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def _ensure_project_dir() -> str:
|
|
106
|
+
return os.environ.get("CLAUDE_PROJECT_DIR", os.getcwd())
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def cmd_ship(args: argparse.Namespace) -> int:
|
|
110
|
+
project_dir = _ensure_project_dir()
|
|
111
|
+
idea_path = args.idea
|
|
112
|
+
idea = _parse_simple_idea_yaml(idea_path) if idea_path.endswith((".yml", ".yaml")) else _load_json(idea_path)
|
|
113
|
+
|
|
114
|
+
runtime = args.runtime
|
|
115
|
+
dispatched = dispatch_runtime(runtime, idea)
|
|
116
|
+
if dispatched.get("status") != "ok":
|
|
117
|
+
print(json.dumps(dispatched, indent=2))
|
|
118
|
+
return 2
|
|
119
|
+
|
|
120
|
+
run_id = args.run_id or _now_run_id()
|
|
121
|
+
verification = dispatched.get("verification", {})
|
|
122
|
+
checks = verification.get("checks", []) if isinstance(verification, dict) else []
|
|
123
|
+
evidence_path = create_evidence_pack(
|
|
124
|
+
project_dir,
|
|
125
|
+
run_id,
|
|
126
|
+
tests=checks if isinstance(checks, list) else [],
|
|
127
|
+
security_scans=[],
|
|
128
|
+
diff_summary={"runtime": runtime, "goal": idea.get("goal", "")},
|
|
129
|
+
reproducibility={"command": f"omg ship --runtime {runtime} --idea {idea_path}"},
|
|
130
|
+
unresolved_risks=[],
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
out = {
|
|
134
|
+
"status": "ok",
|
|
135
|
+
"command": "ship",
|
|
136
|
+
"runtime": runtime,
|
|
137
|
+
"run_id": run_id,
|
|
138
|
+
"goal": idea.get("goal", ""),
|
|
139
|
+
"evidence_path": os.path.relpath(evidence_path, project_dir),
|
|
140
|
+
}
|
|
141
|
+
print(json.dumps(out, indent=2))
|
|
142
|
+
return 0
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def cmd_fix(args: argparse.Namespace) -> int:
|
|
146
|
+
goal = f"Fix issue {args.issue}"
|
|
147
|
+
dispatched = dispatch_runtime(args.runtime, {"goal": goal, "acceptance": [f"issue-{args.issue}-resolved"]})
|
|
148
|
+
print(json.dumps(dispatched, indent=2))
|
|
149
|
+
return 0 if dispatched.get("status") == "ok" else 2
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def cmd_secure(args: argparse.Namespace) -> int:
|
|
153
|
+
decision = evaluate_bash_command(args.command)
|
|
154
|
+
print(json.dumps(decision.to_dict(), indent=2))
|
|
155
|
+
return 0 if decision.action != "deny" else 3
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def cmd_maintainer(args: argparse.Namespace) -> int:
|
|
159
|
+
project_dir = _ensure_project_dir()
|
|
160
|
+
out_dir = Path(project_dir) / ".omg" / "evidence"
|
|
161
|
+
out_dir.mkdir(parents=True, exist_ok=True)
|
|
162
|
+
out_file = out_dir / "oss-impact.json"
|
|
163
|
+
payload = {
|
|
164
|
+
"generated_at": datetime.now(timezone.utc).isoformat(),
|
|
165
|
+
"mode": args.mode,
|
|
166
|
+
"activity": {"commits": "unverified", "reviews": "unverified", "releases": "unverified"},
|
|
167
|
+
"dependents": {"direct": "unverified", "transitive": "unverified"},
|
|
168
|
+
"adoption_signals": {"downloads": "unverified", "stars": "unverified"},
|
|
169
|
+
"summary_500_words": "",
|
|
170
|
+
"integrity": {"metric_manipulation": "forbidden"},
|
|
171
|
+
}
|
|
172
|
+
out_file.write_text(json.dumps(payload, indent=2), encoding="utf-8")
|
|
173
|
+
print(json.dumps({"status": "ok", "path": str(out_file)}, indent=2))
|
|
174
|
+
return 0
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def cmd_trust_review(args: argparse.Namespace) -> int:
|
|
178
|
+
old_cfg = _load_json(args.old)
|
|
179
|
+
new_cfg = _load_json(args.new)
|
|
180
|
+
review = review_config_change(args.file, old_cfg, new_cfg)
|
|
181
|
+
manifest = write_trust_manifest(_ensure_project_dir(), review)
|
|
182
|
+
print(json.dumps({"review": review, "manifest": manifest}, indent=2))
|
|
183
|
+
return 0
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
def cmd_runtime_dispatch(args: argparse.Namespace) -> int:
|
|
187
|
+
if args.idea_json:
|
|
188
|
+
idea = json.loads(args.idea_json)
|
|
189
|
+
elif args.idea:
|
|
190
|
+
idea = _load_json(args.idea)
|
|
191
|
+
else:
|
|
192
|
+
idea = {"goal": "unspecified"}
|
|
193
|
+
result = dispatch_runtime(args.runtime, idea)
|
|
194
|
+
print(json.dumps(result, indent=2))
|
|
195
|
+
return 0 if result.get("status") == "ok" else 2
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
def cmd_lab_train(args: argparse.Namespace) -> int:
|
|
199
|
+
job = json.loads(args.job_json) if args.job_json else _load_json(args.job)
|
|
200
|
+
result = run_pipeline(job)
|
|
201
|
+
print(json.dumps(result, indent=2))
|
|
202
|
+
return 0 if result.get("status") in {"ready", "failed_evaluation"} else 2
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
def cmd_lab_eval(args: argparse.Namespace) -> int:
|
|
206
|
+
result = json.loads(args.result_json) if args.result_json else _load_json(args.result)
|
|
207
|
+
out = publish_artifact(result)
|
|
208
|
+
print(json.dumps(out, indent=2))
|
|
209
|
+
return 0 if out.get("status") == "published" else 2
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
def cmd_teams(args: argparse.Namespace) -> int:
|
|
213
|
+
files = [f.strip() for f in args.files.split(",") if f.strip()] if args.files else []
|
|
214
|
+
req = TeamDispatchRequest(
|
|
215
|
+
target=args.target,
|
|
216
|
+
problem=args.problem,
|
|
217
|
+
context=args.context,
|
|
218
|
+
files=files,
|
|
219
|
+
expected_outcome=args.expected_outcome,
|
|
220
|
+
)
|
|
221
|
+
result = dispatch_team(req).to_dict()
|
|
222
|
+
print(json.dumps(result, indent=2))
|
|
223
|
+
return 0
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
def cmd_ccg(args: argparse.Namespace) -> int:
|
|
227
|
+
files = [f.strip() for f in args.files.split(",") if f.strip()] if args.files else []
|
|
228
|
+
result = execute_ccg_mode(
|
|
229
|
+
problem=args.problem,
|
|
230
|
+
project_dir=_ensure_project_dir(),
|
|
231
|
+
context=args.context,
|
|
232
|
+
files=files,
|
|
233
|
+
)
|
|
234
|
+
print(json.dumps(result, indent=2))
|
|
235
|
+
return 0
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
def cmd_crazy(args: argparse.Namespace) -> int:
|
|
239
|
+
files = [f.strip() for f in args.files.split(",") if f.strip()] if args.files else []
|
|
240
|
+
result = execute_crazy_mode(
|
|
241
|
+
problem=args.problem,
|
|
242
|
+
project_dir=_ensure_project_dir(),
|
|
243
|
+
context=args.context,
|
|
244
|
+
files=files,
|
|
245
|
+
)
|
|
246
|
+
print(json.dumps(result, indent=2))
|
|
247
|
+
return 0
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
def cmd_compat_list(args: argparse.Namespace) -> int:
|
|
251
|
+
skills = list_compat_skills()
|
|
252
|
+
print(json.dumps({"status": "ok", "count": len(skills), "skills": skills}, indent=2))
|
|
253
|
+
return 0
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
def cmd_compat_contract(args: argparse.Namespace) -> int:
|
|
257
|
+
if args.all:
|
|
258
|
+
contracts = list_compat_skill_contracts()
|
|
259
|
+
print(json.dumps({"status": "ok", "count": len(contracts), "contracts": contracts}, indent=2))
|
|
260
|
+
return 0
|
|
261
|
+
if not args.skill:
|
|
262
|
+
print(json.dumps({"status": "error", "message": "Provide --skill or --all"}, indent=2))
|
|
263
|
+
return 2
|
|
264
|
+
contract = get_compat_skill_contract(args.skill)
|
|
265
|
+
if not contract:
|
|
266
|
+
print(json.dumps({"status": "error", "message": f"Unknown skill: {args.skill}"}, indent=2))
|
|
267
|
+
return 2
|
|
268
|
+
print(json.dumps({"status": "ok", "contract": contract}, indent=2))
|
|
269
|
+
return 0
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
def cmd_compat_gap_report(args: argparse.Namespace) -> int:
|
|
273
|
+
report = build_compat_gap_report(_ensure_project_dir())
|
|
274
|
+
if args.output:
|
|
275
|
+
with open(args.output, "w", encoding="utf-8") as f:
|
|
276
|
+
json.dump(report, f, indent=2)
|
|
277
|
+
print(json.dumps({"status": "ok", "report": report}, indent=2))
|
|
278
|
+
return 0
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
def cmd_compat_snapshot(args: argparse.Namespace) -> int:
|
|
282
|
+
payload = build_contract_snapshot_payload(include_generated_at=True)
|
|
283
|
+
out_path = args.output or DEFAULT_CONTRACT_SNAPSHOT_PATH
|
|
284
|
+
with open(out_path, "w", encoding="utf-8") as f:
|
|
285
|
+
json.dump(payload, f, indent=2)
|
|
286
|
+
print(json.dumps({"status": "ok", "output": out_path, "count": payload["count"]}, indent=2))
|
|
287
|
+
return 0
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
def cmd_compat_gate(args: argparse.Namespace) -> int:
|
|
291
|
+
report = build_compat_gap_report(_ensure_project_dir())
|
|
292
|
+
if args.output:
|
|
293
|
+
with open(args.output, "w", encoding="utf-8") as f:
|
|
294
|
+
json.dump(report, f, indent=2)
|
|
295
|
+
bridge_count = int(report.get("maturity_counts", {}).get("bridge", 0))
|
|
296
|
+
if bridge_count > args.max_bridge:
|
|
297
|
+
print(
|
|
298
|
+
json.dumps(
|
|
299
|
+
{
|
|
300
|
+
"status": "error",
|
|
301
|
+
"message": f"OMG compat gate failed: bridge={bridge_count} > max_bridge={args.max_bridge}",
|
|
302
|
+
"report": report,
|
|
303
|
+
},
|
|
304
|
+
indent=2,
|
|
305
|
+
)
|
|
306
|
+
)
|
|
307
|
+
return 3
|
|
308
|
+
print(
|
|
309
|
+
json.dumps(
|
|
310
|
+
{
|
|
311
|
+
"status": "ok",
|
|
312
|
+
"message": f"OMG compat gate passed: bridge={bridge_count} <= max_bridge={args.max_bridge}",
|
|
313
|
+
"report": report,
|
|
314
|
+
},
|
|
315
|
+
indent=2,
|
|
316
|
+
)
|
|
317
|
+
)
|
|
318
|
+
return 0
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
def cmd_compat_run(args: argparse.Namespace) -> int:
|
|
322
|
+
files = [f.strip() for f in args.files.split(",") if f.strip()] if args.files else []
|
|
323
|
+
result = dispatch_compat_skill(
|
|
324
|
+
skill=args.skill,
|
|
325
|
+
problem=args.problem,
|
|
326
|
+
context=args.context,
|
|
327
|
+
files=files,
|
|
328
|
+
expected_outcome=args.expected_outcome,
|
|
329
|
+
project_dir=_ensure_project_dir(),
|
|
330
|
+
)
|
|
331
|
+
print(json.dumps(result, indent=2))
|
|
332
|
+
return 0 if result.get("status") == "ok" else 2
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
def cmd_ecosystem_list(args: argparse.Namespace) -> int:
|
|
336
|
+
repos = list_ecosystem_repos()
|
|
337
|
+
print(json.dumps({"status": "ok", "count": len(repos), "repos": repos}, indent=2))
|
|
338
|
+
return 0
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
def cmd_ecosystem_status(args: argparse.Namespace) -> int:
|
|
342
|
+
result = ecosystem_status(project_dir=_ensure_project_dir())
|
|
343
|
+
print(json.dumps(result, indent=2))
|
|
344
|
+
return 0
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
def cmd_ecosystem_sync(args: argparse.Namespace) -> int:
|
|
348
|
+
names = [name.strip() for name in args.names.split(",") if name.strip()] if args.names else []
|
|
349
|
+
result = sync_ecosystem_repos(
|
|
350
|
+
project_dir=_ensure_project_dir(),
|
|
351
|
+
names=names,
|
|
352
|
+
update=bool(args.update),
|
|
353
|
+
depth=int(args.depth),
|
|
354
|
+
)
|
|
355
|
+
print(json.dumps(result, indent=2))
|
|
356
|
+
errors = [entry for entry in result.get("entries", []) if entry.get("status") == "error"]
|
|
357
|
+
return 0 if not errors else 2
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
def _add_compat_subcommands(parent: argparse.ArgumentParser, *, dest: str) -> None:
|
|
361
|
+
compat_sub = parent.add_subparsers(dest=dest, required=True)
|
|
362
|
+
compat_list = compat_sub.add_parser("list", help="List supported legacy skill names")
|
|
363
|
+
compat_list.set_defaults(func=cmd_compat_list)
|
|
364
|
+
compat_contract = compat_sub.add_parser("contract", help="Show skill contract schema")
|
|
365
|
+
compat_contract.add_argument("--skill", default="")
|
|
366
|
+
compat_contract.add_argument("--all", action="store_true")
|
|
367
|
+
compat_contract.set_defaults(func=cmd_compat_contract)
|
|
368
|
+
compat_gap = compat_sub.add_parser("gap-report", help="Write compatibility maturity report")
|
|
369
|
+
compat_gap.add_argument("--output", default=DEFAULT_GAP_REPORT_PATH)
|
|
370
|
+
compat_gap.set_defaults(func=cmd_compat_gap_report)
|
|
371
|
+
compat_snapshot = compat_sub.add_parser("snapshot", help="Write current skill contracts snapshot")
|
|
372
|
+
compat_snapshot.add_argument("--output", default=DEFAULT_CONTRACT_SNAPSHOT_PATH)
|
|
373
|
+
compat_snapshot.set_defaults(func=cmd_compat_snapshot)
|
|
374
|
+
compat_gate = compat_sub.add_parser("gate", help="Fail if bridge skill count exceeds threshold")
|
|
375
|
+
compat_gate.add_argument("--max-bridge", type=int, default=0)
|
|
376
|
+
compat_gate.add_argument("--output", default=DEFAULT_GAP_REPORT_PATH)
|
|
377
|
+
compat_gate.set_defaults(func=cmd_compat_gate)
|
|
378
|
+
compat_run = compat_sub.add_parser("run", help="Run a legacy skill through OMG router")
|
|
379
|
+
compat_run.add_argument("--skill", required=True)
|
|
380
|
+
compat_run.add_argument("--problem", default="")
|
|
381
|
+
compat_run.add_argument("--context", default="")
|
|
382
|
+
compat_run.add_argument("--files", default="")
|
|
383
|
+
compat_run.add_argument("--expected-outcome", default="")
|
|
384
|
+
compat_run.set_defaults(func=cmd_compat_run)
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
def _add_ecosystem_subcommands(parent: argparse.ArgumentParser, *, dest: str) -> None:
|
|
388
|
+
ecosystem_sub = parent.add_subparsers(dest=dest, required=True)
|
|
389
|
+
ecosystem_list = ecosystem_sub.add_parser("list", help="List OMG ecosystem integration targets")
|
|
390
|
+
ecosystem_list.set_defaults(func=cmd_ecosystem_list)
|
|
391
|
+
|
|
392
|
+
ecosystem_status_cmd = ecosystem_sub.add_parser("status", help="Show current ecosystem install status")
|
|
393
|
+
ecosystem_status_cmd.set_defaults(func=cmd_ecosystem_status)
|
|
394
|
+
|
|
395
|
+
ecosystem_sync = ecosystem_sub.add_parser("sync", help="Clone or refresh ecosystem repositories")
|
|
396
|
+
ecosystem_sync.add_argument("--names", default="", help="Comma-separated repo names or aliases")
|
|
397
|
+
ecosystem_sync.add_argument("--update", action="store_true", help="Fetch latest refs for existing clones")
|
|
398
|
+
ecosystem_sync.add_argument("--depth", type=int, default=1, help="Git depth for shallow clone/fetch")
|
|
399
|
+
ecosystem_sync.set_defaults(func=cmd_ecosystem_sync)
|
|
400
|
+
|
|
401
|
+
|
|
402
|
+
def build_parser() -> argparse.ArgumentParser:
|
|
403
|
+
parser = argparse.ArgumentParser(prog="omg", description=f"OMG {CANONICAL_VERSION} CLI")
|
|
404
|
+
sub = parser.add_subparsers(dest="command", required=True)
|
|
405
|
+
|
|
406
|
+
ship = sub.add_parser("ship", help="Idea -> Evidence -> PR flow")
|
|
407
|
+
ship.add_argument("--idea", default=".omg/idea.yml")
|
|
408
|
+
ship.add_argument("--runtime", default="claude", choices=["claude", "gpt", "local"])
|
|
409
|
+
ship.add_argument("--run-id", default="")
|
|
410
|
+
ship.set_defaults(func=cmd_ship)
|
|
411
|
+
|
|
412
|
+
fix = sub.add_parser("fix", help="Issue-driven fix flow")
|
|
413
|
+
fix.add_argument("--issue", required=True)
|
|
414
|
+
fix.add_argument("--runtime", default="claude", choices=["claude", "gpt", "local"])
|
|
415
|
+
fix.set_defaults(func=cmd_fix)
|
|
416
|
+
|
|
417
|
+
secure = sub.add_parser("secure", help="Evaluate command risk")
|
|
418
|
+
secure.add_argument("--command", required=True)
|
|
419
|
+
secure.set_defaults(func=cmd_secure)
|
|
420
|
+
|
|
421
|
+
maintainer = sub.add_parser("maintainer", help="OSS maintainer evidence helper")
|
|
422
|
+
maintainer.add_argument("--mode", default="impact", choices=["triage", "release", "review", "impact"])
|
|
423
|
+
maintainer.set_defaults(func=cmd_maintainer)
|
|
424
|
+
|
|
425
|
+
trust = sub.add_parser("trust", help="Trust review operations")
|
|
426
|
+
trust_sub = trust.add_subparsers(dest="trust_command", required=True)
|
|
427
|
+
trust_review = trust_sub.add_parser("review", help="Review config change")
|
|
428
|
+
trust_review.add_argument("--file", default="settings.json")
|
|
429
|
+
trust_review.add_argument("--old", required=True, help="Path to old config json")
|
|
430
|
+
trust_review.add_argument("--new", required=True, help="Path to new config json")
|
|
431
|
+
trust_review.set_defaults(func=cmd_trust_review)
|
|
432
|
+
|
|
433
|
+
runtime = sub.add_parser("runtime", help="Runtime operations")
|
|
434
|
+
runtime_sub = runtime.add_subparsers(dest="runtime_command", required=True)
|
|
435
|
+
runtime_dispatch = runtime_sub.add_parser("dispatch", help="Dispatch runtime job")
|
|
436
|
+
runtime_dispatch.add_argument("--runtime", required=True, choices=["claude", "gpt", "local"])
|
|
437
|
+
runtime_dispatch.add_argument("--idea", default="", help="Path to idea json")
|
|
438
|
+
runtime_dispatch.add_argument("--idea-json", default="", help="Inline idea json")
|
|
439
|
+
runtime_dispatch.set_defaults(func=cmd_runtime_dispatch)
|
|
440
|
+
|
|
441
|
+
lab = sub.add_parser("lab", help="Lab pipeline operations")
|
|
442
|
+
lab_sub = lab.add_subparsers(dest="lab_command", required=True)
|
|
443
|
+
lab_train = lab_sub.add_parser("train", help="Run lab pipeline job")
|
|
444
|
+
lab_train.add_argument("--job", default="", help="Path to job json")
|
|
445
|
+
lab_train.add_argument("--job-json", default="", help="Inline job json")
|
|
446
|
+
lab_train.set_defaults(func=cmd_lab_train)
|
|
447
|
+
lab_eval = lab_sub.add_parser("eval", help="Publish lab result when eligible")
|
|
448
|
+
lab_eval.add_argument("--result", default="", help="Path to result json")
|
|
449
|
+
lab_eval.add_argument("--result-json", default="", help="Inline result json")
|
|
450
|
+
lab_eval.set_defaults(func=cmd_lab_eval)
|
|
451
|
+
|
|
452
|
+
teams = sub.add_parser("teams", help="Internal OMG team routing")
|
|
453
|
+
teams.add_argument("--target", default="auto", choices=["auto", "codex", "gemini", "ccg"])
|
|
454
|
+
teams.add_argument("--problem", required=True)
|
|
455
|
+
teams.add_argument("--context", default="")
|
|
456
|
+
teams.add_argument("--files", default="")
|
|
457
|
+
teams.add_argument("--expected-outcome", default="")
|
|
458
|
+
teams.set_defaults(func=cmd_teams)
|
|
459
|
+
|
|
460
|
+
ccg = sub.add_parser("ccg", help="OMG CCG (tri-track) routing")
|
|
461
|
+
ccg.add_argument("--problem", required=True)
|
|
462
|
+
ccg.add_argument("--context", default="")
|
|
463
|
+
ccg.add_argument("--files", default="")
|
|
464
|
+
ccg.add_argument("--expected-outcome", default="")
|
|
465
|
+
ccg.set_defaults(func=cmd_ccg)
|
|
466
|
+
|
|
467
|
+
crazy = sub.add_parser("crazy", help="OMG CRAZY mode - parallel multi-agent orchestration")
|
|
468
|
+
crazy.add_argument("--problem", required=True, help="Task description")
|
|
469
|
+
crazy.add_argument("--context", default="", help="Additional context")
|
|
470
|
+
crazy.add_argument("--files", default="", help="Comma-separated focus files")
|
|
471
|
+
crazy.set_defaults(func=cmd_crazy)
|
|
472
|
+
|
|
473
|
+
compat = sub.add_parser("compat", help="OMG legacy compatibility bridge")
|
|
474
|
+
_add_compat_subcommands(compat, dest="compat_command")
|
|
475
|
+
|
|
476
|
+
omc = sub.add_parser("omc", help="Alias of `compat` for legacy scripts")
|
|
477
|
+
_add_compat_subcommands(omc, dest="omc_command")
|
|
478
|
+
|
|
479
|
+
ecosystem = sub.add_parser("ecosystem", help="Upstream ecosystem sync and status")
|
|
480
|
+
_add_ecosystem_subcommands(ecosystem, dest="ecosystem_command")
|
|
481
|
+
|
|
482
|
+
return parser
|
|
483
|
+
|
|
484
|
+
|
|
485
|
+
def main(argv: list[str] | None = None) -> int:
|
|
486
|
+
parser = build_parser()
|
|
487
|
+
args = parser.parse_args(argv)
|
|
488
|
+
return int(args.func(args))
|
|
489
|
+
|
|
490
|
+
|
|
491
|
+
if __name__ == "__main__":
|
|
492
|
+
raise SystemExit(main())
|