@trac3er/oh-my-god 2.0.3 → 2.0.5
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/.agents/skills/omg/AGENTS.fragment.md +5 -0
- package/.agents/skills/omg/algorithms/SKILL.md +11 -0
- package/.agents/skills/omg/algorithms/openai.yaml +11 -0
- package/.agents/skills/omg/api-twin/SKILL.md +11 -0
- package/.agents/skills/omg/api-twin/openai.yaml +12 -0
- package/.agents/skills/omg/codex-mcp.toml +4 -0
- package/.agents/skills/omg/control-plane/SKILL.md +11 -0
- package/.agents/skills/omg/control-plane/openai.yaml +14 -0
- package/.agents/skills/omg/data-lineage/SKILL.md +11 -0
- package/.agents/skills/omg/data-lineage/openai.yaml +12 -0
- package/.agents/skills/omg/delta-classifier/SKILL.md +11 -0
- package/.agents/skills/omg/delta-classifier/openai.yaml +12 -0
- package/.agents/skills/omg/eval-gate/SKILL.md +11 -0
- package/.agents/skills/omg/eval-gate/openai.yaml +12 -0
- package/.agents/skills/omg/health/SKILL.md +11 -0
- package/.agents/skills/omg/health/openai.yaml +11 -0
- package/.agents/skills/omg/hook-governor/SKILL.md +11 -0
- package/.agents/skills/omg/hook-governor/openai.yaml +11 -0
- package/.agents/skills/omg/incident-replay/SKILL.md +11 -0
- package/.agents/skills/omg/incident-replay/openai.yaml +12 -0
- package/.agents/skills/omg/lsp-pack/SKILL.md +11 -0
- package/.agents/skills/omg/lsp-pack/openai.yaml +11 -0
- package/.agents/skills/omg/mcp-fabric/SKILL.md +11 -0
- package/.agents/skills/omg/mcp-fabric/openai.yaml +13 -0
- package/.agents/skills/omg/preflight/SKILL.md +11 -0
- package/.agents/skills/omg/preflight/openai.yaml +12 -0
- package/.agents/skills/omg/remote-supervisor/SKILL.md +11 -0
- package/.agents/skills/omg/remote-supervisor/openai.yaml +12 -0
- package/.agents/skills/omg/robotics/SKILL.md +11 -0
- package/.agents/skills/omg/robotics/openai.yaml +11 -0
- package/.agents/skills/omg/secure-worktree-pipeline/SKILL.md +11 -0
- package/.agents/skills/omg/secure-worktree-pipeline/openai.yaml +12 -0
- package/.agents/skills/omg/security-check/SKILL.md +11 -0
- package/.agents/skills/omg/security-check/openai.yaml +13 -0
- package/.agents/skills/omg/tracebank/SKILL.md +11 -0
- package/.agents/skills/omg/tracebank/openai.yaml +12 -0
- package/.agents/skills/omg/vision/SKILL.md +11 -0
- package/.agents/skills/omg/vision/openai.yaml +11 -0
- package/.claude-plugin/marketplace.json +3 -3
- package/.claude-plugin/plugin.json +1 -1
- package/.claude-plugin/scripts/uninstall.sh +2 -2
- package/.mcp.json +20 -4
- package/CHANGELOG.md +10 -0
- package/OMG-setup.sh +9 -3
- package/OMG_COMPAT_CONTRACT.md +92 -0
- package/README.md +24 -4
- package/SECURITY.md +6 -0
- package/commands/OMG:api-twin.md +22 -0
- package/commands/OMG:preflight.md +26 -0
- package/commands/OMG:security-check.md +28 -0
- package/commands/__init__.py +1 -0
- package/control_plane/__init__.py +2 -0
- package/control_plane/openapi.yaml +228 -0
- package/control_plane/server.py +123 -0
- package/control_plane/service.py +185 -0
- package/dist/enterprise/bundle/.agents/skills/omg/AGENTS.fragment.md +5 -0
- package/dist/enterprise/bundle/.agents/skills/omg/algorithms/SKILL.md +11 -0
- package/dist/enterprise/bundle/.agents/skills/omg/algorithms/openai.yaml +11 -0
- package/dist/enterprise/bundle/.agents/skills/omg/api-twin/SKILL.md +11 -0
- package/dist/enterprise/bundle/.agents/skills/omg/api-twin/openai.yaml +12 -0
- package/dist/enterprise/bundle/.agents/skills/omg/codex-mcp.toml +4 -0
- package/dist/enterprise/bundle/.agents/skills/omg/control-plane/SKILL.md +11 -0
- package/dist/enterprise/bundle/.agents/skills/omg/control-plane/openai.yaml +14 -0
- package/dist/enterprise/bundle/.agents/skills/omg/data-lineage/SKILL.md +11 -0
- package/dist/enterprise/bundle/.agents/skills/omg/data-lineage/openai.yaml +12 -0
- package/dist/enterprise/bundle/.agents/skills/omg/delta-classifier/SKILL.md +11 -0
- package/dist/enterprise/bundle/.agents/skills/omg/delta-classifier/openai.yaml +12 -0
- package/dist/enterprise/bundle/.agents/skills/omg/eval-gate/SKILL.md +11 -0
- package/dist/enterprise/bundle/.agents/skills/omg/eval-gate/openai.yaml +12 -0
- package/dist/enterprise/bundle/.agents/skills/omg/health/SKILL.md +11 -0
- package/dist/enterprise/bundle/.agents/skills/omg/health/openai.yaml +11 -0
- package/dist/enterprise/bundle/.agents/skills/omg/hook-governor/SKILL.md +11 -0
- package/dist/enterprise/bundle/.agents/skills/omg/hook-governor/openai.yaml +11 -0
- package/dist/enterprise/bundle/.agents/skills/omg/incident-replay/SKILL.md +11 -0
- package/dist/enterprise/bundle/.agents/skills/omg/incident-replay/openai.yaml +12 -0
- package/dist/enterprise/bundle/.agents/skills/omg/lsp-pack/SKILL.md +11 -0
- package/dist/enterprise/bundle/.agents/skills/omg/lsp-pack/openai.yaml +11 -0
- package/dist/enterprise/bundle/.agents/skills/omg/mcp-fabric/SKILL.md +11 -0
- package/dist/enterprise/bundle/.agents/skills/omg/mcp-fabric/openai.yaml +13 -0
- package/dist/enterprise/bundle/.agents/skills/omg/preflight/SKILL.md +11 -0
- package/dist/enterprise/bundle/.agents/skills/omg/preflight/openai.yaml +12 -0
- package/dist/enterprise/bundle/.agents/skills/omg/remote-supervisor/SKILL.md +11 -0
- package/dist/enterprise/bundle/.agents/skills/omg/remote-supervisor/openai.yaml +12 -0
- package/dist/enterprise/bundle/.agents/skills/omg/robotics/SKILL.md +11 -0
- package/dist/enterprise/bundle/.agents/skills/omg/robotics/openai.yaml +11 -0
- package/dist/enterprise/bundle/.agents/skills/omg/secure-worktree-pipeline/SKILL.md +11 -0
- package/dist/enterprise/bundle/.agents/skills/omg/secure-worktree-pipeline/openai.yaml +12 -0
- package/dist/enterprise/bundle/.agents/skills/omg/security-check/SKILL.md +11 -0
- package/dist/enterprise/bundle/.agents/skills/omg/security-check/openai.yaml +13 -0
- package/dist/enterprise/bundle/.agents/skills/omg/tracebank/SKILL.md +11 -0
- package/dist/enterprise/bundle/.agents/skills/omg/tracebank/openai.yaml +12 -0
- package/dist/enterprise/bundle/.agents/skills/omg/vision/SKILL.md +11 -0
- package/dist/enterprise/bundle/.agents/skills/omg/vision/openai.yaml +11 -0
- package/dist/enterprise/bundle/.claude-plugin/marketplace.json +36 -0
- package/dist/enterprise/bundle/.claude-plugin/plugin.json +23 -0
- package/dist/enterprise/bundle/.mcp.json +40 -0
- package/dist/enterprise/bundle/OMG_COMPAT_CONTRACT.md +92 -0
- package/dist/enterprise/bundle/registry/bundles/algorithms.yaml +45 -0
- package/dist/enterprise/bundle/registry/bundles/api-twin.yaml +48 -0
- package/dist/enterprise/bundle/registry/bundles/control-plane.yaml +61 -0
- package/dist/enterprise/bundle/registry/bundles/data-lineage.yaml +47 -0
- package/dist/enterprise/bundle/registry/bundles/delta-classifier.yaml +47 -0
- package/dist/enterprise/bundle/registry/bundles/eval-gate.yaml +47 -0
- package/dist/enterprise/bundle/registry/bundles/health.yaml +45 -0
- package/dist/enterprise/bundle/registry/bundles/hook-governor.yaml +97 -0
- package/dist/enterprise/bundle/registry/bundles/incident-replay.yaml +47 -0
- package/dist/enterprise/bundle/registry/bundles/lsp-pack.yaml +48 -0
- package/dist/enterprise/bundle/registry/bundles/mcp-fabric.yaml +53 -0
- package/dist/enterprise/bundle/registry/bundles/preflight.yaml +48 -0
- package/dist/enterprise/bundle/registry/bundles/remote-supervisor.yaml +49 -0
- package/dist/enterprise/bundle/registry/bundles/robotics.yaml +45 -0
- package/dist/enterprise/bundle/registry/bundles/secure-worktree-pipeline.yaml +54 -0
- package/dist/enterprise/bundle/registry/bundles/security-check.yaml +50 -0
- package/dist/enterprise/bundle/registry/bundles/tracebank.yaml +47 -0
- package/dist/enterprise/bundle/registry/bundles/vision.yaml +45 -0
- package/dist/enterprise/bundle/registry/omg-capability.schema.json +80 -0
- package/dist/enterprise/bundle/settings.json +381 -0
- package/dist/enterprise/manifest.json +255 -0
- package/dist/public/bundle/.agents/skills/omg/AGENTS.fragment.md +5 -0
- package/dist/public/bundle/.agents/skills/omg/algorithms/SKILL.md +11 -0
- package/dist/public/bundle/.agents/skills/omg/algorithms/openai.yaml +11 -0
- package/dist/public/bundle/.agents/skills/omg/api-twin/SKILL.md +11 -0
- package/dist/public/bundle/.agents/skills/omg/api-twin/openai.yaml +12 -0
- package/dist/public/bundle/.agents/skills/omg/codex-mcp.toml +4 -0
- package/dist/public/bundle/.agents/skills/omg/control-plane/SKILL.md +11 -0
- package/dist/public/bundle/.agents/skills/omg/control-plane/openai.yaml +14 -0
- package/dist/public/bundle/.agents/skills/omg/data-lineage/SKILL.md +11 -0
- package/dist/public/bundle/.agents/skills/omg/data-lineage/openai.yaml +12 -0
- package/dist/public/bundle/.agents/skills/omg/delta-classifier/SKILL.md +11 -0
- package/dist/public/bundle/.agents/skills/omg/delta-classifier/openai.yaml +12 -0
- package/dist/public/bundle/.agents/skills/omg/eval-gate/SKILL.md +11 -0
- package/dist/public/bundle/.agents/skills/omg/eval-gate/openai.yaml +12 -0
- package/dist/public/bundle/.agents/skills/omg/health/SKILL.md +11 -0
- package/dist/public/bundle/.agents/skills/omg/health/openai.yaml +11 -0
- package/dist/public/bundle/.agents/skills/omg/hook-governor/SKILL.md +11 -0
- package/dist/public/bundle/.agents/skills/omg/hook-governor/openai.yaml +11 -0
- package/dist/public/bundle/.agents/skills/omg/incident-replay/SKILL.md +11 -0
- package/dist/public/bundle/.agents/skills/omg/incident-replay/openai.yaml +12 -0
- package/dist/public/bundle/.agents/skills/omg/lsp-pack/SKILL.md +11 -0
- package/dist/public/bundle/.agents/skills/omg/lsp-pack/openai.yaml +11 -0
- package/dist/public/bundle/.agents/skills/omg/mcp-fabric/SKILL.md +11 -0
- package/dist/public/bundle/.agents/skills/omg/mcp-fabric/openai.yaml +13 -0
- package/dist/public/bundle/.agents/skills/omg/preflight/SKILL.md +11 -0
- package/dist/public/bundle/.agents/skills/omg/preflight/openai.yaml +12 -0
- package/dist/public/bundle/.agents/skills/omg/remote-supervisor/SKILL.md +11 -0
- package/dist/public/bundle/.agents/skills/omg/remote-supervisor/openai.yaml +12 -0
- package/dist/public/bundle/.agents/skills/omg/robotics/SKILL.md +11 -0
- package/dist/public/bundle/.agents/skills/omg/robotics/openai.yaml +11 -0
- package/dist/public/bundle/.agents/skills/omg/secure-worktree-pipeline/SKILL.md +11 -0
- package/dist/public/bundle/.agents/skills/omg/secure-worktree-pipeline/openai.yaml +12 -0
- package/dist/public/bundle/.agents/skills/omg/security-check/SKILL.md +11 -0
- package/dist/public/bundle/.agents/skills/omg/security-check/openai.yaml +13 -0
- package/dist/public/bundle/.agents/skills/omg/tracebank/SKILL.md +11 -0
- package/dist/public/bundle/.agents/skills/omg/tracebank/openai.yaml +12 -0
- package/dist/public/bundle/.agents/skills/omg/vision/SKILL.md +11 -0
- package/dist/public/bundle/.agents/skills/omg/vision/openai.yaml +11 -0
- package/dist/public/bundle/.claude-plugin/marketplace.json +36 -0
- package/dist/public/bundle/.claude-plugin/plugin.json +23 -0
- package/dist/public/bundle/.mcp.json +40 -0
- package/dist/public/bundle/OMG_COMPAT_CONTRACT.md +92 -0
- package/dist/public/bundle/registry/bundles/algorithms.yaml +45 -0
- package/dist/public/bundle/registry/bundles/api-twin.yaml +48 -0
- package/dist/public/bundle/registry/bundles/control-plane.yaml +61 -0
- package/dist/public/bundle/registry/bundles/data-lineage.yaml +47 -0
- package/dist/public/bundle/registry/bundles/delta-classifier.yaml +47 -0
- package/dist/public/bundle/registry/bundles/eval-gate.yaml +47 -0
- package/dist/public/bundle/registry/bundles/health.yaml +45 -0
- package/dist/public/bundle/registry/bundles/hook-governor.yaml +97 -0
- package/dist/public/bundle/registry/bundles/incident-replay.yaml +47 -0
- package/dist/public/bundle/registry/bundles/lsp-pack.yaml +48 -0
- package/dist/public/bundle/registry/bundles/mcp-fabric.yaml +53 -0
- package/dist/public/bundle/registry/bundles/preflight.yaml +48 -0
- package/dist/public/bundle/registry/bundles/remote-supervisor.yaml +49 -0
- package/dist/public/bundle/registry/bundles/robotics.yaml +45 -0
- package/dist/public/bundle/registry/bundles/secure-worktree-pipeline.yaml +54 -0
- package/dist/public/bundle/registry/bundles/security-check.yaml +50 -0
- package/dist/public/bundle/registry/bundles/tracebank.yaml +47 -0
- package/dist/public/bundle/registry/bundles/vision.yaml +45 -0
- package/dist/public/bundle/registry/omg-capability.schema.json +80 -0
- package/dist/public/bundle/settings.json +379 -0
- package/dist/public/manifest.json +255 -0
- package/docs/assets/omg-hud.svg +32 -0
- package/docs/install/claude-code.md +31 -0
- package/docs/install/codex.md +29 -0
- package/docs/migration/native-adoption.md +57 -0
- package/docs/proof.md +55 -0
- package/docs/release-checklist.md +38 -0
- package/docs/transcripts/crazy.md +17 -0
- package/docs/transcripts/setup.md +25 -0
- package/hooks/policy_engine.py +38 -7
- package/hooks/post-write.py +1 -1
- package/hooks/prompt-enhancer.py +1 -1
- package/hooks/security_validators.py +75 -0
- package/hooks/setup_wizard.py +43 -8
- package/hooks/shadow_manager.py +28 -2
- package/package.json +1 -1
- package/plugins/README.md +3 -1
- package/plugins/__init__.py +1 -0
- package/plugins/advanced/commands/OMG:deep-plan.md +1 -1
- package/plugins/advanced/commands/OMG:security-review.md +10 -113
- package/plugins/advanced/commands/OMG:ship.md +1 -1
- package/plugins/advanced/plugin.json +1 -10
- package/plugins/core/plugin.json +25 -2
- package/pyproject.toml +38 -2
- package/registry/__init__.py +1 -0
- package/registry/bundles/algorithms.yaml +45 -0
- package/registry/bundles/api-twin.yaml +48 -0
- package/registry/bundles/control-plane.yaml +61 -0
- package/registry/bundles/data-lineage.yaml +47 -0
- package/registry/bundles/delta-classifier.yaml +47 -0
- package/registry/bundles/eval-gate.yaml +47 -0
- package/registry/bundles/health.yaml +45 -0
- package/registry/bundles/hook-governor.yaml +97 -0
- package/registry/bundles/incident-replay.yaml +47 -0
- package/registry/bundles/lsp-pack.yaml +48 -0
- package/registry/bundles/mcp-fabric.yaml +53 -0
- package/registry/bundles/preflight.yaml +48 -0
- package/registry/bundles/remote-supervisor.yaml +49 -0
- package/registry/bundles/robotics.yaml +45 -0
- package/registry/bundles/secure-worktree-pipeline.yaml +54 -0
- package/registry/bundles/security-check.yaml +50 -0
- package/registry/bundles/tracebank.yaml +47 -0
- package/registry/bundles/vision.yaml +45 -0
- package/registry/omg-capability.schema.json +80 -0
- package/registry/verify_artifact.py +90 -0
- package/runtime/adapters/claude.py +3 -0
- package/runtime/adapters/gpt.py +3 -0
- package/runtime/adapters/local.py +3 -0
- package/runtime/adoption.py +1 -1
- package/runtime/api_twin.py +179 -0
- package/runtime/asset_loader.py +62 -0
- package/runtime/compat.py +24 -3
- package/runtime/contract_compiler.py +847 -0
- package/runtime/data_lineage.py +73 -0
- package/runtime/delta_classifier.py +81 -0
- package/runtime/domain_packs.py +46 -0
- package/runtime/ecosystem.py +1 -1
- package/runtime/eval_gate.py +50 -0
- package/runtime/guide_assert.py +45 -0
- package/runtime/incident_replay.py +47 -0
- package/runtime/mcp_config_writers.py +147 -30
- package/runtime/mcp_memory_server.py +1 -1
- package/runtime/omg_compat_contract_snapshot.json +9 -8
- package/runtime/omg_contract_snapshot.json +9 -8
- package/runtime/omg_mcp_server.py +207 -0
- package/runtime/preflight.py +73 -0
- package/runtime/providers/codex_provider.py +2 -12
- package/runtime/providers/gemini_provider.py +2 -21
- package/runtime/providers/kimi_provider.py +2 -21
- package/runtime/remote_supervisor.py +64 -0
- package/runtime/runtime_profile.py +61 -0
- package/runtime/security_check.py +464 -0
- package/runtime/subagent_dispatcher.py +117 -10
- package/runtime/team_router.py +3 -1
- package/runtime/tracebank.py +53 -0
- package/runtime/untrusted_content.py +102 -0
- package/scripts/omg.py +360 -2
- package/settings.json +81 -18
- package/tools/python_repl.py +33 -3
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"""Lineage manifests for generated OMG artifacts."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from datetime import datetime, timezone
|
|
5
|
+
import json
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import Any
|
|
8
|
+
from uuid import uuid4
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def _now() -> str:
|
|
12
|
+
return datetime.now(timezone.utc).isoformat()
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def build_lineage_manifest(
|
|
16
|
+
project_dir: str,
|
|
17
|
+
*,
|
|
18
|
+
artifact_type: str,
|
|
19
|
+
sources: list[dict[str, Any]],
|
|
20
|
+
privacy: str,
|
|
21
|
+
license: str,
|
|
22
|
+
derivation: dict[str, Any],
|
|
23
|
+
trace_id: str | None = None,
|
|
24
|
+
) -> dict[str, Any]:
|
|
25
|
+
lineage_id = f"lineage-{uuid4().hex}"
|
|
26
|
+
payload = {
|
|
27
|
+
"schema": "DataLineageManifest",
|
|
28
|
+
"lineage_id": lineage_id,
|
|
29
|
+
"generated_at": _now(),
|
|
30
|
+
"artifact_type": artifact_type,
|
|
31
|
+
"sources": sources,
|
|
32
|
+
"privacy": privacy,
|
|
33
|
+
"license": license,
|
|
34
|
+
"derivation": derivation,
|
|
35
|
+
"trace_id": trace_id or "",
|
|
36
|
+
}
|
|
37
|
+
validation = validate_lineage_manifest(payload)
|
|
38
|
+
payload["status"] = validation["status"]
|
|
39
|
+
payload["errors"] = validation["errors"]
|
|
40
|
+
|
|
41
|
+
rel_path = Path(".omg") / "lineage" / f"{lineage_id}.json"
|
|
42
|
+
path = Path(project_dir) / rel_path
|
|
43
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
44
|
+
path.write_text(json.dumps(payload, indent=2, ensure_ascii=True) + "\n", encoding="utf-8")
|
|
45
|
+
payload["path"] = rel_path.as_posix()
|
|
46
|
+
return payload
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def validate_lineage_manifest(payload: dict[str, Any]) -> dict[str, Any]:
|
|
50
|
+
errors: list[str] = []
|
|
51
|
+
if not payload.get("artifact_type"):
|
|
52
|
+
errors.append("artifact_type is required")
|
|
53
|
+
if not payload.get("privacy"):
|
|
54
|
+
errors.append("privacy is required")
|
|
55
|
+
if not payload.get("license"):
|
|
56
|
+
errors.append("license is required")
|
|
57
|
+
sources = payload.get("sources", [])
|
|
58
|
+
if not isinstance(sources, list) or not sources:
|
|
59
|
+
errors.append("sources are required")
|
|
60
|
+
else:
|
|
61
|
+
for idx, source in enumerate(sources):
|
|
62
|
+
if not isinstance(source, dict):
|
|
63
|
+
errors.append(f"source {idx} must be an object")
|
|
64
|
+
continue
|
|
65
|
+
if not source.get("license"):
|
|
66
|
+
errors.append(f"source {idx} missing license")
|
|
67
|
+
if not source.get("path"):
|
|
68
|
+
errors.append(f"source {idx} missing path")
|
|
69
|
+
return {
|
|
70
|
+
"schema": "DataLineageValidationResult",
|
|
71
|
+
"status": "ok" if not errors else "error",
|
|
72
|
+
"errors": errors,
|
|
73
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"""Repo-aware change classification for routing and policy attachment."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import json
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
import subprocess
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
_CATEGORY_RULES: dict[str, tuple[str, ...]] = {
|
|
11
|
+
"auth": ("auth", "token", "secret", "login", "credential"),
|
|
12
|
+
"payment": ("payment", "billing", "invoice", "stripe", "checkout"),
|
|
13
|
+
"db": ("migration", "schema", "database", "sql", "postgres", "mysql"),
|
|
14
|
+
"infra": ("terraform", ".tf", "deploy", "helm", "k8s", "docker"),
|
|
15
|
+
"api": ("openapi", "swagger", "postman", "endpoint", "api"),
|
|
16
|
+
"data": ("dataset", "lineage", "privacy", "warehouse", "etl"),
|
|
17
|
+
"compliance": ("gdpr", "hipaa", "pci", "soc2", "privacy"),
|
|
18
|
+
"robotics": ("robot", "actuator", "sensor", "simulator"),
|
|
19
|
+
"vision": ("vision", "image", "camera", "cv"),
|
|
20
|
+
"health": ("health", "patient", "clinical", "medical"),
|
|
21
|
+
"algorithms": ("algorithm", "benchmark", "determinism", "complexity"),
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def classify_project_changes(
|
|
26
|
+
project_dir: str,
|
|
27
|
+
*,
|
|
28
|
+
touched_files: list[str] | None = None,
|
|
29
|
+
goal: str = "",
|
|
30
|
+
) -> dict[str, Any]:
|
|
31
|
+
files = touched_files if touched_files is not None else _discover_files(project_dir)
|
|
32
|
+
manifest_names = sorted(path.name for path in Path(project_dir).glob("*") if path.is_file())
|
|
33
|
+
haystacks = [goal.lower(), *[file.lower() for file in files], *[name.lower() for name in manifest_names]]
|
|
34
|
+
|
|
35
|
+
categories = {
|
|
36
|
+
category
|
|
37
|
+
for category, tokens in _CATEGORY_RULES.items()
|
|
38
|
+
if any(token in haystack for token in tokens for haystack in haystacks)
|
|
39
|
+
}
|
|
40
|
+
if not categories:
|
|
41
|
+
categories.add("implementation")
|
|
42
|
+
|
|
43
|
+
result = {
|
|
44
|
+
"schema": "DeltaClassification",
|
|
45
|
+
"project_dir": project_dir,
|
|
46
|
+
"goal": goal,
|
|
47
|
+
"categories": sorted(categories),
|
|
48
|
+
"touched_files": files,
|
|
49
|
+
"manifests": manifest_names,
|
|
50
|
+
}
|
|
51
|
+
return result
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def _discover_files(project_dir: str) -> list[str]:
|
|
55
|
+
root = Path(project_dir)
|
|
56
|
+
git_dir = root / ".git"
|
|
57
|
+
if git_dir.exists():
|
|
58
|
+
proc = subprocess.run(
|
|
59
|
+
["git", "diff", "--name-only", "HEAD"],
|
|
60
|
+
cwd=str(root),
|
|
61
|
+
capture_output=True,
|
|
62
|
+
text=True,
|
|
63
|
+
check=False,
|
|
64
|
+
timeout=10,
|
|
65
|
+
)
|
|
66
|
+
if proc.returncode == 0:
|
|
67
|
+
files = [line.strip() for line in proc.stdout.splitlines() if line.strip()]
|
|
68
|
+
if files:
|
|
69
|
+
return files
|
|
70
|
+
|
|
71
|
+
discovered: list[str] = []
|
|
72
|
+
for path in sorted(root.rglob("*")):
|
|
73
|
+
if not path.is_file():
|
|
74
|
+
continue
|
|
75
|
+
rel = path.relative_to(root).as_posix()
|
|
76
|
+
if rel.startswith(".omg/"):
|
|
77
|
+
continue
|
|
78
|
+
discovered.append(rel)
|
|
79
|
+
if len(discovered) >= 32:
|
|
80
|
+
break
|
|
81
|
+
return discovered
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"""Optional domain pack contracts for high-risk verticals."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
DOMAIN_PACKS: dict[str, dict[str, Any]] = {
|
|
8
|
+
"robotics": {
|
|
9
|
+
"name": "robotics",
|
|
10
|
+
"required_approvals": ["actuation-approval"],
|
|
11
|
+
"required_evidence": ["simulator-replay", "kill-switch-check"],
|
|
12
|
+
"policy_modules": ["safe-actuation", "simulator-gate"],
|
|
13
|
+
"eval_hooks": ["robotics-sim"],
|
|
14
|
+
"replay_hooks": ["incident-replay"],
|
|
15
|
+
},
|
|
16
|
+
"vision": {
|
|
17
|
+
"name": "vision",
|
|
18
|
+
"required_approvals": [],
|
|
19
|
+
"required_evidence": ["dataset-provenance", "drift-check"],
|
|
20
|
+
"policy_modules": ["dataset-lineage", "drift-gate"],
|
|
21
|
+
"eval_hooks": ["vision-regression"],
|
|
22
|
+
"replay_hooks": ["incident-replay"],
|
|
23
|
+
},
|
|
24
|
+
"algorithms": {
|
|
25
|
+
"name": "algorithms",
|
|
26
|
+
"required_approvals": [],
|
|
27
|
+
"required_evidence": ["benchmark-harness", "determinism-check"],
|
|
28
|
+
"policy_modules": ["benchmark-gate", "determinism-gate"],
|
|
29
|
+
"eval_hooks": ["algorithm-benchmarks"],
|
|
30
|
+
"replay_hooks": ["incident-replay"],
|
|
31
|
+
},
|
|
32
|
+
"health": {
|
|
33
|
+
"name": "health",
|
|
34
|
+
"required_approvals": ["human-review"],
|
|
35
|
+
"required_evidence": ["audit-trail", "restricted-tools", "provenance"],
|
|
36
|
+
"policy_modules": ["human-review", "privacy-gate"],
|
|
37
|
+
"eval_hooks": ["health-safety"],
|
|
38
|
+
"replay_hooks": ["incident-replay"],
|
|
39
|
+
},
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def get_domain_pack_contract(name: str) -> dict[str, Any]:
|
|
44
|
+
if name not in DOMAIN_PACKS:
|
|
45
|
+
raise KeyError(name)
|
|
46
|
+
return dict(DOMAIN_PACKS[name])
|
package/runtime/ecosystem.py
CHANGED
|
@@ -8,7 +8,7 @@ import subprocess
|
|
|
8
8
|
from typing import Any
|
|
9
9
|
|
|
10
10
|
ECOSYSTEM_SCHEMA = "OmgEcosystemCatalog"
|
|
11
|
-
ECOSYSTEM_CATALOG_VERSION = "
|
|
11
|
+
ECOSYSTEM_CATALOG_VERSION = "2.0.5"
|
|
12
12
|
ECOSYSTEM_LOCK_SCHEMA = "OmgEcosystemLock"
|
|
13
13
|
DEFAULT_ECOSYSTEM_REPO_DIR = ".omg/ecosystem/repos"
|
|
14
14
|
DEFAULT_ECOSYSTEM_LOCK_PATH = ".omg/state/ecosystem-lock.json"
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"""Reproducible evaluation results for release gating."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from datetime import datetime, timezone
|
|
5
|
+
import json
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
EVAL_GATE_LATEST_REL_PATH = Path(".omg") / "evals" / "latest.json"
|
|
11
|
+
EVAL_GATE_HISTORY_REL_PATH = Path(".omg") / "evals" / "history.jsonl"
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def _now() -> str:
|
|
15
|
+
return datetime.now(timezone.utc).isoformat()
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def evaluate_trace(
|
|
19
|
+
project_dir: str,
|
|
20
|
+
*,
|
|
21
|
+
trace_id: str,
|
|
22
|
+
suites: list[str],
|
|
23
|
+
metrics: dict[str, float],
|
|
24
|
+
regression_threshold: float = 0.95,
|
|
25
|
+
) -> dict[str, Any]:
|
|
26
|
+
scorecard = {name: float(metrics.get(name, 0.0)) for name in suites}
|
|
27
|
+
regressed = any(score < regression_threshold for score in scorecard.values())
|
|
28
|
+
result = {
|
|
29
|
+
"schema": "EvalGateResult",
|
|
30
|
+
"trace_id": trace_id,
|
|
31
|
+
"evaluated_at": _now(),
|
|
32
|
+
"status": "fail" if regressed else "ok",
|
|
33
|
+
"suites": suites,
|
|
34
|
+
"metrics": scorecard,
|
|
35
|
+
"summary": {
|
|
36
|
+
"regressed": regressed,
|
|
37
|
+
"regression_threshold": regression_threshold,
|
|
38
|
+
},
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
latest_path = Path(project_dir) / EVAL_GATE_LATEST_REL_PATH
|
|
42
|
+
latest_path.parent.mkdir(parents=True, exist_ok=True)
|
|
43
|
+
latest_path.write_text(json.dumps(result, indent=2, ensure_ascii=True) + "\n", encoding="utf-8")
|
|
44
|
+
|
|
45
|
+
history_path = Path(project_dir) / EVAL_GATE_HISTORY_REL_PATH
|
|
46
|
+
with history_path.open("a", encoding="utf-8") as handle:
|
|
47
|
+
handle.write(json.dumps(result, ensure_ascii=True) + "\n")
|
|
48
|
+
|
|
49
|
+
result["path"] = EVAL_GATE_LATEST_REL_PATH.as_posix()
|
|
50
|
+
return result
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"""Rule-based output assertions for OMG guide checks."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def guide_assert(candidate: str, rules: dict[str, Any]) -> dict[str, Any]:
|
|
8
|
+
text = candidate or ""
|
|
9
|
+
lowered = text.lower()
|
|
10
|
+
violations: list[dict[str, str]] = []
|
|
11
|
+
|
|
12
|
+
for goal in _as_list(rules.get("goals")):
|
|
13
|
+
if "todo" in goal.lower() and "todo" in lowered:
|
|
14
|
+
violations.append({"rule_type": "goal", "rule": goal, "reason": "candidate still includes TODO markers"})
|
|
15
|
+
|
|
16
|
+
for non_goal in _as_list(rules.get("non_goals")):
|
|
17
|
+
if _mentions(lowered, non_goal):
|
|
18
|
+
violations.append({"rule_type": "non_goal", "rule": non_goal, "reason": "candidate mentions an explicit non-goal"})
|
|
19
|
+
|
|
20
|
+
for criterion in _as_list(rules.get("acceptance_criteria")):
|
|
21
|
+
if "production-ready" in criterion.lower() and any(token in lowered for token in ("todo", "insecure", "placeholder")):
|
|
22
|
+
violations.append({"rule_type": "acceptance_criteria", "rule": criterion, "reason": "candidate contains non-production wording"})
|
|
23
|
+
|
|
24
|
+
return {
|
|
25
|
+
"schema": "GuideAssertionResult",
|
|
26
|
+
"verdict": "fail" if violations else "pass",
|
|
27
|
+
"violations": violations,
|
|
28
|
+
"summary": {
|
|
29
|
+
"rule_count": sum(len(_as_list(rules.get(key))) for key in ("goals", "non_goals", "acceptance_criteria", "architecture_constraints", "style_rules", "risk_appetite")),
|
|
30
|
+
"violation_count": len(violations),
|
|
31
|
+
},
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _as_list(value: Any) -> list[str]:
|
|
36
|
+
if not isinstance(value, list):
|
|
37
|
+
return []
|
|
38
|
+
return [str(item) for item in value if str(item).strip()]
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def _mentions(lowered_candidate: str, rule: str) -> bool:
|
|
42
|
+
tokens = [token.lower() for token in rule.split() if len(token) >= 4]
|
|
43
|
+
if not tokens:
|
|
44
|
+
return False
|
|
45
|
+
return all(token in lowered_candidate for token in tokens)
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"""Replayable incident pack generation."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from datetime import datetime, timezone
|
|
5
|
+
import json
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import Any
|
|
8
|
+
from uuid import uuid4
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def _now() -> str:
|
|
12
|
+
return datetime.now(timezone.utc).isoformat()
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def build_incident_pack(
|
|
16
|
+
project_dir: str,
|
|
17
|
+
*,
|
|
18
|
+
title: str,
|
|
19
|
+
failing_tests: list[str],
|
|
20
|
+
logs: list[str],
|
|
21
|
+
diff_summary: dict[str, Any],
|
|
22
|
+
trace_id: str | None = None,
|
|
23
|
+
) -> dict[str, Any]:
|
|
24
|
+
incident_id = f"incident-{uuid4().hex}"
|
|
25
|
+
payload = {
|
|
26
|
+
"schema": "IncidentReplayPack",
|
|
27
|
+
"incident_id": incident_id,
|
|
28
|
+
"title": title,
|
|
29
|
+
"generated_at": _now(),
|
|
30
|
+
"trace_id": trace_id or "",
|
|
31
|
+
"failing_tests": failing_tests,
|
|
32
|
+
"logs": logs,
|
|
33
|
+
"diff_summary": diff_summary,
|
|
34
|
+
"reproduction_steps": [
|
|
35
|
+
"Replay the failing tests.",
|
|
36
|
+
"Inspect the attached logs.",
|
|
37
|
+
"Validate the diff summary before patching.",
|
|
38
|
+
],
|
|
39
|
+
"regression_guards": failing_tests,
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
rel_path = Path(".omg") / "incidents" / f"{incident_id}.json"
|
|
43
|
+
path = Path(project_dir) / rel_path
|
|
44
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
45
|
+
path.write_text(json.dumps(payload, indent=2, ensure_ascii=True) + "\n", encoding="utf-8")
|
|
46
|
+
payload["path"] = rel_path.as_posix()
|
|
47
|
+
return payload
|
|
@@ -5,6 +5,12 @@ import os
|
|
|
5
5
|
from pathlib import Path
|
|
6
6
|
from typing import cast
|
|
7
7
|
|
|
8
|
+
from hooks.security_validators import (
|
|
9
|
+
toml_quote_string,
|
|
10
|
+
validate_server_name,
|
|
11
|
+
validate_server_url,
|
|
12
|
+
)
|
|
13
|
+
|
|
8
14
|
|
|
9
15
|
def _atomic_write_text(path: Path, content: str) -> None:
|
|
10
16
|
path.parent.mkdir(parents=True, exist_ok=True)
|
|
@@ -29,22 +35,61 @@ def _write_json(path: Path, data: dict[str, object]) -> None:
|
|
|
29
35
|
_atomic_write_text(path, json.dumps(data, indent=2) + "\n")
|
|
30
36
|
|
|
31
37
|
|
|
32
|
-
def
|
|
33
|
-
|
|
34
|
-
|
|
38
|
+
def _validated_server_input(server_url: str, server_name: str) -> tuple[str, str]:
|
|
39
|
+
return validate_server_url(server_url), validate_server_name(server_name)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def _validated_stdio_input(command: str, args: list[str], server_name: str) -> tuple[str, list[str], str]:
|
|
43
|
+
normalized_name = validate_server_name(server_name)
|
|
44
|
+
normalized_command = str(command).strip()
|
|
45
|
+
if not normalized_command or "\n" in normalized_command or "\r" in normalized_command:
|
|
46
|
+
raise ValueError("Invalid command: newline characters are not allowed")
|
|
47
|
+
normalized_args = [str(arg) for arg in args]
|
|
48
|
+
for arg in normalized_args:
|
|
49
|
+
if "\n" in arg or "\r" in arg:
|
|
50
|
+
raise ValueError("Invalid args: newline characters are not allowed")
|
|
51
|
+
return normalized_command, normalized_args, normalized_name
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def _write_json_mcp_server(path: Path, server_name: str, payload: dict[str, object]) -> None:
|
|
55
|
+
config = _load_json(path)
|
|
35
56
|
mcp_servers = config.get("mcpServers")
|
|
36
57
|
if not isinstance(mcp_servers, dict):
|
|
37
58
|
mcp_servers = {}
|
|
38
59
|
config["mcpServers"] = mcp_servers
|
|
39
|
-
mcp_servers[server_name] =
|
|
40
|
-
_write_json(
|
|
60
|
+
mcp_servers[server_name] = payload
|
|
61
|
+
_write_json(path, config)
|
|
41
62
|
|
|
42
63
|
|
|
43
|
-
def
|
|
44
|
-
|
|
45
|
-
config_path
|
|
64
|
+
def write_claude_mcp_config(project_dir: str, server_url: str, server_name: str = "memory-server") -> None:
|
|
65
|
+
server_url, server_name = _validated_server_input(server_url, server_name)
|
|
66
|
+
config_path = Path(project_dir) / ".mcp.json"
|
|
67
|
+
_write_json_mcp_server(config_path, server_name, {"type": "http", "url": server_url})
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def write_claude_mcp_stdio_config(
|
|
71
|
+
project_dir: str,
|
|
72
|
+
*,
|
|
73
|
+
command: str,
|
|
74
|
+
args: list[str],
|
|
75
|
+
server_name: str = "omg-control",
|
|
76
|
+
) -> None:
|
|
77
|
+
command, args, server_name = _validated_stdio_input(command, args, server_name)
|
|
78
|
+
config_path = Path(project_dir) / ".mcp.json"
|
|
79
|
+
_write_json_mcp_server(config_path, server_name, {"command": command, "args": args})
|
|
80
|
+
|
|
46
81
|
|
|
47
|
-
|
|
82
|
+
def write_codex_mcp_config(
|
|
83
|
+
server_url: str,
|
|
84
|
+
server_name: str = "memory-server",
|
|
85
|
+
*,
|
|
86
|
+
config_path: str | Path | None = None,
|
|
87
|
+
) -> None:
|
|
88
|
+
server_url, server_name = _validated_server_input(server_url, server_name)
|
|
89
|
+
target_path = Path(config_path) if config_path is not None else Path.home() / ".codex" / "config.toml"
|
|
90
|
+
target_path.parent.mkdir(parents=True, exist_ok=True)
|
|
91
|
+
|
|
92
|
+
existing = target_path.read_text() if target_path.exists() else ""
|
|
48
93
|
lines = existing.splitlines(keepends=True)
|
|
49
94
|
|
|
50
95
|
header_unquoted = f"[mcp_servers.{server_name}]"
|
|
@@ -60,7 +105,7 @@ def write_codex_mcp_config(server_url: str, server_name: str = "memory-server")
|
|
|
60
105
|
block = [
|
|
61
106
|
f"{header_unquoted}\n",
|
|
62
107
|
'type = "http"\n',
|
|
63
|
-
f'url = "{server_url}"\n',
|
|
108
|
+
f'url = "{toml_quote_string(server_url)}"\n',
|
|
64
109
|
"\n",
|
|
65
110
|
]
|
|
66
111
|
|
|
@@ -68,7 +113,7 @@ def write_codex_mcp_config(server_url: str, server_name: str = "memory-server")
|
|
|
68
113
|
if existing and not existing.endswith("\n"):
|
|
69
114
|
existing += "\n"
|
|
70
115
|
content = existing + "".join(block)
|
|
71
|
-
_atomic_write_text(
|
|
116
|
+
_atomic_write_text(target_path, content)
|
|
72
117
|
return
|
|
73
118
|
|
|
74
119
|
end_idx = len(lines)
|
|
@@ -79,26 +124,98 @@ def write_codex_mcp_config(server_url: str, server_name: str = "memory-server")
|
|
|
79
124
|
break
|
|
80
125
|
|
|
81
126
|
updated_lines = lines[:start_idx] + block + lines[end_idx:]
|
|
82
|
-
_atomic_write_text(
|
|
127
|
+
_atomic_write_text(target_path, "".join(updated_lines))
|
|
83
128
|
|
|
84
129
|
|
|
85
|
-
def
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
130
|
+
def write_codex_mcp_stdio_config(
|
|
131
|
+
*,
|
|
132
|
+
command: str,
|
|
133
|
+
args: list[str],
|
|
134
|
+
server_name: str = "omg-control",
|
|
135
|
+
config_path: str | Path | None = None,
|
|
136
|
+
) -> None:
|
|
137
|
+
command, args, server_name = _validated_stdio_input(command, args, server_name)
|
|
138
|
+
target_path = Path(config_path) if config_path is not None else Path.home() / ".codex" / "config.toml"
|
|
139
|
+
target_path.parent.mkdir(parents=True, exist_ok=True)
|
|
94
140
|
|
|
141
|
+
existing = target_path.read_text() if target_path.exists() else ""
|
|
142
|
+
lines = existing.splitlines(keepends=True)
|
|
143
|
+
header_unquoted = f"[mcp_servers.{server_name}]"
|
|
144
|
+
header_quoted = f"[mcp_servers.\"{server_name}\"]"
|
|
145
|
+
headers = {header_unquoted, header_quoted}
|
|
95
146
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
147
|
+
start_idx: int | None = None
|
|
148
|
+
for idx, line in enumerate(lines):
|
|
149
|
+
if line.strip() in headers:
|
|
150
|
+
start_idx = idx
|
|
151
|
+
break
|
|
152
|
+
|
|
153
|
+
args_text = ", ".join(f'"{toml_quote_string(arg)}"' for arg in args)
|
|
154
|
+
block = [
|
|
155
|
+
f"{header_unquoted}\n",
|
|
156
|
+
f'command = "{toml_quote_string(command)}"\n',
|
|
157
|
+
f"args = [{args_text}]\n",
|
|
158
|
+
"\n",
|
|
159
|
+
]
|
|
160
|
+
|
|
161
|
+
if start_idx is None:
|
|
162
|
+
if existing and not existing.endswith("\n"):
|
|
163
|
+
existing += "\n"
|
|
164
|
+
_atomic_write_text(target_path, existing + "".join(block))
|
|
165
|
+
return
|
|
166
|
+
|
|
167
|
+
end_idx = len(lines)
|
|
168
|
+
for idx in range(start_idx + 1, len(lines)):
|
|
169
|
+
stripped = lines[idx].strip()
|
|
170
|
+
if stripped.startswith("[") and stripped.endswith("]"):
|
|
171
|
+
end_idx = idx
|
|
172
|
+
break
|
|
173
|
+
|
|
174
|
+
updated_lines = lines[:start_idx] + block + lines[end_idx:]
|
|
175
|
+
_atomic_write_text(target_path, "".join(updated_lines))
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def write_gemini_mcp_config(
|
|
179
|
+
server_url: str,
|
|
180
|
+
server_name: str = "memory-server",
|
|
181
|
+
*,
|
|
182
|
+
config_path: str | Path | None = None,
|
|
183
|
+
) -> None:
|
|
184
|
+
server_url, server_name = _validated_server_input(server_url, server_name)
|
|
185
|
+
target_path = Path(config_path) if config_path is not None else Path.home() / ".gemini" / "settings.json"
|
|
186
|
+
_write_json_mcp_server(target_path, server_name, {"httpUrl": server_url})
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
def write_gemini_mcp_stdio_config(
|
|
190
|
+
*,
|
|
191
|
+
command: str,
|
|
192
|
+
args: list[str],
|
|
193
|
+
server_name: str = "omg-control",
|
|
194
|
+
config_path: str | Path | None = None,
|
|
195
|
+
) -> None:
|
|
196
|
+
command, args, server_name = _validated_stdio_input(command, args, server_name)
|
|
197
|
+
target_path = Path(config_path) if config_path is not None else Path.home() / ".gemini" / "settings.json"
|
|
198
|
+
_write_json_mcp_server(target_path, server_name, {"command": command, "args": args})
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
def write_kimi_mcp_config(
|
|
202
|
+
server_url: str,
|
|
203
|
+
server_name: str = "memory-server",
|
|
204
|
+
*,
|
|
205
|
+
config_path: str | Path | None = None,
|
|
206
|
+
) -> None:
|
|
207
|
+
server_url, server_name = _validated_server_input(server_url, server_name)
|
|
208
|
+
target_path = Path(config_path) if config_path is not None else Path.home() / ".kimi" / "mcp.json"
|
|
209
|
+
_write_json_mcp_server(target_path, server_name, {"type": "http", "url": server_url})
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
def write_kimi_mcp_stdio_config(
|
|
213
|
+
*,
|
|
214
|
+
command: str,
|
|
215
|
+
args: list[str],
|
|
216
|
+
server_name: str = "omg-control",
|
|
217
|
+
config_path: str | Path | None = None,
|
|
218
|
+
) -> None:
|
|
219
|
+
command, args, server_name = _validated_stdio_input(command, args, server_name)
|
|
220
|
+
target_path = Path(config_path) if config_path is not None else Path.home() / ".kimi" / "mcp.json"
|
|
221
|
+
_write_json_mcp_server(target_path, server_name, {"command": command, "args": args})
|
|
@@ -66,7 +66,7 @@ mcp = FastMCP("OMG Memory Server", lifespan=lifespan)
|
|
|
66
66
|
|
|
67
67
|
@mcp.custom_route("/health", methods=["GET"])
|
|
68
68
|
async def health(_: Request) -> JSONResponse:
|
|
69
|
-
return JSONResponse({"status": "ok", "version": "
|
|
69
|
+
return JSONResponse({"status": "ok", "version": "2.0.5"})
|
|
70
70
|
|
|
71
71
|
|
|
72
72
|
@mcp.tool()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema": "OmgCompatContractSnapshot",
|
|
3
|
-
"contract_version": "
|
|
3
|
+
"contract_version": "2.0.5",
|
|
4
4
|
"count": 47,
|
|
5
5
|
"contracts": [
|
|
6
6
|
{
|
|
@@ -736,19 +736,19 @@
|
|
|
736
736
|
},
|
|
737
737
|
{
|
|
738
738
|
"skill": "security-review",
|
|
739
|
-
"route": "
|
|
739
|
+
"route": "security_check",
|
|
740
740
|
"maturity": "native",
|
|
741
741
|
"inputs": {
|
|
742
|
-
"required": [
|
|
742
|
+
"required": [],
|
|
743
|
+
"optional": [
|
|
743
744
|
"problem"
|
|
744
|
-
]
|
|
745
|
-
"optional": []
|
|
745
|
+
]
|
|
746
746
|
},
|
|
747
747
|
"outputs": {
|
|
748
|
-
"schema": "
|
|
748
|
+
"schema": "SecurityCheckResult"
|
|
749
749
|
},
|
|
750
750
|
"side_effects": [],
|
|
751
|
-
"notes": ""
|
|
751
|
+
"notes": "Deprecated alias to the canonical OMG security-check engine."
|
|
752
752
|
},
|
|
753
753
|
{
|
|
754
754
|
"skill": "skill",
|
|
@@ -911,5 +911,6 @@
|
|
|
911
911
|
],
|
|
912
912
|
"notes": "Writes long-form memory artifact for writing workflows."
|
|
913
913
|
}
|
|
914
|
-
]
|
|
914
|
+
],
|
|
915
|
+
"generated_at": "2026-03-07T04:51:08.940394+00:00"
|
|
915
916
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema": "OmgCompatContractSnapshot",
|
|
3
|
-
"contract_version": "
|
|
3
|
+
"contract_version": "2.0.5",
|
|
4
4
|
"count": 47,
|
|
5
5
|
"contracts": [
|
|
6
6
|
{
|
|
@@ -736,19 +736,19 @@
|
|
|
736
736
|
},
|
|
737
737
|
{
|
|
738
738
|
"skill": "security-review",
|
|
739
|
-
"route": "
|
|
739
|
+
"route": "security_check",
|
|
740
740
|
"maturity": "native",
|
|
741
741
|
"inputs": {
|
|
742
|
-
"required": [
|
|
742
|
+
"required": [],
|
|
743
|
+
"optional": [
|
|
743
744
|
"problem"
|
|
744
|
-
]
|
|
745
|
-
"optional": []
|
|
745
|
+
]
|
|
746
746
|
},
|
|
747
747
|
"outputs": {
|
|
748
|
-
"schema": "
|
|
748
|
+
"schema": "SecurityCheckResult"
|
|
749
749
|
},
|
|
750
750
|
"side_effects": [],
|
|
751
|
-
"notes": ""
|
|
751
|
+
"notes": "Deprecated alias to the canonical OMG security-check engine."
|
|
752
752
|
},
|
|
753
753
|
{
|
|
754
754
|
"skill": "skill",
|
|
@@ -911,5 +911,6 @@
|
|
|
911
911
|
],
|
|
912
912
|
"notes": "Writes long-form memory artifact for writing workflows."
|
|
913
913
|
}
|
|
914
|
-
]
|
|
914
|
+
],
|
|
915
|
+
"generated_at": "2026-03-07T04:51:08.940453+00:00"
|
|
915
916
|
}
|