{
  "markdown": "<div align=\"center\">\n  <picture>\n    <source media=\"(prefers-color-scheme: dark)\" srcset=\"https://raw.githubusercontent.com/freibergergarcia/phone-a-friend/main/assets/logo-dark.svg\">\n    <source media=\"(prefers-color-scheme: light)\" srcset=\"https://raw.githubusercontent.com/freibergergarcia/phone-a-friend/main/assets/logo-light.svg\">\n    <img alt=\"phone-a-friend\" src=\"https://raw.githubusercontent.com/freibergergarcia/phone-a-friend/main/assets/logo-dark.svg\" width=\"480\">\n  </picture>\n\n  <p><em>When your AI needs a second opinion.</em></p>\n\n  [![npm](https://img.shields.io/npm/v/%40freibergergarcia%2Fphone-a-friend)](https://www.npmjs.com/package/@freibergergarcia/phone-a-friend)\n  [![CI](https://github.com/freibergergarcia/phone-a-friend/actions/workflows/ci.yml/badge.svg)](https://github.com/freibergergarcia/phone-a-friend/actions/workflows/ci.yml)\n  [![License](https://img.shields.io/badge/license-Apache--2.0-blue)](LICENSE)\n  ![Node.js 22.13+](https://img.shields.io/badge/node-%E2%89%A522.13-green)\n\n</div>\n\n`phone-a-friend` is a CLI orchestration layer for AI coding agents.\nRelay tasks to any backend, spin up multi-model teams, or run persistent multi-agent sessions.\n\n| Mode | What it does | Best for |\n|------|-------------|----------|\n| **Relay** | One-shot delegation to Antigravity, Codex, Gemini, Ollama, Claude, or OpenCode | Quick second opinions, code reviews, analysis |\n| **Team** | Iterative multi-backend refinement over N rounds | Collaborative review, converging on a solution |\n| **Agentic** | Persistent multi-agent sessions with @mention routing | Autonomous collaboration, adversarial review, deep analysis |\n\n### Host parity\n\n| Feature | Claude Code | OpenCode | Codex |\n|---|:---:|:---:|:---:|\n| `/phone-a-friend` (single + parallel multi-backend relay) | ✓ | ✓ | ✓ |\n| `/curiosity-engine` (Q&A rally) | ✓ | ✓ | ✓ |\n| `/phone-a-team` (iterative multi-model team) | ✓ | — | ✓ |\n| Plugin marketplace install | ✓ | — | ✓ |\n| CLI plugin install (`phone-a-friend plugin install --<host>`) | ✓ | ✓ | ✓ |\n| Skill auto-discovery | ✓ | ✓ | ✓ |\n| Recursion guard (`PHONE_A_FRIEND_HOST=<host>`) | n/a | ✓ | ✓ |\n\nClaude `/phone-a-team` orchestrates rounds via the Agent Teams primitive (TeamCreate + Task + SendMessage). Codex `/phone-a-team` is pure Bash orchestration directly from the skill body, with Codex's own model handling the synthesis between rounds. OpenCode has no comparable primitive and replicates `/phone-a-team` by running repeated `/phone-a-friend` calls manually.\n\n> [!IMPORTANT]\n> **Codex users:** Codex's default `workspace-write` sandbox blocks subprocess access to the macOS Keychain (where Claude stores OAuth tokens) and OAuth refresh network paths (Gemini and Antigravity). With the default sandbox, relays to Claude fail with a misleading `Not logged in` and Google CLI relays can hang until the timeout. Two workarounds today, both with tradeoffs:\n>\n> **Option A — Lower the sandbox.** Per-session (preferred): launch Codex with `codex --sandbox danger-full-access`. Persistent (convenient but removes sandbox protections from every Codex session, not just PaF relays): add an alias to `~/.zshrc` or `~/.bashrc`:\n> ```bash\n> alias codex='codex --sandbox danger-full-access'\n> ```\n>\n> **Option B — Use API keys for API-key backends.** Skips OAuth entirely for Claude/Gemini CLI, works in any sandbox:\n> ```bash\n> export ANTHROPIC_API_KEY=...\n> export GEMINI_API_KEY=...\n> ```\n>\n> A portable-auth path via `claude setup-token` is planned for the Claude side. Antigravity uses `agy` subscription auth, so the current Antigravity-safe path from Codex is Option A or running PaF from a regular terminal.\n\n## Quick Start\n\n**Prerequisites:** Node.js 22.13+ and at least one backend:\n\n- [Claude Code](https://docs.anthropic.com/en/docs/claude-code/setup)\n- [Google Antigravity CLI](https://antigravity.google/) (`agy`) for Google AI Pro/Ultra or consumer Google accounts\n- [Codex CLI](https://developers.openai.com/codex/quickstart/)\n- [Gemini CLI](https://github.com/google-gemini/gemini-cli) for API key, Vertex AI, or enterprise Gemini Code Assist flows\n- [Ollama](https://ollama.com/download)\n- [OpenCode](https://opencode.ai/docs)\n\n**Install:**\n\n```bash\nnpm install -g @freibergergarcia/phone-a-friend\nphone-a-friend    # first run shows a guided menu — choose Setup\n```\n\nThe setup wizard detects your backends, offers to install detected host integrations, and verifies everything works.\n\n**Claude Code marketplace (commands and skills only):**\n\n```\n/plugin marketplace add freibergergarcia/phone-a-friend\n/plugin install phone-a-friend@phone-a-friend-marketplace\n```\n\nTo update: `/plugin marketplace update phone-a-friend-marketplace` then `/plugin update phone-a-friend@phone-a-friend-marketplace`.\n\n> [!NOTE]\n> Marketplace install ships only the slash commands and skills. For the full CLI (agentic mode and TUI), install via `npm install -g @freibergergarcia/phone-a-friend`.\n\n**OpenCode commands and skills:**\n\nIf you use [OpenCode](https://opencode.ai/docs), install the same Phone-a-Friend skills plus thin slash-command shims into your OpenCode config:\n\n```bash\nphone-a-friend plugin install --opencode\n```\n\nThis installs to `~/.config/opencode/skills/` and `~/.config/opencode/commands/` (or `$XDG_CONFIG_HOME/opencode/...`). From OpenCode, ask naturally, for example:\n\n```\nAsk Codex through phone-a-friend for a short sanity review of this repo; do not edit files.\n```\n\n**Codex plugin (skills + marketplace registration):**\n\nIf you use [Codex CLI](https://developers.openai.com/codex/quickstart/), install the Phone-a-Friend plugin two ways:\n\nVia the Codex marketplace (visible in `/plugins` like Claude):\n\n```\ncodex plugin marketplace add freibergergarcia/phone-a-friend\ncodex plugin add phone-a-friend@phone-a-friend-marketplace\n```\n\nOr via the PaF CLI (does both the marketplace registration AND drops skills into `~/.codex/`):\n\n```bash\nphone-a-friend plugin install --codex\n```\n\nThis installs `phone-a-friend`, `curiosity-engine`, and `phone-a-team` skills into `$CODEX_HOME/skills/` (defaulting to `~/.codex/skills/`). All three are orchestrated through pure Bash from the skill bodies — no Codex subagent primitive is required.\n\n> [!NOTE]\n> Unlike Claude's marketplace, Codex marketplace install ships the skills directly — `codex plugin marketplace add` + `codex plugin add` is sufficient to use `/phone-a-friend`, `/curiosity-engine`, and `/phone-a-team` from inside Codex. For the full CLI (TUI and agentic mode), install via `npm install -g @freibergergarcia/phone-a-friend`. Running `phone-a-friend plugin install --codex` after the npm install additionally drops loose-file skills under `~/.codex/skills/` as a no-marketplace fallback.\n\nFrom Codex, ask naturally:\n\n```\nAsk Claude and Gemini through phone-a-friend what they think of this code.\n\nUse phone-a-team across Claude and Gemini to converge on a fix for this auth bug. Three rounds max.\n```\n\n**From source:**\n\n```bash\ngit clone https://github.com/freibergergarcia/phone-a-friend.git\ncd phone-a-friend\nnpm install && npm run build\n./dist/index.js   # first run guides you through setup\n```\n\nThen from Claude Code or OpenCode, just talk naturally — the host integration loads the skills automatically:\n\n```\nAsk Gemini to review the error handling in relay.ts\n\nSpin up Codex and Gemini to review the docs.\nThen spin another agent to review their reviews and report back.\n\nBuild a team with Claude and Ollama. Have them review the website copy,\nloop through 3 rounds, and converge on final suggestions.\n```\n\nNo slash commands needed once the host integration is installed (see [Host parity](#host-parity) for which slash commands work in which host).\n\n> [!TIP]\n> **Claude Code power-user setup:** Run in [**tmux**](https://formulae.brew.sh/formula/tmux) with [**bypass permissions**](https://docs.anthropic.com/en/docs/claude-code/security) (`⏵⏵`) and [**Agent Teams**](https://docs.anthropic.com/en/docs/claude-code/agent-teams) to watch agents work in parallel split panes. Pair with **phone-a-friend agentic mode** for fully autonomous sessions.\n\n## CLI Usage\n\n### Relay\n\nDelegate a task to any backend and get the result back:\n\n```bash\nphone-a-friend --to codex --prompt \"Review this code\"\nphone-a-friend --to antigravity --prompt \"Review this code\" --sandbox read-only\nphone-a-friend --to gemini --prompt \"Analyze the architecture\"\nphone-a-friend --to claude --prompt \"Refactor this module\"\nphone-a-friend --to ollama --prompt \"Explain this function\"\nphone-a-friend --to opencode --prompt \"Audit this repo\" --model qwen3-coder  # Local agentic (OpenCode + Ollama)\nphone-a-friend --to claude --prompt \"Review this code\" --stream   # Stream tokens live\nphone-a-friend --to codex --prompt \"Audit the auth module\" --quiet # Run silently, save result\nphone-a-friend --to opencode --prompt \"Explain this\" --fast        # Skip OpenCode plugins (faster)\nphone-a-friend --to codex --prompt \"Review my fix\" --include-diff   # Append `git diff HEAD` to the prompt\nphone-a-friend --to codex --prompt \"Quick question\" --no-include-diff  # Override defaults.include_diff = true\nphone-a-friend --to claude --prompt \"Coordinate with the migration session\" --peer-messaging accept\n```\n\n### Structured output\n\nRequest JSON responses matching a schema:\n\n```bash\nphone-a-friend --to codex --prompt \"List files that need refactoring\" \\\n  --schema '{\"type\":\"object\",\"properties\":{\"files\":{\"type\":\"array\",\"items\":{\"type\":\"string\"}}},\"required\":[\"files\"],\"additionalProperties\":false}'\n```\n\nClaude, Codex, and Ollama enforce the schema through their native structured-output surfaces. Antigravity, Gemini, and OpenCode CLI use prompt injection (best-effort), with PaF validating built-in verdict envelopes before returning them.\n\n### Sessions\n\nResume previous relay conversations for multi-turn workflows:\n\n```bash\nphone-a-friend --to codex --prompt \"Review the auth module\" --session auth-review\n# Later, continue the conversation:\nphone-a-friend --to codex --prompt \"Now fix those issues\" --session auth-review\n```\n\nSessions work reliably with Claude, Codex, Gemini, and OpenCode. Ollama replays history (may hit token limits on long conversations). Antigravity is one-shot only in this release, so `--session` is rejected for `--to antigravity`.\n\n### Claude peer messaging\n\nOn supported macOS and Linux setups, Claude Code 2.1.224+ can list and message\nother live Claude Code sessions on the same machine. PaF exposes that\ncapability deliberately for Claude relays:\n\n```bash\n# Use Claude's native inbound policy while allowing peer discovery/messages (default)\nphone-a-friend --to claude --prompt \"Ask the payments session for its status\" \\\n  --peer-messaging native --session payments-coordinator\n\n# Deliver peer messages to the unattended PaF worker immediately\nphone-a-friend --to claude --prompt \"Coordinate the migration\" \\\n  --peer-messaging accept --session migration-coordinator\n\n# Isolate this relay from peer messaging in both directions\nphone-a-friend --to claude --prompt \"Review privately\" --peer-messaging refuse\n```\n\n`native` is the default: PaF makes `ListAgents` and `SendMessage` available but\nleaves inbound delivery to Claude Code's own permission-mode rules. `accept`\nsets `crossSessionInbound` to `accept`, which is the autonomy-first choice for\nunattended workers. `refuse` rejects inbound messages and removes the peer\ntools. Peer-visible workers are named from the PaF session label, such as\n`paf-migration-coordinator`; one-shot relays use `paf-relay`.\n\nSet your preferred mode once:\n\n```bash\nphone-a-friend config set backends.claude.peer_messaging accept\n```\n\n### Job tracking\n\nThe `--quiet` flag saves the result to a local job store for later retrieval:\n\n```bash\nphone-a-friend --to codex --prompt \"Review this\" --quiet   # Returns job ID immediately\nphone-a-friend job status                                    # List all jobs\nphone-a-friend job result <id>                               # Show stored output\nphone-a-friend job cancel <id>                               # Cancel a pending/running job\n```\n\n### Review\n\nContext-aware code reviews collect an explicit Git scope so you don't have to paste code:\n\n```bash\nphone-a-friend --to claude --review                           # Committed branch changes (default)\nphone-a-friend --to codex --review --review-scope working-tree # Staged, unstaged, and untracked\nphone-a-friend --to opencode --review --review-scope all       # Branch plus working-tree changes\nphone-a-friend --to codex --review --base develop              # Use a specific comparison branch\n```\n\n| `--review-scope` | Included changes |\n|---|---|\n| `branch` (default) | Committed changes from the merge base with `--base` through `HEAD` |\n| `working-tree` | Staged, unstaged, and non-ignored untracked files relative to `HEAD` |\n| `all` | Branch changes plus staged, unstaged, and non-ignored untracked files |\n\nPass a repository root, linked Git worktree, or any directory inside one through\n`--repo <path>`; review mode normalizes it to the containing worktree root before\ncollecting changes. Before the first commit, `working-tree` and `all` compare\npending files against Git's empty tree. PaF collects and bounds the selected\nscope before any native or generic backend call, so the normal diff size limit\nalways applies. When PaF supplies a generic diff, untracked binary files use a\nbinary-change marker instead of raw bytes.\n\nIf the selected scope is clean, PaF does not invoke a backend. Plain review\nreturns `No changes found for review scope \"<scope>\".`; `--verdict-json` returns\na valid `abstain` envelope with no findings. Native review is used only when the\nbackend supports the selected non-empty scope; otherwise PaF supplies the\ndeterministic diff through the generic path.\n\n`--include-diff` remains available for normal prompt mode. It cannot be combined with review mode; select `working-tree` or `all` instead. To override a `defaults.include_diff = true` config setting on a normal relay, use `--no-include-diff` (or set `PHONE_A_FRIEND_INCLUDE_DIFF=false` in the environment for older binaries).\n\n> [!TIP]\n> Don't paste code into `--prompt` just to review it — the backend can read the repo directly via `--repo \"$PWD\"` (default: current working directory). Pasting risks leaking uncommitted edits and burns tokens for content the backend can fetch itself.\n\n### Agentic\n\nSpawn multiple agents that collaborate via @mentions (see [Agentic Mode](#agentic-mode) below):\n\n```bash\nphone-a-friend agentic run --agents reviewer:claude,critic:claude --prompt \"Review this code\"\nphone-a-friend agentic logs               # View past sessions\nphone-a-friend agentic replay --session <id>  # Replay transcript\n```\n\n### Ops\n\n```bash\nphone-a-friend                 # Interactive TUI dashboard (TTY only)\nphone-a-friend setup           # Guided setup wizard\nphone-a-friend doctor          # Health check all backends + host install status\nphone-a-friend plugin install --claude    # Install Claude Code plugin\nphone-a-friend plugin install --opencode  # Install OpenCode commands and skills\nphone-a-friend plugin install --codex     # Install Codex skills\nphone-a-friend config show     # Show resolved config\nphone-a-friend config edit     # Open in $EDITOR\n```\n\n`doctor` reports CLI backends, local backends (Ollama), host integration status (Claude / OpenCode / Codex plugin install state), and a summary count. Antigravity and OpenCode CLI are treated as optional: if you don't have `agy` or OpenCode installed, doctor will show them but will not flag that as a degraded state.\n\n### Update notifications\n\nphone-a-friend checks the npm registry for newer stable releases at most once\nevery 24 hours and prints a one-time stderr banner the next time it runs in an\ninteractive terminal. The current invocation is never slowed down: the registry\nfetch happens in the background, with results applied on the next run.\n\nSample banner:\n\n```\n  ↑ phone-a-friend X.Y.Z available (current: A.B.C)\n    Run: npm install -g @freibergergarcia/phone-a-friend@latest\n```\n\nThe banner is suppressed automatically when:\n- stdout or stderr is not a TTY (piped or redirected output)\n- `CI` is set, or `TERM=dumb`\n- the command uses `--quiet`, `--schema`, `--verdict-json`, or any subcommand-level `--json` flag\n- the same version was already shown within the last 7 days\n\nTo disable update checks entirely:\n\n```bash\n# One-off\nPHONE_A_FRIEND_UPDATE_CHECK=false phone-a-friend ...\n\n# Permanent\nphone-a-friend config set defaults.update_check false\n```\n\nThe cache lives at `~/.config/phone-a-friend/update-check.json` (or under\n`$XDG_CONFIG_HOME` if set). Run `phone-a-friend doctor` to inspect the current\nstate.\n\n## Backends\n\n| Backend | Type | Streaming |\n|---------|------|-----------|\n| **Antigravity** | CLI subprocess (`agy`) | No |\n| **Codex** | CLI subprocess | No |\n| **Gemini** | CLI subprocess | No |\n| **Ollama** | HTTP API | Yes (NDJSON) |\n| **Claude** | CLI subprocess | Yes (JSON) |\n| **OpenCode** | CLI subprocess | Yes (NDJSON) |\n\nOllama configuration via environment variables:\n- `OLLAMA_HOST` -- custom host (default: `http://localhost:11434`)\n- `OLLAMA_MODEL` -- default model (overridden by `--model` flag)\n\nClaude configuration via TOML:\n\n```toml\n[backends.claude]\npeer_messaging = \"native\" # native (default), accept, or refuse\n```\n\nPhone-a-friend environment variables:\n- `PHONE_A_FRIEND_INCLUDE_DIFF=false` -- disable diff inclusion globally (equivalent to `--no-include-diff` on every call).\n- `PHONE_A_FRIEND_CLAUDE_PEER_MESSAGING=native|accept|refuse` -- override Claude peer messaging for the current process.\n- `PHONE_A_FRIEND_HOST=opencode|codex` -- mark the calling process as a specific host for the recursion guard. `opencode` blocks `--to opencode`; `codex` blocks `--to codex`. Set automatically by the install shims.\n- `CODEX_HOME` -- override the Codex config root (default: `~/.codex`). Honored by the Codex skill installer.\n- `PHONE_A_FRIEND_GEMINI_DEAD_CACHE=false` -- bypass the Gemini dead-model cache (debugging stale entries).\n\nAntigravity notes:\n- PaF backend name: `antigravity`; executable: `agy`.\n- Antigravity is read-only only for now. Plain `--to antigravity` calls resolve\n  to `read-only`; explicit write sandboxes such as `--sandbox workspace-write`\n  are rejected.\n- `--session` and `--backend-session` are not supported yet.\n- If Gemini CLI says individual Google sign-in is no longer supported, use `--to antigravity` for the Google subscription path or use Gemini CLI with an API key/Vertex flow.\n\nOpenCode configuration via TOML:\n```toml\n[backends.opencode]\nprovider = \"ollama\"     # model prefix (default: \"ollama\")\nmodel = \"qwen3-coder\"   # default model\npure = false             # skip OpenCode plugins (maps to --fast)\n```\n\n## Streaming\n\nBackends that support streaming deliver tokens as they arrive via `--stream`:\n\n```bash\nphone-a-friend --to claude --prompt \"Review this code\" --stream\n```\n\nStreaming is enabled by default in the config (`defaults.stream = true`). Disable with `--no-stream` or `config set defaults.stream false`.\n\n## Agentic Mode\n\n> Let one agent review while another critiques — catching bugs, inconsistencies, and blind spots before you even see the code.\n\nAgentic mode spawns multiple Claude agents that communicate via `@mentions` within a shared session. An orchestrator routes messages between agents, enforces guardrails, and persists the transcript for logs, replay, and TUI browsing.\n\nEach agent accumulates context through persistent CLI sessions — later responses build on earlier ones, so agents develop genuine understanding of the problem as the session progresses.\n\n> [!IMPORTANT]\n> **Agentic mode currently supports Claude agents only.** Codex, Gemini, OpenCode, and Ollama agents are not yet wired into the orchestrator. If you need multi-host adversarial review today, use `/phone-a-team` instead — it does parallel multi-backend rounds with the same iterate-or-ship pattern, just without the persistent session graph. See [AGENTS.md](AGENTS.md) for the agentic architecture.\n\n```bash\n# Start an agentic session\nphone-a-friend agentic run \\\n  --agents reviewer:claude,critic:claude \\\n  --prompt \"Review the auth module\"\n\n# View past sessions and replay transcripts\nphone-a-friend agentic logs\nphone-a-friend agentic replay --session <id>\n```\n\n**What you get:**\n\n- **Persistent sessions** -- agents accumulate context across turns via UUID-based session resumption\n- **@mention routing** -- agents address each other by name (`@ada.reviewer:`), broadcast with `@all`, or surface findings with `@user`\n- **Guardrails** -- max turns (20), ping-pong detection, session timeout (15 min), turn budget warnings\n- **Full audit trail** -- SQLite-backed transcript persistence for replay, logs, and post-session analysis\n- **Creative agent naming** -- agents get memorable human names so you can follow the conversation\n\n## Documentation\n\nFull usage guide, examples, CLI reference, and configuration details:\n\n**[freibergergarcia.github.io/phone-a-friend](https://freibergergarcia.github.io/phone-a-friend/)**\n\n## Uninstall\n\n**npm install:**\n\n```bash\nnpm uninstall -g @freibergergarcia/phone-a-friend\n```\n\nAutomatically removes the Claude Code plugin (CLI-installed), OpenCode commands and skills, Codex skills, and the `~/.config/phone-a-friend` directory (config, sessions, jobs).\n\n> [!WARNING]\n> `npm uninstall -g` deletes `~/.config/phone-a-friend` entirely, including persisted session labels, the background job store, and agentic transcripts. Back up anything you want to keep before uninstalling. The agentic SQLite database at `~/.config/phone-a-friend/agentic.db` and any local config in `~/.config/phone-a-friend/config.toml` are wiped along with it.\n\n**Claude Code marketplace:**\n\n```\n/plugin uninstall phone-a-friend@phone-a-friend-marketplace\n/plugin marketplace remove phone-a-friend-marketplace\n```\n\n## Contributing\n\nAll changes go through pull requests -- no direct pushes to `main`.\n\n1. **Branch off main** using a recognized prefix (see table below)\n2. **Open a PR** against `main` -- a version label is auto-applied from the branch name\n3. **CI must pass** before merge (includes label check)\n4. PRs are **squash-merged** (one commit per change, clean linear history)\n5. Head branches are auto-deleted after merge\n6. On merge, version is **auto-bumped** based on the label\n\n**Branch prefixes:**\n\n| Prefix | Label |\n|--------|-------|\n| `fix/`, `bugfix/` | `patch` |\n| `chore/`, `docs/`, `ci/`, `refactor/` | `patch` |\n| `feat/`, `feature/` | `minor` |\n| `breaking/` | `major` |\n\nUnrecognized prefixes require adding `patch`, `minor`, or `major` manually.\n\n## Development\n\n```bash\nnpm install              # Install dependencies\nnpm run build            # Build dist/ (tsup)\nnpm test                 # Run tests (vitest)\nnpm run typecheck        # Type check (tsc --noEmit)\n```\n\n## Privacy\n\nPhone a Friend does not collect, transmit, or store any data on servers operated by this project. There is no telemetry and no analytics.\n\nPrompts and repository context are passed only to backends you have installed and authenticated yourself: the Claude, Codex, Gemini, Antigravity, and OpenCode CLIs, or a local Ollama instance. Each backend is governed by its own provider's privacy policy and terms.\n\nLocal state (config, sessions, jobs, and agentic transcripts) is written only to `~/.config/phone-a-friend/` on your machine.\n\n## License\n\nApache-2.0. See [`LICENSE`](LICENSE) and [`NOTICE`](NOTICE).\n",
  "bytes": 23462,
  "sha": "571f2f53691d6a65599500af761b75a30696bed243236bfaf93eb6276bb27116",
  "repo_slug": "freibergergarcia/phone-a-friend",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/plg_freibergergarcia_phone_a_friend_phone_a__d01b277e/readme"
}