Ask Antigravity, Codex, Gemini, Claude, OpenCode, pi, or Ollama for a second opinion through the phone-a-friend CLI while preserving the user's request in --prompt.
Installs into .claude/skills of the current project.
Are you the author of Phone A Friend?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/freibergergarcia-phone-a-friend)
---
name: phone-a-friend
description: Ask Antigravity, Codex, Gemini, Claude, OpenCode, pi, or Ollama for a second opinion through the phone-a-friend CLI while preserving the user's request in --prompt.
argument-hint: "[optional review focus]"
---
# /phone-a-friend
Use this skill after an assistant reply you want reviewed by another AI.
## Goal
Send compact task context + the latest assistant reply to a backend (Antigravity, Codex, Gemini, Claude, OpenCode, pi, or Ollama) using `phone-a-friend`, then bring the feedback back into the current conversation.
## Execution rules
- Preserve the user's actual request in `--prompt`. Do not drop it.
- Do not run a bare `phone-a-friend --to <backend> --review` unless the user
explicitly asks to review the current diff, branch changes, or staged changes.
- For code review, map the requested surface explicitly: `branch` for committed
branch changes, `working-tree` for staged/unstaged/untracked files, and `all`
when both are in scope.
- If the user asks for a repo sanity check, architecture opinion, plan critique,
or general second opinion, use normal prompt mode with `--repo "$PWD"`.
- If the user says not to edit files, keep that instruction in `--prompt`.
- From OpenCode, do not select `opencode` as the friend backend. Choose
`antigravity`, `codex`, `gemini`, `claude`, or `ollama`.
- From Codex, do not select `codex` as the friend backend. Choose `claude`,
`antigravity`, `gemini`, `opencode`, or `ollama`. PaF enforces this with the same
`PHONE_A_FRIEND_HOST` recursion guard used for OpenCode.
- From pi, do not select `pi` as the friend backend. Choose `claude`, `codex`,
`antigravity`, `gemini`, `opencode`, or `ollama`. PaF refuses `--to pi` from
inside pi on its own: pi marks every shell command it runs with
`PI_CODING_AGENT=true`, so no host prefix is needed.
- Suppress the working-tree diff by default (see "Diff suppression" below);
only include the diff when the user explicitly asked for a
diff/branch/staged review.
- One backend per call. Never pass comma-separated values to `--to` (e.g.
`phone-a-friend --to codex,gemini`). To consult multiple models, run
separate `phone-a-friend` calls. In Claude Code and Codex, `/phone-a-team`
orchestrates those calls using the host-specific skill. In OpenCode and pi, run
separate invocations yourself; `/phone-a-team` is not installed there.
- `curiosity-engine` is a host slash command / Agent Skill, not a PaF CLI
subcommand. Never run `phone-a-friend curiosity-engine`. Same shape rule
applies to any other slash command: never invoke them as PaF
subcommands (e.g. `phone-a-friend phone-a-team`).
- `--backend` is a `/phone-a-team` skill argument (Claude Code and Codex), not a PaF
CLI flag. Do not pass `--backend` to `phone-a-friend`.
- When running inside OpenCode, always prefix relay invocations with
`PHONE_A_FRIEND_HOST=opencode` (recursion guard) AND
`PHONE_A_FRIEND_INCLUDE_DIFF=false` (diff suppression that works on
every shipped binary version). Do NOT use the `$PAF_NO_DIFF`
probe-and-gate pattern from OpenCode — small host models skip the
probe and inline `--no-include-diff` literally, which fails on stale
CLIs. The probe-and-gate is reserved for the rich orchestrator path
(Claude Code / capable orchestrators).
- When running inside Codex, prefix relay invocations with
`PHONE_A_FRIEND_HOST=codex` (recursion guard). Codex ships modern
PaF binaries, so the `--no-include-diff` flag works directly; the
env-var fallback is also fine if you prefer symmetry with OpenCode.
- When running inside pi, prefix relay invocations with
`PHONE_A_FRIEND_INCLUDE_DIFF=false` (diff suppression, for the same
reason as OpenCode: a local host model tends to skip the probe). Run the
relay through pi's `bash` tool.
- When materializing relay commands, write dynamic prompt/context text into
temp files using single-quoted heredocs. Do not splice user text, prior
model output, or conversation context into double-quoted shell arguments.
- Do NOT dump repo files or git output into `--context-file` or
`--context-text`. Repo-aware backends read files via `--repo "$PWD"`
using their own tools. See "Context hygiene" below.
For example, from OpenCode:
```bash
PHONE_A_FRIEND_HOST=opencode PHONE_A_FRIEND_INCLUDE_DIFF=false \
phone-a-friend --to codex --repo "$PWD" \
--prompt "Give a short sanity review of this repo. Do not edit files." \
--timeout 300 --no-stream --fast
```
From pi:
```bash
PHONE_A_FRIEND_INCLUDE_DIFF=false \
phone-a-friend --to claude --repo "$PWD" \
--prompt "Give a short sanity review of this repo. Do not edit files." \
--timeout 300 --no-stream
```
## Inputs
- Review focus (optional): `$ARGUMENTS`
- In pi this skill runs as `/skill:phone-a-friend <focus>`. `$ARGUMENTS` is not substituted there: the focus is the user request that follows these instructions.
## Host awareness
PaF blocks accidental host recursion (e.g.
`OpenCode -> phone-a-friend --to opencode -> OpenCode`,
`Codex -> phone-a-friend --to codex -> Codex`) using the
`PHONE_A_FRIEND_HOST` environment marker.
When running from OpenCode, always set `PHONE_A_FRIEND_HOST=opencode` on
every relay invocation. From Codex, set `PHONE_A_FRIEND_HOST=codex`. The
install shims set the marker automatically; be explicit when constructing
commands by hand. From Claude Code, the marker is not needed.
When running from OpenCode, do not select `opencode` as the friend backend.
Choose `antigravity`, `codex`, `gemini`, `claude`, or `ollama`.
When running from Codex, do not select `codex` as the friend backend. Choose
`claude`, `antigravity`, `gemini`, `opencode`, or `ollama`.
When running from pi, no marker is needed: pi sets `PI_CODING_AGENT=true` for
the commands its `bash` tool runs, and PaF treats that as the pi host. Do not
select `pi` as the friend backend. Choose `claude`, `codex`, `antigravity`,
`gemini`, `opencode`, or `ollama`.
## Relay mode
```bash
command -v phone-a-friend
```
- If found: set `RELAY_MODE = binary`
- If not found: set `RELAY_MODE = direct`
No hard abort. The skill continues either way.
**Always resolve the binary via `command -v phone-a-friend`.** Never invoke `./phone-a-friend` from the current working directory, even when you are working inside the phone-a-friend repository itself. The repo's `./phone-a-friend` script is a development entry point that may be out of sync with the user's installed version, and assuming it exists will fail every time you are run from anywhere else. Capture the path once and reuse it:
```bash
RELAY_BIN="$(command -v phone-a-friend)"
# Then every relay invocation uses "$RELAY_BIN" ... — never plain "phone-a-friend"
# from PATH lookup and never "./phone-a-friend".
```
## Codex sandbox and installation diagnosis
When a relay fails with an authentication error or timeout, first run
`"$RELAY_BIN" doctor --json` and check the selected backend executable/version.
The host app, PATH-installed PaF, and a checkout build can use different installs.
Doctor reports configured models; it does not establish account/model access.
A Codex host's sandbox may restrict network or keychain access. Compare the same
backend command, executable, and auth profile in a regular terminal before
classifying the failure. A login error or timeout alone does not prove a sandbox
problem or invalidate the user's credentials.
Keep PaF's read-only default. If sandbox restrictions are confirmed, use the
host's authorized command escalation or a separately authorized terminal run.
`--full-auto` is not equivalent to `--sandbox danger-full-access`; do not suggest
it as a keychain/network bypass. Changing sandbox permissions and switching to
API-key billing are separate user decisions, not automatic remediation.
Report the failing executable, error category, and next diagnostic step. Redact
credential-like values from errors and stop automatic retries on auth failures.
### Direct call reference
When `RELAY_MODE = direct`, call backend CLIs directly instead of using the
`phone-a-friend` binary:
| Backend | Direct command |
|---------|---------------|
| **Antigravity** | `agy --add-dir "$PWD" --print-timeout 300s --sandbox --mode plan --prompt "$(cat "$PROMPT_FILE")"` |
| **Codex** | `codex exec -C "$PWD" --skip-git-repo-check --sandbox read-only "$(cat "$PROMPT_FILE")" < /dev/null` |
| **Gemini** | `gemini --sandbox --approval-mode plan --include-directories "$PWD" --output-format text -m <model> --prompt "$(cat "$PROMPT_FILE")"` |
Gemini's `--approval-mode plan` is Gemini Plan Mode, a best-effort read-only restriction: headless Gemini may exit Plan Mode and switch to YOLO. Use Antigravity when enforced read-only behavior is required.
pi has no direct-call row: reach it in binary mode only (`phone-a-friend --to pi`). A direct `pi` call would skip the read-only tool list, the session check, schema validation and the recursion guard.
In direct mode, build `PROMPT_FILE` from prompt + context using this
template and the quoted-heredoc rule:
```
You are helping another coding agent by reviewing or advising on work in a local repository.
Repository path: <repo-path>
Use the repository files for context when needed.
Respond with concise, actionable feedback.
Request:
<relay-prompt>
Additional Context:
<context-payload>
```
In direct mode, also verify the backend CLI is available (`command -v agy`,
`command -v codex`, or `command -v gemini`) before calling it. If not found,
tell the user how to install it and stop. If Gemini CLI reports that
individual Google sign-in is no longer supported, switch to
`phone-a-friend --to antigravity` in binary mode or use Gemini CLI with an
API key/Vertex flow.
Note: do NOT pass PaF flags like `--no-include-diff`, `--fast`, or
`--session` in direct mode. They are CLI flags on the `phone-a-friend`
binary; the underlying backend CLIs do not accept them.
## Context hygiene
Do not generate `--context-file` or `--context-text` from repository files,
`git show`, `git diff`, `git status`, or other local file/git output. Do
not create temp files just to pass repo content. For repo-aware backends
(antigravity, codex, gemini, claude, opencode, pi), pass `--repo "$PWD"` and let the
backend inspect files with its own tools.
`--context-file` and `--context-text` are reserved for **narrative
context that is not already in the repo** — for example: conversation
history that the backend cannot see, your own analysis, user constraints,
prior model output you want reviewed. These remain valid and useful.
Inlining repo content is wasteful, can leak tracked uncommitted edits or
committed secrets into the relay payload, and bypasses the backend's
normal file-access controls.
Backend exception: `ollama` has `localFileAccess: false` and cannot read
the repo on its own. For Ollama specifically, ask the user before sending
file content, and send a minimal excerpt rather than bulk-dumping files
or git output.
## Diff suppression
PaF reads `defaults.include_diff` from user config. If a user has
`include_diff = true` set, every relay would silently leak the working-tree
diff into the prompt. Suppress the diff explicitly on every binary-mode
relay.
The cleanest flag is `--no-include-diff`, added in phone-a-friend v2.2.0.
Older binaries reject the flag with `unknown option '--no-include-diff'`.
Probe once at the start of the workflow, then reuse the gate:
```bash
if phone-a-friend relay --help 2>/dev/null | grep -q -- '--no-include-diff'; then
PAF_NO_DIFF="--no-include-diff"
else
export PHONE_A_FRIEND_INCLUDE_DIFF=false
PAF_NO_DIFF=""
fi
```
Append `$PAF_NO_DIFF` to every binary-mode `phone-a-friend` invocation. The
env var fallback works in v1.7.2 and later; the explicit flag is preferred
when available.
When the user explicitly asks for code review, use `--review` and select
`--review-scope branch|working-tree|all` from the requested surface. Use
`--include-diff` only for a normal prompt-mode relay, never with review mode.
Probe `phone-a-friend relay --help` for `--review-scope` before the first such
call. On an older binary, a branch review may omit the scope flag. A
`working-tree` or `all` review requires the newer CLI; report the upgrade need
instead of silently falling back because legacy `--include-diff` omits
untracked files and cannot represent the combined scope.
Review mode normalizes `--repo` to the containing Git worktree root and supports
`working-tree`/`all` before the first commit. A clean selected scope never calls
the backend: plain mode returns `No changes found for review scope "<scope>".`,
while `--verdict-json` returns `abstain` with no findings. Treat that envelope as
"nothing to review", not as model uncertainty that should be retried.
## Workflow
1. Identify:
- The latest relevant user request.
- The most recent assistant reply to review.
2. Build relay prompt:
- If `$ARGUMENTS` is non-empty: `Review this response in context and provide your opinion. Focus: $ARGUMENTS`
- Otherwise: `Review this response in context and provide your opinion. Focus on correctness, risks, and missing assumptions.`
3. Build context payload:
```text
Task Context:
<latest relevant user request>
Assistant Response:
<latest assistant reply>
Review Request:
I'm working on this task and got the above response. Please review it and return:
1) Verdict: agree / partly agree / disagree
2) Corrections or risks
3) A revised concise answer
```
4. Run:
**Binary mode** (`RELAY_MODE = binary`):
```bash
RELAY_BIN="$(command -v phone-a-friend)"
PROMPT_FILE="$(mktemp)"
CONTEXT_FILE="$(mktemp)"
trap 'rm -f "$PROMPT_FILE" "$CONTEXT_FILE"' EXIT
cat > "$PROMPT_FILE" <<'PAF_PROMPT_EOF'
<relay-prompt>
PAF_PROMPT_EOF
cat > "$CONTEXT_FILE" <<'PAF_CONTEXT_EOF'
<context-payload>
PAF_CONTEXT_EOF
"$RELAY_BIN" --to codex --repo "$PWD" --prompt "$(cat "$PROMPT_FILE")" --context-file "$CONTEXT_FILE" $PAF_NO_DIFF [--fast] [--session <id>]
# Antigravity supports native session resume in read-only mode.
"$RELAY_BIN" --to antigravity --repo "$PWD" --sandbox read-only --prompt "$(cat "$PROMPT_FILE")" --context-file "$CONTEXT_FILE" $PAF_NO_DIFF [--fast] [--session <id>]
# For gemini, omit --model by default (let auto-routing pick); see "Gemini model selection" below.
# Gemini supports --session via native resume (see "Session continuity" below):
"$RELAY_BIN" --to gemini --repo "$PWD" --prompt "$(cat "$PROMPT_FILE")" --context-file "$CONTEXT_FILE" $PAF_NO_DIFF [--fast] [--session <id>]
# pi (local models): the provider comes from `[backends.pi] provider` in PaF config.
# Add --fast for small local models (skips AGENTS.md/CLAUDE.md and pi skills).
"$RELAY_BIN" --to pi --repo "$PWD" --prompt "$(cat "$PROMPT_FILE")" --context-file "$CONTEXT_FILE" $PAF_NO_DIFF [--fast] [--session <id>]
```
Use delimiter names that do not appear in the payload. The quoted heredoc
marker (`<<'PAF_PROMPT_EOF'`) is intentional: it makes shell treat the
body as data, not executable text.
`$PAF_NO_DIFF` comes from the probe in "Diff suppression" above. For code
review, use `--review --review-scope branch|working-tree|all` based on the
requested surface. Use `--include-diff` only for normal prompt mode.
See "Speed optimization" and "Session continuity" below for when to
include `--fast` and `--session`.
**Direct mode** (`RELAY_MODE = direct`):
```bash
# Antigravity:
agy --add-dir "$PWD" --print-timeout 300s --sandbox --mode plan --prompt "$(cat "$PROMPT_FILE")"
# Codex:
codex exec -C "$PWD" --skip-git-repo-check --sandbox read-only "$(cat "$PROMPT_FILE")" < /dev/null
# Gemini (omit -m for auto-routing; pin only when reproducibility/capability is needed):
gemini --sandbox --approval-mode plan --include-directories "$PWD" --output-format text --prompt "$(cat "$PROMPT_FILE")"
```
In direct mode, build `PROMPT_FILE` from the template in the "Direct call
reference" section using the same quoted-heredoc rule, substituting
`<relay-prompt>` and `<context-payload>` into the file body.
Note: `--fast`, `--session`, and `--no-include-diff` are PaF CLI flags
only available in binary mode. Do not append them to direct-mode
invocations of `agy`, `codex`, or `gemini`.
5. Return backend feedback in concise review format:
- Critical issues
- Important issues
- Suggested fixes
## Speed optimization
When building binary-mode relay commands, add `--fast` if ALL of these are true:
- The relay prompt is self-contained (all needed context is in `--prompt`
and/or `--context-text`)
- The task does NOT reference project conventions, coding standards, or
CLAUDE.md rules that the backend needs to read
- The task does NOT need MCP tools (GitHub API, Slack, database queries)
`--fast` maps to `--pure` for OpenCode 1.x, skipping external plugins; OpenCode
2.x has no `--pure`, so `--fast` has no effect there. It maps to
`-nc -ns` for pi (no AGENTS.md/CLAUDE.md context files, no pi skills), which
makes the prompt far smaller; that matters for small local models. It is a
no-op for Antigravity, Claude, Codex, Gemini, and Ollama. Claude intentionally does not
use `--bare` because bare mode skips OAuth/keychain reads and can break
subscription auth.
Most `/phone-a-friend` relay calls are self-contained reviews where the
context is already in the prompt. Default to including `--fast` when the
backend may be OpenCode or pi; it is a no-op elsewhere. With pi, leave it off
when the task depends on the project's AGENTS.md/CLAUDE.md.
## Claude cross-session messaging
When the backend is Claude and the user asks it to coordinate with another
live Claude Code session, report status across sessions, or work autonomously
with peer sessions, use PaF's peer-messaging mode:
```bash
phone-a-friend --to claude --repo "$PWD" \
--prompt "<prompt>" --peer-messaging accept --session <descriptive-label>
```
Modes:
- `native` (default): expose Claude's `ListAgents` and `SendMessage` tools and
defer inbound delivery to Claude Code's native permission-mode rules.
- `accept`: expose the peer tools and set `crossSessionInbound` to `accept` so
a non-interactive worker receives messages without an approval dialog.
- `refuse`: reject inbound messages and remove outbound peer tools.
Peer messaging is Claude-only and requires Claude Code 2.1.224+ on a supported
macOS or Linux setup. PaF fails clearly when `accept` is requested on an older
CLI; `native` degrades to the legacy isolated tool surface. Never pass
`--peer-messaging` to another backend. Prefer a descriptive `--session` label:
PaF exposes it as `paf-<label>` in `/list-agents`; one-shot relays appear as
`paf-relay`. If the user wants unattended peer collaboration routinely, point
them to the one-time setting:
```bash
phone-a-friend config set backends.claude.peer_messaging accept
```
## Multi-backend parallel
When the user asks more than one backend in the same request (e.g. "ask claude and gemini X", "what does codex and ollama think about Y"), run all relays **in parallel**, not sequentially. Sequential calls feel slow even when each one is fast, and a single hung backend should not block the others.
**Quick-question default**: for casual, conversational questions (favourite colour, one-line opinion, sanity check) use `--timeout 60`. The relay's default is 600s, which is correct for code review and bad for "what's your fav colour" — a hung backend can stall the whole interaction. For longer tasks (code review, refactor advice) the default 600s is right; do not lower it.
**Bash pattern** (use this exactly when you have two or more backends to query):
```bash
RELAY_BIN="$(command -v phone-a-friend)"
PROMPT_FILE="$(mktemp)"
trap 'rm -f "$PROMPT_FILE" "$OUT_DIR"/*; rmdir "$OUT_DIR" 2>/dev/null || true' EXIT
OUT_DIR="$(mktemp -d)"
cat > "$PROMPT_FILE" <<'PAF_PROMPT_EOF'
<relay-prompt>
PAF_PROMPT_EOF
# Fire each backend in the background, writing stdout to a per-backend file.
# Apply --no-include-diff for casual questions (no diff payload needed).
for BACKEND in claude gemini; do
PHONE_A_FRIEND_HOST=<your-host> PHONE_A_FRIEND_INCLUDE_DIFF=false \
"$RELAY_BIN" --to "$BACKEND" --repo "$PWD" \
--prompt "$(cat "$PROMPT_FILE")" \
--no-include-diff --timeout 60 --no-stream \
> "$OUT_DIR/$BACKEND.out" 2> "$OUT_DIR/$BACKEND.err" &
done
wait
```
After `wait` returns, every backend has either produced output or timed out at 60s. Read each `$OUT_DIR/<backend>.out` (or `.err` if the backend exited non-zero) and **present the results as a compact markdown table**:
```
| Backend | Answer |
|---|---|
| Claude | Blue. |
| Gemini | Electric cyan. |
```
If a backend failed or timed out, surface the error in the table cell so the user sees what happened ("(timed out after 60s)", "(not logged in)") rather than silently dropping that backend.
**Host-specific notes**:
- From Codex: set `PHONE_A_FRIEND_HOST=codex` on every backgrounded call.
- From OpenCode: same with `opencode`.
- From Claude: no host marker required, but the parallel-then-table pattern is the same.
- Never select `--to codex` from Codex or `--to opencode` from OpenCode (the recursion guard refuses).
When waiting on another local Claude session, the main conversation can use
`SendMessage` with `notify_when_idle` if both sessions support it (2.1.236+).
This is a one-shot notice, not proof of task completion; check the final result.
See [Claude peer notifications](https://code.claude.com/docs/en/cross-session-messaging#get-a-notice-when-another-session-goes-idle).
## Background reviews and task tracking
For every binary-mode review, or when checking progress, recovering a result, or changing retention, read [task tracking](references/task-tracking.md) before running the command. Claude Code reviews use its background reviewer workflow.
## Session continuity
For a follow-up, session label or supplied backend thread ID, read [session continuity](references/sessions.md) before constructing the relay. Omit `--session` for one-off requests.
## Antigravity vs Gemini CLI
When selecting Antigravity versus Gemini, pinning a Gemini model, or diagnosing a Gemini failure, read [Google backend guidance](references/google-backends.md). Omit `--model` by default and let the CLI route.
## Notes
- Prefer `--context-text` for small narrative payloads.
- `--context-file` and `--context-text` are mutually exclusive.
- If your narrative context is too large for inline args, write it to a
temp file outside the repo (e.g. under `/tmp`). Do NOT use a repo-local
temp file — it muddies git status and risks accidental commit. Repo
content itself does not need a temp file at all; see "Context hygiene"
above.