feat: add pi reviewer support to workflow variants

This commit is contained in:
Stefano Fiorini
2026-04-23 21:03:45 -05:00
parent ce4746b769
commit 231a66f2b1
26 changed files with 512 additions and 20 deletions
+12
View File
@@ -33,6 +33,7 @@ To use the iterative plan review feature, one of these CLIs must be installed:
| `codex` | `npm install -g @openai/codex` | `codex --version` | | `codex` | `npm install -g @openai/codex` | `codex --version` |
| `claude` | `npm install -g @anthropic-ai/claude-code` | `claude --version` | | `claude` | `npm install -g @anthropic-ai/claude-code` | `claude --version` |
| `cursor` | `curl https://cursor.com/install -fsS \| bash` | `cursor-agent --version` (binary: `cursor-agent`; alias `cursor agent` also works) | | `cursor` | `curl https://cursor.com/install -fsS \| bash` | `cursor-agent --version` (binary: `cursor-agent`; alias `cursor agent` also works) |
| `pi` | Install Pi coding agent | `pi --version`; list models with `pi --list-models [search]` |
The reviewer CLI is independent of which agent is running the planning — e.g., Claude Code can send plans to Codex for review, and vice versa. The reviewer CLI is independent of which agent is running the planning — e.g., Claude Code can send plans to Codex for review, and vice versa.
@@ -188,6 +189,7 @@ ts=<ISO-8601> level=<info|warn|error> state=<running-silent|running-active|in-pr
| `codex` | `codex exec -m <model> -s read-only` | Yes (`codex exec resume <id>`) | `-s read-only` | | `codex` | `codex exec -m <model> -s read-only` | Yes (`codex exec resume <id>`) | `-s read-only` |
| `claude` | `claude -p --model <model> --strict-mcp-config --setting-sources user` | No (fresh call each round) | `--strict-mcp-config --setting-sources user` | | `claude` | `claude -p --model <model> --strict-mcp-config --setting-sources user` | No (fresh call each round) | `--strict-mcp-config --setting-sources user` |
| `cursor` | `cursor-agent -p --mode=ask --model <model> --trust --output-format json` | Yes (`--resume <id>`) | `--mode=ask` | | `cursor` | `cursor-agent -p --mode=ask --model <model> --trust --output-format json` | Yes (`--resume <id>`) | `--mode=ask` |
| `pi` | See [PI-COMMON-REVIEWER.md](./PI-COMMON-REVIEWER.md) | No (fresh call each round) | `--tools read,grep,find,ls` |
For all three CLIs, the preferred execution path is: For all three CLIs, the preferred execution path is:
@@ -195,6 +197,16 @@ For all three CLIs, the preferred execution path is:
2. run that script through `reviewer-runtime/run-review.sh` 2. run that script through `reviewer-runtime/run-review.sh`
3. fall back to direct synchronous execution only if the helper is missing or not executable 3. fall back to direct synchronous execution only if the helper is missing or not executable
## Pi Reviewer Support
All workflow variants can use Pi itself as a reviewer CLI. Use `pi/<pi-model-name>` shorthand, for example `pi/claude-opus-4-7`; this means `REVIEWER_CLI=pi` and `REVIEWER_MODEL=claude-opus-4-7`. Provider-qualified or multi-slash Pi model IDs are preserved after the first `pi/` prefix, for example `pi/anthropic/claude-opus-4-7`.
The canonical isolated read-only Pi reviewer flag contract lives in [PI-COMMON-REVIEWER.md](./PI-COMMON-REVIEWER.md). This workflow passes the plan review payload at `/tmp/plan-${REVIEW_ID}.md` and expects the standard `## Summary`, `## Findings`, and `## Verdict` response. Pi reviewer output is captured as markdown stdout, not JSON.
If the Pi reviewer model or provider is unavailable, surface the helper stderr/status and use `pi --list-models [search]` to inspect configured models.
## Notifications ## Notifications
- Telegram is the only supported notification path. - Telegram is the only supported notification path.
+12
View File
@@ -49,6 +49,7 @@ One of these CLIs must be installed to drive either of the two review loops:
| `claude` | `npm install -g @anthropic-ai/claude-code` | `claude --version` | `--strict-mcp-config --setting-sources user` | No (fresh call each round) | | `claude` | `npm install -g @anthropic-ai/claude-code` | `claude --version` | `--strict-mcp-config --setting-sources user` | No (fresh call each round) |
| `cursor` | `curl https://cursor.com/install -fsS \| bash` | `cursor-agent --version` (binary: `cursor-agent`; alias `cursor agent` also works) | `--mode=ask` | Yes (`--resume <id>`) | | `cursor` | `curl https://cursor.com/install -fsS \| bash` | `cursor-agent --version` (binary: `cursor-agent`; alias `cursor agent` also works) | `--mode=ask` | Yes (`--resume <id>`) |
| `opencode` | `brew install opencode` or your package manager | `opencode --version` | `--agent plan` | Opt-in (`-s <id>`; fresh call is the default) | | `opencode` | `brew install opencode` or your package manager | `opencode --version` | `--agent plan` | Opt-in (`-s <id>`; fresh call is the default) |
| `pi` | Install Pi coding agent | `pi --version`; list models with `pi --list-models [search]` | `--tools read,grep,find,ls` | No (fresh call each round) |
The reviewer CLI is independent of which agent is running the skill — e.g., Claude Code can send both the plan and the implementation to Codex for review. The reviewer CLI is independent of which agent is running the skill — e.g., Claude Code can send both the plan and the implementation to Codex for review.
@@ -290,6 +291,7 @@ The user answers `yes` / `no` / `redact`:
| `claude` | `claude -p "<prompt>" --model <model> --strict-mcp-config --setting-sources user` | Fresh call with prior-round context summary | `cp <runner.out> <out.md>` | | `claude` | `claude -p "<prompt>" --model <model> --strict-mcp-config --setting-sources user` | Fresh call with prior-round context summary | `cp <runner.out> <out.md>` |
| `cursor` | `cursor-agent -p --mode=ask --model <model> --trust --output-format json "<prompt>" > <out.json>` | `cursor-agent --resume <id> -p --mode=ask --model <model> --trust --output-format json "<prompt>" > <out.json>` | `jq -r '.result' <out.json> > <out.md>` | | `cursor` | `cursor-agent -p --mode=ask --model <model> --trust --output-format json "<prompt>" > <out.json>` | `cursor-agent --resume <id> -p --mode=ask --model <model> --trust --output-format json "<prompt>" > <out.json>` | `jq -r '.result' <out.json> > <out.md>` |
| `opencode` | `opencode run -m <provider>/<model> --agent plan --format json "<prompt>" > <out.json>` | Fresh call (default) OR `opencode run -s <id> -m <provider>/<model> --agent plan --format json "<prompt>" > <out.json>` (opt-in) | `jq -r '.[] \| select(.type == "message" and .role == "assistant") \| .content' <out.json> > <out.md>` | | `opencode` | `opencode run -m <provider>/<model> --agent plan --format json "<prompt>" > <out.json>` | Fresh call (default) OR `opencode run -s <id> -m <provider>/<model> --agent plan --format json "<prompt>" > <out.json>` (opt-in) | `jq -r '.[] \| select(.type == "message" and .role == "assistant") \| .content' <out.json> > <out.md>` |
| `pi` | See [PI-COMMON-REVIEWER.md](./PI-COMMON-REVIEWER.md) | Fresh call | Markdown stdout copied to `<out.md>` |
For all four CLIs, the preferred execution path is: For all four CLIs, the preferred execution path is:
@@ -297,6 +299,16 @@ For all four CLIs, the preferred execution path is:
2. Run that script through `reviewer-runtime/run-review.sh`. 2. Run that script through `reviewer-runtime/run-review.sh`.
3. Fall back to direct synchronous execution only if the helper is missing or not executable. 3. Fall back to direct synchronous execution only if the helper is missing or not executable.
## Pi Reviewer Support
All workflow variants can use Pi itself as a reviewer CLI. Use `pi/<pi-model-name>` shorthand, for example `pi/claude-opus-4-7`; this means `REVIEWER_CLI=pi` and `REVIEWER_MODEL=claude-opus-4-7`. Provider-qualified or multi-slash Pi model IDs are preserved after the first `pi/` prefix, for example `pi/anthropic/claude-opus-4-7`.
The canonical isolated read-only Pi reviewer flag contract lives in [PI-COMMON-REVIEWER.md](./PI-COMMON-REVIEWER.md). This workflow passes the plan and implementation review payload at `/tmp/do-task-${REVIEW_KIND}-${REVIEW_ID}.md` and expects the standard `## Summary`, `## Findings`, and `## Verdict` response. Pi reviewer output is captured as markdown stdout, not JSON.
If the Pi reviewer model or provider is unavailable, surface the helper stderr/status and use `pi --list-models [search]` to inspect configured models.
## Notifications ## Notifications
- Telegram is the only supported notification path. - Telegram is the only supported notification path.
+12
View File
@@ -40,6 +40,7 @@ To use the iterative milestone review feature, one of these CLIs must be install
| `codex` | `npm install -g @openai/codex` | `codex --version` | | `codex` | `npm install -g @openai/codex` | `codex --version` |
| `claude` | `npm install -g @anthropic-ai/claude-code` | `claude --version` | | `claude` | `npm install -g @anthropic-ai/claude-code` | `claude --version` |
| `cursor` | `curl https://cursor.com/install -fsS \| bash` | `cursor-agent --version` (binary: `cursor-agent`; alias `cursor agent` also works) | | `cursor` | `curl https://cursor.com/install -fsS \| bash` | `cursor-agent --version` (binary: `cursor-agent`; alias `cursor agent` also works) |
| `pi` | Install Pi coding agent | `pi --version`; list models with `pi --list-models [search]` |
The reviewer CLI is independent of which agent is running the implementation — e.g., Claude Code can send milestones to Codex for review, and vice versa. The reviewer CLI is independent of which agent is running the implementation — e.g., Claude Code can send milestones to Codex for review, and vice versa.
@@ -200,6 +201,7 @@ ts=<ISO-8601> level=<info|warn|error> state=<running-silent|running-active|in-pr
| `codex` | `codex exec -m <model> -s read-only` | Yes (`codex exec resume <id>`) | `-s read-only` | | `codex` | `codex exec -m <model> -s read-only` | Yes (`codex exec resume <id>`) | `-s read-only` |
| `claude` | `claude -p --model <model> --strict-mcp-config --setting-sources user` | No (fresh call each round) | `--strict-mcp-config --setting-sources user` | | `claude` | `claude -p --model <model> --strict-mcp-config --setting-sources user` | No (fresh call each round) | `--strict-mcp-config --setting-sources user` |
| `cursor` | `cursor-agent -p --mode=ask --model <model> --trust --output-format json` | Yes (`--resume <id>`) | `--mode=ask` | | `cursor` | `cursor-agent -p --mode=ask --model <model> --trust --output-format json` | Yes (`--resume <id>`) | `--mode=ask` |
| `pi` | See [PI-COMMON-REVIEWER.md](./PI-COMMON-REVIEWER.md) | No (fresh call each round) | `--tools read,grep,find,ls` |
For all three CLIs, the preferred execution path is: For all three CLIs, the preferred execution path is:
@@ -207,6 +209,16 @@ For all three CLIs, the preferred execution path is:
2. run that script through `reviewer-runtime/run-review.sh` 2. run that script through `reviewer-runtime/run-review.sh`
3. fall back to direct synchronous execution only if the helper is missing or not executable 3. fall back to direct synchronous execution only if the helper is missing or not executable
## Pi Reviewer Support
All workflow variants can use Pi itself as a reviewer CLI. Use `pi/<pi-model-name>` shorthand, for example `pi/claude-opus-4-7`; this means `REVIEWER_CLI=pi` and `REVIEWER_MODEL=claude-opus-4-7`. Provider-qualified or multi-slash Pi model IDs are preserved after the first `pi/` prefix, for example `pi/anthropic/claude-opus-4-7`.
The canonical isolated read-only Pi reviewer flag contract lives in [PI-COMMON-REVIEWER.md](./PI-COMMON-REVIEWER.md). This workflow passes the milestone review payload at `/tmp/milestone-${REVIEW_ID}.md` and expects the standard `## Summary`, `## Findings`, and `## Verdict` response. Pi reviewer output is captured as markdown stdout, not JSON.
If the Pi reviewer model or provider is unavailable, surface the helper stderr/status and use `pi --list-models [search]` to inspect configured models.
## Notifications ## Notifications
- Telegram is the only supported notification path. - Telegram is the only supported notification path.
+12
View File
@@ -16,6 +16,18 @@ The canonical isolated, read-only reviewer command is:
pi --no-session --no-skills --no-prompt-templates --no-extensions --no-context-files --model "$REVIEWER_MODEL" --tools read,grep,find,ls -p "Read the review payload and return the requested verdict." pi --no-session --no-skills --no-prompt-templates --no-extensions --no-context-files --model "$REVIEWER_MODEL" --tools read,grep,find,ls -p "Read the review payload and return the requested verdict."
``` ```
Workflow docs should link to this section instead of restating the full flag contract. Each workflow substitutes its own payload path and verdict prompt:
- `create-plan`: `/tmp/plan-${REVIEW_ID}.md`
- `implement-plan`: `/tmp/milestone-${REVIEW_ID}.md`
- `do-task`: `/tmp/do-task-${REVIEW_KIND}-${REVIEW_ID}.md`
User-facing shorthand `pi/<pi-model-name>` means `REVIEWER_CLI=pi` and `REVIEWER_MODEL=<pi-model-name>`. Split only on the first slash when the prefix before that slash is exactly `pi`; keep the remainder verbatim. Examples:
- `pi/claude-opus-4-7` -> `claude-opus-4-7`
- `pi/anthropic/claude-opus-4-7` -> `anthropic/claude-opus-4-7`
- `pi/openrouter/anthropic/claude-opus-4-7` -> `openrouter/anthropic/claude-opus-4-7`
Pi reviewer calls must stay isolated from the main workflow: Pi reviewer calls must stay isolated from the main workflow:
- Use `--no-session` so the reviewer does not continue or persist the workflow session. - Use `--no-session` so the reviewer does not continue or persist the workflow session.
+8
View File
@@ -85,6 +85,14 @@ Reviewer CLI: `codex`, `claude`, `cursor`, `opencode`, `pi`, or `skip`
Store `REVIEWER_CLI`, `REVIEWER_MODEL`, and `MAX_ROUNDS` for the review loop. Store `REVIEWER_CLI`, `REVIEWER_MODEL`, and `MAX_ROUNDS` for the review loop.
If `REVIEWER_CLI=pi`, verify the Pi reviewer binary before entering the review loop:
```bash
pi --version
```
For shorthand `pi/<pi-model-name>`, split only on the first slash when the prefix is exactly `pi`; store the complete remainder in `REVIEWER_MODEL`. Examples: `pi/claude-opus-4-7` -> `claude-opus-4-7`, `pi/anthropic/claude-opus-4-7` -> `anthropic/claude-opus-4-7`, and `pi/openrouter/anthropic/claude-opus-4-7` -> `openrouter/anthropic/claude-opus-4-7`.
When `REVIEWER_CLI=pi`, the reviewer model is configured independently from the pi model running this workflow. Use any configured pi model string, including provider-qualified model IDs. If the reviewer model or provider is unavailable, surface the review helper stderr/status and ask for a configured model; use `pi --list-models [search]` to inspect configured models. When `REVIEWER_CLI=pi`, the reviewer model is configured independently from the pi model running this workflow. Use any configured pi model string, including provider-qualified model IDs. If the reviewer model or provider is unavailable, surface the review helper stderr/status and ask for a configured model; use `pi --list-models [search]` to inspect configured models.
The pi reviewer command rendered into `/tmp/plan-review-${REVIEW_ID}.sh` must be isolated and read-only: The pi reviewer command rendered into `/tmp/plan-review-${REVIEW_ID}.sh` must be isolated and read-only:
+8
View File
@@ -103,6 +103,14 @@ Reviewer CLI: `codex`, `claude`, `cursor`, `opencode`, `pi`, or `skip`
Store `REVIEWER_CLI`, `REVIEWER_MODEL`, and `MAX_ROUNDS`. Store `REVIEWER_CLI`, `REVIEWER_MODEL`, and `MAX_ROUNDS`.
If `REVIEWER_CLI=pi`, verify the Pi reviewer binary before entering the review loop:
```bash
pi --version
```
For shorthand `pi/<pi-model-name>`, split only on the first slash when the prefix is exactly `pi`; store the complete remainder in `REVIEWER_MODEL`. Examples: `pi/claude-opus-4-7` -> `claude-opus-4-7`, `pi/anthropic/claude-opus-4-7` -> `anthropic/claude-opus-4-7`, and `pi/openrouter/anthropic/claude-opus-4-7` -> `openrouter/anthropic/claude-opus-4-7`.
When `REVIEWER_CLI=pi`, the reviewer model is configured independently from the pi model running this workflow. Use any configured pi model string, including provider-qualified model IDs. If the reviewer model or provider is unavailable, surface the review helper stderr/status and ask for a configured model; use `pi --list-models [search]` to inspect configured models. When `REVIEWER_CLI=pi`, the reviewer model is configured independently from the pi model running this workflow. Use any configured pi model string, including provider-qualified model IDs. If the reviewer model or provider is unavailable, surface the review helper stderr/status and ask for a configured model; use `pi --list-models [search]` to inspect configured models.
The pi reviewer command rendered into `/tmp/do-task-${REVIEW_KIND}-review-${REVIEW_ID}.sh` must be isolated and read-only: The pi reviewer command rendered into `/tmp/do-task-${REVIEW_KIND}-review-${REVIEW_ID}.sh` must be isolated and read-only:
@@ -86,6 +86,14 @@ Reviewer CLI: `codex`, `claude`, `cursor`, `opencode`, `pi`, or `skip`
Store `REVIEWER_CLI`, `REVIEWER_MODEL`, and `MAX_ROUNDS`. Store `REVIEWER_CLI`, `REVIEWER_MODEL`, and `MAX_ROUNDS`.
If `REVIEWER_CLI=pi`, verify the Pi reviewer binary before entering the review loop:
```bash
pi --version
```
For shorthand `pi/<pi-model-name>`, split only on the first slash when the prefix is exactly `pi`; store the complete remainder in `REVIEWER_MODEL`. Examples: `pi/claude-opus-4-7` -> `claude-opus-4-7`, `pi/anthropic/claude-opus-4-7` -> `anthropic/claude-opus-4-7`, and `pi/openrouter/anthropic/claude-opus-4-7` -> `openrouter/anthropic/claude-opus-4-7`.
When `REVIEWER_CLI=pi`, the reviewer model is configured independently from the pi model running this workflow. Use any configured pi model string, including provider-qualified model IDs. If the reviewer model or provider is unavailable, surface the review helper stderr/status and ask for a configured model; use `pi --list-models [search]` to inspect configured models. When `REVIEWER_CLI=pi`, the reviewer model is configured independently from the pi model running this workflow. Use any configured pi model string, including provider-qualified model IDs. If the reviewer model or provider is unavailable, surface the review helper stderr/status and ask for a configured model; use `pi --list-models [search]` to inspect configured models.
The pi reviewer command rendered into `/tmp/milestone-review-${REVIEW_ID}.sh` must be isolated and read-only: The pi reviewer command rendered into `/tmp/milestone-review-${REVIEW_ID}.sh` must be isolated and read-only:
+38 -1
View File
@@ -33,6 +33,19 @@ If any dependency is missing, stop immediately and return:
### Phase 3: Configure Reviewer ### Phase 3: Configure Reviewer
Reviewer CLI: `codex`, `claude`, `cursor`, `opencode`, `pi`, or `skip`.
If `REVIEWER_CLI=pi`, verify the Pi reviewer binary before entering the review loop:
```bash
pi --version
```
For shorthand `pi/<pi-model-name>`, split only on the first slash when the prefix is exactly `pi`; store the complete remainder in `REVIEWER_MODEL`. Examples: `pi/claude-opus-4-7` -> `claude-opus-4-7`, `pi/anthropic/claude-opus-4-7` -> `anthropic/claude-opus-4-7`, and `pi/openrouter/anthropic/claude-opus-4-7` -> `openrouter/anthropic/claude-opus-4-7`.
When `REVIEWER_CLI=pi`, the reviewer model is configured independently from the model running this workflow. If the model/provider is unavailable, surface helper stderr/status and use `pi --list-models [search]` to inspect configured models.
If the user has already specified a reviewer CLI and model (e.g., "create a plan, review with codex o4-mini"), use those values. Otherwise, ask: If the user has already specified a reviewer CLI and model (e.g., "create a plan, review with codex o4-mini"), use those values. Otherwise, ask:
1. **Which CLI should review the plan?** 1. **Which CLI should review the plan?**
@@ -152,6 +165,18 @@ Write the reviewer invocation to `/tmp/plan-review-${REVIEW_ID}.sh` as a bash sc
set -euo pipefail set -euo pipefail
``` ```
**If `REVIEWER_CLI` is `pi`:**
Fresh call every round (Pi reviewer calls do not use session resume):
```bash
pi --no-session --no-skills --no-prompt-templates --no-extensions --no-context-files \
--model "$REVIEWER_MODEL" \
--tools read,grep,find,ls \
-p "Read the file /tmp/plan-${REVIEW_ID}.md and review. Return exactly the required ## Summary, ## Findings, and ## Verdict structure."
```
**If `REVIEWER_CLI` is `codex`:** **If `REVIEWER_CLI` is `codex`:**
```bash ```bash
@@ -281,7 +306,7 @@ jq -r '.result' /tmp/plan-review-${REVIEW_ID}.json > /tmp/plan-review-${REVIEW_I
``` ```
- If `REVIEWER_CLI=codex`, extract `CODEX_SESSION_ID` from `/tmp/plan-review-${REVIEW_ID}.runner.out` after the helper or fallback run. If the review text is only in `.runner.out`, move or copy the actual review body into `/tmp/plan-review-${REVIEW_ID}.md` before verdict parsing. - If `REVIEWER_CLI=codex`, extract `CODEX_SESSION_ID` from `/tmp/plan-review-${REVIEW_ID}.runner.out` after the helper or fallback run. If the review text is only in `.runner.out`, move or copy the actual review body into `/tmp/plan-review-${REVIEW_ID}.md` before verdict parsing.
- If `REVIEWER_CLI=claude`, promote stdout captured by the helper or fallback runner into the markdown review file: - If `REVIEWER_CLI=claude` or `REVIEWER_CLI=pi`, promote stdout captured by the helper or fallback runner into the markdown review file:
```bash ```bash
cp /tmp/plan-review-${REVIEW_ID}.runner.out /tmp/plan-review-${REVIEW_ID}.md cp /tmp/plan-review-${REVIEW_ID}.runner.out /tmp/plan-review-${REVIEW_ID}.md
@@ -331,6 +356,18 @@ If a revision contradicts the user's explicit requirements, skip it and note it
Rewrite `/tmp/plan-review-${REVIEW_ID}.sh` for the next round. The script should contain the reviewer invocation only; do not run it directly. Rewrite `/tmp/plan-review-${REVIEW_ID}.sh` for the next round. The script should contain the reviewer invocation only; do not run it directly.
**If `REVIEWER_CLI` is `pi`:**
Fresh call with prior-round context (Pi reviewer calls do not use session resume):
```bash
pi --no-session --no-skills --no-prompt-templates --no-extensions --no-context-files \
--model "$REVIEWER_MODEL" \
--tools read,grep,find,ls \
-p "You previously reviewed this plan and requested revisions. Read the updated payload at /tmp/plan-${REVIEW_ID}.md and re-review using the same ## Summary, ## Findings, and ## Verdict structure."
```
**If `REVIEWER_CLI` is `codex`:** **If `REVIEWER_CLI` is `codex`:**
Resume the existing session: Resume the existing session:
+38 -1
View File
@@ -58,6 +58,19 @@ If any dependency is missing, stop and return:
### Phase 3: Configure Reviewer ### Phase 3: Configure Reviewer
Reviewer CLI: `codex`, `claude`, `cursor`, `opencode`, `pi`, or `skip`.
If `REVIEWER_CLI=pi`, verify the Pi reviewer binary before entering the review loop:
```bash
pi --version
```
For shorthand `pi/<pi-model-name>`, split only on the first slash when the prefix is exactly `pi`; store the complete remainder in `REVIEWER_MODEL`. Examples: `pi/claude-opus-4-7` -> `claude-opus-4-7`, `pi/anthropic/claude-opus-4-7` -> `anthropic/claude-opus-4-7`, and `pi/openrouter/anthropic/claude-opus-4-7` -> `openrouter/anthropic/claude-opus-4-7`.
When `REVIEWER_CLI=pi`, the reviewer model is configured independently from the model running this workflow. If the model/provider is unavailable, surface helper stderr/status and use `pi --list-models [search]` to inspect configured models.
If the user has already specified a reviewer CLI and model (e.g., "create a plan, review with claude sonnet"), use those values. Otherwise, ask: If the user has already specified a reviewer CLI and model (e.g., "create a plan, review with claude sonnet"), use those values. Otherwise, ask:
1. **Which CLI should review the plan?** 1. **Which CLI should review the plan?**
@@ -175,6 +188,18 @@ Write the reviewer invocation to `/tmp/plan-review-${REVIEW_ID}.sh` as a bash sc
set -euo pipefail set -euo pipefail
``` ```
**If `REVIEWER_CLI` is `pi`:**
Fresh call every round (Pi reviewer calls do not use session resume):
```bash
pi --no-session --no-skills --no-prompt-templates --no-extensions --no-context-files \
--model "$REVIEWER_MODEL" \
--tools read,grep,find,ls \
-p "Read the file /tmp/plan-${REVIEW_ID}.md and review. Return exactly the required ## Summary, ## Findings, and ## Verdict structure."
```
**If `REVIEWER_CLI` is `codex`:** **If `REVIEWER_CLI` is `codex`:**
```bash ```bash
@@ -304,7 +329,7 @@ jq -r '.result' /tmp/plan-review-${REVIEW_ID}.json > /tmp/plan-review-${REVIEW_I
``` ```
- If `REVIEWER_CLI=codex`, extract `CODEX_SESSION_ID` from `/tmp/plan-review-${REVIEW_ID}.runner.out` after the helper or fallback run. If the review text is only in `.runner.out`, move or copy the actual review body into `/tmp/plan-review-${REVIEW_ID}.md` before verdict parsing. - If `REVIEWER_CLI=codex`, extract `CODEX_SESSION_ID` from `/tmp/plan-review-${REVIEW_ID}.runner.out` after the helper or fallback run. If the review text is only in `.runner.out`, move or copy the actual review body into `/tmp/plan-review-${REVIEW_ID}.md` before verdict parsing.
- If `REVIEWER_CLI=claude`, promote stdout captured by the helper or fallback runner into the markdown review file: - If `REVIEWER_CLI=claude` or `REVIEWER_CLI=pi`, promote stdout captured by the helper or fallback runner into the markdown review file:
```bash ```bash
cp /tmp/plan-review-${REVIEW_ID}.runner.out /tmp/plan-review-${REVIEW_ID}.md cp /tmp/plan-review-${REVIEW_ID}.runner.out /tmp/plan-review-${REVIEW_ID}.md
@@ -354,6 +379,18 @@ If a revision contradicts the user's explicit requirements, skip it and note it
Rewrite `/tmp/plan-review-${REVIEW_ID}.sh` for the next round. The script should contain the reviewer invocation only; do not run it directly. Rewrite `/tmp/plan-review-${REVIEW_ID}.sh` for the next round. The script should contain the reviewer invocation only; do not run it directly.
**If `REVIEWER_CLI` is `pi`:**
Fresh call with prior-round context (Pi reviewer calls do not use session resume):
```bash
pi --no-session --no-skills --no-prompt-templates --no-extensions --no-context-files \
--model "$REVIEWER_MODEL" \
--tools read,grep,find,ls \
-p "You previously reviewed this plan and requested revisions. Read the updated payload at /tmp/plan-${REVIEW_ID}.md and re-review using the same ## Summary, ## Findings, and ## Verdict structure."
```
**If `REVIEWER_CLI` is `codex`:** **If `REVIEWER_CLI` is `codex`:**
Resume the existing session: Resume the existing session:
+38 -1
View File
@@ -59,6 +59,19 @@ If any dependency is missing, stop and return:
### Phase 3: Configure Reviewer ### Phase 3: Configure Reviewer
Reviewer CLI: `codex`, `claude`, `cursor`, `opencode`, `pi`, or `skip`.
If `REVIEWER_CLI=pi`, verify the Pi reviewer binary before entering the review loop:
```bash
pi --version
```
For shorthand `pi/<pi-model-name>`, split only on the first slash when the prefix is exactly `pi`; store the complete remainder in `REVIEWER_MODEL`. Examples: `pi/claude-opus-4-7` -> `claude-opus-4-7`, `pi/anthropic/claude-opus-4-7` -> `anthropic/claude-opus-4-7`, and `pi/openrouter/anthropic/claude-opus-4-7` -> `openrouter/anthropic/claude-opus-4-7`.
When `REVIEWER_CLI=pi`, the reviewer model is configured independently from the model running this workflow. If the model/provider is unavailable, surface helper stderr/status and use `pi --list-models [search]` to inspect configured models.
If the user has already specified a reviewer CLI and model (e.g., "create a plan, review with codex o4-mini"), use those values. Otherwise, ask: If the user has already specified a reviewer CLI and model (e.g., "create a plan, review with codex o4-mini"), use those values. Otherwise, ask:
1. **Which CLI should review the plan?** 1. **Which CLI should review the plan?**
@@ -181,6 +194,18 @@ Write the reviewer invocation to `/tmp/plan-review-${REVIEW_ID}.sh` as a bash sc
set -euo pipefail set -euo pipefail
``` ```
**If `REVIEWER_CLI` is `pi`:**
Fresh call every round (Pi reviewer calls do not use session resume):
```bash
pi --no-session --no-skills --no-prompt-templates --no-extensions --no-context-files \
--model "$REVIEWER_MODEL" \
--tools read,grep,find,ls \
-p "Read the file /tmp/plan-${REVIEW_ID}.md and review. Return exactly the required ## Summary, ## Findings, and ## Verdict structure."
```
**If `REVIEWER_CLI` is `codex`:** **If `REVIEWER_CLI` is `codex`:**
```bash ```bash
@@ -316,7 +341,7 @@ jq -r '.result' /tmp/plan-review-${REVIEW_ID}.json > /tmp/plan-review-${REVIEW_I
``` ```
- If `REVIEWER_CLI=codex`, extract `CODEX_SESSION_ID` from `/tmp/plan-review-${REVIEW_ID}.runner.out` after the helper or fallback run. If the review text is only in `.runner.out`, move or copy the actual review body into `/tmp/plan-review-${REVIEW_ID}.md` before verdict parsing. - If `REVIEWER_CLI=codex`, extract `CODEX_SESSION_ID` from `/tmp/plan-review-${REVIEW_ID}.runner.out` after the helper or fallback run. If the review text is only in `.runner.out`, move or copy the actual review body into `/tmp/plan-review-${REVIEW_ID}.md` before verdict parsing.
- If `REVIEWER_CLI=claude`, promote stdout captured by the helper or fallback runner into the markdown review file: - If `REVIEWER_CLI=claude` or `REVIEWER_CLI=pi`, promote stdout captured by the helper or fallback runner into the markdown review file:
```bash ```bash
cp /tmp/plan-review-${REVIEW_ID}.runner.out /tmp/plan-review-${REVIEW_ID}.md cp /tmp/plan-review-${REVIEW_ID}.runner.out /tmp/plan-review-${REVIEW_ID}.md
@@ -364,6 +389,18 @@ If a revision contradicts the user's explicit requirements, skip it and note it
Rewrite `/tmp/plan-review-${REVIEW_ID}.sh` for the next round. The script should contain the reviewer invocation only; do not run it directly. Rewrite `/tmp/plan-review-${REVIEW_ID}.sh` for the next round. The script should contain the reviewer invocation only; do not run it directly.
**If `REVIEWER_CLI` is `pi`:**
Fresh call with prior-round context (Pi reviewer calls do not use session resume):
```bash
pi --no-session --no-skills --no-prompt-templates --no-extensions --no-context-files \
--model "$REVIEWER_MODEL" \
--tools read,grep,find,ls \
-p "You previously reviewed this plan and requested revisions. Read the updated payload at /tmp/plan-${REVIEW_ID}.md and re-review using the same ## Summary, ## Findings, and ## Verdict structure."
```
**If `REVIEWER_CLI` is `codex`:** **If `REVIEWER_CLI` is `codex`:**
Resume the existing session: Resume the existing session:
+38 -1
View File
@@ -64,6 +64,19 @@ If the user has already specified a reviewer CLI and model (e.g., "create a plan
Store the chosen `REVIEWER_CLI`, `REVIEWER_MODEL`, and `MAX_ROUNDS` for Phase 7 (Iterative Plan Review). Store the chosen `REVIEWER_CLI`, `REVIEWER_MODEL`, and `MAX_ROUNDS` for Phase 7 (Iterative Plan Review).
Reviewer CLI: `codex`, `claude`, `cursor`, `opencode`, `pi`, or `skip`.
If `REVIEWER_CLI=pi`, verify the Pi reviewer binary before entering the review loop:
```bash
pi --version
```
For shorthand `pi/<pi-model-name>`, split only on the first slash when the prefix is exactly `pi`; store the complete remainder in `REVIEWER_MODEL`. Examples: `pi/claude-opus-4-7` -> `claude-opus-4-7`, `pi/anthropic/claude-opus-4-7` -> `anthropic/claude-opus-4-7`, and `pi/openrouter/anthropic/claude-opus-4-7` -> `openrouter/anthropic/claude-opus-4-7`.
When `REVIEWER_CLI=pi`, the reviewer model is configured independently from the model running this workflow. If the model/provider is unavailable, surface helper stderr/status and use `pi --list-models [search]` to inspect configured models.
### Phase 5: Design (REQUIRED SUB-SKILL) ### Phase 5: Design (REQUIRED SUB-SKILL)
Use OpenCode's native skill tool to load: Use OpenCode's native skill tool to load:
@@ -169,6 +182,18 @@ Write the reviewer invocation to `/tmp/plan-review-${REVIEW_ID}.sh` as a bash sc
set -euo pipefail set -euo pipefail
``` ```
**If `REVIEWER_CLI` is `pi`:**
Fresh call every round (Pi reviewer calls do not use session resume):
```bash
pi --no-session --no-skills --no-prompt-templates --no-extensions --no-context-files \
--model "$REVIEWER_MODEL" \
--tools read,grep,find,ls \
-p "Read the file /tmp/plan-${REVIEW_ID}.md and review. Return exactly the required ## Summary, ## Findings, and ## Verdict structure."
```
**If `REVIEWER_CLI` is `codex`:** **If `REVIEWER_CLI` is `codex`:**
```bash ```bash
@@ -298,7 +323,7 @@ jq -r '.result' /tmp/plan-review-${REVIEW_ID}.json > /tmp/plan-review-${REVIEW_I
``` ```
- If `REVIEWER_CLI=codex`, extract `CODEX_SESSION_ID` from `/tmp/plan-review-${REVIEW_ID}.runner.out` after the helper or fallback run. If the review text is only in `.runner.out`, move or copy the actual review body into `/tmp/plan-review-${REVIEW_ID}.md` before verdict parsing. - If `REVIEWER_CLI=codex`, extract `CODEX_SESSION_ID` from `/tmp/plan-review-${REVIEW_ID}.runner.out` after the helper or fallback run. If the review text is only in `.runner.out`, move or copy the actual review body into `/tmp/plan-review-${REVIEW_ID}.md` before verdict parsing.
- If `REVIEWER_CLI=claude`, promote stdout captured by the helper or fallback runner into the markdown review file: - If `REVIEWER_CLI=claude` or `REVIEWER_CLI=pi`, promote stdout captured by the helper or fallback runner into the markdown review file:
```bash ```bash
cp /tmp/plan-review-${REVIEW_ID}.runner.out /tmp/plan-review-${REVIEW_ID}.md cp /tmp/plan-review-${REVIEW_ID}.runner.out /tmp/plan-review-${REVIEW_ID}.md
@@ -346,6 +371,18 @@ If a revision contradicts the user's explicit requirements, skip it and note it
Rewrite `/tmp/plan-review-${REVIEW_ID}.sh` for the next round. The script should contain the reviewer invocation only; do not run it directly. Rewrite `/tmp/plan-review-${REVIEW_ID}.sh` for the next round. The script should contain the reviewer invocation only; do not run it directly.
**If `REVIEWER_CLI` is `pi`:**
Fresh call with prior-round context (Pi reviewer calls do not use session resume):
```bash
pi --no-session --no-skills --no-prompt-templates --no-extensions --no-context-files \
--model "$REVIEWER_MODEL" \
--tools read,grep,find,ls \
-p "You previously reviewed this plan and requested revisions. Read the updated payload at /tmp/plan-${REVIEW_ID}.md and re-review using the same ## Summary, ## Findings, and ## Verdict structure."
```
**If `REVIEWER_CLI` is `codex`:** **If `REVIEWER_CLI` is `codex`:**
Resume the existing session: Resume the existing session:
+8
View File
@@ -85,6 +85,14 @@ Reviewer CLI: `codex`, `claude`, `cursor`, `opencode`, `pi`, or `skip`
Store `REVIEWER_CLI`, `REVIEWER_MODEL`, and `MAX_ROUNDS` for the review loop. Store `REVIEWER_CLI`, `REVIEWER_MODEL`, and `MAX_ROUNDS` for the review loop.
If `REVIEWER_CLI=pi`, verify the Pi reviewer binary before entering the review loop:
```bash
pi --version
```
For shorthand `pi/<pi-model-name>`, split only on the first slash when the prefix is exactly `pi`; store the complete remainder in `REVIEWER_MODEL`. Examples: `pi/claude-opus-4-7` -> `claude-opus-4-7`, `pi/anthropic/claude-opus-4-7` -> `anthropic/claude-opus-4-7`, and `pi/openrouter/anthropic/claude-opus-4-7` -> `openrouter/anthropic/claude-opus-4-7`.
When `REVIEWER_CLI=pi`, the reviewer model is configured independently from the pi model running this workflow. Use any configured pi model string, including provider-qualified model IDs. If the reviewer model or provider is unavailable, surface the review helper stderr/status and ask for a configured model; use `pi --list-models [search]` to inspect configured models. When `REVIEWER_CLI=pi`, the reviewer model is configured independently from the pi model running this workflow. Use any configured pi model string, including provider-qualified model IDs. If the reviewer model or provider is unavailable, surface the review helper stderr/status and ask for a configured model; use `pi --list-models [search]` to inspect configured models.
The pi reviewer command rendered into `/tmp/plan-review-${REVIEW_ID}.sh` must be isolated and read-only: The pi reviewer command rendered into `/tmp/plan-review-${REVIEW_ID}.sh` must be isolated and read-only:
+27 -2
View File
@@ -111,6 +111,19 @@ If the user has already specified a reviewer CLI and model (e.g., "do task X, re
Store `REVIEWER_CLI`, `REVIEWER_MODEL`, and `MAX_ROUNDS` for Phases 5 and 8. Store `REVIEWER_CLI`, `REVIEWER_MODEL`, and `MAX_ROUNDS` for Phases 5 and 8.
Reviewer CLI: `codex`, `claude`, `cursor`, `opencode`, `pi`, or `skip`.
If `REVIEWER_CLI=pi`, verify the Pi reviewer binary before entering the review loop:
```bash
pi --version
```
For shorthand `pi/<pi-model-name>`, split only on the first slash when the prefix is exactly `pi`; store the complete remainder in `REVIEWER_MODEL`. Examples: `pi/claude-opus-4-7` -> `claude-opus-4-7`, `pi/anthropic/claude-opus-4-7` -> `anthropic/claude-opus-4-7`, and `pi/openrouter/anthropic/claude-opus-4-7` -> `openrouter/anthropic/claude-opus-4-7`.
When `REVIEWER_CLI=pi`, the reviewer model is configured independently from the model running this workflow. If the model/provider is unavailable, surface helper stderr/status and use `pi --list-models [search]` to inspect configured models.
### Phase 4: Initialize Plan Workspace ### Phase 4: Initialize Plan Workspace
**PLAN MODE CHECK:** If currently in plan mode: **PLAN MODE CHECK:** If currently in plan mode:
@@ -344,7 +357,7 @@ This subroutine is invoked twice per `do-task` run: once in Phase 5 (`REVIEW_KIN
| `REVIEW_ID` | 8-char hex (from `uuidgen`); reused across rounds of the same loop | | `REVIEW_ID` | 8-char hex (from `uuidgen`); reused across rounds of the same loop |
| `PAYLOAD_PATH` | `/tmp/do-task-${REVIEW_KIND}-${REVIEW_ID}.md` | | `PAYLOAD_PATH` | `/tmp/do-task-${REVIEW_KIND}-${REVIEW_ID}.md` |
| `PROMPT_TEMPLATE` | `PLAN_REVIEW_PROMPT` or `IMPL_REVIEW_PROMPT` | | `PROMPT_TEMPLATE` | `PLAN_REVIEW_PROMPT` or `IMPL_REVIEW_PROMPT` |
| `REVIEWER_CLI` | `codex` \| `claude` \| `cursor` \| `opencode` | | `REVIEWER_CLI` | `codex` \| `claude` \| `cursor` \| `opencode` \| `pi` |
| `REVIEWER_MODEL` | Model name | | `REVIEWER_MODEL` | Model name |
| `MAX_ROUNDS` | Default 10 | | `MAX_ROUNDS` | Default 10 |
| `SESSION_ID_VAR` | `CODEX_PLAN_SESSION_ID` \| `CODEX_IMPL_SESSION_ID` \| `CURSOR_PLAN_SESSION_ID` \| `CURSOR_IMPL_SESSION_ID` \| `OPENCODE_PLAN_SESSION_ID` \| `OPENCODE_IMPL_SESSION_ID` | | `SESSION_ID_VAR` | `CODEX_PLAN_SESSION_ID` \| `CODEX_IMPL_SESSION_ID` \| `CURSOR_PLAN_SESSION_ID` \| `CURSOR_IMPL_SESSION_ID` \| `OPENCODE_PLAN_SESSION_ID` \| `OPENCODE_IMPL_SESSION_ID` |
@@ -437,6 +450,18 @@ Write the reviewer invocation to `/tmp/do-task-${REVIEW_KIND}-review-${REVIEW_ID
set -euo pipefail set -euo pipefail
``` ```
**If `REVIEWER_CLI` is `pi`:**
Fresh call every round (Pi reviewer calls do not use session resume):
```bash
pi --no-session --no-skills --no-prompt-templates --no-extensions --no-context-files \
--model "$REVIEWER_MODEL" \
--tools read,grep,find,ls \
-p "Read the file /tmp/do-task-${REVIEW_KIND}-${REVIEW_ID}.md and review. Return exactly the required ## Summary, ## Findings, and ## Verdict structure."
```
**If `REVIEWER_CLI` is `codex`:** **If `REVIEWER_CLI` is `codex`:**
Round 1 — fresh `codex exec`: Round 1 — fresh `codex exec`:
@@ -633,7 +658,7 @@ After the command completes:
cp /tmp/do-task-${REVIEW_KIND}-review-${REVIEW_ID}.runner.out \ cp /tmp/do-task-${REVIEW_KIND}-review-${REVIEW_ID}.runner.out \
/tmp/do-task-${REVIEW_KIND}-review-${REVIEW_ID}.md /tmp/do-task-${REVIEW_KIND}-review-${REVIEW_ID}.md
``` ```
- `claude`: promote `.runner.out` into the `.md` file: - `claude` or `pi`: promote `.runner.out` into the `.md` file:
```bash ```bash
cp /tmp/do-task-${REVIEW_KIND}-review-${REVIEW_ID}.runner.out \ cp /tmp/do-task-${REVIEW_KIND}-review-${REVIEW_ID}.runner.out \
/tmp/do-task-${REVIEW_KIND}-review-${REVIEW_ID}.md /tmp/do-task-${REVIEW_KIND}-review-${REVIEW_ID}.md
@@ -9,7 +9,7 @@
| Created | YYYY-MM-DD | | Created | YYYY-MM-DD |
| Slug | YYYY-MM-DD-<slug> | | Slug | YYYY-MM-DD-<slug> |
| Runtime | claude-code | | Runtime | claude-code |
| Reviewer CLI | codex \| claude \| cursor \| opencode | | Reviewer CLI | codex \| claude \| cursor \| opencode \| pi |
| Reviewer Model | <model> | | Reviewer Model | <model> |
| MAX_ROUNDS | 10 | | MAX_ROUNDS | 10 |
| Branch Strategy | current-branch \| worktree | | Branch Strategy | current-branch \| worktree |
+27 -2
View File
@@ -133,6 +133,19 @@ If the user has already specified a reviewer CLI and model (e.g., "do task X, re
Store `REVIEWER_CLI`, `REVIEWER_MODEL`, and `MAX_ROUNDS` for Phases 5 and 8. Store `REVIEWER_CLI`, `REVIEWER_MODEL`, and `MAX_ROUNDS` for Phases 5 and 8.
Reviewer CLI: `codex`, `claude`, `cursor`, `opencode`, `pi`, or `skip`.
If `REVIEWER_CLI=pi`, verify the Pi reviewer binary before entering the review loop:
```bash
pi --version
```
For shorthand `pi/<pi-model-name>`, split only on the first slash when the prefix is exactly `pi`; store the complete remainder in `REVIEWER_MODEL`. Examples: `pi/claude-opus-4-7` -> `claude-opus-4-7`, `pi/anthropic/claude-opus-4-7` -> `anthropic/claude-opus-4-7`, and `pi/openrouter/anthropic/claude-opus-4-7` -> `openrouter/anthropic/claude-opus-4-7`.
When `REVIEWER_CLI=pi`, the reviewer model is configured independently from the model running this workflow. If the model/provider is unavailable, surface helper stderr/status and use `pi --list-models [search]` to inspect configured models.
### Phase 4: Initialize Plan Workspace ### Phase 4: Initialize Plan Workspace
Codex has no plan-mode concept; there is no plan-mode guard here. Codex has no plan-mode concept; there is no plan-mode guard here.
@@ -363,7 +376,7 @@ This subroutine is invoked twice per `do-task` run: once in Phase 5 (`REVIEW_KIN
| `REVIEW_ID` | 8-char hex (from `uuidgen`); reused across rounds of the same loop | | `REVIEW_ID` | 8-char hex (from `uuidgen`); reused across rounds of the same loop |
| `PAYLOAD_PATH` | `/tmp/do-task-${REVIEW_KIND}-${REVIEW_ID}.md` | | `PAYLOAD_PATH` | `/tmp/do-task-${REVIEW_KIND}-${REVIEW_ID}.md` |
| `PROMPT_TEMPLATE` | `PLAN_REVIEW_PROMPT` or `IMPL_REVIEW_PROMPT` | | `PROMPT_TEMPLATE` | `PLAN_REVIEW_PROMPT` or `IMPL_REVIEW_PROMPT` |
| `REVIEWER_CLI` | `codex` \| `claude` \| `cursor` \| `opencode` | | `REVIEWER_CLI` | `codex` \| `claude` \| `cursor` \| `opencode` \| `pi` |
| `REVIEWER_MODEL` | Model name | | `REVIEWER_MODEL` | Model name |
| `MAX_ROUNDS` | Default 10 | | `MAX_ROUNDS` | Default 10 |
| `SESSION_ID_VAR` | `CODEX_PLAN_SESSION_ID` \| `CODEX_IMPL_SESSION_ID` \| `CURSOR_PLAN_SESSION_ID` \| `CURSOR_IMPL_SESSION_ID` \| `OPENCODE_PLAN_SESSION_ID` \| `OPENCODE_IMPL_SESSION_ID` | | `SESSION_ID_VAR` | `CODEX_PLAN_SESSION_ID` \| `CODEX_IMPL_SESSION_ID` \| `CURSOR_PLAN_SESSION_ID` \| `CURSOR_IMPL_SESSION_ID` \| `OPENCODE_PLAN_SESSION_ID` \| `OPENCODE_IMPL_SESSION_ID` |
@@ -456,6 +469,18 @@ Write the reviewer invocation to `/tmp/do-task-${REVIEW_KIND}-review-${REVIEW_ID
set -euo pipefail set -euo pipefail
``` ```
**If `REVIEWER_CLI` is `pi`:**
Fresh call every round (Pi reviewer calls do not use session resume):
```bash
pi --no-session --no-skills --no-prompt-templates --no-extensions --no-context-files \
--model "$REVIEWER_MODEL" \
--tools read,grep,find,ls \
-p "Read the file /tmp/do-task-${REVIEW_KIND}-${REVIEW_ID}.md and review. Return exactly the required ## Summary, ## Findings, and ## Verdict structure."
```
**If `REVIEWER_CLI` is `codex`:** **If `REVIEWER_CLI` is `codex`:**
Round 1 — fresh `codex exec`: Round 1 — fresh `codex exec`:
@@ -652,7 +677,7 @@ After the command completes:
cp /tmp/do-task-${REVIEW_KIND}-review-${REVIEW_ID}.runner.out \ cp /tmp/do-task-${REVIEW_KIND}-review-${REVIEW_ID}.runner.out \
/tmp/do-task-${REVIEW_KIND}-review-${REVIEW_ID}.md /tmp/do-task-${REVIEW_KIND}-review-${REVIEW_ID}.md
``` ```
- `claude`: promote `.runner.out` into the `.md` file: - `claude` or `pi`: promote `.runner.out` into the `.md` file:
```bash ```bash
cp /tmp/do-task-${REVIEW_KIND}-review-${REVIEW_ID}.runner.out \ cp /tmp/do-task-${REVIEW_KIND}-review-${REVIEW_ID}.runner.out \
/tmp/do-task-${REVIEW_KIND}-review-${REVIEW_ID}.md /tmp/do-task-${REVIEW_KIND}-review-${REVIEW_ID}.md
+1 -1
View File
@@ -9,7 +9,7 @@
| Created | YYYY-MM-DD | | Created | YYYY-MM-DD |
| Slug | YYYY-MM-DD-<slug> | | Slug | YYYY-MM-DD-<slug> |
| Runtime | codex | | Runtime | codex |
| Reviewer CLI | codex \| claude \| cursor \| opencode | | Reviewer CLI | codex \| claude \| cursor \| opencode \| pi |
| Reviewer Model | <model> | | Reviewer Model | <model> |
| MAX_ROUNDS | 10 | | MAX_ROUNDS | 10 |
| Branch Strategy | current-branch \| worktree | | Branch Strategy | current-branch \| worktree |
+27 -2
View File
@@ -132,6 +132,19 @@ If the user has already specified a reviewer CLI and model (e.g., "do task X, re
Store `REVIEWER_CLI`, `REVIEWER_MODEL`, and `MAX_ROUNDS` for Phases 5 and 8. Store `REVIEWER_CLI`, `REVIEWER_MODEL`, and `MAX_ROUNDS` for Phases 5 and 8.
Reviewer CLI: `codex`, `claude`, `cursor`, `opencode`, `pi`, or `skip`.
If `REVIEWER_CLI=pi`, verify the Pi reviewer binary before entering the review loop:
```bash
pi --version
```
For shorthand `pi/<pi-model-name>`, split only on the first slash when the prefix is exactly `pi`; store the complete remainder in `REVIEWER_MODEL`. Examples: `pi/claude-opus-4-7` -> `claude-opus-4-7`, `pi/anthropic/claude-opus-4-7` -> `anthropic/claude-opus-4-7`, and `pi/openrouter/anthropic/claude-opus-4-7` -> `openrouter/anthropic/claude-opus-4-7`.
When `REVIEWER_CLI=pi`, the reviewer model is configured independently from the model running this workflow. If the model/provider is unavailable, surface helper stderr/status and use `pi --list-models [search]` to inspect configured models.
### Phase 4: Initialize Plan Workspace ### Phase 4: Initialize Plan Workspace
Cursor Agent CLI has no plan-mode concept; there is no plan-mode guard here. Cursor Agent CLI has no plan-mode concept; there is no plan-mode guard here.
@@ -366,7 +379,7 @@ This subroutine is invoked twice per `do-task` run: once in Phase 5 (`REVIEW_KIN
| `REVIEW_ID` | 8-char hex (from `uuidgen`); reused across rounds of the same loop | | `REVIEW_ID` | 8-char hex (from `uuidgen`); reused across rounds of the same loop |
| `PAYLOAD_PATH` | `/tmp/do-task-${REVIEW_KIND}-${REVIEW_ID}.md` | | `PAYLOAD_PATH` | `/tmp/do-task-${REVIEW_KIND}-${REVIEW_ID}.md` |
| `PROMPT_TEMPLATE` | `PLAN_REVIEW_PROMPT` or `IMPL_REVIEW_PROMPT` | | `PROMPT_TEMPLATE` | `PLAN_REVIEW_PROMPT` or `IMPL_REVIEW_PROMPT` |
| `REVIEWER_CLI` | `codex` \| `claude` \| `cursor` \| `opencode` | | `REVIEWER_CLI` | `codex` \| `claude` \| `cursor` \| `opencode` \| `pi` |
| `REVIEWER_MODEL` | Model name | | `REVIEWER_MODEL` | Model name |
| `MAX_ROUNDS` | Default 10 | | `MAX_ROUNDS` | Default 10 |
| `SESSION_ID_VAR` | `CODEX_PLAN_SESSION_ID` \| `CODEX_IMPL_SESSION_ID` \| `CURSOR_PLAN_SESSION_ID` \| `CURSOR_IMPL_SESSION_ID` \| `OPENCODE_PLAN_SESSION_ID` \| `OPENCODE_IMPL_SESSION_ID` | | `SESSION_ID_VAR` | `CODEX_PLAN_SESSION_ID` \| `CODEX_IMPL_SESSION_ID` \| `CURSOR_PLAN_SESSION_ID` \| `CURSOR_IMPL_SESSION_ID` \| `OPENCODE_PLAN_SESSION_ID` \| `OPENCODE_IMPL_SESSION_ID` |
@@ -463,6 +476,18 @@ Write the reviewer invocation to `/tmp/do-task-${REVIEW_KIND}-review-${REVIEW_ID
set -euo pipefail set -euo pipefail
``` ```
**If `REVIEWER_CLI` is `pi`:**
Fresh call every round (Pi reviewer calls do not use session resume):
```bash
pi --no-session --no-skills --no-prompt-templates --no-extensions --no-context-files \
--model "$REVIEWER_MODEL" \
--tools read,grep,find,ls \
-p "Read the file /tmp/do-task-${REVIEW_KIND}-${REVIEW_ID}.md and review. Return exactly the required ## Summary, ## Findings, and ## Verdict structure."
```
**If `REVIEWER_CLI` is `codex`:** **If `REVIEWER_CLI` is `codex`:**
Round 1 — fresh `codex exec`: Round 1 — fresh `codex exec`:
@@ -659,7 +684,7 @@ After the command completes:
cp /tmp/do-task-${REVIEW_KIND}-review-${REVIEW_ID}.runner.out \ cp /tmp/do-task-${REVIEW_KIND}-review-${REVIEW_ID}.runner.out \
/tmp/do-task-${REVIEW_KIND}-review-${REVIEW_ID}.md /tmp/do-task-${REVIEW_KIND}-review-${REVIEW_ID}.md
``` ```
- `claude`: promote `.runner.out` into the `.md` file: - `claude` or `pi`: promote `.runner.out` into the `.md` file:
```bash ```bash
cp /tmp/do-task-${REVIEW_KIND}-review-${REVIEW_ID}.runner.out \ cp /tmp/do-task-${REVIEW_KIND}-review-${REVIEW_ID}.runner.out \
/tmp/do-task-${REVIEW_KIND}-review-${REVIEW_ID}.md /tmp/do-task-${REVIEW_KIND}-review-${REVIEW_ID}.md
+1 -1
View File
@@ -9,7 +9,7 @@
| Created | YYYY-MM-DD | | Created | YYYY-MM-DD |
| Slug | YYYY-MM-DD-<slug> | | Slug | YYYY-MM-DD-<slug> |
| Runtime | cursor | | Runtime | cursor |
| Reviewer CLI | codex \| claude \| cursor \| opencode | | Reviewer CLI | codex \| claude \| cursor \| opencode \| pi |
| Reviewer Model | <model> | | Reviewer Model | <model> |
| MAX_ROUNDS | 10 | | MAX_ROUNDS | 10 |
| Branch Strategy | current-branch \| worktree | | Branch Strategy | current-branch \| worktree |
+27 -2
View File
@@ -132,6 +132,19 @@ If the user has already specified a reviewer CLI and model (e.g., "do task X, re
Store `REVIEWER_CLI`, `REVIEWER_MODEL`, and `MAX_ROUNDS` for Phases 5 and 8. Store `REVIEWER_CLI`, `REVIEWER_MODEL`, and `MAX_ROUNDS` for Phases 5 and 8.
Reviewer CLI: `codex`, `claude`, `cursor`, `opencode`, `pi`, or `skip`.
If `REVIEWER_CLI=pi`, verify the Pi reviewer binary before entering the review loop:
```bash
pi --version
```
For shorthand `pi/<pi-model-name>`, split only on the first slash when the prefix is exactly `pi`; store the complete remainder in `REVIEWER_MODEL`. Examples: `pi/claude-opus-4-7` -> `claude-opus-4-7`, `pi/anthropic/claude-opus-4-7` -> `anthropic/claude-opus-4-7`, and `pi/openrouter/anthropic/claude-opus-4-7` -> `openrouter/anthropic/claude-opus-4-7`.
When `REVIEWER_CLI=pi`, the reviewer model is configured independently from the model running this workflow. If the model/provider is unavailable, surface helper stderr/status and use `pi --list-models [search]` to inspect configured models.
### Phase 4: Initialize Plan Workspace ### Phase 4: Initialize Plan Workspace
OpenCode has no plan-mode concept; there is no plan-mode guard here. OpenCode has no plan-mode concept; there is no plan-mode guard here.
@@ -362,7 +375,7 @@ This subroutine is invoked twice per `do-task` run: once in Phase 5 (`REVIEW_KIN
| `REVIEW_ID` | 8-char hex (from `uuidgen`); reused across rounds of the same loop | | `REVIEW_ID` | 8-char hex (from `uuidgen`); reused across rounds of the same loop |
| `PAYLOAD_PATH` | `/tmp/do-task-${REVIEW_KIND}-${REVIEW_ID}.md` | | `PAYLOAD_PATH` | `/tmp/do-task-${REVIEW_KIND}-${REVIEW_ID}.md` |
| `PROMPT_TEMPLATE` | `PLAN_REVIEW_PROMPT` or `IMPL_REVIEW_PROMPT` | | `PROMPT_TEMPLATE` | `PLAN_REVIEW_PROMPT` or `IMPL_REVIEW_PROMPT` |
| `REVIEWER_CLI` | `codex` \| `claude` \| `cursor` \| `opencode` | | `REVIEWER_CLI` | `codex` \| `claude` \| `cursor` \| `opencode` \| `pi` |
| `REVIEWER_MODEL` | Model name | | `REVIEWER_MODEL` | Model name |
| `MAX_ROUNDS` | Default 10 | | `MAX_ROUNDS` | Default 10 |
| `SESSION_ID_VAR` | `CODEX_PLAN_SESSION_ID` \| `CODEX_IMPL_SESSION_ID` \| `CURSOR_PLAN_SESSION_ID` \| `CURSOR_IMPL_SESSION_ID` \| `OPENCODE_PLAN_SESSION_ID` \| `OPENCODE_IMPL_SESSION_ID` | | `SESSION_ID_VAR` | `CODEX_PLAN_SESSION_ID` \| `CODEX_IMPL_SESSION_ID` \| `CURSOR_PLAN_SESSION_ID` \| `CURSOR_IMPL_SESSION_ID` \| `OPENCODE_PLAN_SESSION_ID` \| `OPENCODE_IMPL_SESSION_ID` |
@@ -455,6 +468,18 @@ Write the reviewer invocation to `/tmp/do-task-${REVIEW_KIND}-review-${REVIEW_ID
set -euo pipefail set -euo pipefail
``` ```
**If `REVIEWER_CLI` is `pi`:**
Fresh call every round (Pi reviewer calls do not use session resume):
```bash
pi --no-session --no-skills --no-prompt-templates --no-extensions --no-context-files \
--model "$REVIEWER_MODEL" \
--tools read,grep,find,ls \
-p "Read the file /tmp/do-task-${REVIEW_KIND}-${REVIEW_ID}.md and review. Return exactly the required ## Summary, ## Findings, and ## Verdict structure."
```
**If `REVIEWER_CLI` is `codex`:** **If `REVIEWER_CLI` is `codex`:**
Round 1 — fresh `codex exec`: Round 1 — fresh `codex exec`:
@@ -651,7 +676,7 @@ After the command completes:
cp /tmp/do-task-${REVIEW_KIND}-review-${REVIEW_ID}.runner.out \ cp /tmp/do-task-${REVIEW_KIND}-review-${REVIEW_ID}.runner.out \
/tmp/do-task-${REVIEW_KIND}-review-${REVIEW_ID}.md /tmp/do-task-${REVIEW_KIND}-review-${REVIEW_ID}.md
``` ```
- `claude`: promote `.runner.out` into the `.md` file: - `claude` or `pi`: promote `.runner.out` into the `.md` file:
```bash ```bash
cp /tmp/do-task-${REVIEW_KIND}-review-${REVIEW_ID}.runner.out \ cp /tmp/do-task-${REVIEW_KIND}-review-${REVIEW_ID}.runner.out \
/tmp/do-task-${REVIEW_KIND}-review-${REVIEW_ID}.md /tmp/do-task-${REVIEW_KIND}-review-${REVIEW_ID}.md
@@ -9,7 +9,7 @@
| Created | YYYY-MM-DD | | Created | YYYY-MM-DD |
| Slug | YYYY-MM-DD-<slug> | | Slug | YYYY-MM-DD-<slug> |
| Runtime | opencode | | Runtime | opencode |
| Reviewer CLI | codex \| claude \| cursor \| opencode | | Reviewer CLI | codex \| claude \| cursor \| opencode \| pi |
| Reviewer Model | <model> | | Reviewer Model | <model> |
| MAX_ROUNDS | 10 | | MAX_ROUNDS | 10 |
| Branch Strategy | current-branch \| worktree | | Branch Strategy | current-branch \| worktree |
+8
View File
@@ -103,6 +103,14 @@ Reviewer CLI: `codex`, `claude`, `cursor`, `opencode`, `pi`, or `skip`
Store `REVIEWER_CLI`, `REVIEWER_MODEL`, and `MAX_ROUNDS`. Store `REVIEWER_CLI`, `REVIEWER_MODEL`, and `MAX_ROUNDS`.
If `REVIEWER_CLI=pi`, verify the Pi reviewer binary before entering the review loop:
```bash
pi --version
```
For shorthand `pi/<pi-model-name>`, split only on the first slash when the prefix is exactly `pi`; store the complete remainder in `REVIEWER_MODEL`. Examples: `pi/claude-opus-4-7` -> `claude-opus-4-7`, `pi/anthropic/claude-opus-4-7` -> `anthropic/claude-opus-4-7`, and `pi/openrouter/anthropic/claude-opus-4-7` -> `openrouter/anthropic/claude-opus-4-7`.
When `REVIEWER_CLI=pi`, the reviewer model is configured independently from the pi model running this workflow. Use any configured pi model string, including provider-qualified model IDs. If the reviewer model or provider is unavailable, surface the review helper stderr/status and ask for a configured model; use `pi --list-models [search]` to inspect configured models. When `REVIEWER_CLI=pi`, the reviewer model is configured independently from the pi model running this workflow. Use any configured pi model string, including provider-qualified model IDs. If the reviewer model or provider is unavailable, surface the review helper stderr/status and ask for a configured model; use `pi --list-models [search]` to inspect configured models.
The pi reviewer command rendered into `/tmp/do-task-${REVIEW_KIND}-review-${REVIEW_ID}.sh` must be isolated and read-only: The pi reviewer command rendered into `/tmp/do-task-${REVIEW_KIND}-review-${REVIEW_ID}.sh` must be isolated and read-only:
+38 -1
View File
@@ -61,6 +61,19 @@ If the user has already specified a reviewer CLI and model (e.g., "implement the
Store `REVIEWER_CLI`, `REVIEWER_MODEL`, and `MAX_ROUNDS`. These values are fixed for the entire run. Store `REVIEWER_CLI`, `REVIEWER_MODEL`, and `MAX_ROUNDS`. These values are fixed for the entire run.
Reviewer CLI: `codex`, `claude`, `cursor`, `opencode`, `pi`, or `skip`.
If `REVIEWER_CLI=pi`, verify the Pi reviewer binary before entering the review loop:
```bash
pi --version
```
For shorthand `pi/<pi-model-name>`, split only on the first slash when the prefix is exactly `pi`; store the complete remainder in `REVIEWER_MODEL`. Examples: `pi/claude-opus-4-7` -> `claude-opus-4-7`, `pi/anthropic/claude-opus-4-7` -> `anthropic/claude-opus-4-7`, and `pi/openrouter/anthropic/claude-opus-4-7` -> `openrouter/anthropic/claude-opus-4-7`.
When `REVIEWER_CLI=pi`, the reviewer model is configured independently from the model running this workflow. If the model/provider is unavailable, surface helper stderr/status and use `pi --list-models [search]` to inspect configured models.
### Phase 3: Set Up Worktree (REQUIRED SUB-SKILL) ### Phase 3: Set Up Worktree (REQUIRED SUB-SKILL)
Invoke `superpowers:using-git-worktrees` explicitly. Invoke `superpowers:using-git-worktrees` explicitly.
@@ -235,6 +248,18 @@ Write the reviewer invocation to `/tmp/milestone-review-${REVIEW_ID}.sh` as a ba
set -euo pipefail set -euo pipefail
``` ```
**If `REVIEWER_CLI` is `pi`:**
Fresh call every round (Pi reviewer calls do not use session resume):
```bash
pi --no-session --no-skills --no-prompt-templates --no-extensions --no-context-files \
--model "$REVIEWER_MODEL" \
--tools read,grep,find,ls \
-p "Read the file /tmp/milestone-${REVIEW_ID}.md and review. Return exactly the required ## Summary, ## Findings, and ## Verdict structure."
```
**If `REVIEWER_CLI` is `codex`:** **If `REVIEWER_CLI` is `codex`:**
```bash ```bash
@@ -372,7 +397,7 @@ jq -r '.result' /tmp/milestone-review-${REVIEW_ID}.json > /tmp/milestone-review-
``` ```
- If `REVIEWER_CLI=codex`, extract `CODEX_SESSION_ID` from `/tmp/milestone-review-${REVIEW_ID}.runner.out` after the helper or fallback run. If the review text is only in `.runner.out`, move or copy the actual review body into `/tmp/milestone-review-${REVIEW_ID}.md` before verdict parsing. - If `REVIEWER_CLI=codex`, extract `CODEX_SESSION_ID` from `/tmp/milestone-review-${REVIEW_ID}.runner.out` after the helper or fallback run. If the review text is only in `.runner.out`, move or copy the actual review body into `/tmp/milestone-review-${REVIEW_ID}.md` before verdict parsing.
- If `REVIEWER_CLI=claude`, promote stdout captured by the helper or fallback runner into the markdown review file: - If `REVIEWER_CLI=claude` or `REVIEWER_CLI=pi`, promote stdout captured by the helper or fallback runner into the markdown review file:
```bash ```bash
cp /tmp/milestone-review-${REVIEW_ID}.runner.out /tmp/milestone-review-${REVIEW_ID}.md cp /tmp/milestone-review-${REVIEW_ID}.runner.out /tmp/milestone-review-${REVIEW_ID}.md
@@ -424,6 +449,18 @@ If a revision contradicts the user's explicit requirements, skip it and note it
Rewrite `/tmp/milestone-review-${REVIEW_ID}.sh` for the next round. The script should contain the reviewer invocation only; do not run it directly. Rewrite `/tmp/milestone-review-${REVIEW_ID}.sh` for the next round. The script should contain the reviewer invocation only; do not run it directly.
**If `REVIEWER_CLI` is `pi`:**
Fresh call with prior-round context (Pi reviewer calls do not use session resume):
```bash
pi --no-session --no-skills --no-prompt-templates --no-extensions --no-context-files \
--model "$REVIEWER_MODEL" \
--tools read,grep,find,ls \
-p "You previously reviewed this milestone and requested revisions. Read the updated payload at /tmp/milestone-${REVIEW_ID}.md and re-review using the same ## Summary, ## Findings, and ## Verdict structure."
```
**If `REVIEWER_CLI` is `codex`:** **If `REVIEWER_CLI` is `codex`:**
Resume the existing session: Resume the existing session:
+38 -1
View File
@@ -94,6 +94,19 @@ If the user has already specified a reviewer CLI and model (e.g., "implement the
Store `REVIEWER_CLI`, `REVIEWER_MODEL`, and `MAX_ROUNDS`. These values are fixed for the entire run. Store `REVIEWER_CLI`, `REVIEWER_MODEL`, and `MAX_ROUNDS`. These values are fixed for the entire run.
Reviewer CLI: `codex`, `claude`, `cursor`, `opencode`, `pi`, or `skip`.
If `REVIEWER_CLI=pi`, verify the Pi reviewer binary before entering the review loop:
```bash
pi --version
```
For shorthand `pi/<pi-model-name>`, split only on the first slash when the prefix is exactly `pi`; store the complete remainder in `REVIEWER_MODEL`. Examples: `pi/claude-opus-4-7` -> `claude-opus-4-7`, `pi/anthropic/claude-opus-4-7` -> `anthropic/claude-opus-4-7`, and `pi/openrouter/anthropic/claude-opus-4-7` -> `openrouter/anthropic/claude-opus-4-7`.
When `REVIEWER_CLI=pi`, the reviewer model is configured independently from the model running this workflow. If the model/provider is unavailable, surface helper stderr/status and use `pi --list-models [search]` to inspect configured models.
### Phase 3: Set Up Worktree (REQUIRED SUB-SKILL) ### Phase 3: Set Up Worktree (REQUIRED SUB-SKILL)
Invoke `superpowers:using-git-worktrees`. Invoke `superpowers:using-git-worktrees`.
@@ -268,6 +281,18 @@ Write the reviewer invocation to `/tmp/milestone-review-${REVIEW_ID}.sh` as a ba
set -euo pipefail set -euo pipefail
``` ```
**If `REVIEWER_CLI` is `pi`:**
Fresh call every round (Pi reviewer calls do not use session resume):
```bash
pi --no-session --no-skills --no-prompt-templates --no-extensions --no-context-files \
--model "$REVIEWER_MODEL" \
--tools read,grep,find,ls \
-p "Read the file /tmp/milestone-${REVIEW_ID}.md and review. Return exactly the required ## Summary, ## Findings, and ## Verdict structure."
```
**If `REVIEWER_CLI` is `codex`:** **If `REVIEWER_CLI` is `codex`:**
```bash ```bash
@@ -405,7 +430,7 @@ jq -r '.result' /tmp/milestone-review-${REVIEW_ID}.json > /tmp/milestone-review-
``` ```
- If `REVIEWER_CLI=codex`, extract `CODEX_SESSION_ID` from `/tmp/milestone-review-${REVIEW_ID}.runner.out` after the helper or fallback run. If the review text is only in `.runner.out`, move or copy the actual review body into `/tmp/milestone-review-${REVIEW_ID}.md` before verdict parsing. - If `REVIEWER_CLI=codex`, extract `CODEX_SESSION_ID` from `/tmp/milestone-review-${REVIEW_ID}.runner.out` after the helper or fallback run. If the review text is only in `.runner.out`, move or copy the actual review body into `/tmp/milestone-review-${REVIEW_ID}.md` before verdict parsing.
- If `REVIEWER_CLI=claude`, promote stdout captured by the helper or fallback runner into the markdown review file: - If `REVIEWER_CLI=claude` or `REVIEWER_CLI=pi`, promote stdout captured by the helper or fallback runner into the markdown review file:
```bash ```bash
cp /tmp/milestone-review-${REVIEW_ID}.runner.out /tmp/milestone-review-${REVIEW_ID}.md cp /tmp/milestone-review-${REVIEW_ID}.runner.out /tmp/milestone-review-${REVIEW_ID}.md
@@ -457,6 +482,18 @@ If a revision contradicts the user's explicit requirements, skip it and note it
Rewrite `/tmp/milestone-review-${REVIEW_ID}.sh` for the next round. The script should contain the reviewer invocation only; do not run it directly. Rewrite `/tmp/milestone-review-${REVIEW_ID}.sh` for the next round. The script should contain the reviewer invocation only; do not run it directly.
**If `REVIEWER_CLI` is `pi`:**
Fresh call with prior-round context (Pi reviewer calls do not use session resume):
```bash
pi --no-session --no-skills --no-prompt-templates --no-extensions --no-context-files \
--model "$REVIEWER_MODEL" \
--tools read,grep,find,ls \
-p "You previously reviewed this milestone and requested revisions. Read the updated payload at /tmp/milestone-${REVIEW_ID}.md and re-review using the same ## Summary, ## Findings, and ## Verdict structure."
```
**If `REVIEWER_CLI` is `codex`:** **If `REVIEWER_CLI` is `codex`:**
Resume the existing session: Resume the existing session:
+38 -1
View File
@@ -94,6 +94,19 @@ If the user has already specified a reviewer CLI and model (e.g., "implement the
Store `REVIEWER_CLI`, `REVIEWER_MODEL`, and `MAX_ROUNDS`. These values are fixed for the entire run. Store `REVIEWER_CLI`, `REVIEWER_MODEL`, and `MAX_ROUNDS`. These values are fixed for the entire run.
Reviewer CLI: `codex`, `claude`, `cursor`, `opencode`, `pi`, or `skip`.
If `REVIEWER_CLI=pi`, verify the Pi reviewer binary before entering the review loop:
```bash
pi --version
```
For shorthand `pi/<pi-model-name>`, split only on the first slash when the prefix is exactly `pi`; store the complete remainder in `REVIEWER_MODEL`. Examples: `pi/claude-opus-4-7` -> `claude-opus-4-7`, `pi/anthropic/claude-opus-4-7` -> `anthropic/claude-opus-4-7`, and `pi/openrouter/anthropic/claude-opus-4-7` -> `openrouter/anthropic/claude-opus-4-7`.
When `REVIEWER_CLI=pi`, the reviewer model is configured independently from the model running this workflow. If the model/provider is unavailable, surface helper stderr/status and use `pi --list-models [search]` to inspect configured models.
### Phase 3: Set Up Worktree (REQUIRED SUB-SKILL) ### Phase 3: Set Up Worktree (REQUIRED SUB-SKILL)
Invoke `superpowers:using-git-worktrees`. Invoke `superpowers:using-git-worktrees`.
@@ -272,6 +285,18 @@ Write the reviewer invocation to `/tmp/milestone-review-${REVIEW_ID}.sh` as a ba
set -euo pipefail set -euo pipefail
``` ```
**If `REVIEWER_CLI` is `pi`:**
Fresh call every round (Pi reviewer calls do not use session resume):
```bash
pi --no-session --no-skills --no-prompt-templates --no-extensions --no-context-files \
--model "$REVIEWER_MODEL" \
--tools read,grep,find,ls \
-p "Read the file /tmp/milestone-${REVIEW_ID}.md and review. Return exactly the required ## Summary, ## Findings, and ## Verdict structure."
```
**If `REVIEWER_CLI` is `codex`:** **If `REVIEWER_CLI` is `codex`:**
```bash ```bash
@@ -415,7 +440,7 @@ jq -r '.result' /tmp/milestone-review-${REVIEW_ID}.json > /tmp/milestone-review-
``` ```
- If `REVIEWER_CLI=codex`, extract `CODEX_SESSION_ID` from `/tmp/milestone-review-${REVIEW_ID}.runner.out` after the helper or fallback run. If the review text is only in `.runner.out`, move or copy the actual review body into `/tmp/milestone-review-${REVIEW_ID}.md` before verdict parsing. - If `REVIEWER_CLI=codex`, extract `CODEX_SESSION_ID` from `/tmp/milestone-review-${REVIEW_ID}.runner.out` after the helper or fallback run. If the review text is only in `.runner.out`, move or copy the actual review body into `/tmp/milestone-review-${REVIEW_ID}.md` before verdict parsing.
- If `REVIEWER_CLI=claude`, promote stdout captured by the helper or fallback runner into the markdown review file: - If `REVIEWER_CLI=claude` or `REVIEWER_CLI=pi`, promote stdout captured by the helper or fallback runner into the markdown review file:
```bash ```bash
cp /tmp/milestone-review-${REVIEW_ID}.runner.out /tmp/milestone-review-${REVIEW_ID}.md cp /tmp/milestone-review-${REVIEW_ID}.runner.out /tmp/milestone-review-${REVIEW_ID}.md
@@ -467,6 +492,18 @@ If a revision contradicts the user's explicit requirements, skip it and note it
Rewrite `/tmp/milestone-review-${REVIEW_ID}.sh` for the next round. The script should contain the reviewer invocation only; do not run it directly. Rewrite `/tmp/milestone-review-${REVIEW_ID}.sh` for the next round. The script should contain the reviewer invocation only; do not run it directly.
**If `REVIEWER_CLI` is `pi`:**
Fresh call with prior-round context (Pi reviewer calls do not use session resume):
```bash
pi --no-session --no-skills --no-prompt-templates --no-extensions --no-context-files \
--model "$REVIEWER_MODEL" \
--tools read,grep,find,ls \
-p "You previously reviewed this milestone and requested revisions. Read the updated payload at /tmp/milestone-${REVIEW_ID}.md and re-review using the same ## Summary, ## Findings, and ## Verdict structure."
```
**If `REVIEWER_CLI` is `codex`:** **If `REVIEWER_CLI` is `codex`:**
Resume the existing session: Resume the existing session:
+38 -1
View File
@@ -76,6 +76,19 @@ If the user has already specified a reviewer CLI and model (e.g., "implement the
Store `REVIEWER_CLI`, `REVIEWER_MODEL`, and `MAX_ROUNDS`. These values are fixed for the entire run. Store `REVIEWER_CLI`, `REVIEWER_MODEL`, and `MAX_ROUNDS`. These values are fixed for the entire run.
Reviewer CLI: `codex`, `claude`, `cursor`, `opencode`, `pi`, or `skip`.
If `REVIEWER_CLI=pi`, verify the Pi reviewer binary before entering the review loop:
```bash
pi --version
```
For shorthand `pi/<pi-model-name>`, split only on the first slash when the prefix is exactly `pi`; store the complete remainder in `REVIEWER_MODEL`. Examples: `pi/claude-opus-4-7` -> `claude-opus-4-7`, `pi/anthropic/claude-opus-4-7` -> `anthropic/claude-opus-4-7`, and `pi/openrouter/anthropic/claude-opus-4-7` -> `openrouter/anthropic/claude-opus-4-7`.
When `REVIEWER_CLI=pi`, the reviewer model is configured independently from the model running this workflow. If the model/provider is unavailable, surface helper stderr/status and use `pi --list-models [search]` to inspect configured models.
### Phase 4: Set Up Worktree (REQUIRED SUB-SKILL) ### Phase 4: Set Up Worktree (REQUIRED SUB-SKILL)
Use OpenCode's native skill tool to load: Use OpenCode's native skill tool to load:
@@ -253,6 +266,18 @@ Write the reviewer invocation to `/tmp/milestone-review-${REVIEW_ID}.sh` as a ba
set -euo pipefail set -euo pipefail
``` ```
**If `REVIEWER_CLI` is `pi`:**
Fresh call every round (Pi reviewer calls do not use session resume):
```bash
pi --no-session --no-skills --no-prompt-templates --no-extensions --no-context-files \
--model "$REVIEWER_MODEL" \
--tools read,grep,find,ls \
-p "Read the file /tmp/milestone-${REVIEW_ID}.md and review. Return exactly the required ## Summary, ## Findings, and ## Verdict structure."
```
**If `REVIEWER_CLI` is `codex`:** **If `REVIEWER_CLI` is `codex`:**
```bash ```bash
@@ -390,7 +415,7 @@ jq -r '.result' /tmp/milestone-review-${REVIEW_ID}.json > /tmp/milestone-review-
``` ```
- If `REVIEWER_CLI=codex`, extract `CODEX_SESSION_ID` from `/tmp/milestone-review-${REVIEW_ID}.runner.out` after the helper or fallback run. If the review text is only in `.runner.out`, move or copy the actual review body into `/tmp/milestone-review-${REVIEW_ID}.md` before verdict parsing. - If `REVIEWER_CLI=codex`, extract `CODEX_SESSION_ID` from `/tmp/milestone-review-${REVIEW_ID}.runner.out` after the helper or fallback run. If the review text is only in `.runner.out`, move or copy the actual review body into `/tmp/milestone-review-${REVIEW_ID}.md` before verdict parsing.
- If `REVIEWER_CLI=claude`, promote stdout captured by the helper or fallback runner into the markdown review file: - If `REVIEWER_CLI=claude` or `REVIEWER_CLI=pi`, promote stdout captured by the helper or fallback runner into the markdown review file:
```bash ```bash
cp /tmp/milestone-review-${REVIEW_ID}.runner.out /tmp/milestone-review-${REVIEW_ID}.md cp /tmp/milestone-review-${REVIEW_ID}.runner.out /tmp/milestone-review-${REVIEW_ID}.md
@@ -442,6 +467,18 @@ If a revision contradicts the user's explicit requirements, skip it and note it
Rewrite `/tmp/milestone-review-${REVIEW_ID}.sh` for the next round. The script should contain the reviewer invocation only; do not run it directly. Rewrite `/tmp/milestone-review-${REVIEW_ID}.sh` for the next round. The script should contain the reviewer invocation only; do not run it directly.
**If `REVIEWER_CLI` is `pi`:**
Fresh call with prior-round context (Pi reviewer calls do not use session resume):
```bash
pi --no-session --no-skills --no-prompt-templates --no-extensions --no-context-files \
--model "$REVIEWER_MODEL" \
--tools read,grep,find,ls \
-p "You previously reviewed this milestone and requested revisions. Read the updated payload at /tmp/milestone-${REVIEW_ID}.md and re-review using the same ## Summary, ## Findings, and ## Verdict structure."
```
**If `REVIEWER_CLI` is `codex`:** **If `REVIEWER_CLI` is `codex`:**
Resume the existing session: Resume the existing session:
+8
View File
@@ -86,6 +86,14 @@ Reviewer CLI: `codex`, `claude`, `cursor`, `opencode`, `pi`, or `skip`
Store `REVIEWER_CLI`, `REVIEWER_MODEL`, and `MAX_ROUNDS`. Store `REVIEWER_CLI`, `REVIEWER_MODEL`, and `MAX_ROUNDS`.
If `REVIEWER_CLI=pi`, verify the Pi reviewer binary before entering the review loop:
```bash
pi --version
```
For shorthand `pi/<pi-model-name>`, split only on the first slash when the prefix is exactly `pi`; store the complete remainder in `REVIEWER_MODEL`. Examples: `pi/claude-opus-4-7` -> `claude-opus-4-7`, `pi/anthropic/claude-opus-4-7` -> `anthropic/claude-opus-4-7`, and `pi/openrouter/anthropic/claude-opus-4-7` -> `openrouter/anthropic/claude-opus-4-7`.
When `REVIEWER_CLI=pi`, the reviewer model is configured independently from the pi model running this workflow. Use any configured pi model string, including provider-qualified model IDs. If the reviewer model or provider is unavailable, surface the review helper stderr/status and ask for a configured model; use `pi --list-models [search]` to inspect configured models. When `REVIEWER_CLI=pi`, the reviewer model is configured independently from the pi model running this workflow. Use any configured pi model string, including provider-qualified model IDs. If the reviewer model or provider is unavailable, surface the review helper stderr/status and ask for a configured model; use `pi --list-models [search]` to inspect configured models.
The pi reviewer command rendered into `/tmp/milestone-review-${REVIEW_ID}.sh` must be isolated and read-only: The pi reviewer command rendered into `/tmp/milestone-review-${REVIEW_ID}.sh` must be isolated and read-only: