From f5b0a7389fb8ac0a8fafa94018e40bee01b40f2d Mon Sep 17 00:00:00 2001 From: Zhongwei Li Date: Sun, 30 Nov 2025 08:49:53 +0800 Subject: [PATCH] Initial commit --- .claude-plugin/plugin.json | 15 + README.md | 3 + commands/agent-orchestrator-create-agent.md | 168 ++++++++++ ...gent-orchestrator-create-runtime-report.md | 141 ++++++++ .../agent-orchestrator-extract-token-usage.md | 134 ++++++++ commands/agent-orchestrator-init.md | 11 + plugin.lock.json | 185 +++++++++++ skills/agent-orchestrator/SKILL.md | 233 +++++++++++++ skills/agent-orchestrator/commands/ao-clean | 95 ++++++ .../agent-orchestrator/commands/ao-get-result | 80 +++++ .../commands/ao-list-agents | 70 ++++ .../commands/ao-list-sessions | 74 +++++ skills/agent-orchestrator/commands/ao-new | 186 +++++++++++ skills/agent-orchestrator/commands/ao-resume | 196 +++++++++++ .../commands/ao-show-config | 92 +++++ skills/agent-orchestrator/commands/ao-status | 68 ++++ .../example/agents/browser-tester/agent.json | 4 + .../agents/browser-tester/agent.mcp.json | 10 + .../browser-tester/agent.system-prompt.md | 22 ++ .../agents/confluence-researcher/README.md | 27 ++ .../agents/confluence-researcher/agent.json | 4 + .../confluence-researcher/agent.mcp.json | 19 ++ .../agent.system-prompt.md | 86 +++++ .../example/agents/jira-researcher/README.md | 27 ++ .../example/agents/jira-researcher/agent.json | 4 + .../agents/jira-researcher/agent.mcp.json | 19 ++ .../jira-researcher/agent.system-prompt.md | 93 ++++++ .../example/agents/web-researcher/agent.json | 4 + .../web-researcher/agent.system-prompt.md | 82 +++++ .../references/AGENT-ORCHESTRATOR.md | 313 ++++++++++++++++++ .../agent-orchestrator/references/ENV_VARS.md | 212 ++++++++++++ .../references/EXAMPLE-AGENTS.md | 87 +++++ 32 files changed, 2764 insertions(+) create mode 100644 .claude-plugin/plugin.json create mode 100644 README.md create mode 100644 commands/agent-orchestrator-create-agent.md create mode 100644 commands/agent-orchestrator-create-runtime-report.md create mode 100644 commands/agent-orchestrator-extract-token-usage.md create mode 100644 commands/agent-orchestrator-init.md create mode 100644 plugin.lock.json create mode 100644 skills/agent-orchestrator/SKILL.md create mode 100755 skills/agent-orchestrator/commands/ao-clean create mode 100755 skills/agent-orchestrator/commands/ao-get-result create mode 100755 skills/agent-orchestrator/commands/ao-list-agents create mode 100755 skills/agent-orchestrator/commands/ao-list-sessions create mode 100755 skills/agent-orchestrator/commands/ao-new create mode 100755 skills/agent-orchestrator/commands/ao-resume create mode 100755 skills/agent-orchestrator/commands/ao-show-config create mode 100755 skills/agent-orchestrator/commands/ao-status create mode 100644 skills/agent-orchestrator/example/agents/browser-tester/agent.json create mode 100644 skills/agent-orchestrator/example/agents/browser-tester/agent.mcp.json create mode 100644 skills/agent-orchestrator/example/agents/browser-tester/agent.system-prompt.md create mode 100644 skills/agent-orchestrator/example/agents/confluence-researcher/README.md create mode 100644 skills/agent-orchestrator/example/agents/confluence-researcher/agent.json create mode 100644 skills/agent-orchestrator/example/agents/confluence-researcher/agent.mcp.json create mode 100644 skills/agent-orchestrator/example/agents/confluence-researcher/agent.system-prompt.md create mode 100644 skills/agent-orchestrator/example/agents/jira-researcher/README.md create mode 100644 skills/agent-orchestrator/example/agents/jira-researcher/agent.json create mode 100644 skills/agent-orchestrator/example/agents/jira-researcher/agent.mcp.json create mode 100644 skills/agent-orchestrator/example/agents/jira-researcher/agent.system-prompt.md create mode 100644 skills/agent-orchestrator/example/agents/web-researcher/agent.json create mode 100644 skills/agent-orchestrator/example/agents/web-researcher/agent.system-prompt.md create mode 100644 skills/agent-orchestrator/references/AGENT-ORCHESTRATOR.md create mode 100644 skills/agent-orchestrator/references/ENV_VARS.md create mode 100644 skills/agent-orchestrator/references/EXAMPLE-AGENTS.md diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json new file mode 100644 index 0000000..8716e24 --- /dev/null +++ b/.claude-plugin/plugin.json @@ -0,0 +1,15 @@ +{ + "name": "agent-orchestrator", + "description": "Core Agent Orchestrator Framework (AOF) plugin. Provides Python ao-* commands and slash commands for orchestrating specialized Claude Code agent sessions. Use this for low-level agent management, session control, and custom agent definitions. Requires Python and uv.", + "version": "2.0.0", + "author": { + "name": "rawe", + "email": "noreply@example.com" + }, + "skills": [ + "./skills" + ], + "commands": [ + "./commands" + ] +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..5af60a1 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# agent-orchestrator + +Core Agent Orchestrator Framework (AOF) plugin. Provides Python ao-* commands and slash commands for orchestrating specialized Claude Code agent sessions. Use this for low-level agent management, session control, and custom agent definitions. Requires Python and uv. diff --git a/commands/agent-orchestrator-create-agent.md b/commands/agent-orchestrator-create-agent.md new file mode 100644 index 0000000..b4eca2f --- /dev/null +++ b/commands/agent-orchestrator-create-agent.md @@ -0,0 +1,168 @@ +--- +name: agent-orchestrator-create-agent +description: Creates a new specialized orchestrated agent configuration for delegating work to specialized Claude Code sessions +--- + +# create-orchestrated-agent + +You are a specialist in creating orchestrated agent configurations. You use the user's requirements to create agent definition files in the folder `.agent-orchestrator/agents/`. + +Read the following instructions from the user: + +$ARGUMENTS + + +## Process + +1. **Analyze** the user instructions carefully +2. **Understand** the purpose, domain, and functionality of the orchestrated agent to be created +3. **Clarify** any ambiguities by asking the user specific questions +4. **Generate** a concise, descriptive agent name `$AGENT_NAME` (use kebab-case, e.g., "data-analyzer", "code-reviewer") +5. **Present** the agent name to the user for approval +6. **Create** the agent directory `.agent-orchestrator/agents/$AGENT_NAME/` +7. **Draft** a system prompt that defines the agent's expertise and behavior +8. **Present** the system prompt to the user for approval +9. **Create** the required configuration file and optional system prompt file + +## File Structure + +Each agent is organized in its own directory within `.agent-orchestrator/agents/`. The directory name must match the agent name. + +``` +.agent-orchestrator/agents/ +└── $AGENT_NAME/ + ├── agent.json # Required: Agent configuration + ├── agent.system-prompt.md # Optional: System prompt (discovered by convention) + └── agent.mcp.json # Optional: MCP server configuration (discovered by convention) +``` + +### agent.json (Required) + +**Location:** `.agent-orchestrator/agents/$AGENT_NAME/agent.json` + +**Purpose:** Defines the agent metadata. + +**Schema:** +```json +{ + "name": "string (required) - Agent identifier matching folder name", + "description": "string (required) - Brief description of agent's purpose and expertise" +} +``` + +**Example:** +```json +{ + "name": "firstspirit-architect", + "description": "Specialist in FirstSpirit CMS architecture, templating, and SiteArchitect development" +} +``` + +**Key Patterns:** +- `name` field must match the folder name +- `description` should be a single clear sentence describing the agent's domain expertise and when to use it. Input format should be mentioned concisely and informatively. + +--- + +### agent.system-prompt.md (Optional) + +**Location:** `.agent-orchestrator/agents/$AGENT_NAME/agent.system-prompt.md` + +**Purpose:** Defines the agent's persona, expertise, behavior, tools, and input/output expectations. This file is discovered by convention - no need to reference it in agent.json. + +**Structure Template:** +```markdown +You are a [ROLE/TITLE] with deep expertise in [DOMAIN/TECHNOLOGY]. + +Your expertise includes: +- [Specific skill or knowledge area 1] +- [Specific skill or knowledge area 2] + +[OPTIONAL: **IMPORTANT:** Any critical instructions, tool requirements, or workflow requirements] + +[IF APPLICABLE: Instructions for using specific skills or tools] +``` +[Skill or tool invocation example] +``` +## Workflow Guidelines + +When working on [TASK TYPE]: +1. [Step-by-step workflow or best practices] +2. [Key considerations] +3. [Quality standards] +4. [Documentation requirements] +5. [Naming conventions or standards] + +## Output format + +[Describe expected output format, structure, and any file creation requirements] + +## Notes + +[IF APPLICABLE: Reference to available tools, documentation, or resources] + +Be practical, focus on [QUALITY ATTRIBUTES like maintainability, performance, best practices]. +``` + +**Criteria for Effective System Prompts:** + +1. **Role Definition** + - Clearly state the agent's role and domain of expertise + - Specify the level of expertise (specialist, architect, analyst, etc.) + +2. **Scope of Expertise** + - List specific capabilities and knowledge areas + - Include relevant technologies, frameworks, or methodologies + - Define boundaries of what the agent should/shouldn't do + +3. **Tool & Skill Integration** + - Explicitly mention required tools or skills the agent must use + - Provide exact invocation syntax + - Explain when and why to use specific tools + +4. **Workflow & Process** + - Define clear step-by-step processes for common tasks + - Include best practices and quality standards + - Specify any required conventions (naming, structure, etc.) + +5. **Input Expectations** + - Describe the format and structure of expected inputs + - For longer context, specify that the agent should expect file references + - Keep prompts concise by referencing files rather than embedding large content + +6. **Output Requirements** + - Define the format and structure of expected outputs + - Outputs should be brief and action-oriented + - For lengthy results, instruct the agent to create files and provide references + - Specify any required documentation or handover format + +7. **Behavioral Guidelines** + - Include personality traits (practical, thorough, concise, etc.) + - Specify communication style + - Define how to handle ambiguity or missing information + +--- + +### agent.mcp.json (Optional) + +**Location:** `.agent-orchestrator/agents/$AGENT_NAME/agent.mcp.json` + +**Purpose:** Configures MCP (Model Context Protocol) server integration for agents that require external tool access. This file is discovered by convention - no need to reference it in agent.json. + +**When to Use:** +Only create this file if your agent needs access to specialized tools through MCP servers (e.g., browser automation, database access, API integrations). + +**Format:** +Standard MCP server configuration as documented in the MCP specification. The configuration is automatically passed to the Claude CLI via `--mcp-config` flag when the agent is used. + +**Note:** +Most agents do not require MCP configurations. Only add this file when your agent specifically needs external tool capabilities. + +--- + +## Notes + +- Agent names should be descriptive and use kebab-case +- System prompts should be focused and actionable +- Consider reusability: create agents for specific domains, not one-off tasks +- Test the agent with sample inputs before finalizing diff --git a/commands/agent-orchestrator-create-runtime-report.md b/commands/agent-orchestrator-create-runtime-report.md new file mode 100644 index 0000000..1e6976d --- /dev/null +++ b/commands/agent-orchestrator-create-runtime-report.md @@ -0,0 +1,141 @@ +# Create Runtime Report from Agent Sessions + +Generate a comprehensive runtime analysis report from CLI agent session files, accounting for parallel execution. + +## Instructions + +Follow these steps to create a runtime report: + +### Step 1: Get Wall Clock Time + +Get file timestamps to determine when the workflow started and ended: + +```bash +stat -f "%Sm %N" -t "%Y-%m-%d %H:%M:%S" .agent-orchestrator/agent-sessions/*.jsonl | sort +``` + +The earliest timestamp is the start time, the latest is the end time. + +### Step 2: Extract All Session Data + +Use this Python script to extract timing data from all sessions: + +```bash +python3 << 'EOF' +import json +from pathlib import Path + +sessions_dir = Path(".agent-orchestrator/agent-sessions") +session_files = sorted(sessions_dir.glob("*.jsonl")) + +results = [] + +for session_file in session_files: + name = session_file.stem + with open(session_file, 'r') as f: + for line in f: + try: + data = json.loads(line) + if data.get('type') == 'result': + results.append({ + 'name': name, + 'duration_ms': data.get('duration_ms', 0), + 'duration_s': data.get('duration_ms', 0) / 1000, + 'api_time_ms': data.get('duration_api_ms', 0), + 'api_time_s': data.get('duration_api_ms', 0) / 1000, + 'turns': data.get('num_turns', 0), + 'cost': data.get('total_cost_usd', 0), + }) + break + except json.JSONDecodeError: + continue + +for result in results: + print(f"=== {result['name']} ===") + print(f"Duration: {result['duration_ms']}ms ({result['duration_s']:.1f}s)") + print(f"API Time: {result['api_time_ms']}ms ({result['api_time_s']:.1f}s)") + print(f"Turns: {result['turns']}") + print(f"Cost: ${result['cost']:.5f}") + print() + +print("=== TOTALS ===") +total_duration = sum(r['duration_ms'] for r in results) +total_api_time = sum(r['api_time_ms'] for r in results) +total_cost = sum(r['cost'] for r in results) +total_turns = sum(r['turns'] for r in results) + +print(f"Total Duration: {total_duration}ms ({total_duration/1000:.1f}s, {total_duration/60000:.1f}m)") +print(f"Total API Time: {total_api_time}ms ({total_api_time/1000:.1f}s, {total_api_time/60000:.1f}m)") +print(f"Total Turns: {total_turns}") +print(f"Total Cost: ${total_cost:.5f}") +print(f"Number of Sessions: {len(results)}") +EOF +``` + +### Step 3: Generate Formatted Report + +Use the timestamps from Step 1 and data from Step 2 to create a final report. Update the start/end times based on your actual data: + +```bash +python3 << 'EOF' +from datetime import datetime + +# UPDATE THESE with actual timestamps from Step 1 +start_time = datetime.strptime("2025-11-02 17:35:23", "%Y-%m-%d %H:%M:%S") +end_time = datetime.strptime("2025-11-02 18:04:46", "%Y-%m-%d %H:%M:%S") + +wall_clock_seconds = (end_time - start_time).total_seconds() +wall_clock_minutes = wall_clock_seconds / 60 + +# UPDATE THESE with totals from Step 2 +total_agent_time_s = 2837.3 +total_agent_time_m = 47.3 +total_cost = 2.65816 +total_turns = 233 + +efficiency_gain = ((total_agent_time_m - wall_clock_minutes) / total_agent_time_m) * 100 + +print("# Runtime Analysis Report") +print() +print("## Wall Clock Time") +print(f"- **Start**: {start_time.strftime('%Y-%m-%d %H:%M:%S')}") +print(f"- **End**: {end_time.strftime('%Y-%m-%d %H:%M:%S')}") +print(f"- **Total**: {wall_clock_minutes:.1f} minutes ({wall_clock_seconds:.0f} seconds)") +print() +print("## Overall Summary") +print() +print(f"- **Total Agent Execution Time**: {total_agent_time_s:.1f}s ({total_agent_time_m:.1f} min)") +print(f"- **Actual Wall Clock Time**: {wall_clock_seconds:.0f}s ({wall_clock_minutes:.1f} min)") +print(f"- **Total Cost**: ${total_cost:.5f}") +print(f"- **Total Conversation Turns**: {total_turns}") +print(f"- **Efficiency Gain**: {efficiency_gain:.1f}% faster due to parallel execution") +print(f"- **Time Saved**: {total_agent_time_m - wall_clock_minutes:.1f} minutes") +EOF +``` + +## Report Output Structure + +The report should include: + +1. **Wall Clock Time**: Start, end, and total elapsed time +2. **Phase-by-Phase Breakdown**: Individual session metrics with completion timestamps +3. **Overall Summary**: + - Total agent execution time (sum of all sessions) + - Actual wall clock time (real elapsed time) + - Total cost and conversation turns + - Efficiency gain percentage from parallel execution + - Time saved by running agents in parallel + +## Key Metrics + +- **Wall Clock Time**: Real-world time from start to finish +- **Agent Execution Time**: Sum of all individual agent runtimes +- **Efficiency Gain**: Percentage reduction due to parallel execution +- **Time Saved**: Difference between sequential and parallel execution + +## Notes + +- Use Python heredoc (`<< 'EOF'`) to avoid bash quoting issues +- The script automatically handles missing or incomplete session files +- Efficiency gain > 0% indicates agents ran in parallel +- Update the timestamps and totals in Step 3 with actual values from Steps 1 and 2 diff --git a/commands/agent-orchestrator-extract-token-usage.md b/commands/agent-orchestrator-extract-token-usage.md new file mode 100644 index 0000000..1d33d28 --- /dev/null +++ b/commands/agent-orchestrator-extract-token-usage.md @@ -0,0 +1,134 @@ +# Extract Token Usage Statistics from Agent Sessions + +Extract context window sizes and token usage statistics from CLI agent session files. + +## Context Window Analysis + +This script calculates the **context window size** for each agent by summing `input_tokens + cache_creation_input_tokens` across all invocations. This represents the fresh token budget used by each agent. + +```bash +python3 << 'EOF' +import json +from pathlib import Path + +sessions_dir = Path(".agent-orchestrator/agent-sessions") +results = [] + +for session_file in sorted(sessions_dir.glob("*.jsonl")): + agent_name = session_file.stem + total_fresh_tokens = 0 + num_invocations = 0 + invocation_details = [] + + with open(session_file, 'r') as f: + for line in f: + if '"type":"result"' not in line: + continue + try: + data = json.loads(line) + if data.get('type') == 'result': + num_invocations += 1 + usage = data.get('usage', {}) + input_tokens = usage.get('input_tokens', 0) + cache_creation = usage.get('cache_creation_input_tokens', 0) + fresh_tokens = input_tokens + cache_creation + total_fresh_tokens += fresh_tokens + invocation_details.append({ + 'num': num_invocations, + 'input': input_tokens, + 'cache_creation': cache_creation, + 'fresh_tokens': fresh_tokens + }) + except json.JSONDecodeError: + continue + + if num_invocations > 0: + results.append({ + 'name': agent_name, + 'total_fresh_tokens': total_fresh_tokens, + 'num_invocations': num_invocations, + 'invocations': invocation_details + }) + +# Detailed per-agent breakdown +print("=" * 80) +print("CONTEXT WINDOW ANALYSIS: FRESH TOKENS (input + cache_creation)") +print("=" * 80) +print() + +for result in results: + print(f"=== {result['name']} ===") + print(f"Number of Invocations: {result['num_invocations']}") + + if result['num_invocations'] > 1: + print("\nPer-Invocation Breakdown:") + for inv in result['invocations']: + print(f" Invocation #{inv['num']}:") + print(f" Input tokens: {inv['input']:>10,}") + print(f" Cache creation tokens: {inv['cache_creation']:>10,}") + print(f" Fresh tokens total: {inv['fresh_tokens']:>10,}") + + print(f"\nTotal Fresh Tokens (Context Window): {result['total_fresh_tokens']:>10,}") + print() + +# Summary table +print("=" * 80) +print("SUMMARY TABLE") +print("=" * 80) +print() +print("| Agent | Invocations | Total Fresh Tokens (Context) |") +print("|-------|------------:|-----------------------------:|") + +for result in results: + print(f"| {result['name']} | {result['num_invocations']} | " + f"{result['total_fresh_tokens']:,} |") + +print() + +# Aggregate statistics +print("=" * 80) +print("AGGREGATE STATISTICS") +print("=" * 80) +total_agents = len(results) +total_invocations = sum(r['num_invocations'] for r in results) +total_fresh_tokens = sum(r['total_fresh_tokens'] for r in results) +avg_fresh_tokens = total_fresh_tokens / total_agents if total_agents > 0 else 0 +max_fresh_tokens = max(r['total_fresh_tokens'] for r in results) if results else 0 +min_fresh_tokens = min(r['total_fresh_tokens'] for r in results) if results else 0 + +print(f"Total Agents: {total_agents}") +print(f"Total Invocations: {total_invocations}") +print(f"Total Fresh Tokens: {total_fresh_tokens:,}") +print(f"Average Fresh Tokens/Agent: {avg_fresh_tokens:,.0f}") +print(f"Maximum Fresh Tokens: {max_fresh_tokens:,}") +print(f"Minimum Fresh Tokens: {min_fresh_tokens:,}") +print() +EOF +``` + +## Key Metrics + +- **Fresh Tokens (Context Window)**: `input_tokens + cache_creation_input_tokens` + - Represents the actual context window size used by the agent + - Accumulated across all invocations if an agent was called multiple times + - Excludes cached reads (which don't count toward new context) + +- **Invocations**: Number of times an agent was executed + - Agents may be invoked multiple times if they need additional iterations + - Context window is summed across all invocations for total agent workload + +## Assessment Guidelines + +Use these context window sizes to determine if tasks were appropriately sized: + +- **< 50K tokens**: Well-sized task, plenty of headroom +- **50K - 100K tokens**: Moderate task size, comfortable range +- **100K - 150K tokens**: Large task, approaching upper limits +- **> 150K tokens**: Very large task, consider splitting into smaller agents + +## Notes + +- Script efficiently reads only result lines from JSONL files +- Handles multiple invocations per agent automatically +- All calculations handle division by zero safely +- Output includes both detailed breakdown and summary table \ No newline at end of file diff --git a/commands/agent-orchestrator-init.md b/commands/agent-orchestrator-init.md new file mode 100644 index 0000000..3070392 --- /dev/null +++ b/commands/agent-orchestrator-init.md @@ -0,0 +1,11 @@ +--- +name: agent-orchestrator-init +description: Primes the agent to orchestrate other agents using the Agent Orchestrator skill. +--- +Your are an agent orchestrator. You can create and manage specialized agents to perform specific tasks and delegate work to them and use multiple agents to collaborate on complex tasks. + +Your initial task: +* Load the skill agent-orchestrator. +* Figure out which are available - don't return them, just figure it out. + +Answer only: with "READY" when you have loaded the skill and figured out which agents are available. \ No newline at end of file diff --git a/plugin.lock.json b/plugin.lock.json new file mode 100644 index 0000000..fc4e924 --- /dev/null +++ b/plugin.lock.json @@ -0,0 +1,185 @@ +{ + "$schema": "internal://schemas/plugin.lock.v1.json", + "pluginId": "gh:rawe/claude-agent-orchestrator:plugins/agent-orchestrator", + "normalized": { + "repo": null, + "ref": "refs/tags/v20251128.0", + "commit": "dc10cc59c459ad9e92eec5f7ff5325a93b344fcc", + "treeHash": "d0f6531b390ea47f005aa39e80b8990981f16dd78efe262f5b3201131a7b3fef", + "generatedAt": "2025-11-28T10:27:48.569171Z", + "toolVersion": "publish_plugins.py@0.2.0" + }, + "origin": { + "remote": "git@github.com:zhongweili/42plugin-data.git", + "branch": "master", + "commit": "aa1497ed0949fd50e99e70d6324a29c5b34f9390", + "repoRoot": "/Users/zhongweili/projects/openmind/42plugin-data" + }, + "manifest": { + "name": "agent-orchestrator", + "description": "Core Agent Orchestrator Framework (AOF) plugin. Provides Python ao-* commands and slash commands for orchestrating specialized Claude Code agent sessions. Use this for low-level agent management, session control, and custom agent definitions. Requires Python and uv.", + "version": "2.0.0" + }, + "content": { + "files": [ + { + "path": "README.md", + "sha256": "74ba47ab25c3cf2cb56ab5f0ecee34acdf47b3ccdf5bb90ffc866a13614058c2" + }, + { + "path": ".claude-plugin/plugin.json", + "sha256": "0cf6e50877ec30e464699f616bdfaf117f5cbb619abf76990c7460a1d072a1f6" + }, + { + "path": "commands/agent-orchestrator-init.md", + "sha256": "dfe5d0cceb6f9488cbe2501a3cb95a54a543d7ffb918702656c8d231c975f968" + }, + { + "path": "commands/agent-orchestrator-create-runtime-report.md", + "sha256": "94980514e65b81d16729c3349adeef4a9b341f6973b17189cb0a5e61c5dd928b" + }, + { + "path": "commands/agent-orchestrator-create-agent.md", + "sha256": "d9f29f2d7b1eaf98039217e066caf4b178212f684663d0e577f8767bea818c9c" + }, + { + "path": "commands/agent-orchestrator-extract-token-usage.md", + "sha256": "4410276ea6f74e86403dd5e24a72264fc4168d74a9d14b16d88a08b5cc662a5e" + }, + { + "path": "skills/agent-orchestrator/SKILL.md", + "sha256": "c742918fb1ce23dbbe3e207f2bd6402ae6af3d58fc6d26ccd8623d79f92ad925" + }, + { + "path": "skills/agent-orchestrator/references/EXAMPLE-AGENTS.md", + "sha256": "51728d442f26135154a5ec2a52f30614e4c1b7e74748902678cfc90aa15cf414" + }, + { + "path": "skills/agent-orchestrator/references/AGENT-ORCHESTRATOR.md", + "sha256": "84de534d082433ef98546fc6a320e758baa57ff32941e0dad075e06d3ab4ebbb" + }, + { + "path": "skills/agent-orchestrator/references/ENV_VARS.md", + "sha256": "6a27bbc62ba8eef2f141b72894c60e87a40139b582c9438464bd6017778c604b" + }, + { + "path": "skills/agent-orchestrator/example/agents/confluence-researcher/agent.system-prompt.md", + "sha256": "b3bf67d4ce6f5d8d7a9ad0933e11f750c17385f62fbcdc91a066b32936c1691e" + }, + { + "path": "skills/agent-orchestrator/example/agents/confluence-researcher/agent.json", + "sha256": "dbcd7e4aa15d10ed9cda0d179c3602ff1f1a1e953b1edcc03d663aeac7198358" + }, + { + "path": "skills/agent-orchestrator/example/agents/confluence-researcher/README.md", + "sha256": "90bd668c20cb94bd3e6095a83dd4d0f295693731f15d358c802f9d1342207f82" + }, + { + "path": "skills/agent-orchestrator/example/agents/confluence-researcher/agent.mcp.json", + "sha256": "427788b67eac8c6a7b23b19af37a886571b8c3a5300932f8bb788dd063ef0cd0" + }, + { + "path": "skills/agent-orchestrator/example/agents/jira-researcher/agent.system-prompt.md", + "sha256": "997010c801d410d14fd6d4f571fdee1a393912e5bb064cec540ee04a5797365c" + }, + { + "path": "skills/agent-orchestrator/example/agents/jira-researcher/agent.json", + "sha256": "9b862af6cd283d851d522fa8d3087ceb672c9b8a579c6fc8b8123e04807c36d9" + }, + { + "path": "skills/agent-orchestrator/example/agents/jira-researcher/README.md", + "sha256": "27e7d302f9b3a77fedf0211d5915b54098d0f6830a3a106fc01b6c50b63f9366" + }, + { + "path": "skills/agent-orchestrator/example/agents/jira-researcher/agent.mcp.json", + "sha256": "427788b67eac8c6a7b23b19af37a886571b8c3a5300932f8bb788dd063ef0cd0" + }, + { + "path": "skills/agent-orchestrator/example/agents/browser-tester/agent.system-prompt.md", + "sha256": "8d0b3775bcbb89dfae710e254106cfdefce6924d41ed4b532d595b6b18606161" + }, + { + "path": "skills/agent-orchestrator/example/agents/browser-tester/agent.json", + "sha256": "dff9be637b27366ab797ce01eb14d522fe2dd7d540d906ebda4d0a8137dc8b04" + }, + { + "path": "skills/agent-orchestrator/example/agents/browser-tester/agent.mcp.json", + "sha256": "77a711f0ed6c082ede0094fd212fe8a7d440bf72074150021a3b152f2683da04" + }, + { + "path": "skills/agent-orchestrator/example/agents/web-researcher/agent.system-prompt.md", + "sha256": "7100cca40e89242777b463736fe2520ca5bb3c6c29e51ae14f6ce79922d3b0a5" + }, + { + "path": "skills/agent-orchestrator/example/agents/web-researcher/agent.json", + "sha256": "3bd8ed7ca77caa439dfd8b0434ab0cf4b0c1228cc1b664ced3c6ea219c8152c8" + }, + { + "path": "skills/agent-orchestrator/commands/ao-get-result", + "sha256": "d717e3d2adf480a7d845e6d0b9dbfe087df955cf2a5e2d4e3361d064a70d231e" + }, + { + "path": "skills/agent-orchestrator/commands/ao-status", + "sha256": "af2c53b15b268cbe759b7c1900c36293e2d0904adf5d4f0d02f22c16615ed066" + }, + { + "path": "skills/agent-orchestrator/commands/ao-clean", + "sha256": "2f71de6463f188bc7e4cb61c4280263bdf5763bbfbdc08f73e8eb9d71c0c8c17" + }, + { + "path": "skills/agent-orchestrator/commands/ao-resume", + "sha256": "8411e44d92b4f91a87829042719bd259c979a328611c3db5472b6299fc5cd8f1" + }, + { + "path": "skills/agent-orchestrator/commands/ao-list-agents", + "sha256": "dcb45f3b6df226a72a4c07945d83da925edd0e3ed08367e8bb1c78859bf63f32" + }, + { + "path": "skills/agent-orchestrator/commands/ao-show-config", + "sha256": "edb43b5d60fe41e1eab02b69769a45ae6842d014aa844916bc8973271f3f7cb0" + }, + { + "path": "skills/agent-orchestrator/commands/ao-list-sessions", + "sha256": "8e6080da2e4ae696e29b0a26b8bbf8ed1521d94f9d089536baf94a72bbebd4ef" + }, + { + "path": "skills/agent-orchestrator/commands/ao-new", + "sha256": "3cd9696cd79cf4543f4ee20c4ae14e8df4cb8cee06e268c7f3f41f38b54404a3" + }, + { + "path": "skills/agent-orchestrator/commands/lib/config.py", + "sha256": "3bd0be78b65203cc71f551da88dccbbb392cb5362358ec9084a1381098f403fc" + }, + { + "path": "skills/agent-orchestrator/commands/lib/session.py", + "sha256": "0c67cd61c62ff2a2028aa190b680498a9dfbc307bdfde2734d755d849cea6b67" + }, + { + "path": "skills/agent-orchestrator/commands/lib/__init__.py", + "sha256": "825220284b30eefb645fafc6c2795cd6427bc1c44faa0de3d7f7ca6c6328550d" + }, + { + "path": "skills/agent-orchestrator/commands/lib/observability.py", + "sha256": "dd651397596fa81b06fdb39ca0191dc3bf66771ae3d130afc5ec3ca94ad24e80" + }, + { + "path": "skills/agent-orchestrator/commands/lib/utils.py", + "sha256": "fa7d0781fbcfb42cf2a31533bf67f1c547d1722ec71c7d91f3b79ff248ad7ab6" + }, + { + "path": "skills/agent-orchestrator/commands/lib/agent.py", + "sha256": "eb7aa1a618801d18a507684aaffbf5dbbcbec400043da2b6343a84ff51d56067" + }, + { + "path": "skills/agent-orchestrator/commands/lib/claude_client.py", + "sha256": "873643bc1f32d3af545cf1aeac767aba0e999c7fdcde08cf374912e8b12148b4" + } + ], + "dirSha256": "d0f6531b390ea47f005aa39e80b8990981f16dd78efe262f5b3201131a7b3fef" + }, + "security": { + "scannedAt": null, + "scannerVersion": null, + "flags": [] + } +} \ No newline at end of file diff --git a/skills/agent-orchestrator/SKILL.md b/skills/agent-orchestrator/SKILL.md new file mode 100644 index 0000000..e3a2ef2 --- /dev/null +++ b/skills/agent-orchestrator/SKILL.md @@ -0,0 +1,233 @@ +--- +name: agent-orchestrator +description: Use this skill when you need to orchestrate specialized Claude agents in separate sessions. Perfect for long-running tasks, specialized agents with MCP tools, and resumable workflows. +--- + +# Agent Orchestrator Skill + +## What & When + +**What**: Commands for managing specialized Claude AI agent sessions with optional agent definitions and MCP server integration. + +**When to use**: +- Delegate tasks to specialized sessions with different MCP configurations +- Run long-running operations that can be resumed later +- Use agent definitions for specialized behavior (research, testing, etc.) +- Manage multiple concurrent agent conversations +- Work with persistent sessions using simple names (no session ID management) + +**Key Benefits**: +- Session names instead of session IDs (simpler tracking) +- Automatic session management and persistence +- Built-in result extraction (no manual JSON parsing) +- Optional agent definitions for specialized capabilities +- Sessions can be resumed (even after finished) + +--- + +## Quick Reference + +### `ao-new` - Create new session +```bash +uv run commands/ao-new +``` +**Use when**: Starting a new Claude agent session. Reads prompt from stdin or `-p` flag. + +### `ao-resume` - Continue existing session +```bash +uv run commands/ao-resume +``` +**Use when**: Adding messages to an existing session. Reads prompt from stdin or `-p` flag. + +### `ao-status` - Check session state +```bash +uv run commands/ao-status +``` +**Use when**: Need to know if session is `running`, `finished`, or `not_existent`. + +### `ao-get-result` - Extract result from finished session +```bash +uv run commands/ao-get-result +``` +**Use when**: Session is finished and you need the final result text. + +### `ao-list-sessions` - List all sessions +```bash +uv run commands/ao-list-sessions +``` +**Use when**: Need to see available sessions with their IDs and project directories. + +### `ao-list-agents` - List available agent definitions +```bash +uv run commands/ao-list-agents +``` +**Use when**: Need to see what specialized agent definitions are available. + +### `ao-show-config` - Display session configuration +```bash +uv run commands/ao-show-config +``` +**Use when**: Need to see session metadata (project dir, agent used, timestamps, etc.). + +### `ao-clean` - Remove all sessions +```bash +uv run commands/ao-clean +``` +**Use when**: Need to delete all session data. **Use with caution.** + +--- + +## Command Location + +**IMPORTANT**: All commands are located in the `commands/` subdirectory of this skill folder. + +Before using commands for the first time: +1. Locate this skill's root folder (same directory as this SKILL.md) +2. Commands are in: `/commands/ao-*` +3. Execute using: `uv run /commands/ao- ` + +**Example**: +```bash +# If skill is at /path/to/skills/agent-orchestrator +uv run /path/to/skills/agent-orchestrator/commands/ao-new my-session -p "Research topic X" +``` + +--- + +## Parameters Reference + +### Required +- `` - Alphanumeric + dash/underscore, max 60 chars (e.g., `research-task`, `code_review_123`) + +### Common Options +- `-p "prompt"` or `--prompt "prompt"` - Provide prompt via CLI instead of stdin +- `--agent ` - Use specialized agent definition (only for `ao-new`) +- `--project-dir ` - Override project directory (default: current directory) + +--- + +## Typical Workflows + +### Basic Session Workflow +```bash +# Create new session +echo "Analyze this codebase structure" | uv run commands/ao-new analysis + +# Check status +uv run commands/ao-status analysis # Output: finished + +# Get result +uv run commands/ao-get-result analysis + +# Resume with follow-up +echo "Now focus on security patterns" | uv run commands/ao-resume analysis +``` + +### Using Specialized Agents +```bash +# List available agents +uv run commands/ao-list-agents + +# Create session with specific agent +uv run commands/ao-new research-task --agent web-researcher -p "Research Claude AI capabilities" + +# View agent configuration +uv run commands/ao-show-config research-task +``` + +### Managing Sessions +```bash +# List all active sessions +uv run commands/ao-list-sessions + +# Check specific session +uv run commands/ao-status my-session + +# Clean up all sessions +uv run commands/ao-clean +``` + +--- + +## Key Concepts + +### Session States +- **`not_existent`** - Session doesn't exist +- **`running`** - Session active, ready to resume +- **`finished`** - Session complete, result available + +### Working Directory +- Sessions operate in `--project-dir` (default: current directory) +- All file operations within the session are relative to this directory + +### Agents vs Sessions +- **Agent**: Reusable configuration (system prompt + MCP tools) +- **Session**: Running conversation instance +- One agent can be used by multiple sessions +- Sessions can run without agents (general purpose) + +--- + +## Notes for AI Assistants + +1. **Always check status** before resuming: `ao-status ` → only resume if `running` or `finished` +2. **Session names** must be unique and valid (no spaces, max 60 chars, alphanumeric + dash/underscore) +3. **Prompt input**: Use stdin (pipe) OR `-p` flag, not both (stdin takes precedence) +4. **Get result** only works on `finished` sessions - check status first +5. **Agent definitions** are read-only - list them with `ao-list-agents` before using `--agent` +6. **Sessions are persistent** - they survive between command invocations +7. **Command location** - Always use commands from this skill's `commands/` folder +8. **Async execution** - Sessions run in Claude Code, commands return immediately after submission + +--- + +## Error Handling + +Common errors and solutions: + +| Error | Cause | Solution | +|-------|-------|----------| +| "Session already exists" | Creating duplicate session | Use `ao-resume` or choose different name | +| "Session not found" | Wrong name or doesn't exist | Check `ao-list-sessions` | +| "Session is not finished" | Getting result from running session | Check `ao-status`, wait for `finished` | +| "Invalid session name" | Bad characters or too long | Use alphanumeric + dash/underscore, max 60 chars | +| "No prompt provided" | Missing `-p` and stdin | Provide prompt via stdin or `-p` flag | +| "Agent not found" | Agent definition missing | Check `ao-list-agents` for available agents | + +--- + +## Exit Codes + +- `0` - Success +- `1` - Error (invalid input, session not found, etc.) + +--- + +## Quick Decision Tree + +**Want to start a new agent conversation?** → `ao-new ` +- With specialized agent? → Add `--agent ` +- In specific location? → Add `--project-dir ` + +**Want to continue a conversation?** → `ao-resume ` +- Not sure if it exists? → Check with `ao-status ` first + +**Want to see the result?** → `ao-get-result ` +- Must check status first → `ao-status ` (must be `finished`) + +**Want to see what exists?** +- Sessions → `ao-list-sessions` +- Agents → `ao-list-agents` + +**Want session details?** → `ao-show-config ` + +**Want to clean up?** → `ao-clean` (removes all sessions) + +--- + +## Additional Resources + +- **Example Agents**: See `example/agents/` folder for working examples +- **Agent Details & Usage**: See `references/EXAMPLE-AGENTS.md` +- **Architecture & Agent Creation**: See `references/AGENT-ORCHESTRATOR.md` +- **Environment Variables**: See `references/ENV_VARS.md` for configuration options diff --git a/skills/agent-orchestrator/commands/ao-clean b/skills/agent-orchestrator/commands/ao-clean new file mode 100755 index 0000000..80ee398 --- /dev/null +++ b/skills/agent-orchestrator/commands/ao-clean @@ -0,0 +1,95 @@ +#!/usr/bin/env -S uv run --script +# /// script +# requires-python = ">=3.11" +# dependencies = [ +# "typer", +# "httpx", +# ] +# /// +""" +Remove all agent orchestrator sessions. +""" + +import sys +from pathlib import Path + +sys.path.insert(0, str(Path(__file__).parent / "lib")) + +import typer +from typing import Optional +import httpx + +app = typer.Typer(add_completion=False) + + +def delete_from_observability(session_id: str, observability_url: str) -> bool: + """ + Delete session from observability backend. + + Returns True if successful or session not found, False on error. + """ + try: + response = httpx.delete( + f"{observability_url}/sessions/{session_id}", + timeout=2.0 + ) + # 200 = deleted, 404 = not found (both OK) + return response.status_code in (200, 404) + except Exception: + # Silent failure - don't block cleanup + return False + + +@app.command() +def main( + project_dir: Optional[Path] = typer.Option(None, "--project-dir", help="Project directory"), + sessions_dir: Optional[Path] = typer.Option(None, "--sessions-dir", help="Sessions directory"), +): + """ + Remove all sessions. + + Examples: + ao-clean + ao-clean --sessions-dir /custom/path + """ + from config import load_config + from session import list_all_sessions + import shutil + + try: + # Load configuration with CLI overrides + config = load_config( + cli_project_dir=str(project_dir) if project_dir else None, + cli_sessions_dir=str(sessions_dir) if sessions_dir else None, + cli_agents_dir=None, + ) + + # Check if sessions directory exists + if config.sessions_dir.exists(): + # Delete from observability if enabled + if config.observability_enabled: + try: + sessions = list_all_sessions(config.sessions_dir) + for session_name, session_id, project_dir_path in sessions: + if session_id and session_id != "unknown": + delete_from_observability( + session_id, + config.observability_url + ) + except Exception: + # Ignore errors - sessions might not exist or be incomplete + pass + + # Remove entire directory + shutil.rmtree(config.sessions_dir) + print("All sessions removed") + else: + print("No sessions to remove") + + except Exception as e: + print(f"Error: {e}", file=sys.stderr) + raise typer.Exit(1) + + +if __name__ == "__main__": + app() diff --git a/skills/agent-orchestrator/commands/ao-get-result b/skills/agent-orchestrator/commands/ao-get-result new file mode 100755 index 0000000..7f906a7 --- /dev/null +++ b/skills/agent-orchestrator/commands/ao-get-result @@ -0,0 +1,80 @@ +#!/usr/bin/env -S uv run --script +# /// script +# requires-python = ">=3.11" +# dependencies = [ +# "typer", +# ] +# /// +""" +Extract the result from a completed agent orchestrator session. +""" + +import sys +from pathlib import Path + +sys.path.insert(0, str(Path(__file__).parent / "lib")) + +import typer +from typing import Optional + +app = typer.Typer(add_completion=False) + + +@app.command() +def main( + session_name: str = typer.Argument(..., help="Name of the session"), + project_dir: Optional[Path] = typer.Option(None, "--project-dir", help="Project directory"), + sessions_dir: Optional[Path] = typer.Option(None, "--sessions-dir", help="Sessions directory"), +): + """ + Extract the result from a completed session. + + Examples: + ao-get-result mysession + """ + from config import load_config + from session import validate_session_name, get_session_status, extract_result + + try: + # Validate session name + validate_session_name(session_name) + + # Load configuration with CLI overrides + config = load_config( + cli_project_dir=str(project_dir) if project_dir else None, + cli_sessions_dir=str(sessions_dir) if sessions_dir else None, + cli_agents_dir=None, + ) + + # Check session status + status = get_session_status(session_name, config.sessions_dir) + + if status == "not_existent": + print(f"Error: Session '{session_name}' does not exist", file=sys.stderr) + raise typer.Exit(1) + + if status == "running": + print(f"Error: Session '{session_name}' is still running. Wait for completion or check status with ao-status.", file=sys.stderr) + raise typer.Exit(1) + + # Extract and print result + session_file = config.sessions_dir / f"{session_name}.jsonl" + result = extract_result(session_file) + print(result) + + except ValueError as e: + # Session validation errors or result extraction errors + print(f"Error: {e}", file=sys.stderr) + raise typer.Exit(1) + except FileNotFoundError as e: + # Session file not found + print(f"Error: {e}", file=sys.stderr) + raise typer.Exit(1) + except Exception as e: + # Unexpected errors + print(f"Error: {e}", file=sys.stderr) + raise typer.Exit(1) + + +if __name__ == "__main__": + app() diff --git a/skills/agent-orchestrator/commands/ao-list-agents b/skills/agent-orchestrator/commands/ao-list-agents new file mode 100755 index 0000000..8fb891a --- /dev/null +++ b/skills/agent-orchestrator/commands/ao-list-agents @@ -0,0 +1,70 @@ +#!/usr/bin/env -S uv run --script +# /// script +# requires-python = ">=3.11" +# dependencies = [ +# "typer", +# ] +# /// +""" +List all available agent definitions. +""" + +import sys +from pathlib import Path + +sys.path.insert(0, str(Path(__file__).parent / "lib")) + +import typer +from typing import Optional +from config import load_config +from agent import list_all_agents + +app = typer.Typer(add_completion=False) + + +@app.command() +def main( + project_dir: Optional[Path] = typer.Option(None, "--project-dir", help="Project directory"), + agents_dir: Optional[Path] = typer.Option(None, "--agents-dir", help="Agents directory"), +): + """ + List all available agent definitions. + + Displays: agent name, description + + Examples: + ao-list-agents + ao-list-agents --agents-dir /path/to/agents + ao-list-agents --project-dir /my/project + """ + # 1. Load configuration + config = load_config( + cli_project_dir=str(project_dir) if project_dir else None, + cli_agents_dir=str(agents_dir) if agents_dir else None, + ) + + # 2. Get list of agents (list_all_agents handles missing directory gracefully) + agents = list_all_agents(config.agents_dir) + + # 3. Handle empty case + if not agents: + print("No agent definitions found") + return + + # 4. Display agents with bash-compatible formatting + first = True + for name, description in agents: + if first: + first = False + else: + # Add separator before subsequent agents + print("---") + print() + + print(f"{name}:") + print(description) + print() + + +if __name__ == "__main__": + app() diff --git a/skills/agent-orchestrator/commands/ao-list-sessions b/skills/agent-orchestrator/commands/ao-list-sessions new file mode 100755 index 0000000..baa314e --- /dev/null +++ b/skills/agent-orchestrator/commands/ao-list-sessions @@ -0,0 +1,74 @@ +#!/usr/bin/env -S uv run --script +# /// script +# requires-python = ">=3.11" +# dependencies = [ +# "typer", +# ] +# /// +""" +List all agent orchestrator sessions with metadata. +""" + +import sys +from pathlib import Path + +sys.path.insert(0, str(Path(__file__).parent / "lib")) + +import typer +from typing import Optional + +app = typer.Typer(add_completion=False) + + +@app.command() +def main( + project_dir: Optional[Path] = typer.Option(None, "--project-dir", help="Project directory"), + sessions_dir: Optional[Path] = typer.Option(None, "--sessions-dir", help="Sessions directory"), +): + """ + List all sessions with metadata. + + Displays: session name (session-id: session_id, project-dir: project_dir) + + Examples: + ao-list-sessions + ao-list-sessions --sessions-dir /custom/path + """ + from config import load_config + from session import list_all_sessions + from utils import debug_log + + # DEBUG LOGGING - Command entry + debug_log("COMMAND - ao-list-sessions", { + "cwd": str(Path.cwd()), + "argv": sys.argv, + "project_dir": str(project_dir) if project_dir else "None", + "sessions_dir": str(sessions_dir) if sessions_dir else "None", + }) + + try: + # Load configuration with CLI overrides + config = load_config( + cli_project_dir=str(project_dir) if project_dir else None, + cli_sessions_dir=str(sessions_dir) if sessions_dir else None, + cli_agents_dir=None, + ) + + # Get all sessions (list_all_sessions handles missing directory gracefully) + sessions = list_all_sessions(config.sessions_dir) + + # Display results + if not sessions: + print("No sessions found") + else: + for session_name, session_id, project_dir_path in sessions: + print(f"{session_name} (session-id: {session_id}, project-dir: {project_dir_path})") + + except Exception as e: + # Handle errors + print(f"Error: {e}", file=sys.stderr) + raise typer.Exit(1) + + +if __name__ == "__main__": + app() diff --git a/skills/agent-orchestrator/commands/ao-new b/skills/agent-orchestrator/commands/ao-new new file mode 100755 index 0000000..fe29a8d --- /dev/null +++ b/skills/agent-orchestrator/commands/ao-new @@ -0,0 +1,186 @@ +#!/usr/bin/env -S uv run --script +# /// script +# requires-python = ">=3.11" +# dependencies = [ +# "claude-agent-sdk", +# "typer", +# "httpx", +# ] +# /// +""" +Create a new agent orchestrator session. + +This command creates a new Claude AI session, optionally with an agent configuration. +""" + +import sys +from pathlib import Path + +# Add lib to path for shared modules +sys.path.insert(0, str(Path(__file__).parent / "lib")) + +import typer +from typing import Optional + +app = typer.Typer(add_completion=False) + + +@app.command() +def main( + session_name: str = typer.Argument(..., help="Name of the session"), + prompt: Optional[str] = typer.Option(None, "-p", "--prompt", help="Session prompt"), + agent: Optional[str] = typer.Option(None, "--agent", help="Agent to use"), + project_dir: Optional[Path] = typer.Option(None, "--project-dir", help="Project directory"), + sessions_dir: Optional[Path] = typer.Option(None, "--sessions-dir", help="Sessions directory"), + agents_dir: Optional[Path] = typer.Option(None, "--agents-dir", help="Agents directory"), +): + """ + Create a new agent orchestrator session. + + Examples: + ao-new mysession -p "Write hello world" + ao-new research --agent web-researcher -p "Research AI" + cat prompt.md | ao-new mysession + """ + from config import load_config + from session import ( + validate_session_name, + get_session_status, + save_session_metadata, + ) + from agent import load_agent_config, build_mcp_servers_dict + from claude_client import run_session_sync + from utils import ( + get_prompt_from_args_and_stdin, + ensure_directory_exists, + log_command, + log_result, + error_exit, + debug_log, + ) + + # DEBUG LOGGING - Command entry + debug_log("COMMAND - ao-new", { + "cwd": str(Path.cwd()), + "argv": sys.argv, + "session_name": session_name, + "prompt": prompt or "None (will read from stdin)", + "agent": agent or "None", + "project_dir": str(project_dir) if project_dir else "None", + "sessions_dir": str(sessions_dir) if sessions_dir else "None", + "agents_dir": str(agents_dir) if agents_dir else "None", + }) + + try: + # 1. Validate session name + validate_session_name(session_name) + + # 2. Load configuration + config = load_config( + cli_project_dir=str(project_dir) if project_dir else None, + cli_sessions_dir=str(sessions_dir) if sessions_dir else None, + cli_agents_dir=str(agents_dir) if agents_dir else None, + ) + + # 3. Check session doesn't already exist + status = get_session_status(session_name, config.sessions_dir) + if status != "not_existent": + error_exit( + f"Session '{session_name}' already exists. " + "Use 'ao-resume' command to continue or choose a different name" + ) + + # 4. Get prompt (from -p and/or stdin) + user_prompt = get_prompt_from_args_and_stdin(prompt) + + # 5. Load agent if specified + final_prompt = user_prompt + mcp_servers = None + agent_name = None + + if agent: + agent_config = load_agent_config(agent, config.agents_dir) + agent_name = agent_config.name + + # Prepend system prompt if available + if agent_config.system_prompt: + final_prompt = f"{agent_config.system_prompt}\n\n---\n\n{user_prompt}" + + # Build MCP servers dict + mcp_servers = build_mcp_servers_dict(agent_config.mcp_config) + + # 6. Ensure directories exist + ensure_directory_exists(config.sessions_dir) + + # 7. STAGE 1: Save initial session metadata WITHOUT session_id + # This allows users to see the session was started + save_session_metadata( + session_name=session_name, + agent=agent_name, + project_dir=config.project_dir, + agents_dir=config.agents_dir, + sessions_dir=config.sessions_dir, + session_id=None, # Will be added in Stage 2 during streaming + ) + + # 8. Log command (if logging enabled) + if config.enable_logging: + # Build command string for logging (similar to bash) + mcp_info = f"with MCP servers: {list(mcp_servers.keys())}" if mcp_servers else "no MCP" + full_command = ( + f"cd {config.project_dir} && " + f"query(prompt=, cwd={config.project_dir}, " + f"permission_mode=bypassPermissions, {mcp_info})" + ) + log_command( + session_name=session_name, + command_type="new", + agent_name=agent_name, + mcp_config_path=str(agent_config.mcp_config) if agent and agent_config.mcp_config else None, + full_command=full_command, + prompt=final_prompt, + sessions_dir=config.sessions_dir, + project_dir=config.project_dir, + agents_dir=config.agents_dir, + enable_logging=config.enable_logging, + ) + + # 9. Run Claude session + # STAGE 2 happens automatically during streaming when session_id is received + session_file = config.sessions_dir / f"{session_name}.jsonl" + + session_id, result = run_session_sync( + prompt=final_prompt, + session_file=session_file, + project_dir=config.project_dir, + session_name=session_name, # For Stage 2 metadata update + sessions_dir=config.sessions_dir, # For Stage 2 metadata update + mcp_servers=mcp_servers, + observability_enabled=config.observability_enabled, + observability_url=config.observability_url, + agent_name=agent_name, + ) + + # 10. Log result (if logging enabled) + if config.enable_logging: + log_result(session_name, result, config.sessions_dir, config.enable_logging) + + # 11. Print result to stdout + print(result) + + except ValueError as e: + # Session validation errors, prompt errors, etc. + error_exit(str(e)) + except FileNotFoundError as e: + # Agent not found, config file issues, etc. + error_exit(str(e)) + except ImportError as e: + # SDK not installed + error_exit(str(e)) + except Exception as e: + # Unexpected errors (SDK errors, etc.) + error_exit(f"Unexpected error: {e}") + + +if __name__ == "__main__": + app() diff --git a/skills/agent-orchestrator/commands/ao-resume b/skills/agent-orchestrator/commands/ao-resume new file mode 100755 index 0000000..ec69386 --- /dev/null +++ b/skills/agent-orchestrator/commands/ao-resume @@ -0,0 +1,196 @@ +#!/usr/bin/env -S uv run --script +# /// script +# requires-python = ">=3.11" +# dependencies = [ +# "claude-agent-sdk", +# "typer", +# "httpx", +# ] +# /// +""" +Resume an existing agent orchestrator session. + +This command continues a previous session with a new prompt. +""" + +import sys +from pathlib import Path + +sys.path.insert(0, str(Path(__file__).parent / "lib")) + +import typer +from typing import Optional + +app = typer.Typer(add_completion=False) + + +@app.command() +def main( + session_name: str = typer.Argument(..., help="Name of the session"), + prompt: Optional[str] = typer.Option(None, "-p", "--prompt", help="Continuation prompt"), + project_dir: Optional[Path] = typer.Option(None, "--project-dir", help="Project directory"), + sessions_dir: Optional[Path] = typer.Option(None, "--sessions-dir", help="Sessions directory"), + agents_dir: Optional[Path] = typer.Option(None, "--agents-dir", help="Agents directory"), +): + """ + Resume an existing agent orchestrator session. + + Examples: + ao-resume mysession -p "Add error handling" + cat additional-requirements.md | ao-resume mysession + """ + from config import load_config + from session import ( + validate_session_name, + get_session_status, + load_session_metadata, + update_session_metadata, + ) + from agent import load_agent_config, build_mcp_servers_dict + from claude_client import run_session_sync + from utils import ( + get_prompt_from_args_and_stdin, + log_command, + log_result, + error_exit, + debug_log, + ) + + # DEBUG LOGGING - Command entry + debug_log("COMMAND - ao-resume", { + "cwd": str(Path.cwd()), + "argv": sys.argv, + "session_name": session_name, + "prompt": prompt or "None (will read from stdin)", + "project_dir": str(project_dir) if project_dir else "None", + "sessions_dir": str(sessions_dir) if sessions_dir else "None", + "agents_dir": str(agents_dir) if agents_dir else "None", + }) + + try: + # 1. Validate session name + validate_session_name(session_name) + + # 2. Load configuration + config = load_config( + cli_project_dir=str(project_dir) if project_dir else None, + cli_sessions_dir=str(sessions_dir) if sessions_dir else None, + cli_agents_dir=str(agents_dir) if agents_dir else None, + ) + + # 3. Check session exists + status = get_session_status(session_name, config.sessions_dir) + if status == "not_existent": + error_exit( + f"Session '{session_name}' does not exist. " + "Use 'ao-new' command to create it" + ) + + # 4. Load session metadata (contains session_id, agent, paths) + metadata = load_session_metadata(session_name, config.sessions_dir) + + # 5. Context consistency validation + # Warn if CLI overrides differ from metadata (but don't fail) + if project_dir and Path(project_dir).resolve() != metadata.project_dir: + print( + f"Warning: --project-dir override ignored. " + f"Using session metadata value: {metadata.project_dir}", + file=sys.stderr, + ) + + if agents_dir and Path(agents_dir).resolve() != metadata.agents_dir: + print( + f"Warning: --agents-dir override ignored. " + f"Using session metadata value: {metadata.agents_dir}", + file=sys.stderr, + ) + + # 6. Extract session_id from metadata + resume_session_id = metadata.session_id + if not resume_session_id: + error_exit( + f"Session '{session_name}' has no session_id in metadata. " + "Cannot resume incomplete session" + ) + + # 7. Get prompt (from -p and/or stdin) + user_prompt = get_prompt_from_args_and_stdin(prompt) + + # 8. Load agent configuration if session has agent + # NOTE: Do NOT prepend system prompt for resume (only for new sessions) + mcp_servers = None + agent_config = None + + if metadata.agent: + agent_config = load_agent_config(metadata.agent, metadata.agents_dir) + # Build MCP servers dict for SDK + mcp_servers = build_mcp_servers_dict(agent_config.mcp_config) + + # 9. Log command (if logging enabled) + if config.enable_logging: + # Build command string for logging (similar to bash) + mcp_info = f"with MCP servers: {list(mcp_servers.keys())}" if mcp_servers else "no MCP" + full_command = ( + f"cd {metadata.project_dir} && " + f"query(prompt=, cwd={metadata.project_dir}, " + f"permission_mode=bypassPermissions, resume={resume_session_id}, {mcp_info})" + ) + log_command( + session_name=session_name, + command_type="resume", + agent_name=metadata.agent, + mcp_config_path=str(agent_config.mcp_config) if agent_config and agent_config.mcp_config else None, + full_command=full_command, + prompt=user_prompt, + sessions_dir=config.sessions_dir, + project_dir=config.project_dir, + agents_dir=config.agents_dir, + enable_logging=config.enable_logging, + ) + + # 10. Run Claude session with resume + # Use metadata paths (not CLI overrides) to ensure context consistency + session_file = config.sessions_dir / f"{session_name}.jsonl" + + session_id, result = run_session_sync( + prompt=user_prompt, # No system prompt prepended! + session_file=session_file, + project_dir=metadata.project_dir, # From metadata + session_name=session_name, + sessions_dir=config.sessions_dir, + mcp_servers=mcp_servers, + resume_session_id=resume_session_id, # KEY: Enable resume + observability_enabled=config.observability_enabled, + observability_url=config.observability_url, + agent_name=metadata.agent, + ) + + # 11. Update session metadata timestamp + update_session_metadata(session_name, config.sessions_dir) + + # 12. Log result (if logging enabled) + if config.enable_logging: + log_result(session_name, result, config.sessions_dir, config.enable_logging) + + # 13. Print result to stdout + print(result) + + except ValueError as e: + # Session validation errors, prompt errors, etc. + error_exit(str(e)) + except FileNotFoundError as e: + # Session not found, agent not found, etc. + error_exit(str(e)) + except ImportError as e: + # SDK not installed + error_exit( + f"Claude SDK not installed: {e}\n" + "Install with: uv pip install claude-agent-sdk" + ) + except Exception as e: + # Unexpected errors (SDK errors, etc.) + error_exit(f"Unexpected error: {e}") + + +if __name__ == "__main__": + app() diff --git a/skills/agent-orchestrator/commands/ao-show-config b/skills/agent-orchestrator/commands/ao-show-config new file mode 100755 index 0000000..1304e55 --- /dev/null +++ b/skills/agent-orchestrator/commands/ao-show-config @@ -0,0 +1,92 @@ +#!/usr/bin/env -S uv run --script +# /// script +# requires-python = ">=3.11" +# dependencies = [ +# "typer", +# ] +# /// +""" +Display session configuration and context. +""" + +import sys +import json +from pathlib import Path + +sys.path.insert(0, str(Path(__file__).parent / "lib")) + +import typer +from typing import Optional + +app = typer.Typer(add_completion=False) + + +@app.command() +def main( + session_name: str = typer.Argument(..., help="Name of the session"), + project_dir: Optional[Path] = typer.Option(None, "--project-dir", help="Project directory"), + sessions_dir: Optional[Path] = typer.Option(None, "--sessions-dir", help="Sessions directory"), +): + """ + Display session configuration and context. + + Shows: agent used, directories, session metadata + + Examples: + ao-show-config mysession + ao-show-config mysession --project-dir /my/project + """ + from config import load_config + from session import validate_session_name, load_session_metadata + + try: + # Validate session name + validate_session_name(session_name) + + # Load configuration with CLI overrides + config = load_config( + cli_project_dir=str(project_dir) if project_dir else None, + cli_sessions_dir=str(sessions_dir) if sessions_dir else None, + cli_agents_dir=None, + ) + + # Check if session exists + meta_file = config.sessions_dir / f"{session_name}.meta.json" + if not meta_file.exists(): + print(f"Error: Session '{session_name}' does not exist", file=sys.stderr) + raise typer.Exit(1) + + # Load session metadata + metadata = load_session_metadata(session_name, config.sessions_dir) + + # Display configuration matching bash format + print(f"Configuration for session '{session_name}':") + print(f" Session file: {config.sessions_dir}/{session_name}.jsonl") + print(f" Project dir: {metadata.project_dir} (from meta.json)") + print(f" Agents dir: {metadata.agents_dir} (from meta.json)") + print(f" Sessions dir: {config.sessions_dir} (current)") + print(f" Agent: {metadata.agent if metadata.agent else 'none'}") + print(f" Created: {metadata.created_at.isoformat()}Z") + print(f" Last resumed: {metadata.last_resumed_at.isoformat()}Z") + print(f" Schema version: {metadata.schema_version}") + + except ValueError as e: + # Session validation errors + print(f"Error: {e}", file=sys.stderr) + raise typer.Exit(1) + except FileNotFoundError as e: + # Session metadata not found + print(f"Error: {e}", file=sys.stderr) + raise typer.Exit(1) + except (json.JSONDecodeError, KeyError) as e: + # JSON parsing errors + print(f"Error: Invalid session metadata: {e}", file=sys.stderr) + raise typer.Exit(1) + except Exception as e: + # Unexpected errors + print(f"Error: {e}", file=sys.stderr) + raise typer.Exit(1) + + +if __name__ == "__main__": + app() diff --git a/skills/agent-orchestrator/commands/ao-status b/skills/agent-orchestrator/commands/ao-status new file mode 100755 index 0000000..656c0f4 --- /dev/null +++ b/skills/agent-orchestrator/commands/ao-status @@ -0,0 +1,68 @@ +#!/usr/bin/env -S uv run --script +# /// script +# requires-python = ">=3.11" +# dependencies = [ +# "typer", +# ] +# /// +""" +Check the status of an agent orchestrator session. + +Returns: running, finished, or not_existent +""" + +import sys +from pathlib import Path + +sys.path.insert(0, str(Path(__file__).parent / "lib")) + +import typer +from typing import Optional + +app = typer.Typer(add_completion=False) + + +@app.command() +def main( + session_name: str = typer.Argument(..., help="Name of the session"), + project_dir: Optional[Path] = typer.Option(None, "--project-dir", help="Project directory"), + sessions_dir: Optional[Path] = typer.Option(None, "--sessions-dir", help="Sessions directory"), +): + """ + Check the status of a session. + + Outputs one of: running, finished, not_existent + + Examples: + ao-status mysession + """ + from config import load_config + from session import validate_session_name, get_session_status + + try: + # Validate session name + validate_session_name(session_name) + + # Load configuration with CLI overrides + config = load_config( + cli_project_dir=str(project_dir) if project_dir else None, + cli_sessions_dir=str(sessions_dir) if sessions_dir else None, + cli_agents_dir=None, + ) + + # Get and print session status + status = get_session_status(session_name, config.sessions_dir) + print(status) + + except ValueError as e: + # Session validation errors + print(f"Error: {e}", file=sys.stderr) + raise typer.Exit(1) + except Exception as e: + # Unexpected errors + print(f"Error: {e}", file=sys.stderr) + raise typer.Exit(1) + + +if __name__ == "__main__": + app() diff --git a/skills/agent-orchestrator/example/agents/browser-tester/agent.json b/skills/agent-orchestrator/example/agents/browser-tester/agent.json new file mode 100644 index 0000000..b513ca2 --- /dev/null +++ b/skills/agent-orchestrator/example/agents/browser-tester/agent.json @@ -0,0 +1,4 @@ +{ + "name": "browser-tester", + "description": "Specialist in browser automation and end-to-end testing using Playwright" +} diff --git a/skills/agent-orchestrator/example/agents/browser-tester/agent.mcp.json b/skills/agent-orchestrator/example/agents/browser-tester/agent.mcp.json new file mode 100644 index 0000000..542500e --- /dev/null +++ b/skills/agent-orchestrator/example/agents/browser-tester/agent.mcp.json @@ -0,0 +1,10 @@ +{ + "mcpServers": { + "playwright": { + "command": "npx", + "args": [ + "@playwright/mcp@latest" + ] + } + } +} diff --git a/skills/agent-orchestrator/example/agents/browser-tester/agent.system-prompt.md b/skills/agent-orchestrator/example/agents/browser-tester/agent.system-prompt.md new file mode 100644 index 0000000..41b08bc --- /dev/null +++ b/skills/agent-orchestrator/example/agents/browser-tester/agent.system-prompt.md @@ -0,0 +1,22 @@ +You are a browser automation and testing specialist with expertise in end-to-end testing using Playwright. + +Your expertise includes: +- Browser automation across Chromium, Firefox, and WebKit +- End-to-end test design and implementation +- Test selectors and locator strategies +- Handling async operations and waiters +- Screenshot and video capture for debugging +- Cross-browser compatibility testing +- Accessibility testing + +When creating tests: +1. Write clear, maintainable test code +2. Use reliable selectors (prefer data-testid, role, or text) +3. Implement proper wait strategies +4. Add meaningful assertions +5. Consider edge cases and error scenarios +6. Follow Playwright best practices + +You have access to the Playwright MCP server which provides browser automation capabilities. Use it to navigate web pages, interact with elements, take screenshots, and verify behavior. + +Be practical and focus on creating robust, reliable tests that provide real value. diff --git a/skills/agent-orchestrator/example/agents/confluence-researcher/README.md b/skills/agent-orchestrator/example/agents/confluence-researcher/README.md new file mode 100644 index 0000000..c934ec8 --- /dev/null +++ b/skills/agent-orchestrator/example/agents/confluence-researcher/README.md @@ -0,0 +1,27 @@ +# Confluence Researcher Agent + +This agent uses the **mcp-atlassian** MCP server for Confluence integration. + +**MCP Server:** [sooperset/mcp-atlassian](https://github.com/sooperset/mcp-atlassian) + +## Environment Variables + +This agent requires Atlassian credentials. Set these in `.claude/settings.local.json`: + +```json +{ + "env": { + "CONFLUENCE_URL": "https://your-domain.atlassian.net", + "CONFLUENCE_USERNAME": "your-email@example.com", + "CONFLUENCE_API_TOKEN": "your-confluence-api-token" + } +} +``` + +## Required Variables + +- `CONFLUENCE_URL` - Your Confluence instance URL +- `CONFLUENCE_USERNAME` - Your Confluence email +- `CONFLUENCE_API_TOKEN` - Confluence API token (generate at atlassian.com) + +**Note:** The tokens can be the same if using a unified Atlassian account. diff --git a/skills/agent-orchestrator/example/agents/confluence-researcher/agent.json b/skills/agent-orchestrator/example/agents/confluence-researcher/agent.json new file mode 100644 index 0000000..6bb74e8 --- /dev/null +++ b/skills/agent-orchestrator/example/agents/confluence-researcher/agent.json @@ -0,0 +1,4 @@ +{ + "name": "confluence-researcher", + "description": "Conducts iterative Confluence research to answer questions, generates concise answers with documented JSON sources. Input: working_folder (path for sources file), question (research query)" +} diff --git a/skills/agent-orchestrator/example/agents/confluence-researcher/agent.mcp.json b/skills/agent-orchestrator/example/agents/confluence-researcher/agent.mcp.json new file mode 100644 index 0000000..bec1771 --- /dev/null +++ b/skills/agent-orchestrator/example/agents/confluence-researcher/agent.mcp.json @@ -0,0 +1,19 @@ +{ + "mcpServers": { + "mcp-atlassian": { + "command": "docker", + "args": [ + "run", + "-i", + "--rm", + "-e", "CONFLUENCE_URL", + "-e", "CONFLUENCE_USERNAME", + "-e", "CONFLUENCE_API_TOKEN", + "-e", "JIRA_URL", + "-e", "JIRA_USERNAME", + "-e", "JIRA_API_TOKEN", + "ghcr.io/sooperset/mcp-atlassian:latest" + ] + } + } +} \ No newline at end of file diff --git a/skills/agent-orchestrator/example/agents/confluence-researcher/agent.system-prompt.md b/skills/agent-orchestrator/example/agents/confluence-researcher/agent.system-prompt.md new file mode 100644 index 0000000..bfa5ead --- /dev/null +++ b/skills/agent-orchestrator/example/agents/confluence-researcher/agent.system-prompt.md @@ -0,0 +1,86 @@ +You are a Confluence Research Specialist with expertise in conducting thorough, iterative Confluence searches to answer user questions. + +Your expertise includes: +- Formulating effective Confluence CQL (Confluence Query Language) queries +- Evaluating search result relevance +- Extracting key information from Confluence pages +- Iteratively refining searches when information is insufficient +- Documenting sources with precision + +## Workflow + +When conducting research: + +1. **Initial Search** + - Use the mcp__mcp-atlassian__confluence_search tool with a well-crafted query based on the user's question + - Analyze the search results to identify the most promising pages + - You can use simple text queries or CQL queries + +2. **Fetch & Evaluate** + - Use the mcp__mcp-atlassian__confluence_get_page tool to retrieve content from the top relevant results + - Evaluate if the fetched information is sufficient to answer the question + - Track which page IDs and URLs actually contributed to your answer + +3. **Iterate if Needed** + - If information is insufficient, formulate a refined search query + - Adjust your search strategy based on what you've learned + - Consider using CQL for more precise searches (e.g., 'type=page AND space=DEV') + - Repeat the fetch and evaluate process + - Continue until you have adequate information + +4. **Generate Answer, Result File & Sources File** + - Create a result markdown file summarizing your findings + - Provide a concise, direct answer to the research question + - Create a JSON sources file in the specified working folder + - Only include pages that actually contributed to your answer + - Reference the sources file and the result file in your response + +## Input Expectations + +You will receive: +- **working_folder**: The directory path where you should save the sources JSON file and the result file +- **question**: The research question to investigate + +## Output Requirements + +Your response must be: +- **Concise**: Brief and to-the-point answer +- **Accurate**: Based only on fetched information +- **Sourced**: Reference the JSON sources file you created and also the result file + + +### Sources File Format + +Create a JSON file named `research-sources.json` in the working folder with this structure: + +```json +{ + "question": "The original research question", + "sources": [ + { + "page_id": "123456789", + "url": "https://your-instance.atlassian.net/wiki/spaces/SPACE/pages/123456789/Page+Title", + "title": "Page title", + "space": "SPACE", + "relevance": "Why this source was used" + } + ], + "search_iterations": 2, + "timestamp": "ISO 8601 timestamp" +} +``` + +### Result File + +Create a result markdown file named `research-result.md` summarizing your findings. + + +## Quality Standards + +- Only document sources that directly contributed to your answer +- Be strategic with search queries - adjust them intelligently +- Avoid redundant searches +- Prioritize authoritative and recent pages +- Keep your final answer concise but complete + +Be practical, thorough in research, but concise in communication. diff --git a/skills/agent-orchestrator/example/agents/jira-researcher/README.md b/skills/agent-orchestrator/example/agents/jira-researcher/README.md new file mode 100644 index 0000000..27f7a22 --- /dev/null +++ b/skills/agent-orchestrator/example/agents/jira-researcher/README.md @@ -0,0 +1,27 @@ +# Jira Researcher Agent + +This agent uses the **mcp-atlassian** MCP server for Jira integration. + +**MCP Server:** [sooperset/mcp-atlassian](https://github.com/sooperset/mcp-atlassian) + +## Environment Variables + +This agent requires Jira credentials. Set these in `.claude/settings.local.json`: + +```json +{ + "env": { + "JIRA_URL": "https://your-domain.atlassian.net", + "JIRA_USERNAME": "your-email@example.com", + "JIRA_API_TOKEN": "your-jira-api-token" + } +} +``` + +## Required Variables + +- `JIRA_URL` - Your Jira instance URL +- `JIRA_USERNAME` - Your Jira email +- `JIRA_API_TOKEN` - Jira API token (generate at atlassian.com) + +**Note:** If the MCP server also supports Confluence, you may need to include Confluence variables as well, but they are not required for Jira-only operations. diff --git a/skills/agent-orchestrator/example/agents/jira-researcher/agent.json b/skills/agent-orchestrator/example/agents/jira-researcher/agent.json new file mode 100644 index 0000000..d7a6024 --- /dev/null +++ b/skills/agent-orchestrator/example/agents/jira-researcher/agent.json @@ -0,0 +1,4 @@ +{ + "name": "jira-researcher", + "description": "Conducts iterative Jira research to answer questions using JQL queries, generates concise answers with documented JSON sources. Input: working_folder (path for sources file), question (research query)" +} diff --git a/skills/agent-orchestrator/example/agents/jira-researcher/agent.mcp.json b/skills/agent-orchestrator/example/agents/jira-researcher/agent.mcp.json new file mode 100644 index 0000000..bec1771 --- /dev/null +++ b/skills/agent-orchestrator/example/agents/jira-researcher/agent.mcp.json @@ -0,0 +1,19 @@ +{ + "mcpServers": { + "mcp-atlassian": { + "command": "docker", + "args": [ + "run", + "-i", + "--rm", + "-e", "CONFLUENCE_URL", + "-e", "CONFLUENCE_USERNAME", + "-e", "CONFLUENCE_API_TOKEN", + "-e", "JIRA_URL", + "-e", "JIRA_USERNAME", + "-e", "JIRA_API_TOKEN", + "ghcr.io/sooperset/mcp-atlassian:latest" + ] + } + } +} \ No newline at end of file diff --git a/skills/agent-orchestrator/example/agents/jira-researcher/agent.system-prompt.md b/skills/agent-orchestrator/example/agents/jira-researcher/agent.system-prompt.md new file mode 100644 index 0000000..a0140ca --- /dev/null +++ b/skills/agent-orchestrator/example/agents/jira-researcher/agent.system-prompt.md @@ -0,0 +1,93 @@ +You are a Jira Research Specialist with expertise in conducting thorough, iterative Jira searches to answer user questions. + +Your expertise includes: +- Formulating effective JQL (Jira Query Language) queries +- Evaluating search result relevance +- Extracting key information from Jira issues +- Analyzing linked issues when they provide relevant context +- Iteratively refining searches when information is insufficient +- Documenting sources with precision + +## Workflow + +When conducting research: + +1. **Initial Search** + - Use the mcp__mcp-atlassian__jira_search tool with a well-crafted JQL query based on the user's question + - Analyze the search results to identify the most promising issues + - You can use simple text queries or JQL queries + - Example JQL: 'project = PROJ AND status != Closed AND text ~ "keyword"' + +2. **Fetch & Evaluate** + - Use the mcp__mcp-atlassian__jira_get_issue tool to retrieve content from the top relevant results + - Initially focus on issue key, summary, description, status, and assignee + - If prompted for deeper search, also examine comments using the appropriate tool + - Check linked issues to determine if they provide helpful context + - Evaluate if the fetched information is sufficient to answer the question + - Track which issue keys and URLs actually contributed to your answer + +3. **Iterate if Needed** + - If information is insufficient, formulate a refined JQL query + - Adjust your search strategy based on what you've learned + - Consider refining by project, status, issue type, or other fields + - Example refined JQL: 'project = PROJ AND issuetype = Bug AND status = Open' + - Repeat the fetch and evaluate process + - Continue until you have adequate information + +4. **Generate Answer, Result File & Sources File** + - Create a result markdown file summarizing your findings + - Provide a concise, direct answer to the research question + - Create a JSON sources file in the specified working folder + - Only include issues that actually contributed to your answer + - Reference the sources file and the result file in your response + +## Input Expectations + +You will receive: +- **working_folder**: The directory path where you should save the sources JSON file and the result file +- **question**: The research question to investigate + +## Output Requirements + +Your response must be: +- **Concise**: Brief and to-the-point answer +- **Accurate**: Based only on fetched information +- **Sourced**: Reference the JSON sources file you created and also the result file + + +### Sources File Format + +Create a JSON file named `research-sources.json` in the working folder with this structure: + +```json +{ + "question": "The original research question", + "sources": [ + { + "key": "PROJ-123", + "url": "https://your-instance.atlassian.net/browse/PROJ-123", + "title": "Issue summary", + "relevance": "Why this source was used" + } + ], + "search_iterations": 2, + "timestamp": "ISO 8601 timestamp" +} +``` + +### Result File + +Create a result markdown file named `research-result.md` summarizing your findings. + + +## Quality Standards + +- Only document sources that directly contributed to your answer +- Be strategic with JQL queries - adjust them intelligently +- Avoid redundant searches +- Prioritize relevant issues based on status, priority, and recency +- When project scope is specified in JQL, respect those boundaries +- Check linked issues only when they add relevant context +- Keep your final answer concise but complete + +Be practical, thorough in research, but concise in communication. diff --git a/skills/agent-orchestrator/example/agents/web-researcher/agent.json b/skills/agent-orchestrator/example/agents/web-researcher/agent.json new file mode 100644 index 0000000..fee73cf --- /dev/null +++ b/skills/agent-orchestrator/example/agents/web-researcher/agent.json @@ -0,0 +1,4 @@ +{ + "name": "web-researcher", + "description": "Conducts iterative web research to answer questions, generates concise answers with documented JSON sources. Input: working_folder (path for sources file), question (research query)" +} diff --git a/skills/agent-orchestrator/example/agents/web-researcher/agent.system-prompt.md b/skills/agent-orchestrator/example/agents/web-researcher/agent.system-prompt.md new file mode 100644 index 0000000..8c9b3e3 --- /dev/null +++ b/skills/agent-orchestrator/example/agents/web-researcher/agent.system-prompt.md @@ -0,0 +1,82 @@ +You are a Web Research Specialist with expertise in conducting thorough, iterative internet research to answer user questions. + +Your expertise includes: +- Formulating effective web search queries +- Evaluating search result relevance +- Extracting key information from web pages +- Iteratively refining searches when information is insufficient +- Documenting sources with precision + +## Workflow + +When conducting research: + +1. **Initial Search** + - Use the WebSearch tool with a well-crafted query based on the user's question + - Analyze the search results to identify the most promising sources + +2. **Fetch & Evaluate** + - Use the WebFetch tool to retrieve content from the top relevant results + - Evaluate if the fetched information is sufficient to answer the question + - Track which URLs actually contributed to your answer + +3. **Iterate if Needed** + - If information is insufficient, formulate a refined search query + - Adjust your search strategy based on what you've learned + - Repeat the fetch and evaluate process + - Continue until you have adequate information + +4. **Generate Answer, Result File & Sources File** + - Create an result mardown file summarizing your findings + - Provide a concise, direct answer to the research question + - Create a JSON sources file in the specified working folder + - Only include URLs that actually contributed to your answer + - Reference the sources file and the result file in your response + +## Input Expectations + +You will receive: +- **working_folder**: The directory path where you should save the sources JSON file and the result file +- **question**: The research question to investigate + +## Output Requirements + +Your response must be: +- **Concise**: Brief and to-the-point answer +- **Accurate**: Based only on fetched information +- **Sourced**: Reference the JSON sources file you created and also the result file + + +### Sources File Format + +Create a JSON file named `research-sources.json` in the working folder with this structure: + +```json +{ + "question": "The original research question", + "sources": [ + { + "url": "https://example.com/page1", + "title": "Page title or brief description", + "relevance": "Why this source was used" + } + ], + "search_iterations": 2, + "timestamp": "ISO 8601 timestamp" +} +``` + +### Result File + +Create a result markdown file name `research-result.md` summarizing your findings. + + +## Quality Standards + +- Only document sources that directly contributed to your answer +- Be strategic with search queries - adjust them intelligently +- Avoid redundant searches +- Prioritize authoritative and recent sources +- Keep your final answer concise but complete + +Be practical, thorough in research, but concise in communication. diff --git a/skills/agent-orchestrator/references/AGENT-ORCHESTRATOR.md b/skills/agent-orchestrator/references/AGENT-ORCHESTRATOR.md new file mode 100644 index 0000000..c466b12 --- /dev/null +++ b/skills/agent-orchestrator/references/AGENT-ORCHESTRATOR.md @@ -0,0 +1,313 @@ +# Agent Orchestrator + +A lightweight orchestration layer for managing multiple Claude Code agent sessions through a simple command-line interface. + +## Overview + +The Agent Orchestrator provides a simplified abstraction for delegating work to Claude Code. Instead of manually managing session IDs, output files, and JSON parsing, you work with **named sessions** that can be created, resumed, and monitored through intuitive commands. Sessions can optionally use **agent definitions** to provide specialized behavior and capabilities. + +## Core Concepts + +### Sessions + +A **session** is a named, persistent conversation with Claude Code. Each session: +- Has a unique name (e.g., `architect`, `reviewer`, `dev-agent`) +- Maintains conversation history across multiple interactions +- Can be paused and resumed at any time +- Operates independently from other sessions +- Optionally uses an **agent** definition for specialized behavior + +Think of sessions as individual workstreams or conversations you can delegate tasks to and check back with later. + +### Agents (Definitions) + +An **agent** is a reusable configuration that defines the behavior, expertise, and capabilities for sessions. Agents are optional - you can create generic sessions without them, or use agents to create specialized sessions with predefined behavior. + +#### Agent Structure + +Each agent is organized in its own directory within `.agent-orchestrator/agents/`. Each agent directory must match the agent name and contains: + +``` +.agent-orchestrator/agents/ +└── / + ├── agent.json # Required: Agent configuration + ├── agent.system-prompt.md # Optional: System prompt by convention + └── agent.mcp.json # Optional: MCP configuration by convention +``` + +**1. agent.json** (Required) +```json +{ + "name": "browser-tester", + "description": "Specialist in browser automation and end-to-end testing using Playwright" +} +``` +- `name`: Agent identifier (must match folder name) +- `description`: Human-readable description + +**2. agent.system-prompt.md** (Optional) +Markdown file containing the agent's role definition, expertise areas, and behavioral guidelines. When present, this prompt is automatically prepended to user prompts. Discovered by convention - no need to reference in agent.json. + +**3. agent.mcp.json** (Optional) +Standard MCP server configuration enabling the agent to access external tools and capabilities. Passed to Claude CLI via `--mcp-config` flag. Discovered by convention - no need to reference in agent.json. + +#### Agent Workflow + +When creating a session with an agent: +1. Agent JSON config is loaded and validated +2. System prompt (if specified) is prepended to user's prompt +3. MCP config (if specified) is passed to Claude CLI +4. Agent association is stored with session metadata +5. When resuming, the session automatically uses its associated agent + +### Session Management + +The tool abstracts away Claude Code's internal session ID management. You interact with sessions using memorable names rather than UUIDs, while the tool handles: +- Session file storage and organization (`.jsonl` + `.meta.json` files) +- Session ID extraction and tracking +- Agent association and configuration +- Result retrieval and formatting +- State management + +#### Session States + +Sessions can be in one of three states (returned by `ao-status`): +- **`not_existent`** - Session doesn't exist yet (never created or was cleaned up) +- **`running`** - Session created but hasn't returned a result yet (actively processing or ready for resume) +- **`finished`** - Session completed with result available (use `ao-get-result` to retrieve) + +#### Session Storage + +Each session is stored as: +- `{session-name}.jsonl` - Complete conversation history in JSONL format +- `{session-name}.meta.json` - Session metadata (agent association, project directory, timestamps, session ID) + +Location: `{sessions-dir}/` (default: `.agent-orchestrator/agent-sessions/`) + +#### Working Directory Context + +- Sessions operate in a `project-dir` (default: current working directory when command is invoked) +- All file operations within the session are relative to this directory +- The project directory is stored in session metadata and preserved across resumes + +## Use Cases + +### Multi-Session Workflows + +Coordinate multiple specialized sessions working on different aspects of a project: +```bash +# First, discover available agent definitions +uv run commands/ao-list-agents + +# Architecture session using system-architect agent +uv run commands/ao-new architect --agent system-architect -p "Design microservices architecture for e-commerce" + +# Development session implements based on architecture +cat architecture.md | uv run commands/ao-new developer --agent senior-developer -p "Implement based on this design:" + +# Reviewer session provides feedback +uv run commands/ao-new reviewer --agent security-reviewer -p "Review the implementation for best practices" +``` + +### Long-Running Background Tasks + +Delegate time-consuming tasks to background sessions while you continue working: +- Large codebase analysis +- Comprehensive documentation generation +- Multi-step refactoring operations +- Complex test suite creation + +### Iterative Refinement + +Resume sessions to continue and refine their previous work: +```bash +# Initial work +uv run commands/ao-new technical-writer --agent documentation-expert -p "Create API documentation" + +# Later refinement +uv run commands/ao-resume technical-writer -p "Add authentication examples" + +# Further enhancement +uv run commands/ao-resume technical-writer -p "Include error handling section" +``` + +### Stateful Conversations + +Maintain context across multiple prompts without re-explaining background: +- Each session retains full conversation history +- No need to repeat requirements or context +- Build on previous responses naturally + +## Features + +### Current Capabilities + +**Session Management** +- Create new sessions with descriptive names +- Resume existing sessions by name +- List all active sessions with status +- List all available agent definitions +- Clean up all sessions in one command +- Optional agent associations for specialized behavior + +**Flexible Prompting** +- Direct prompt input via `-p` flag +- File-based prompts via stdin piping +- Combined prompts (prefix + file content) +- Large prompt support without character limits + +**Execution Modes** +- Synchronous execution (wait for completion) +- Background execution with polling support +- Automatic result extraction +- Clean stdout/stderr separation + +**State Tracking** +- Session status visibility (active, initializing, completed) +- Session ID management (hidden from user) +- Agent association tracking +- Conversation history persistence +- Cross-session identification + +### Companion Skill + +The `agent-orchestrator` skill provides integration guidance for Claude Code agents to use this tool within their own workflows. The skill documents: +- Synchronous and asynchronous usage patterns +- Background execution with polling logic +- Result extraction and error handling +- Best practices for agent orchestration + +## Future Directions + +### Agent Definitions (Current Implementation) + +The tool now supports **agent definitions** - reusable configurations that define behavior, capabilities, and constraints for sessions: + +**System Prompt Templates** +- Predefined role-based system prompts (architect, developer, reviewer, etc.) +- Consistent behavior across multiple sessions using the same agent +- Custom agent definitions for specialized workflows +- Markdown format for natural prompt editing + +**Configuration Profiles** +- MCP (Model Context Protocol) server configurations per agent +- Tool access through MCP integration +- Hybrid JSON + Markdown format for easy editing + +**Agent-Based Sessions** +```bash +# Create session with agent +uv run commands/ao-new architect --agent system-architect -p "Design e-commerce system" + +# Create generic session (no agent) +uv run commands/ao-new quick-task -p "Simple task" + +# Resume remembers agent association +uv run commands/ao-resume architect -p "Add security layer" +``` + +**Separation of Concerns** +- **Agent**: Blueprint/configuration (reusable definition) +- **Session**: Running conversation (specific instance) +- Agents are reusable; sessions are unique conversations + +### Additional Planned Features + +**Advanced Orchestration** +- Session-to-session communication patterns +- Dependency chains between sessions +- Parallel session execution coordination +- Result aggregation and synthesis + +**Enhanced State Management** +- Session snapshots and rollback +- Conversation branching +- Selective history pruning +- Export/import of sessions + +**Observability** +- Detailed execution logs per session +- Token usage tracking +- Performance metrics +- Conversation visualization + +**Workflow Automation** +- Declarative multi-session workflows +- Event-driven session triggering +- Conditional execution paths +- Workflow templates + +## Architecture + +### Components + +**`ao-*` Commands** +Collection of Python-based CLI commands providing the command-line interface and orchestration logic. Handles session management, Claude Code SDK invocation, and result extraction. Commands include: +- `ao-new` - Create new sessions +- `ao-resume` - Resume existing sessions +- `ao-status` - Check session state +- `ao-get-result` - Extract results +- `ao-list-sessions` - List all sessions +- `ao-list-agents` - List available agents +- `ao-show-config` - Display session configuration +- `ao-clean` - Remove all sessions + +### Directory Structure + +The Agent Orchestrator uses a project-relative directory structure located at `.agent-orchestrator/` in the current working directory where the script is invoked. + +**`.agent-orchestrator/agent-sessions/`** +Storage directory for session files (JSONL format). Each file contains the complete conversation history and session metadata for one session. Companion `.meta.json` files track agent associations and timestamps. + +**`.agent-orchestrator/agents/`** +Storage directory for agent definitions specific to the current project. Each agent is organized in its own subdirectory named after the agent, containing: +- `agent.json` - Required configuration file with agent metadata +- `agent.system-prompt.md` - Optional system prompt (discovered by convention) +- `agent.mcp.json` - Optional MCP configuration for tool access (discovered by convention) + +All sessions and agent definitions are stored relative to the project directory (`$PWD`) where the script is invoked, ensuring each project maintains its own isolated agent environment. + +### Design Philosophy + +**Simplicity First** +Minimize cognitive overhead for users. Named sessions instead of UUIDs, intuitive commands, sensible defaults. + +**Progressive Enhancement** +Start simple, add complexity only when needed. Basic usage is straightforward; advanced features are opt-in. + +**Composability** +Tool plays well with Unix pipes, scripts, and other CLI tools. Clean input/output separation enables chaining and automation. + +**Transparency** +Clear feedback, meaningful error messages, visible state. Users always know what's happening. + +## Integration + +The Agent Orchestrator is designed to work within the Claude Code ecosystem: + +**Slash Commands** +Create custom slash commands that delegate to sessions via the runner. + +**Skills** +Skills can orchestrate multiple sessions for complex, multi-step operations. + +**MCP Servers** +Agents support MCP server configurations for enhanced capabilities. +The MCP configuration is passed to the Claude CLI when starting or resuming sessions. + +**Workflows** _(Future)_ +Declarative workflow definitions will coordinate multiple sessions. + +## Status + +**Current Version**: Initial Release +**Status**: Production Ready + +The core functionality is stable and tested. Agent type system and advanced features are in design phase. + +## Related Documentation + +- **Command Help**: Run `uv run commands/ao- --help` for command-specific syntax and options (e.g., `uv run commands/ao-new --help`) +- **Skill Documentation**: See the main `SKILL.md` file for comprehensive usage guide and examples +- **Example Agents**: See `EXAMPLE-AGENTS.md` for detailed agent definition examples +- **Claude Code SDK**: The commands use the Claude Code SDK for agent orchestration \ No newline at end of file diff --git a/skills/agent-orchestrator/references/ENV_VARS.md b/skills/agent-orchestrator/references/ENV_VARS.md new file mode 100644 index 0000000..080697a --- /dev/null +++ b/skills/agent-orchestrator/references/ENV_VARS.md @@ -0,0 +1,212 @@ +# Environment Variables Reference + +## Overview + +The Agent Orchestrator Skill uses environment variables to configure directory paths, logging, and observability integration. These variables control where agent definitions, sessions, and logs are stored, and how sessions interact with monitoring systems. + +**Configuration Precedence:** CLI Flags > Environment Variables > Defaults + +## Quick Reference + +| Variable | Default | Type | Description | +|----------|---------|------|-------------| +| `AGENT_ORCHESTRATOR_PROJECT_DIR` | `$PWD` | Path | Project working directory | +| `AGENT_ORCHESTRATOR_SESSIONS_DIR` | `{project_dir}/.agent-orchestrator/agent-sessions` | Path | Session storage directory | +| `AGENT_ORCHESTRATOR_AGENTS_DIR` | `{project_dir}/.agent-orchestrator/agents` | Path | Agent definitions directory | +| `AGENT_ORCHESTRATOR_ENABLE_LOGGING` | `false` | Boolean | Enable session logging | +| `AGENT_ORCHESTRATOR_OBSERVABILITY_ENABLED` | `false` | Boolean | Enable observability events | +| `AGENT_ORCHESTRATOR_OBSERVABILITY_URL` | `http://127.0.0.1:8765` | URL | Observability backend endpoint | + +## Detailed Descriptions + +### Directory Configuration + +#### `AGENT_ORCHESTRATOR_PROJECT_DIR` +**Default:** Current working directory (`$PWD`) +**Type:** Absolute or relative path +**Purpose:** Sets the working directory where agent sessions execute. All commands run by Claude during the session inherit this as their current working directory. + +**Validation:** Must exist, must be a directory, must be readable. + +**Example:** +```bash +export AGENT_ORCHESTRATOR_PROJECT_DIR="/Users/username/my-project" +``` + +--- + +#### `AGENT_ORCHESTRATOR_SESSIONS_DIR` +**Default:** `{project_dir}/.agent-orchestrator/agent-sessions` +**Type:** Absolute or relative path +**Purpose:** Directory for storing session files (.jsonl) and metadata (.meta.json). Sessions can be resumed by reading these files. Centralize sessions across projects by setting this to a fixed path. + +**Validation:** Parent directory must be writable (auto-creates if missing). + +**Example:** +```bash +# Store all sessions in a central location +export AGENT_ORCHESTRATOR_SESSIONS_DIR="/Users/username/.agent-sessions" +``` + +--- + +#### `AGENT_ORCHESTRATOR_AGENTS_DIR` +**Default:** `{project_dir}/.agent-orchestrator/agents` +**Type:** Absolute or relative path +**Purpose:** Directory containing agent definition files (agent.md, agent.mcp.json). Use this to share agent configurations across multiple projects. + +**Validation:** Parent directory must be writable (auto-creates if missing). + +**Example:** +```bash +# Share agent definitions across projects +export AGENT_ORCHESTRATOR_AGENTS_DIR="/Users/username/.shared-agents" +``` + +--- + +### Logging Configuration + +#### `AGENT_ORCHESTRATOR_ENABLE_LOGGING` +**Default:** `false` (disabled) +**Type:** Boolean (`"1"`, `"true"`, `"yes"` = enabled, case-insensitive) +**Purpose:** Enable detailed logging of session commands, prompts, and results to `.log` files in the sessions directory. + +**Log Location:** `{sessions_dir}/{session_name}.log` +**Log Contents:** Command invocations, full prompts, environment variables, timestamps, results. + +**Example:** +```bash +# Enable logging +export AGENT_ORCHESTRATOR_ENABLE_LOGGING="true" +``` + +--- + +### Observability Configuration + +#### `AGENT_ORCHESTRATOR_OBSERVABILITY_ENABLED` +**Default:** `false` (disabled) +**Type:** Boolean (`"1"`, `"true"`, `"yes"` = enabled, case-insensitive) +**Purpose:** Enable real-time event streaming to an observability backend. Captures session lifecycle events, tool calls, and assistant messages for monitoring and analysis. + +**Events Tracked:** +- `session_start` - Session initialization +- `message` - User prompts and assistant responses +- `pre_tool` - Before tool execution +- `post_tool` - After tool execution (includes errors) +- `session_stop` - Session completion + +**Example:** +```bash +# Enable observability +export AGENT_ORCHESTRATOR_OBSERVABILITY_ENABLED="true" +``` + +--- + +#### `AGENT_ORCHESTRATOR_OBSERVABILITY_URL` +**Default:** `http://127.0.0.1:8765` +**Type:** URL (HTTP endpoint) +**Purpose:** Base URL of the observability backend service. Events are sent to `{url}/events` via HTTP POST. + +**Requirements:** +- Must be accessible from where skill commands run +- Must accept JSON POST requests to `/events` endpoint +- Failures are silent (won't block session execution) + +**Example:** +```bash +# Use custom observability backend +export AGENT_ORCHESTRATOR_OBSERVABILITY_URL="http://localhost:9000" +``` + +--- + +## CLI Flag Overrides + +The following CLI flags override environment variables when specified: + +| CLI Flag | Overrides | Available In | +|----------|-----------|--------------| +| `--project-dir` | `AGENT_ORCHESTRATOR_PROJECT_DIR` | `ao-new`, `ao-resume`, `ao-show-config`, `ao-status`, `ao-clean` | +| `--sessions-dir` | `AGENT_ORCHESTRATOR_SESSIONS_DIR` | `ao-new`, `ao-resume`, `ao-show-config`, `ao-list-sessions`, `ao-status`, `ao-get-result`, `ao-clean` | +| `--agents-dir` | `AGENT_ORCHESTRATOR_AGENTS_DIR` | `ao-new`, `ao-resume`, `ao-list-agents` | + +**Note:** Observability settings (`OBSERVABILITY_ENABLED`, `OBSERVABILITY_URL`) and logging (`ENABLE_LOGGING`) can only be configured via environment variables, not CLI flags. + +### Example Usage + +```bash +# Override project directory for a single command +ao-new mysession --project-dir /path/to/project -p "Build feature" + +# Override sessions directory to use centralized storage +ao-list-sessions --sessions-dir /Users/username/.agent-sessions + +# Override agents directory to use shared agent definitions +ao-new research --agent web-researcher --agents-dir /shared/agents +``` + +--- + +## Configuration Resolution Order + +1. **CLI Flags** (highest priority) - `--project-dir`, `--sessions-dir`, `--agents-dir` +2. **Environment Variables** (medium priority) - `AGENT_ORCHESTRATOR_*` +3. **Defaults** (lowest priority) - `$PWD` or `{project}/.agent-orchestrator/*` + +**Example Resolution:** +```bash +# Environment variables set +export AGENT_ORCHESTRATOR_PROJECT_DIR="/home/user/project-a" +export AGENT_ORCHESTRATOR_SESSIONS_DIR="/home/user/.sessions" + +# Command with CLI override +ao-new test --project-dir /home/user/project-b -p "Hello" + +# Resolution: +# project_dir = /home/user/project-b (CLI flag wins) +# sessions_dir = /home/user/.sessions (from env var) +# agents_dir = /home/user/project-b/.agent-orchestrator/agents (default) +``` + +--- + +## Common Patterns + +### Pattern 1: Centralized Sessions and Agents +Useful for maintaining all agent work in a dedicated location, regardless of which project you're working in. + +```bash +# In ~/.bashrc or ~/.zshrc +export AGENT_ORCHESTRATOR_SESSIONS_DIR="$HOME/.agent-orchestrator/sessions" +export AGENT_ORCHESTRATOR_AGENTS_DIR="$HOME/.agent-orchestrator/agents" +export AGENT_ORCHESTRATOR_ENABLE_LOGGING="true" +``` + +### Pattern 2: Project-Specific with Observability +Keep sessions and agents per-project but enable monitoring. + +```bash +# In project directory or .env file +export AGENT_ORCHESTRATOR_OBSERVABILITY_ENABLED="true" +export AGENT_ORCHESTRATOR_OBSERVABILITY_URL="http://localhost:8765" + +# Sessions go to ./.agent-orchestrator/agent-sessions (default) +# Agents go to ./.agent-orchestrator/agents (default) +``` + +### Pattern 3: Claude Code Local Settings +Configure via `.claude/settings.local.json` for persistence across sessions. + +```json +{ + "env": { + "AGENT_ORCHESTRATOR_SESSIONS_DIR": "/Users/username/projects/ai/orchestrator/.agent-orchestrator/agent-sessions", + "AGENT_ORCHESTRATOR_AGENTS_DIR": "/Users/username/projects/ai/orchestrator/.agent-orchestrator/agents", + "AGENT_ORCHESTRATOR_OBSERVABILITY_ENABLED": "true", + "AGENT_ORCHESTRATOR_OBSERVABILITY_URL": "http://127.0.0.1:8765" + } +} +``` diff --git a/skills/agent-orchestrator/references/EXAMPLE-AGENTS.md b/skills/agent-orchestrator/references/EXAMPLE-AGENTS.md new file mode 100644 index 0000000..7f5f57c --- /dev/null +++ b/skills/agent-orchestrator/references/EXAMPLE-AGENTS.md @@ -0,0 +1,87 @@ +# Example Agent Definitions + +This reference provides a complete example agent definition demonstrating the Agent Orchestrator folder-based agent structure. + +## Example Source Location + +The example agent is located at `../example/agents/browser-tester/` (relative to this file) and includes: + +``` +browser-tester/ +├── agent.json # Agent configuration +├── agent.system-prompt.md # System prompt (optional) +└── agent.mcp.json # MCP configuration (optional) +``` + +**agent.json** - Agent configuration +- Defines agent name and description +- Name must match the folder name + +**agent.system-prompt.md** - System prompt +- Contains role definition, expertise areas, and behavioral guidelines +- Automatically prepended to user prompts when the agent is used +- Discovered by convention (no need to reference in agent.json) + +**agent.mcp.json** - MCP configuration +- Configures Playwright MCP server for browser automation capabilities +- Provides tool access to the agent's sessions +- Discovered by convention (no need to reference in agent.json) +- IMPORTANT: Not all agents require MCP configurations; this is specific to agents needing external tool access + +## Using the Example + +**Source**: Copy the entire folder from `../example/agents/browser-tester/` (relative to this file) +**Destination**: Place it in `.agent-orchestrator/agents/` in your project directory + +```bash +# From your project root +cp -r path/to/agent-orchestrator/example/agents/browser-tester .agent-orchestrator/agents/ +``` + +Once copied to your project, the agent can be used with the Agent Orchestrator commands: + +```bash +# List available agents +uv run commands/ao-list-agents + +# Create session with the browser-tester agent +uv run commands/ao-new my-test --agent browser-tester -p "Test login flow" +``` + +## Customizing Agents + +To create your own agents based on this example: + +1. **Copy the example folder** and rename it to match your agent's purpose +2. **Edit agent.json**: Update the `name` field to match the new folder name +3. **Edit agent.system-prompt.md**: Define your agent's role, expertise, and behavior +4. **Edit or remove agent.mcp.json**: Configure tools your agent needs, or delete if not needed +5. **Place in your project**: Copy the folder to `.agent-orchestrator/agents/` in your project + +The folder structure keeps each agent self-contained and easy to distribute or version control. + +## Available Example Agents + +The following example agents are available in the `../example/agents/` directory: + +### browser-tester +**Location**: `../example/agents/browser-tester/` +**Description**: Browser automation agent with Playwright MCP integration for testing web applications +**Features**: Includes MCP configuration for browser automation tools + +### web-researcher +**Location**: `../example/agents/web-researcher/` +**Description**: Conducts iterative web research using WebSearch and WebFetch tools to answer questions +**Features**: Generates documented JSON sources and markdown research results + +### confluence-researcher +**Location**: `../example/agents/confluence-researcher/` +**Description**: Conducts iterative Confluence research using CQL queries to answer questions +**Features**: Includes mcp-atlassian MCP server integration, generates documented JSON sources and markdown research results +**Setup**: See README.md for required environment variables configuration + +### jira-researcher +**Location**: `../example/agents/jira-researcher/` +**Description**: Conducts iterative Jira research using JQL queries to answer questions +**Features**: Includes mcp-atlassian MCP server integration, analyzes issues and linked items, generates documented JSON sources and markdown research results +**Setup**: See README.md for required environment variables configuration