From d18418548dedc4567a48a29060ad2b4633c0aa17 Mon Sep 17 00:00:00 2001 From: salvacybersec Date: Mon, 6 Apr 2026 22:31:50 +0300 Subject: [PATCH] feat: --install claude now deploys agents to /agents menu install_claude() now creates both: - 111 slash commands in ~/.claude/commands/ (persona-neo-general etc.) - 29 agent .yml files in ~/.claude/agents/ (visible in /agents menu) Each agent includes Soul, Methodology, Behavior sections + mapped skills. Agents appear alongside GSD agents in the /agents picker. Co-Authored-By: Claude Opus 4.6 (1M context) --- build.py | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 54 insertions(+), 6 deletions(-) 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):