diff --git a/README.md b/README.md index 00f0e1a..f23b29d 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,8 @@ Let your AI coding agent talk to other AI coding agents. x-agent is a set of [agentskills.io](https://agentskills.io) skills that enable any AI CLI tool — Codex, Cursor, Claude -Code, Gemini CLI, Junie, Qwen Code, OpenCode — to delegate tasks to or get second opinions from the others. Install it once, and your agent -gains the ability to call any of the other six. +Code, Gemini CLI, Junie, Qwen Code, OpenCode, Pi — to delegate tasks to or get second opinions from the others. Install it once, and your agent +gains the ability to call any of the other seven. ## Why @@ -42,6 +42,7 @@ adds a round-trip to another CLI, so use it when the extra signal is worth the t | Junie | `junie` | Junie default | LLM-agnostic, BYOK support | | Qwen Code | `qwen` | Qwen default | Qwen model family, `--yolo` for auto-approve | | OpenCode | `opencode` | OpenCode default | Multi-provider, uses `run` subcommand with auto-approval | +| Pi | `pi` | `sonnet` | Multi-provider, minimal terminal coding harness | ## How to use it @@ -117,7 +118,7 @@ git clone https://github.com/darshitpp/x-agent.git .claude/skills/x-agent ``` After installation, the skills appear automatically in Claude Code's available skills list. Each CLI has its own skill ( -`codex`, `cursor`, `claude`, `gemini`, `junie`, `qwen`, `opencode`) that triggers based on context. +`codex`, `cursor`, `claude`, `gemini`, `junie`, `qwen`, `opencode`, `pi`) that triggers based on context. To update later: @@ -142,6 +143,7 @@ x-agent/ ├── junie/SKILL.md # Thin entry point (~27 lines) ├── qwen/SKILL.md # Thin entry point (~27 lines) ├── opencode/SKILL.md # Thin entry point (~27 lines) +├── pi/SKILL.md # Thin entry point (~20 lines) ├── references/ │ ├── shared-procedure.md # Core procedure (~105 lines) │ ├── cli-codex.md # Codex CLI identity, invocation, version matrix @@ -150,7 +152,8 @@ x-agent/ │ ├── cli-gemini.md # Gemini CLI identity, invocation, version matrix │ ├── cli-junie.md # Junie CLI identity, invocation, version matrix │ ├── cli-qwen.md # Qwen Code CLI identity, invocation, version matrix -│ └── cli-opencode.md # OpenCode CLI identity, invocation, version matrix +│ ├── cli-opencode.md # OpenCode CLI identity, invocation, version matrix +│ └── cli-pi.md # Pi CLI identity, invocation, version matrix ├── scripts/ │ ├── validate-metadata.py # Validates SKILL.md frontmatter (authoring + CI) │ ├── query-cli.sh # Maintainer-only CLI wrapper (not used by skills at runtime) @@ -241,7 +244,7 @@ a `SKILL.md` entry point. | Project | `.claude/skills/x-agent/` | **Invoke:** Ask naturally ("get a second opinion from Cursor") or explicitly with `/codex`, `/cursor`, `/claude`, -`/gemini`, `/junie`, `/qwen`, `/opencode`. Claude loads the skill automatically when relevant. +`/gemini`, `/junie`, `/qwen`, `/opencode`, `/pi`. Claude loads the skill automatically when relevant. [Claude Code skills docs](https://code.claude.com/docs/en/skills) diff --git a/assets/result-template.md b/assets/result-template.md index 75df649..969c91c 100644 --- a/assets/result-template.md +++ b/assets/result-template.md @@ -39,4 +39,4 @@ - + \ No newline at end of file diff --git a/claude/assets/result-template.md b/claude/assets/result-template.md index 75df649..969c91c 100644 --- a/claude/assets/result-template.md +++ b/claude/assets/result-template.md @@ -39,4 +39,4 @@ - + \ No newline at end of file diff --git a/claude/references/shared-procedure.md b/claude/references/shared-procedure.md index 5f0826e..83306bc 100644 --- a/claude/references/shared-procedure.md +++ b/claude/references/shared-procedure.md @@ -120,4 +120,4 @@ Delegation mode uses lighter context — task description and relevant file path | Version not in matrix | Use latest known version's flags, warn user | | Host model family undetectable | Prefer models from a different provider than target CLI's default | | CLI execution timeout (>120s) | Kill process, report timeout, suggest simpler prompt or different model | -| Unrecognized model name | Classify as Balanced, proceed normally | +| Unrecognized model name | Classify as Balanced, proceed normally | \ No newline at end of file diff --git a/codex/assets/result-template.md b/codex/assets/result-template.md index 75df649..969c91c 100644 --- a/codex/assets/result-template.md +++ b/codex/assets/result-template.md @@ -39,4 +39,4 @@ - + \ No newline at end of file diff --git a/codex/references/shared-procedure.md b/codex/references/shared-procedure.md index 5f0826e..83306bc 100644 --- a/codex/references/shared-procedure.md +++ b/codex/references/shared-procedure.md @@ -120,4 +120,4 @@ Delegation mode uses lighter context — task description and relevant file path | Version not in matrix | Use latest known version's flags, warn user | | Host model family undetectable | Prefer models from a different provider than target CLI's default | | CLI execution timeout (>120s) | Kill process, report timeout, suggest simpler prompt or different model | -| Unrecognized model name | Classify as Balanced, proceed normally | +| Unrecognized model name | Classify as Balanced, proceed normally | \ No newline at end of file diff --git a/cursor/assets/result-template.md b/cursor/assets/result-template.md index 75df649..969c91c 100644 --- a/cursor/assets/result-template.md +++ b/cursor/assets/result-template.md @@ -39,4 +39,4 @@ - + \ No newline at end of file diff --git a/cursor/references/shared-procedure.md b/cursor/references/shared-procedure.md index 5f0826e..83306bc 100644 --- a/cursor/references/shared-procedure.md +++ b/cursor/references/shared-procedure.md @@ -120,4 +120,4 @@ Delegation mode uses lighter context — task description and relevant file path | Version not in matrix | Use latest known version's flags, warn user | | Host model family undetectable | Prefer models from a different provider than target CLI's default | | CLI execution timeout (>120s) | Kill process, report timeout, suggest simpler prompt or different model | -| Unrecognized model name | Classify as Balanced, proceed normally | +| Unrecognized model name | Classify as Balanced, proceed normally | \ No newline at end of file diff --git a/gemini/assets/result-template.md b/gemini/assets/result-template.md index 75df649..969c91c 100644 --- a/gemini/assets/result-template.md +++ b/gemini/assets/result-template.md @@ -39,4 +39,4 @@ - + \ No newline at end of file diff --git a/gemini/references/shared-procedure.md b/gemini/references/shared-procedure.md index 5f0826e..83306bc 100644 --- a/gemini/references/shared-procedure.md +++ b/gemini/references/shared-procedure.md @@ -120,4 +120,4 @@ Delegation mode uses lighter context — task description and relevant file path | Version not in matrix | Use latest known version's flags, warn user | | Host model family undetectable | Prefer models from a different provider than target CLI's default | | CLI execution timeout (>120s) | Kill process, report timeout, suggest simpler prompt or different model | -| Unrecognized model name | Classify as Balanced, proceed normally | +| Unrecognized model name | Classify as Balanced, proceed normally | \ No newline at end of file diff --git a/junie/assets/result-template.md b/junie/assets/result-template.md index 75df649..969c91c 100644 --- a/junie/assets/result-template.md +++ b/junie/assets/result-template.md @@ -39,4 +39,4 @@ - + \ No newline at end of file diff --git a/junie/references/shared-procedure.md b/junie/references/shared-procedure.md index 5f0826e..83306bc 100644 --- a/junie/references/shared-procedure.md +++ b/junie/references/shared-procedure.md @@ -120,4 +120,4 @@ Delegation mode uses lighter context — task description and relevant file path | Version not in matrix | Use latest known version's flags, warn user | | Host model family undetectable | Prefer models from a different provider than target CLI's default | | CLI execution timeout (>120s) | Kill process, report timeout, suggest simpler prompt or different model | -| Unrecognized model name | Classify as Balanced, proceed normally | +| Unrecognized model name | Classify as Balanced, proceed normally | \ No newline at end of file diff --git a/opencode/assets/result-template.md b/opencode/assets/result-template.md index 75df649..969c91c 100644 --- a/opencode/assets/result-template.md +++ b/opencode/assets/result-template.md @@ -39,4 +39,4 @@ - + \ No newline at end of file diff --git a/opencode/references/shared-procedure.md b/opencode/references/shared-procedure.md index 5f0826e..83306bc 100644 --- a/opencode/references/shared-procedure.md +++ b/opencode/references/shared-procedure.md @@ -120,4 +120,4 @@ Delegation mode uses lighter context — task description and relevant file path | Version not in matrix | Use latest known version's flags, warn user | | Host model family undetectable | Prefer models from a different provider than target CLI's default | | CLI execution timeout (>120s) | Kill process, report timeout, suggest simpler prompt or different model | -| Unrecognized model name | Classify as Balanced, proceed normally | +| Unrecognized model name | Classify as Balanced, proceed normally | \ No newline at end of file diff --git a/pi/SKILL.md b/pi/SKILL.md new file mode 100644 index 0000000..bf0c15c --- /dev/null +++ b/pi/SKILL.md @@ -0,0 +1,20 @@ +--- +name: pi +description: Delegate tasks or get a second opinion from Pi CLI. Infers mode (delegation vs validation) from prompt context. Detects available models at runtime via the CLI. Use when cross-validating code, plans, or architecture with Pi, or offloading work to it. Do not use when already running inside Pi CLI or for tasks that do not benefit from cross-model input. +--- + +# Cross-Agent Task Runner — Pi CLI + +## Procedures + +**Step 1: Self-Call Detection** + +1. Check for `PI_AGENT` environment variable or `pi` in process ancestry. +2. If detected, stop and inform the user: + "Cannot invoke Pi from within Pi. Use a different target CLI." + +**Step 2: Execute Shared Procedure** + +1. Read `references/shared-procedure.md` for the core workflow (mode inference, context gathering, prompt construction, result presentation). +2. Read `references/cli-pi.md` for Pi-specific flags, model selection heuristics, and version compatibility matrix. +3. Follow the shared procedure using the Pi-specific details. \ No newline at end of file diff --git a/pi/assets/result-template.md b/pi/assets/result-template.md new file mode 100644 index 0000000..969c91c --- /dev/null +++ b/pi/assets/result-template.md @@ -0,0 +1,42 @@ + + +## Cross-Model Validation + +**Target CLI:** `` +**Model:** `` () +**Review type:** `` +**Mode:** validation + +### Second Opinion + + + +### Agreement + + + +### Counterpoints + + + +### Synthesis + + + + + +## Delegated Task Result + +**Target CLI:** `` +**Model:** `` () +**Mode:** delegation + +### Result + + + +### Notes + + + + \ No newline at end of file diff --git a/pi/references/cli-pi.md b/pi/references/cli-pi.md new file mode 100644 index 0000000..3981aaf --- /dev/null +++ b/pi/references/cli-pi.md @@ -0,0 +1,31 @@ +# Pi CLI Reference + +## 1. CLI Identity & Invocation + +- **Command:** `pi` +- **Non-interactive flag:** `-p` / `--print` +- **Output format flag:** `--output-format text|json|stream-json` +- **Trust/auto-approve flag:** `--dangerously-skip-permissions` +- **List models command:** `pi --list-models 2>&1` (if available) or infer from `pi --help` +- **Self-call detection:** Check for `PI_AGENT` environment variable or `pi` in process ancestry + +## 2. Model Selection Heuristic + +- **Default model (fallback):** `sonnet` (alias for claude-sonnet-4-6) +- **Aliases:** `opus` → claude-opus-4-6, `sonnet` → claude-sonnet-4-6, `haiku` → claude-haiku-4-5 +- **Quirks:** Model can also be set via `ANTHROPIC_MODEL` env var. Supports `--fallback-model` for overload scenarios. + +## 3. Invocation Template + +| Mode | Command | +|----------------|------------------------------------------------------------------------| +| **Validation** | `cat "$PROMPT_FILE" \| pi -p --model --output-format text` | +| **Delegation** | `cat "$PROMPT_FILE" \| pi -p --model --output-format text` | + +Note: Pi validation and delegation use the same invocation — no separate trust flag needed for print mode. + +## 4. Version Compatibility Matrix + +| Version | Print Flag | Model Flag | Output Format | Notes | +|---------|------------------|------------|-------------------------------------------|---------| +| 2.1.x | `-p` / `--print` | `--model` | `--output-format text\|json\|stream-json` | Current | \ No newline at end of file diff --git a/pi/references/shared-procedure.md b/pi/references/shared-procedure.md new file mode 100644 index 0000000..83306bc --- /dev/null +++ b/pi/references/shared-procedure.md @@ -0,0 +1,123 @@ +# Shared Procedure for Cross-Agent Task Running + +## Step 1: Infer Mode + +Classify the user's request based on prompt signals: + +| Mode | Signals | Behavior | +|----------------|----------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------| +| **validation** | "review", "check", "second opinion", "verify", "validate", "what do you think", "compare" | Gather context, send to target CLI, present structured comparison | +| **delegation** | "fix", "implement", "build", "refactor", "add", "create", "do", "run" — or absence of validation signals | Hand off task entirely, return output with minimal framing | + +**Conflict resolution:** If both validation and delegation signals are present, validation takes precedence. The user +asked for review; fixes are a natural outcome. + +Default to **delegation** if no clear signals are present. + +## Step 2: Detect Model Override + +1. Check if the user specified a model in the prompt (e.g., `--model gpt-5.3` or natural language like "use sonnet for + this"). +2. If a model name or alias is found, use it directly and skip auto-selection. +3. If not, proceed to Step 3. + +## Step 3: Select Model + +1. Run the target CLI's list-models command (read the exact command from the CLI reference file). +2. If the list-models command fails or returns no results, fall back to the default model specified in the CLI reference + file and skip to Step 4. +3. Parse and classify all available models into tiers. Match signals in order — **first match wins**: + +| Priority | Tier | Signal in model name | Traits | +|----------|------------------------|------------------------------------------------|-----------------------------------| +| 1 | **Flagship reasoning** | `opus`, `pro`, `grok-4`, `o3`, `o4` | Best quality, highest cost | +| 2 | **Code-specialized** | `codex`, `code` | Optimized for code tasks | +| 3 | **Balanced** | `sonnet`, `flash`, `gpt-5.x` (base) | Good all-round, moderate cost | +| 4 | **Fast/cheap** | `haiku`, `flash-lite`, `mini`, `nano`, `-fast` | Lowest cost | +| 5 | **Unknown** | No signal match | Classified as Balanced by default | + +4. Pick based on mode + task context: + +| Mode | Task Type | Preferred Tier | +|--------------------------------------|----------------|-----------------------------------------------------------------| +| **Validation** — plan/architecture | Complex | Flagship reasoning (different model family than host preferred) | +| **Validation** — code review | Moderate | Code-specialized → Balanced (different model family preferred) | +| **Delegation** — implement/build | Active coding | Code-specialized → Balanced | +| **Delegation** — simple fix/refactor | Low complexity | Balanced → Fast/cheap | +| **General** | Unknown | Balanced | + +5. **Validation mode family filter:** "Different family" means a different model provider family than the model the host + agent is currently using. Detection: check the host agent's model via environment variables (`ANTHROPIC_MODEL`, + `CURSOR_MODEL`) or the host CLI's config. If undetectable, prefer models from a provider other than the target CLI's + default provider. This is a preference, not a hard filter — if only same-family models are available, use them. + +6. Within the selected tier, break ties: + - Latest version number wins. Parse version from model name: numeric versions (`5.3` > `5.2`), date-based versions ( + `20260401` > `20250514`). If not parseable, treat as equal. + - Standard reasoning tier preferred (no `-low`, `-high`, `-xhigh` suffix). + - Non-fast variant preferred over fast. + +7. User override from Step 2 always wins over any auto-selection. + +## Step 4: Gather Context + +Classify the review type and gather appropriate context: + +| Review Type | Signal | Context to gather | +|------------------|-----------------------------------|---------------------------------| +| **plan** | plan, design, spec, approach | Read plan/design doc | +| **code** | implementation, diff, changes, PR | `git diff`, changed files | +| **architecture** | structure, modules, dependencies | Key interfaces, directory tree | +| **general** | anything else | Files/context from conversation | + +Delegation mode uses lighter context — task description and relevant file paths, not full diffs. + +## Step 5: Construct Prompt + +- **Validation mode:** Start with a role prompt ("senior engineer providing a review"). Include gathered context, the + user's specific question, and request for issues/edge cases/alternatives with confidence ratings. End with "Be direct. + Flag only real issues, not style preferences." Keep under 12,000 tokens (~8,000 words). If context exceeds this limit, + prioritize: (a) most recent changes, (b) files directly relevant to the user's question, (c) truncate long diffs to + changed hunks only, (d) summarize large files rather than including verbatim. For fast/cheap tier models with smaller + context windows, reduce to 6,000 tokens. +- **Delegation mode:** Use the user's original request as the task prompt. Include relevant file contents and context. + No review framing. Same token limits apply. + +## Step 6: Execute CLI + +1. Read the CLI-specific reference file for the invocation template and flags. +2. Detect the installed CLI version via ` --version`. +3. Look up the version matrix for the correct flags. If the installed version is not in the matrix, use the latest known + version's flags and warn the user. +4. Write the constructed prompt to a temp file (safe prompt transport — never embed prompt in shell argument strings): + ```bash + PROMPT_FILE=$(mktemp) + cat <<'PROMPT_EOF' > "$PROMPT_FILE" + + PROMPT_EOF + ``` +5. Run in non-interactive/print mode with a **120-second timeout**. If the CLI does not respond within this window, kill + the process and report a timeout error. +6. Capture full output. Clean up the temp file: `rm -f "$PROMPT_FILE"`. +7. On failure, report the error and suggest checking CLI installation/authentication. + +## Step 7: Present Results + +- **Validation mode:** Read `assets/result-template.md` and follow the validation template structure. Present the second + opinion, agreement, counterpoints, and synthesis. Do not blindly agree with the second model. If the second model's + output is generic or unhelpful, say so. +- **Delegation mode:** Present the target CLI's output directly with a brief header noting which CLI and model were + used. Add commentary only if the output needs clarification or has issues. + +## Error Handling + +| Condition | Behavior | +|--------------------------------|-------------------------------------------------------------------------| +| CLI not found | Inform user with install instructions from CLI reference file | +| Model unavailable | Fall back to default model from CLI reference file, inform user | +| `--list-models` fails | Fall back to default model from CLI reference file | +| Output empty or garbled | Report failure, suggest retry with explicit `--model` | +| Version not in matrix | Use latest known version's flags, warn user | +| Host model family undetectable | Prefer models from a different provider than target CLI's default | +| CLI execution timeout (>120s) | Kill process, report timeout, suggest simpler prompt or different model | +| Unrecognized model name | Classify as Balanced, proceed normally | \ No newline at end of file diff --git a/qwen/assets/result-template.md b/qwen/assets/result-template.md index 75df649..969c91c 100644 --- a/qwen/assets/result-template.md +++ b/qwen/assets/result-template.md @@ -39,4 +39,4 @@ - + \ No newline at end of file diff --git a/qwen/references/shared-procedure.md b/qwen/references/shared-procedure.md index 5f0826e..83306bc 100644 --- a/qwen/references/shared-procedure.md +++ b/qwen/references/shared-procedure.md @@ -120,4 +120,4 @@ Delegation mode uses lighter context — task description and relevant file path | Version not in matrix | Use latest known version's flags, warn user | | Host model family undetectable | Prefer models from a different provider than target CLI's default | | CLI execution timeout (>120s) | Kill process, report timeout, suggest simpler prompt or different model | -| Unrecognized model name | Classify as Balanced, proceed normally | +| Unrecognized model name | Classify as Balanced, proceed normally | \ No newline at end of file diff --git a/references/cli-pi.md b/references/cli-pi.md new file mode 100644 index 0000000..3981aaf --- /dev/null +++ b/references/cli-pi.md @@ -0,0 +1,31 @@ +# Pi CLI Reference + +## 1. CLI Identity & Invocation + +- **Command:** `pi` +- **Non-interactive flag:** `-p` / `--print` +- **Output format flag:** `--output-format text|json|stream-json` +- **Trust/auto-approve flag:** `--dangerously-skip-permissions` +- **List models command:** `pi --list-models 2>&1` (if available) or infer from `pi --help` +- **Self-call detection:** Check for `PI_AGENT` environment variable or `pi` in process ancestry + +## 2. Model Selection Heuristic + +- **Default model (fallback):** `sonnet` (alias for claude-sonnet-4-6) +- **Aliases:** `opus` → claude-opus-4-6, `sonnet` → claude-sonnet-4-6, `haiku` → claude-haiku-4-5 +- **Quirks:** Model can also be set via `ANTHROPIC_MODEL` env var. Supports `--fallback-model` for overload scenarios. + +## 3. Invocation Template + +| Mode | Command | +|----------------|------------------------------------------------------------------------| +| **Validation** | `cat "$PROMPT_FILE" \| pi -p --model --output-format text` | +| **Delegation** | `cat "$PROMPT_FILE" \| pi -p --model --output-format text` | + +Note: Pi validation and delegation use the same invocation — no separate trust flag needed for print mode. + +## 4. Version Compatibility Matrix + +| Version | Print Flag | Model Flag | Output Format | Notes | +|---------|------------------|------------|-------------------------------------------|---------| +| 2.1.x | `-p` / `--print` | `--model` | `--output-format text\|json\|stream-json` | Current | \ No newline at end of file diff --git a/references/shared-procedure.md b/references/shared-procedure.md index 5f0826e..83306bc 100644 --- a/references/shared-procedure.md +++ b/references/shared-procedure.md @@ -120,4 +120,4 @@ Delegation mode uses lighter context — task description and relevant file path | Version not in matrix | Use latest known version's flags, warn user | | Host model family undetectable | Prefer models from a different provider than target CLI's default | | CLI execution timeout (>120s) | Kill process, report timeout, suggest simpler prompt or different model | -| Unrecognized model name | Classify as Balanced, proceed normally | +| Unrecognized model name | Classify as Balanced, proceed normally | \ No newline at end of file diff --git a/tests/pytest/test_skill_integrity.py b/tests/pytest/test_skill_integrity.py index 928e33d..c880fba 100644 --- a/tests/pytest/test_skill_integrity.py +++ b/tests/pytest/test_skill_integrity.py @@ -9,7 +9,7 @@ from conftest import REPO_ROOT -SKILL_DIRS = ["codex", "cursor", "claude", "gemini", "junie", "qwen", "opencode"] +SKILL_DIRS = ["codex", "cursor", "claude", "gemini", "junie", "qwen", "opencode", "pi"] SHARED_FILES = [ "references/shared-procedure.md", diff --git a/tests/pytest/test_validate_metadata.py b/tests/pytest/test_validate_metadata.py index b933733..cbf751d 100644 --- a/tests/pytest/test_validate_metadata.py +++ b/tests/pytest/test_validate_metadata.py @@ -5,7 +5,7 @@ from conftest import REPO_ROOT -SKILL_DIRS = ["codex", "cursor", "claude", "gemini", "junie", "qwen", "opencode"] +SKILL_DIRS = ["codex", "cursor", "claude", "gemini", "junie", "qwen", "opencode", "pi"] # ---------------------------------------------------------------------------