mirror of
https://github.com/codeflash-ai/codeflash-agent.git
synced 2026-05-04 18:25:19 +00:00
99 lines
3.6 KiB
Python
99 lines
3.6 KiB
Python
"""Assemble language-specific Claude Code plugin directories.
|
|
|
|
This is the cross-platform equivalent of the Makefile build target. It copies the
|
|
language-agnostic plugin files, overlays one language's agents/references/skills,
|
|
and rewrites source-tree reference paths to the flattened assembled layout.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import shutil
|
|
from pathlib import Path
|
|
|
|
|
|
EXCLUDE_FROM_BASE = {"languages", "README.md", "ARCHITECTURE.md", "ROADMAP.md"}
|
|
|
|
|
|
def copy_base(plugin_root: Path, output_dir: Path) -> None:
|
|
for item in plugin_root.iterdir():
|
|
if item.name in EXCLUDE_FROM_BASE:
|
|
continue
|
|
|
|
dest = output_dir / item.name
|
|
if item.is_dir():
|
|
shutil.copytree(item, dest, dirs_exist_ok=True)
|
|
else:
|
|
shutil.copy2(item, dest)
|
|
|
|
|
|
def overlay_language(plugin_root: Path, output_dir: Path, language: str) -> None:
|
|
lang_root = plugin_root / "languages" / language
|
|
if not lang_root.is_dir():
|
|
raise SystemExit(f"Unknown language: {language} ({lang_root} not found)")
|
|
|
|
for folder in ("agents", "references", "skills"):
|
|
src = lang_root / folder
|
|
if src.is_dir():
|
|
shutil.copytree(src, output_dir / folder, dirs_exist_ok=True)
|
|
|
|
|
|
def rewrite_paths(output_dir: Path, language: str) -> None:
|
|
replacements = {
|
|
f"languages/{language}/references/": "references/",
|
|
f"languages/{language}/agents/": "agents/",
|
|
f"languages/{language}/skills/": "skills/",
|
|
f"languages\\{language}\\references\\": "references/",
|
|
f"languages\\{language}\\agents\\": "agents/",
|
|
f"languages\\{language}\\skills\\": "skills/",
|
|
}
|
|
|
|
for path in output_dir.rglob("*.md"):
|
|
text = path.read_text(encoding="utf-8")
|
|
updated = text
|
|
for old, new in replacements.items():
|
|
updated = updated.replace(old, new)
|
|
if updated != text:
|
|
path.write_text(updated, encoding="utf-8", newline="\n")
|
|
|
|
|
|
def build_language(plugin_root: Path, output_parent: Path, language: str, clean: bool) -> Path:
|
|
output_dir = output_parent / f"dist-{language}"
|
|
if clean and output_dir.exists():
|
|
shutil.rmtree(output_dir)
|
|
output_dir.mkdir(parents=True, exist_ok=True)
|
|
|
|
copy_base(plugin_root, output_dir)
|
|
overlay_language(plugin_root, output_dir, language)
|
|
rewrite_paths(output_dir, language)
|
|
return output_dir
|
|
|
|
|
|
def discover_languages(plugin_root: Path) -> list[str]:
|
|
languages_root = plugin_root / "languages"
|
|
return sorted(path.name for path in languages_root.iterdir() if path.is_dir())
|
|
|
|
|
|
def main() -> None:
|
|
parser = argparse.ArgumentParser(description="Build language-specific Claude plugin directories.")
|
|
parser.add_argument("--lang", action="append", help="Language to build. Repeat for multiple. Defaults to all.")
|
|
parser.add_argument("--plugin-root", default="plugin", help="Path to the source plugin directory.")
|
|
parser.add_argument("--output-dir", default=".", help="Directory where dist-<lang>/ folders are written.")
|
|
parser.add_argument("--no-clean", action="store_true", help="Do not remove existing dist-<lang>/ before building.")
|
|
args = parser.parse_args()
|
|
|
|
plugin_root = Path(args.plugin_root).resolve()
|
|
output_parent = Path(args.output_dir).resolve()
|
|
languages = args.lang or discover_languages(plugin_root)
|
|
|
|
built: list[Path] = []
|
|
for language in languages:
|
|
output = build_language(plugin_root, output_parent, language, clean=not args.no_clean)
|
|
built.append(output)
|
|
print(f"Assembled plugin ({language}) -> {output}")
|
|
|
|
print("Built: " + ", ".join(str(path) for path in built))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|