feat(casan): add native plugin facade
CASAN Supply Chain and Provenance / verify-scan-attest (push) Canceled after 0s
CASAN CI Gate / Frontend Tests (H3 gate) (push) Canceled after 0s
CASAN CI Gate / CASAN Security Gate + Vault KMS (H4/H5) (push) Canceled after 0s
CASAN CI Gate / Build & Deploy OKR → /opt/webapps/okr (push) Canceled after 0s
CASAN Harness CI / harness (push) Canceled after 0s
CASAN Supply Chain and Provenance / verify-scan-attest (push) Canceled after 0s
CASAN CI Gate / Frontend Tests (H3 gate) (push) Canceled after 0s
CASAN CI Gate / CASAN Security Gate + Vault KMS (H4/H5) (push) Canceled after 0s
CASAN CI Gate / Build & Deploy OKR → /opt/webapps/okr (push) Canceled after 0s
CASAN Harness CI / harness (push) Canceled after 0s
This commit is contained in:
@@ -70,6 +70,10 @@ for forbidden in (
|
||||
):
|
||||
assert not (root / forbidden).exists(), forbidden
|
||||
for required in (
|
||||
".codex-plugin/plugin.json",
|
||||
".claude-plugin/plugin.json",
|
||||
".claude-plugin/marketplace.json",
|
||||
"skills/casan/SKILL.md",
|
||||
"packages/casan-harness/assets/local-viewer/index.html",
|
||||
"packages/casan-harness/assets/local-viewer/app.css",
|
||||
"packages/casan-harness/assets/local-viewer/app.js",
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Validate the repository-root CASAN native plugin facades."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[3]
|
||||
VERSION = (ROOT / "VERSION").read_text(encoding="utf-8").strip()
|
||||
|
||||
|
||||
def load_json(relative_path: str) -> dict[str, object]:
|
||||
payload = json.loads((ROOT / relative_path).read_text(encoding="utf-8"))
|
||||
assert isinstance(payload, dict), relative_path
|
||||
return payload
|
||||
|
||||
|
||||
def main() -> None:
|
||||
codex = load_json(".codex-plugin/plugin.json")
|
||||
assert codex["name"] == "casan"
|
||||
assert codex["version"] == VERSION
|
||||
assert codex["skills"] == "./skills/"
|
||||
assert "hooks" not in codex
|
||||
assert codex["license"] == "Proprietary"
|
||||
|
||||
interface = codex["interface"]
|
||||
assert isinstance(interface, dict)
|
||||
for field in (
|
||||
"displayName",
|
||||
"shortDescription",
|
||||
"longDescription",
|
||||
"developerName",
|
||||
"category",
|
||||
"capabilities",
|
||||
"defaultPrompt",
|
||||
):
|
||||
assert interface.get(field), field
|
||||
|
||||
claude = load_json(".claude-plugin/plugin.json")
|
||||
assert claude["name"] == "casan"
|
||||
assert claude["version"] == VERSION
|
||||
assert claude["skills"] == ["./skills/"]
|
||||
assert "hooks" not in claude
|
||||
|
||||
marketplace = load_json(".claude-plugin/marketplace.json")
|
||||
plugins = marketplace["plugins"]
|
||||
assert isinstance(plugins, list) and len(plugins) == 1
|
||||
entry = plugins[0]
|
||||
assert isinstance(entry, dict)
|
||||
assert entry["name"] == "casan"
|
||||
assert entry["source"] == "./"
|
||||
assert entry["version"] == VERSION
|
||||
|
||||
skill = (ROOT / "skills/casan/SKILL.md").read_text(encoding="utf-8")
|
||||
assert skill.startswith("---\nname: casan\n")
|
||||
assert "description:" in skill
|
||||
assert "[TODO:" not in skill
|
||||
assert (ROOT / "skills/casan/agents/openai.yaml").is_file()
|
||||
|
||||
levels = load_json("packaging/levels.json")
|
||||
level_map = levels["levels"]
|
||||
assert isinstance(level_map, dict)
|
||||
core = level_map["core"]
|
||||
assert isinstance(core, dict)
|
||||
includes = core["includes"]
|
||||
assert isinstance(includes, list)
|
||||
for required in (".codex-plugin", ".claude-plugin", "skills"):
|
||||
assert required in includes, required
|
||||
|
||||
print(f"NATIVE_PLUGIN_PASS version={VERSION} codex=true claude=true")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user