diff --git a/.agents/plugins/marketplace.json b/.agents/plugins/marketplace.json index c3c6bdb..7eda4f6 100644 --- a/.agents/plugins/marketplace.json +++ b/.agents/plugins/marketplace.json @@ -1,13 +1,23 @@ { "name": "artic", - "display_name": "Artic", + "interface": { + "displayName": "Artic" + }, "description": "Reference-driven AI-native design docs for homepage generation.", - "version": "0.4.0", + "version": "0.4.1", "author": "baskduf", "plugins": [ { "name": "codex-artic", - "path": "plugins/codex-artic" + "source": { + "source": "local", + "path": "./plugins/codex-artic" + }, + "policy": { + "installation": "AVAILABLE", + "authentication": "ON_INSTALL" + }, + "category": "Productivity" } ] } diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index bc72fea..35a71fa 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -2,7 +2,7 @@ "name": "artic", "display_name": "Artic", "description": "Reference-driven AI-native design docs for homepage generation.", - "version": "0.4.0", + "version": "0.4.1", "author": "baskduf", "plugins": [ { diff --git a/CHANGELOG.md b/CHANGELOG.md index 3979735..27dd69e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 0.4.1 - 2026-06-20 + +### Fixed +- Updated the Codex marketplace manifest to use the current `plugins[].source` schema required by `codex plugin marketplace add`. + ## 0.4.0 - 2026-06-19 ### Added diff --git a/README.ja.md b/README.ja.md index f00353a..103e5e7 100644 --- a/README.ja.md +++ b/README.ja.md @@ -65,7 +65,7 @@ codex plugin marketplace add baskduf/artic 安定したインストールが必要な場合はリリースタグに固定します: ```bash -codex plugin marketplace add baskduf/artic@v0.4.0 +codex plugin marketplace add baskduf/artic@v0.4.1 ``` プラグインブラウザから `codex-artic` をインストールします: diff --git a/README.ko.md b/README.ko.md index 9088da5..75d4836 100644 --- a/README.ko.md +++ b/README.ko.md @@ -65,7 +65,7 @@ codex plugin marketplace add baskduf/artic 안정적인 설치가 필요하면 릴리즈 태그로 고정: ```bash -codex plugin marketplace add baskduf/artic@v0.4.0 +codex plugin marketplace add baskduf/artic@v0.4.1 ``` 플러그인 브라우저에서 `codex-artic` 설치: diff --git a/README.md b/README.md index c36bbdc..a46e240 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ codex plugin marketplace add baskduf/artic Pin a released version when you want a stable install: ```bash -codex plugin marketplace add baskduf/artic@v0.4.0 +codex plugin marketplace add baskduf/artic@v0.4.1 ``` Install `codex-artic` from the plugin browser: diff --git a/README.zh-CN.md b/README.zh-CN.md index ea2f2fa..286e9f7 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -65,7 +65,7 @@ codex plugin marketplace add baskduf/artic 需要稳定安装时固定到发布标签: ```bash -codex plugin marketplace add baskduf/artic@v0.4.0 +codex plugin marketplace add baskduf/artic@v0.4.1 ``` 在插件浏览器中安装 `codex-artic`: diff --git a/README.zh-TW.md b/README.zh-TW.md index d2a471b..ff0cfd6 100644 --- a/README.zh-TW.md +++ b/README.zh-TW.md @@ -65,7 +65,7 @@ codex plugin marketplace add baskduf/artic 需要穩定安裝時固定到發布標籤: ```bash -codex plugin marketplace add baskduf/artic@v0.4.0 +codex plugin marketplace add baskduf/artic@v0.4.1 ``` 在外掛瀏覽器中安裝 `codex-artic`: diff --git a/plugins/claude-artic/.claude-plugin/plugin.json b/plugins/claude-artic/.claude-plugin/plugin.json index d5accee..afce9c5 100644 --- a/plugins/claude-artic/.claude-plugin/plugin.json +++ b/plugins/claude-artic/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "claude-artic", - "version": "0.4.0", + "version": "0.4.1", "description": "Artic design onboarding skill for Claude Code.", "skills": [ { diff --git a/plugins/claude-artic/skills/artic/SKILL.md b/plugins/claude-artic/skills/artic/SKILL.md index 2462c7b..1181f69 100644 --- a/plugins/claude-artic/skills/artic/SKILL.md +++ b/plugins/claude-artic/skills/artic/SKILL.md @@ -1,7 +1,7 @@ --- name: artic description: "Use when creating or improving a homepage/website and design rules are missing or weak. Artic is an agent design-direction protocol: @artic init interviews the user, @artic start authors strategy artifacts, then the compiler produces AI-native DESIGN.md docs without copying protected brand assets." -version: 0.4.0 +version: 0.4.1 author: Hermes Agent license: MIT metadata: diff --git a/plugins/claude-artic/skills/artic/scripts/artic_init.py b/plugins/claude-artic/skills/artic/scripts/artic_init.py index ed09bde..13f61ee 100644 --- a/plugins/claude-artic/skills/artic/scripts/artic_init.py +++ b/plugins/claude-artic/skills/artic/scripts/artic_init.py @@ -280,7 +280,7 @@ def create_init_outputs(root: Path, args: argparse.Namespace) -> dict: ] brief = { - "artic_version": "0.4.0", + "artic_version": "0.4.1", "project": { "name": normalized_project["name"], "type": "homepage", @@ -314,7 +314,7 @@ def create_init_outputs(root: Path, args: argparse.Namespace) -> dict: "source_plan": source_plan, "synthesis": "Use selected sources as compatible patterns; localize prose according to the brief language contract while preserving source names and protected terms.", } - state = {"artic_version": "0.4.0", "last_generated_at": now, "status": "initialized", "language": lang, "intent_path": ".artic/intent.json"} + state = {"artic_version": "0.4.1", "last_generated_at": now, "status": "initialized", "language": lang, "intent_path": ".artic/intent.json"} write(root / ".artic" / "intent.json", json.dumps(intent, indent=2, ensure_ascii=False) + "\n") write(root / ".artic" / "brief.json", json.dumps(brief, indent=2, ensure_ascii=False) + "\n") diff --git a/plugins/claude-artic/skills/artic/scripts/artic_start.py b/plugins/claude-artic/skills/artic/scripts/artic_start.py index 0625df9..63e32e8 100644 --- a/plugins/claude-artic/skills/artic/scripts/artic_start.py +++ b/plugins/claude-artic/skills/artic/scripts/artic_start.py @@ -523,7 +523,7 @@ def update_state(root: Path, brief: dict[str, Any]) -> None: state = loaded except json.JSONDecodeError: state = {} - state.update({"artic_version": str(brief.get("artic_version") or state.get("artic_version") or "0.4.0"), "last_generated_at": datetime.now(timezone.utc).isoformat(), "status": "generated", "language": brief_language(brief), "strategy_path": ".artic/strategy.json"}) + state.update({"artic_version": str(brief.get("artic_version") or state.get("artic_version") or "0.4.1"), "last_generated_at": datetime.now(timezone.utc).isoformat(), "status": "generated", "language": brief_language(brief), "strategy_path": ".artic/strategy.json"}) write(state_path, json.dumps(state, indent=2, ensure_ascii=False) + "\n") diff --git a/plugins/claude-artic/skills/artic/scripts/scaffold_artic_files.py b/plugins/claude-artic/skills/artic/scripts/scaffold_artic_files.py index 71de746..ddec398 100755 --- a/plugins/claude-artic/skills/artic/scripts/scaffold_artic_files.py +++ b/plugins/claude-artic/skills/artic/scripts/scaffold_artic_files.py @@ -100,7 +100,7 @@ def scaffold(root: Path, project_name: str, locale: str = "en-US") -> None: "forbidden_copy_elements": ["logos", "trademarks", "proprietary illustrations", "exact layouts", "source copywriting"], } brief = { - "artic_version": "0.4.0", + "artic_version": "0.4.1", "project": { "name": project_name, "type": "homepage", @@ -139,7 +139,7 @@ def scaffold(root: Path, project_name: str, locale: str = "en-US") -> None: ], "synthesis": "Clean SaaS hierarchy with token discipline and mobile-first accessibility.", } - state = {"artic_version": "0.4.0", "last_generated_at": now, "status": "scaffolded", "language": language, "intent_path": ".artic/intent.json", "strategy_path": ".artic/strategy.json"} + state = {"artic_version": "0.4.1", "last_generated_at": now, "status": "scaffolded", "language": language, "intent_path": ".artic/intent.json", "strategy_path": ".artic/strategy.json"} write(root / ".artic" / "intent.json", json.dumps(intent, indent=2, ensure_ascii=False) + "\n") write(root / ".artic" / "strategy.json", json.dumps(strategy, indent=2, ensure_ascii=False) + "\n") write(root / ".artic" / "brief.json", json.dumps(brief, indent=2, ensure_ascii=False) + "\n") diff --git a/plugins/codex-artic/.codex-plugin/plugin.json b/plugins/codex-artic/.codex-plugin/plugin.json index a293fd4..6f6745e 100644 --- a/plugins/codex-artic/.codex-plugin/plugin.json +++ b/plugins/codex-artic/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "codex-artic", - "version": "0.4.0", + "version": "0.4.1", "description": "Artic design onboarding skill for Codex.", "skills": [ { diff --git a/plugins/codex-artic/skills/artic/SKILL.md b/plugins/codex-artic/skills/artic/SKILL.md index 2462c7b..1181f69 100644 --- a/plugins/codex-artic/skills/artic/SKILL.md +++ b/plugins/codex-artic/skills/artic/SKILL.md @@ -1,7 +1,7 @@ --- name: artic description: "Use when creating or improving a homepage/website and design rules are missing or weak. Artic is an agent design-direction protocol: @artic init interviews the user, @artic start authors strategy artifacts, then the compiler produces AI-native DESIGN.md docs without copying protected brand assets." -version: 0.4.0 +version: 0.4.1 author: Hermes Agent license: MIT metadata: diff --git a/plugins/codex-artic/skills/artic/scripts/artic_init.py b/plugins/codex-artic/skills/artic/scripts/artic_init.py index ed09bde..13f61ee 100644 --- a/plugins/codex-artic/skills/artic/scripts/artic_init.py +++ b/plugins/codex-artic/skills/artic/scripts/artic_init.py @@ -280,7 +280,7 @@ def create_init_outputs(root: Path, args: argparse.Namespace) -> dict: ] brief = { - "artic_version": "0.4.0", + "artic_version": "0.4.1", "project": { "name": normalized_project["name"], "type": "homepage", @@ -314,7 +314,7 @@ def create_init_outputs(root: Path, args: argparse.Namespace) -> dict: "source_plan": source_plan, "synthesis": "Use selected sources as compatible patterns; localize prose according to the brief language contract while preserving source names and protected terms.", } - state = {"artic_version": "0.4.0", "last_generated_at": now, "status": "initialized", "language": lang, "intent_path": ".artic/intent.json"} + state = {"artic_version": "0.4.1", "last_generated_at": now, "status": "initialized", "language": lang, "intent_path": ".artic/intent.json"} write(root / ".artic" / "intent.json", json.dumps(intent, indent=2, ensure_ascii=False) + "\n") write(root / ".artic" / "brief.json", json.dumps(brief, indent=2, ensure_ascii=False) + "\n") diff --git a/plugins/codex-artic/skills/artic/scripts/artic_start.py b/plugins/codex-artic/skills/artic/scripts/artic_start.py index 0625df9..63e32e8 100644 --- a/plugins/codex-artic/skills/artic/scripts/artic_start.py +++ b/plugins/codex-artic/skills/artic/scripts/artic_start.py @@ -523,7 +523,7 @@ def update_state(root: Path, brief: dict[str, Any]) -> None: state = loaded except json.JSONDecodeError: state = {} - state.update({"artic_version": str(brief.get("artic_version") or state.get("artic_version") or "0.4.0"), "last_generated_at": datetime.now(timezone.utc).isoformat(), "status": "generated", "language": brief_language(brief), "strategy_path": ".artic/strategy.json"}) + state.update({"artic_version": str(brief.get("artic_version") or state.get("artic_version") or "0.4.1"), "last_generated_at": datetime.now(timezone.utc).isoformat(), "status": "generated", "language": brief_language(brief), "strategy_path": ".artic/strategy.json"}) write(state_path, json.dumps(state, indent=2, ensure_ascii=False) + "\n") diff --git a/plugins/codex-artic/skills/artic/scripts/scaffold_artic_files.py b/plugins/codex-artic/skills/artic/scripts/scaffold_artic_files.py index 71de746..ddec398 100755 --- a/plugins/codex-artic/skills/artic/scripts/scaffold_artic_files.py +++ b/plugins/codex-artic/skills/artic/scripts/scaffold_artic_files.py @@ -100,7 +100,7 @@ def scaffold(root: Path, project_name: str, locale: str = "en-US") -> None: "forbidden_copy_elements": ["logos", "trademarks", "proprietary illustrations", "exact layouts", "source copywriting"], } brief = { - "artic_version": "0.4.0", + "artic_version": "0.4.1", "project": { "name": project_name, "type": "homepage", @@ -139,7 +139,7 @@ def scaffold(root: Path, project_name: str, locale: str = "en-US") -> None: ], "synthesis": "Clean SaaS hierarchy with token discipline and mobile-first accessibility.", } - state = {"artic_version": "0.4.0", "last_generated_at": now, "status": "scaffolded", "language": language, "intent_path": ".artic/intent.json", "strategy_path": ".artic/strategy.json"} + state = {"artic_version": "0.4.1", "last_generated_at": now, "status": "scaffolded", "language": language, "intent_path": ".artic/intent.json", "strategy_path": ".artic/strategy.json"} write(root / ".artic" / "intent.json", json.dumps(intent, indent=2, ensure_ascii=False) + "\n") write(root / ".artic" / "strategy.json", json.dumps(strategy, indent=2, ensure_ascii=False) + "\n") write(root / ".artic" / "brief.json", json.dumps(brief, indent=2, ensure_ascii=False) + "\n") diff --git a/pyproject.toml b/pyproject.toml index 8044540..bc56a5c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "artic" -version = "0.4.0" +version = "0.4.1" description = "Reference-driven AI-native design docs for homepage generation" readme = "README.md" requires-python = ">=3.9" diff --git a/skills/artic/SKILL.md b/skills/artic/SKILL.md index 2462c7b..1181f69 100644 --- a/skills/artic/SKILL.md +++ b/skills/artic/SKILL.md @@ -1,7 +1,7 @@ --- name: artic description: "Use when creating or improving a homepage/website and design rules are missing or weak. Artic is an agent design-direction protocol: @artic init interviews the user, @artic start authors strategy artifacts, then the compiler produces AI-native DESIGN.md docs without copying protected brand assets." -version: 0.4.0 +version: 0.4.1 author: Hermes Agent license: MIT metadata: diff --git a/skills/artic/scripts/artic_init.py b/skills/artic/scripts/artic_init.py index ed09bde..13f61ee 100644 --- a/skills/artic/scripts/artic_init.py +++ b/skills/artic/scripts/artic_init.py @@ -280,7 +280,7 @@ def create_init_outputs(root: Path, args: argparse.Namespace) -> dict: ] brief = { - "artic_version": "0.4.0", + "artic_version": "0.4.1", "project": { "name": normalized_project["name"], "type": "homepage", @@ -314,7 +314,7 @@ def create_init_outputs(root: Path, args: argparse.Namespace) -> dict: "source_plan": source_plan, "synthesis": "Use selected sources as compatible patterns; localize prose according to the brief language contract while preserving source names and protected terms.", } - state = {"artic_version": "0.4.0", "last_generated_at": now, "status": "initialized", "language": lang, "intent_path": ".artic/intent.json"} + state = {"artic_version": "0.4.1", "last_generated_at": now, "status": "initialized", "language": lang, "intent_path": ".artic/intent.json"} write(root / ".artic" / "intent.json", json.dumps(intent, indent=2, ensure_ascii=False) + "\n") write(root / ".artic" / "brief.json", json.dumps(brief, indent=2, ensure_ascii=False) + "\n") diff --git a/skills/artic/scripts/artic_start.py b/skills/artic/scripts/artic_start.py index 0625df9..63e32e8 100644 --- a/skills/artic/scripts/artic_start.py +++ b/skills/artic/scripts/artic_start.py @@ -523,7 +523,7 @@ def update_state(root: Path, brief: dict[str, Any]) -> None: state = loaded except json.JSONDecodeError: state = {} - state.update({"artic_version": str(brief.get("artic_version") or state.get("artic_version") or "0.4.0"), "last_generated_at": datetime.now(timezone.utc).isoformat(), "status": "generated", "language": brief_language(brief), "strategy_path": ".artic/strategy.json"}) + state.update({"artic_version": str(brief.get("artic_version") or state.get("artic_version") or "0.4.1"), "last_generated_at": datetime.now(timezone.utc).isoformat(), "status": "generated", "language": brief_language(brief), "strategy_path": ".artic/strategy.json"}) write(state_path, json.dumps(state, indent=2, ensure_ascii=False) + "\n") diff --git a/skills/artic/scripts/scaffold_artic_files.py b/skills/artic/scripts/scaffold_artic_files.py index 71de746..ddec398 100755 --- a/skills/artic/scripts/scaffold_artic_files.py +++ b/skills/artic/scripts/scaffold_artic_files.py @@ -100,7 +100,7 @@ def scaffold(root: Path, project_name: str, locale: str = "en-US") -> None: "forbidden_copy_elements": ["logos", "trademarks", "proprietary illustrations", "exact layouts", "source copywriting"], } brief = { - "artic_version": "0.4.0", + "artic_version": "0.4.1", "project": { "name": project_name, "type": "homepage", @@ -139,7 +139,7 @@ def scaffold(root: Path, project_name: str, locale: str = "en-US") -> None: ], "synthesis": "Clean SaaS hierarchy with token discipline and mobile-first accessibility.", } - state = {"artic_version": "0.4.0", "last_generated_at": now, "status": "scaffolded", "language": language, "intent_path": ".artic/intent.json", "strategy_path": ".artic/strategy.json"} + state = {"artic_version": "0.4.1", "last_generated_at": now, "status": "scaffolded", "language": language, "intent_path": ".artic/intent.json", "strategy_path": ".artic/strategy.json"} write(root / ".artic" / "intent.json", json.dumps(intent, indent=2, ensure_ascii=False) + "\n") write(root / ".artic" / "strategy.json", json.dumps(strategy, indent=2, ensure_ascii=False) + "\n") write(root / ".artic" / "brief.json", json.dumps(brief, indent=2, ensure_ascii=False) + "\n") diff --git a/tests/test_artic_package.py b/tests/test_artic_package.py index 7a705ba..40849a9 100644 --- a/tests/test_artic_package.py +++ b/tests/test_artic_package.py @@ -130,6 +130,18 @@ def test_json_manifests_parse(): for rel in [".claude-plugin/marketplace.json", ".agents/plugins/marketplace.json", "plugins/claude-artic/.claude-plugin/plugin.json", "plugins/codex-artic/.codex-plugin/plugin.json", "skills/artic/references/source-catalog.json", "skills/artic/templates/brief.schema.json", "skills/artic/templates/strategy.schema.json"]: json.loads((ROOT / rel).read_text()) +def test_codex_marketplace_manifest_uses_current_source_schema(): + manifest = json.loads((ROOT / ".agents" / "plugins" / "marketplace.json").read_text(encoding="utf-8")) + plugin = manifest["plugins"][0] + + assert manifest["interface"]["displayName"] == "Artic" + assert "display_name" not in manifest + assert plugin["name"] == "codex-artic" + assert plugin["source"] == {"source": "local", "path": "./plugins/codex-artic"} + assert "path" not in plugin + assert plugin["policy"] == {"installation": "AVAILABLE", "authentication": "ON_INSTALL"} + + def test_skill_copies_are_in_sync(): canonical = ROOT / "skills" / "artic" for copy in [ROOT / "plugins" / "claude-artic" / "skills" / "artic", ROOT / "plugins" / "codex-artic" / "skills" / "artic"]: