Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,4 @@ integrations/kimi/*/
!integrations/openclaw/README.md
!integrations/kimi/README.md
integrations/codex/agents/*
integrations/pi/agency-*/
19 changes: 19 additions & 0 deletions integrations/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ supported agentic coding tools.
- **[Kimi Code](#kimi-code)** — YAML agent specs in `kimi/`
- **[Qwen Code](#qwen-code)** — project-scoped `.md` SubAgents in `.qwen/agents/`
- **[Codex](#codex)** — `.toml` custom agents in `codex/`
- **[Pi](#pi)** — `SKILL.md` per agent in `pi/`

## Quick Install

Expand All @@ -30,6 +31,7 @@ supported agentic coding tools.
./scripts/install.sh --tool openclaw
./scripts/install.sh --tool claude-code
./scripts/install.sh --tool codex
./scripts/install.sh --tool pi

# Gemini CLI needs generated integration files on a fresh clone
./scripts/convert.sh --tool gemini-cli
Expand Down Expand Up @@ -257,3 +259,20 @@ directly, run the converter before installing from a fresh clone:
```

See [codex/README.md](codex/README.md) for details.

---

## Pi

Each agent becomes a Pi Coding Agent skill folder containing a `SKILL.md` file.
Skills are installed to `~/.pi/agent/skills/`.

Because the skill files are generated from the source Markdown, run
`./scripts/convert.sh --tool pi` before installing from a fresh clone.

```bash
./scripts/convert.sh --tool pi
./scripts/install.sh --tool pi
```

See [pi/README.md](pi/README.md) for details.
56 changes: 56 additions & 0 deletions integrations/pi/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Pi Coding Agent Integration

Installs the full Agency roster as Pi skills. Each agent is prefixed
with `agency-` to avoid conflicts with existing skills.

## Install

```bash
./scripts/install.sh --tool pi
```

This copies files from `integrations/pi/` to
`~/.pi/agent/skills/`.

## Activate a Skill

In Pi, activate an agent by its slug:

```
Use the agency-frontend-developer skill to review this component.
```

Available slugs follow the pattern `agency-<agent-name>`, e.g.:
- `agency-frontend-developer`
- `agency-backend-architect`
- `agency-reality-checker`
- `agency-growth-hacker`

## Regenerate

After modifying agents, regenerate the skill files:

```bash
./scripts/convert.sh --tool pi
```

## File Format

Each skill is a `SKILL.md` file with standard frontmatter:

```yaml
---
name: agency-frontend-developer
description: Expert frontend developer specializing in...
---
```

## Skill Locations

Pi discovers skills from several locations:

- **Global (user-level):** `~/.pi/agent/skills/`
- **Project-level:** `.pi/skills/`

The installer copies skills to the global location by default. Set the
`PI_SKILLS_DIR` environment variable to override the destination path.
31 changes: 28 additions & 3 deletions scripts/convert.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
# qwen — Qwen Code SubAgent files (~/.qwen/agents/*.md)
# kimi — Kimi Code CLI agent files (~/.config/kimi/agents/)
# codex — Codex custom agent TOML files (~/.codex/agents/*.toml)
# pi — Pi Coding Agent skill files (~/.pi/agent/skills/)
# all — All tools (default)
#
# Output is written to integrations/<tool>/ relative to the repo root.
Expand Down Expand Up @@ -130,6 +131,29 @@ ${body}
HEREDOC
}

convert_pi() {
local file="$1"
local name description slug outdir outfile body

name="$(get_field "name" "$file")"
description="$(get_field "description" "$file")"
slug="agency-$(slugify "$name")"
body="$(get_body "$file")"

outdir="$OUT_DIR/pi/$slug"
outfile="$outdir/SKILL.md"
mkdir -p "$outdir"

# Pi Coding Agent SKILL.md format: folder per skill in ~/.pi/agent/skills/
cat > "$outfile" <<HEREDOC
---
name: ${slug}
description: ${description}
---
${body}
HEREDOC
}

convert_codex() {
local file="$1"
local name description slug outfile body
Expand Down Expand Up @@ -527,6 +551,7 @@ run_conversions() {
openclaw) convert_openclaw "$file" ;;
qwen) convert_qwen "$file" ;;
kimi) convert_kimi "$file" ;;
pi) convert_pi "$file" ;;
aider) accumulate_aider "$file" ;;
windsurf) accumulate_windsurf "$file" ;;
esac
Expand Down Expand Up @@ -557,7 +582,7 @@ main() {
esac
done

local valid_tools=("antigravity" "gemini-cli" "opencode" "cursor" "aider" "windsurf" "openclaw" "qwen" "kimi" "codex" "all")
local valid_tools=("antigravity" "gemini-cli" "opencode" "cursor" "aider" "windsurf" "openclaw" "qwen" "kimi" "codex" "pi" "all")
local valid=false
for t in "${valid_tools[@]}"; do [[ "$t" == "$tool" ]] && valid=true && break; done
if ! $valid; then
Expand All @@ -576,7 +601,7 @@ main() {

local tools_to_run=()
if [[ "$tool" == "all" ]]; then
tools_to_run=("antigravity" "gemini-cli" "opencode" "cursor" "aider" "windsurf" "openclaw" "qwen" "kimi" "codex")
tools_to_run=("antigravity" "gemini-cli" "opencode" "cursor" "aider" "windsurf" "openclaw" "qwen" "kimi" "codex" "pi")
else
tools_to_run=("$tool")
fi
Expand All @@ -587,7 +612,7 @@ main() {

if $use_parallel && [[ "$tool" == "all" ]]; then
# Tools that write to separate dirs can run in parallel; buffer output so each tool's output stays together
local parallel_tools=(antigravity gemini-cli opencode cursor openclaw qwen codex)
local parallel_tools=(antigravity gemini-cli opencode cursor openclaw qwen codex pi)
local parallel_out_dir
parallel_out_dir="$(mktemp -d)"
info "Converting: ${#parallel_tools[@]}/${n_tools} tools in parallel (output buffered per tool)..."
Expand Down
32 changes: 28 additions & 4 deletions scripts/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
# openclaw -- Copy workspaces to ~/.openclaw/agency-agents/
# qwen -- Copy SubAgents to ~/.qwen/agents/ (user-wide) or .qwen/agents/ (project)
# codex -- Copy custom agent TOML files to ~/.codex/agents/
# pi -- Copy skills to ~/.pi/agent/skills/
# all -- Install for all detected tools (default)
#
# Selection (compose freely; empty = everything):
Expand All @@ -46,7 +47,8 @@
# --help Show this help
#
# Env: CLAUDE_CONFIG_DIR, COPILOT_AGENT_DIR, CURSOR_RULES_DIR, GEMINI_AGENTS_DIR,
# OPENCODE_AGENTS_DIR, OPENCLAW_DIR, QWEN_AGENTS_DIR, CODEX_AGENTS_DIR
# OPENCODE_AGENTS_DIR, OPENCLAW_DIR, QWEN_AGENTS_DIR, CODEX_AGENTS_DIR,
# PI_SKILLS_DIR
# override default install paths (checked before hardcoded defaults).
#
# --- USAGE-END --- (sentinel for usage(); do not remove)
Expand Down Expand Up @@ -125,7 +127,7 @@ INTEGRATIONS="$REPO_ROOT/integrations"
# shellcheck source=lib.sh
. "$SCRIPT_DIR/lib.sh"

ALL_TOOLS=(claude-code copilot antigravity gemini-cli opencode openclaw cursor aider windsurf qwen kimi codex)
ALL_TOOLS=(claude-code copilot antigravity gemini-cli opencode openclaw cursor aider windsurf qwen kimi codex pi)

# Standard agent category directories (keep sorted, sync with convert.sh / lint-agents.sh)
AGENT_DIRS=(
Expand Down Expand Up @@ -255,6 +257,7 @@ resolve_dest() {
openclaw) var="OPENCLAW_DIR" ;;
qwen) var="QWEN_AGENTS_DIR" ;;
codex) var="CODEX_AGENTS_DIR" ;;
pi) var="PI_SKILLS_DIR" ;;
esac
if [[ -n "$var" && -n "${!var:-}" ]]; then printf '%s' "${!var}"; else printf '%s' "$def"; fi
}
Expand All @@ -266,7 +269,7 @@ resolve_tool_path() {
claude-code) bin="claude" ;; copilot) bin="code" ;; gemini-cli) bin="gemini" ;;
opencode) bin="opencode" ;; openclaw) bin="openclaw" ;; cursor) bin="cursor" ;;
aider) bin="aider" ;; windsurf) bin="windsurf" ;; qwen) bin="qwen" ;;
kimi) bin="kimi" ;; codex) bin="codex" ;; antigravity) bin="" ;;
kimi) bin="kimi" ;; codex) bin="codex" ;; antigravity) bin="" ;; pi) bin="pi" ;;
esac
[[ -n "$bin" ]] && command -v "$bin" 2>/dev/null
}
Expand Down Expand Up @@ -363,6 +366,7 @@ detect_windsurf() { command -v windsurf >/dev/null 2>&1 || [[ -d "${HOME}/.c
detect_qwen() { command -v qwen >/dev/null 2>&1 || [[ -d "${HOME}/.qwen" ]]; }
detect_kimi() { command -v kimi >/dev/null 2>&1; }
detect_codex() { command -v codex >/dev/null 2>&1 || [[ -d "${HOME}/.codex" ]]; }
detect_pi() { command -v pi >/dev/null 2>&1 || [[ -d "${HOME}/.pi" ]]; }

is_detected() {
case "$1" in
Expand All @@ -378,6 +382,7 @@ is_detected() {
qwen) detect_qwen ;;
kimi) detect_kimi ;;
codex) detect_codex ;;
pi) detect_pi ;;
*) return 1 ;;
esac
}
Expand All @@ -397,6 +402,7 @@ tool_label() {
qwen) printf "%-14s %s" "Qwen Code" "(~/.qwen/agents)" ;;
kimi) printf "%-14s %s" "Kimi Code" "(~/.config/kimi/agents)" ;;
codex) printf "%-14s %s" "Codex" "(~/.codex/agents)" ;;
pi) printf "%-14s %s" "Pi" "(~/.pi/agent/skills)" ;;
esac
}

Expand Down Expand Up @@ -520,7 +526,7 @@ tool_simple_name() {
claude-code) echo "Claude Code";; copilot) echo "Copilot";; antigravity) echo "Antigravity";;
gemini-cli) echo "Gemini CLI";; opencode) echo "OpenCode";; openclaw) echo "OpenClaw";;
cursor) echo "Cursor";; aider) echo "Aider";; windsurf) echo "Windsurf";;
qwen) echo "Qwen Code";; kimi) echo "Kimi Code";; codex) echo "Codex";; *) echo "$1";;
qwen) echo "Qwen Code";; kimi) echo "Kimi Code";; codex) echo "Codex";; pi) echo "Pi";; *) echo "$1";;
esac
}

Expand Down Expand Up @@ -897,6 +903,23 @@ install_codex() {
ok "Codex: $count agents -> $dest"
}

install_pi() {
local src="$INTEGRATIONS/pi"
local dest; dest="$(resolve_dest pi "${HOME}/.pi/agent/skills")"
local count=0
[[ -d "$src" ]] || { err "integrations/pi missing. Run convert.sh first."; return 1; }
mkdir -p "$dest"
local d
while IFS= read -r -d '' d; do
local name; name="$(basename "$d")"
slug_allowed "$name" || continue
mkdir -p "$dest/$name"
install_file "$d/SKILL.md" "$dest/$name/SKILL.md"
incr count
done < <(find "$src" -mindepth 1 -maxdepth 1 -type d -print0)
ok "Pi: $count skills -> $dest"
}

install_tool() {
ensure_converted "$1"
case "$1" in
Expand All @@ -912,6 +935,7 @@ install_tool() {
qwen) install_qwen ;;
kimi) install_kimi ;;
codex) install_codex ;;
pi) install_pi ;;
esac
}

Expand Down