71 lines
2.8 KiB
Python
71 lines
2.8 KiB
Python
"""Generate the IDE's narrow control contract from the reviewed gateway schema.
|
|
|
|
Usage: python generate-codex-link-control.py PATH_TO_SCHEMA [--check]
|
|
No runtime/namespace/archive messages are included in this surface.
|
|
"""
|
|
import hashlib
|
|
import json
|
|
from pathlib import Path
|
|
import sys
|
|
|
|
root = Path(__file__).resolve().parents[1]
|
|
schema = json.loads(Path(sys.argv[1]).read_text(encoding="utf-8"))
|
|
definitions = schema["$defs"]
|
|
selected = {}
|
|
|
|
def collect(name):
|
|
if name in selected:
|
|
return
|
|
selected[name] = definitions[name]
|
|
def visit(value):
|
|
if isinstance(value, dict):
|
|
if "$ref" in value:
|
|
collect(value["$ref"].removeprefix("#/$defs/"))
|
|
for child in value.values():
|
|
visit(child)
|
|
elif isinstance(value, list):
|
|
for child in value:
|
|
visit(child)
|
|
visit(selected[name])
|
|
|
|
for name in ("control_request", "control_response"):
|
|
collect(name)
|
|
|
|
def typename(name):
|
|
return "CodexLink" + "".join(part.title() for part in name.split("_"))
|
|
|
|
def ts(rule):
|
|
if "$ref" in rule:
|
|
return typename(rule["$ref"].split("/")[-1])
|
|
if "const" in rule:
|
|
return json.dumps(rule["const"], ensure_ascii=False)
|
|
if "enum" in rule:
|
|
return " | ".join(json.dumps(x, ensure_ascii=False) for x in rule["enum"])
|
|
for key in ("oneOf", "anyOf"):
|
|
if key in rule:
|
|
return "(" + " | ".join(ts(x) for x in rule[key]) + ")"
|
|
kind = rule["type"]
|
|
if kind == "object":
|
|
return "{ " + "; ".join(json.dumps(k) + ("" if k in rule["required"] else "?") + ": " + ts(v) for k, v in rule["properties"].items()) + " }"
|
|
if kind == "array":
|
|
return "Array<" + ts(rule["items"]) + ">"
|
|
return {"integer": "number", "boolean": "boolean", "string": "string", "null": "null"}[kind]
|
|
|
|
subset = {"$defs": {k: selected[k] for k in sorted(selected)}}
|
|
canonical = json.dumps(subset, ensure_ascii=False, sort_keys=True, separators=(",", ":")).encode()
|
|
digest = "sha256:" + hashlib.sha256(canonical).hexdigest()
|
|
types = "// Generated by scripts/generate-codex-link-control.py. Do not edit.\n"
|
|
types += "export const CODEX_LINK_CONTROL_SCHEMA_HASH = " + json.dumps(digest) + "\n"
|
|
types += "\n".join("export type " + typename(k) + " = " + ts(v) for k, v in sorted(selected.items())) + "\n"
|
|
outputs = {
|
|
root / "apps/desktop/codex-link-control.schema.json": json.dumps(subset, ensure_ascii=False, indent=2) + "\n",
|
|
root / "apps/desktop/codex-link-control.types.ts": types,
|
|
}
|
|
for path, content in outputs.items():
|
|
if "--check" in sys.argv:
|
|
if not path.exists() or path.read_text(encoding="utf-8") != content:
|
|
raise SystemExit("Generated control contract is stale: " + str(path))
|
|
else:
|
|
path.write_text(content, encoding="utf-8", newline="\n")
|
|
print(digest)
|