diff --git a/.agents/plugins/marketplace.json b/.agents/plugins/marketplace.json new file mode 100644 index 00000000..4e3b4350 --- /dev/null +++ b/.agents/plugins/marketplace.json @@ -0,0 +1,20 @@ +{ + "name": "superpowers-dev", + "interface": { + "displayName": "Superpowers Dev" + }, + "plugins": [ + { + "name": "superpowers", + "source": { + "source": "url", + "url": "./" + }, + "policy": { + "installation": "AVAILABLE", + "authentication": "ON_INSTALL" + }, + "category": "Developer Tools" + } + ] +} diff --git a/.codex-plugin/plugin.json b/.codex-plugin/plugin.json index 7f8ae7b6..c98b525f 100644 --- a/.codex-plugin/plugin.json +++ b/.codex-plugin/plugin.json @@ -21,7 +21,6 @@ "workflow" ], "skills": "./skills/", - "hooks": "./hooks/hooks-codex.json", "interface": { "displayName": "Superpowers", "shortDescription": "Planning, TDD, debugging, and delivery workflows for coding agents", diff --git a/tests/codex/test-marketplace-manifest.sh b/tests/codex/test-marketplace-manifest.sh new file mode 100755 index 00000000..486cb301 --- /dev/null +++ b/tests/codex/test-marketplace-manifest.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +MARKETPLACE="$REPO_ROOT/.agents/plugins/marketplace.json" + +python3 - "$MARKETPLACE" "$REPO_ROOT" <<'PY' +import json +import sys +from pathlib import Path + +marketplace_path = Path(sys.argv[1]) +repo_root = Path(sys.argv[2]) + +if not marketplace_path.exists(): + raise AssertionError(".agents/plugins/marketplace.json must exist") + +marketplace = json.loads(marketplace_path.read_text(encoding="utf-8")) + +def assert_equal(actual, expected, label): + if actual != expected: + raise AssertionError(f"{label}: expected {expected!r}, got {actual!r}") + +assert_equal(marketplace.get("name"), "superpowers-dev", "marketplace name") +assert_equal( + marketplace.get("interface", {}).get("displayName"), + "Superpowers Dev", + "marketplace display name", +) + +plugins = marketplace.get("plugins") +if not isinstance(plugins, list): + raise AssertionError("plugins must be a list") + +matching_plugins = [plugin for plugin in plugins if plugin.get("name") == "superpowers"] +assert_equal(len(matching_plugins), 1, "superpowers plugin entry count") + +plugin = matching_plugins[0] +assert_equal(plugin.get("source"), {"source": "url", "url": "./"}, "plugin source") +assert_equal( + plugin.get("policy"), + {"installation": "AVAILABLE", "authentication": "ON_INSTALL"}, + "plugin policy", +) +assert_equal(plugin.get("category"), "Developer Tools", "plugin category") + +plugin_manifest = repo_root / ".codex-plugin" / "plugin.json" +if not plugin_manifest.exists(): + raise AssertionError(".codex-plugin/plugin.json must exist") + +manifest = json.loads(plugin_manifest.read_text(encoding="utf-8")) +assert_equal(manifest.get("name"), plugin.get("name"), "plugin manifest name") + +unsupported_manifest_fields = ["hooks"] +present_unsupported = sorted( + field for field in unsupported_manifest_fields if field in manifest +) +if present_unsupported: + raise AssertionError( + "unsupported Codex manifest fields present: " + + ", ".join(present_unsupported) + ) + +print("Codex marketplace manifest looks good") +PY