diff --git a/build.py b/build.py index e7c445d..efa910a 100755 --- a/build.py +++ b/build.py @@ -624,25 +624,73 @@ def print_summary(config: dict, total_personas: int, total_variants: int, total_ def install_claude(output_dir: Path): - """Install personas to Claude Code as slash commands (~/.claude/commands/).""" + """Install personas to Claude Code as slash commands + agents.""" commands_dir = Path.home() / ".claude" / "commands" + agents_dir = Path.home() / ".claude" / "agents" commands_dir.mkdir(parents=True, exist_ok=True) - count = 0 + agents_dir.mkdir(parents=True, exist_ok=True) + + cmd_count = 0 + agent_count = 0 + for persona_dir in sorted(output_dir.iterdir()): if not persona_dir.is_dir() or persona_dir.name.startswith("_"): continue + + # Install slash commands for all variants for prompt_file in persona_dir.glob("*.prompt.md"): variant = prompt_file.stem codename = persona_dir.name cmd_name = f"persona-{codename}" if variant == "general" else f"persona-{codename}-{variant}" dest = commands_dir / f"{cmd_name}.md" content = prompt_file.read_text(encoding="utf-8") - # Wrap as Claude command: $ARGUMENTS placeholder for user query command_content = f"{content}\n\n---\nUser query: $ARGUMENTS\n" dest.write_text(command_content, encoding="utf-8") - count += 1 - print(f" Claude: {count} commands installed to {commands_dir}") - return count + cmd_count += 1 + + # Install agent .yml for general variant (appears in /agents menu) + general_json = persona_dir / "general.json" + if not general_json.exists(): + continue + + data = json.loads(general_json.read_text(encoding="utf-8")) + codename = data.get("codename", persona_dir.name) + name = data.get("name", codename.title()) + role = data.get("role", "Specialist") + domain = data.get("domain", "") + tone = data.get("tone", "") + address_to = data.get("address_to", "") + skills = data.get("skills", []) + quote = data.get("quote", "") + + soul = data.get("sections", {}).get("soul", "") + methodology = data.get("sections", {}).get("methodology", "") + behavior = data.get("sections", {}).get("behavior_rules", "") + + instructions = f"You are **{name}** ({address_to}) — {role}.\n\n" + instructions += f"Domain: {domain} | Tone: {tone}\n\n" + if quote: + instructions += f'> "{quote}"\n\n' + instructions += "## Soul\n" + soul[:1500] + "\n\n" + if methodology: + instructions += "## Methodology\n" + methodology[:1500] + "\n\n" + if behavior: + instructions += "## Behavior\n" + behavior[:800] + "\n" + if skills: + instructions += "\n## Mapped Skills\n" + ", ".join(skills) + "\n" + + agent = { + "name": codename, + "description": f"{name} ({address_to}) — {role}. {domain}.", + "instructions": instructions, + "allowedTools": ["Read(*)", "Edit(*)", "Write(*)", "Bash(*)", "Glob(*)", "Grep(*)", "WebFetch(*)", "WebSearch(*)"], + } + agent_file = agents_dir / f"{codename}.yml" + agent_file.write_text(yaml.dump(agent, allow_unicode=True, default_flow_style=False, sort_keys=False), encoding="utf-8") + agent_count += 1 + + print(f" Claude: {cmd_count} commands + {agent_count} agents installed") + return cmd_count def install_antigravity(output_dir: Path):