@freibergergarcia/phone-a-friend 2.2.1 → 2.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +10 -1
- package/commands/curiosity-engine.md +18 -13
- package/commands/phone-a-friend.md +42 -38
- package/commands/phone-a-team.md +30 -38
- package/dist/index.js +478 -150
- package/package.json +1 -1
- package/skills/curiosity-engine/COMMAND.opencode.md +1 -1
- package/skills/curiosity-engine/SKILL.md +18 -13
- package/skills/phone-a-friend/COMMAND.opencode.md +1 -1
- package/skills/phone-a-friend/SKILL.md +42 -38
package/README.md
CHANGED
|
@@ -116,7 +116,7 @@ Delegate a task to any backend and get the result back:
|
|
|
116
116
|
|
|
117
117
|
```bash
|
|
118
118
|
phone-a-friend --to codex --prompt "Review this code"
|
|
119
|
-
phone-a-friend --to gemini --prompt "Analyze the architecture"
|
|
119
|
+
phone-a-friend --to gemini --prompt "Analyze the architecture"
|
|
120
120
|
phone-a-friend --to claude --prompt "Refactor this module"
|
|
121
121
|
phone-a-friend --to ollama --prompt "Explain this function"
|
|
122
122
|
phone-a-friend --to opencode --prompt "Audit this repo" --model qwen3-coder # Local agentic (OpenCode + Ollama)
|
|
@@ -218,6 +218,7 @@ Ollama configuration via environment variables:
|
|
|
218
218
|
Phone-a-friend environment variables:
|
|
219
219
|
- `PHONE_A_FRIEND_INCLUDE_DIFF=false` -- disable diff inclusion globally (equivalent to `--no-include-diff` on every call).
|
|
220
220
|
- `PHONE_A_FRIEND_HOST=opencode` -- mark the calling process as OpenCode for the recursion guard (set automatically by the OpenCode shims).
|
|
221
|
+
- `PHONE_A_FRIEND_GEMINI_DEAD_CACHE=false` -- bypass the Gemini dead-model cache (debugging stale entries).
|
|
221
222
|
|
|
222
223
|
OpenCode configuration via TOML:
|
|
223
224
|
```toml
|
|
@@ -325,6 +326,14 @@ npm test # Run tests (vitest)
|
|
|
325
326
|
npm run typecheck # Type check (tsc --noEmit)
|
|
326
327
|
```
|
|
327
328
|
|
|
329
|
+
## Privacy
|
|
330
|
+
|
|
331
|
+
Phone a Friend does not collect, transmit, or store any data on servers operated by this project. There is no telemetry and no analytics.
|
|
332
|
+
|
|
333
|
+
Prompts and repository context are passed only to backends you have installed and authenticated yourself: the Claude, Codex, Gemini, and OpenCode CLIs, or a local Ollama instance. Each backend is governed by its own provider's privacy policy and terms.
|
|
334
|
+
|
|
335
|
+
Local state (config, sessions, jobs, agentic transcripts, and the web dashboard event log) is written only to `~/.config/phone-a-friend/` on your machine. The web dashboard is served on `localhost` and is not exposed to the network.
|
|
336
|
+
|
|
328
337
|
## License
|
|
329
338
|
|
|
330
339
|
Apache-2.0. See [`LICENSE`](LICENSE) and [`NOTICE`](NOTICE).
|
|
@@ -351,28 +351,33 @@ Present the full session summary:
|
|
|
351
351
|
<2-3 questions raised during the rally that weren't followed up on, worth exploring in a future session>
|
|
352
352
|
```
|
|
353
353
|
|
|
354
|
-
## Gemini
|
|
354
|
+
## Gemini model selection
|
|
355
355
|
|
|
356
|
-
|
|
356
|
+
For BACKEND=gemini, **omit `--model` by default** and let Gemini CLI's
|
|
357
|
+
auto-routing pick. Set `--model` only when reproducibility, specific
|
|
358
|
+
capability, or debugging requires a pin.
|
|
357
359
|
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
360
|
+
**Binary mode** (preferred — when a pinned model returns a strong 404
|
|
361
|
+
`ModelNotFoundError`, PaF caches it for 24h at
|
|
362
|
+
`~/.config/phone-a-friend/gemini-models.json` and surfaces a clear error
|
|
363
|
+
with cache path, expiry, and bypass instructions; no auto-substitution):
|
|
361
364
|
|
|
362
|
-
When BACKEND=gemini, the relay command must include `--model`:
|
|
363
|
-
|
|
364
|
-
**Binary mode:**
|
|
365
365
|
```bash
|
|
366
|
-
phone-a-friend --to gemini --
|
|
366
|
+
phone-a-friend --to gemini --repo "$PWD" --sandbox read-only --fast $PAF_NO_DIFF --prompt "<relay-prompt>"
|
|
367
367
|
```
|
|
368
368
|
|
|
369
|
-
|
|
369
|
+
To bypass the cache: `PHONE_A_FRIEND_GEMINI_DEAD_CACHE=false`. Or delete the
|
|
370
|
+
cache file to clear it.
|
|
371
|
+
|
|
372
|
+
**Direct mode** (no PaF wrapper — orchestrator handles retry):
|
|
370
373
|
```bash
|
|
371
|
-
gemini --sandbox --yolo --include-directories "$PWD" --output-format text
|
|
374
|
+
gemini --sandbox --yolo --include-directories "$PWD" --output-format text --prompt "<relay-prompt>"
|
|
372
375
|
```
|
|
373
376
|
|
|
374
|
-
|
|
375
|
-
|
|
377
|
+
In direct mode, on capacity/transient errors (429, 500, 503), retry with a
|
|
378
|
+
different model before treating as round failure. On `ModelNotFoundError`,
|
|
379
|
+
surface immediately. Either omit `--model` entirely or pass a concrete
|
|
380
|
+
model name; do NOT use aliases like `auto`, `pro`, or `flash`.
|
|
376
381
|
|
|
377
382
|
## Constraints
|
|
378
383
|
|
|
@@ -169,9 +169,9 @@ I'm working on this task and got the above response. Please review it and return
|
|
|
169
169
|
**Binary mode** (`RELAY_MODE = binary`):
|
|
170
170
|
```bash
|
|
171
171
|
phone-a-friend --to codex --repo "$PWD" --prompt "<relay-prompt>" --context-text "<context-payload>" $PAF_NO_DIFF [--fast] [--session <id>]
|
|
172
|
-
# For gemini,
|
|
172
|
+
# For gemini, omit --model by default (let auto-routing pick); see "Gemini model selection" below.
|
|
173
173
|
# Do NOT pass --session to gemini — it will error (see "Session continuity" below):
|
|
174
|
-
phone-a-friend --to gemini --repo "$PWD" --prompt "<relay-prompt>" --context-text "<context-payload>"
|
|
174
|
+
phone-a-friend --to gemini --repo "$PWD" --prompt "<relay-prompt>" --context-text "<context-payload>" $PAF_NO_DIFF [--fast]
|
|
175
175
|
```
|
|
176
176
|
|
|
177
177
|
`$PAF_NO_DIFF` comes from the probe in "Diff suppression" above. It
|
|
@@ -186,8 +186,8 @@ I'm working on this task and got the above response. Please review it and return
|
|
|
186
186
|
```bash
|
|
187
187
|
# Codex:
|
|
188
188
|
codex exec -C "$PWD" --skip-git-repo-check --sandbox read-only "<combined-prompt>" < /dev/null
|
|
189
|
-
# Gemini (
|
|
190
|
-
gemini --sandbox --yolo --include-directories "$PWD" --output-format text
|
|
189
|
+
# Gemini (omit -m for auto-routing; pin only when reproducibility/capability is needed):
|
|
190
|
+
gemini --sandbox --yolo --include-directories "$PWD" --output-format text --prompt "<combined-prompt>"
|
|
191
191
|
```
|
|
192
192
|
|
|
193
193
|
In direct mode, build `<combined-prompt>` using the template from the
|
|
@@ -284,51 +284,55 @@ This is rarely the right move from inside a Claude Code conversation — the
|
|
|
284
284
|
common case is `--session <label>` with a fresh label. Only use
|
|
285
285
|
`--backend-session` when the user supplied a specific backend thread ID.
|
|
286
286
|
|
|
287
|
-
## Gemini
|
|
287
|
+
## Gemini model selection
|
|
288
288
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
289
|
+
By default, **omit `--model`** for `--to gemini` and let Gemini CLI's
|
|
290
|
+
auto-routing pick. This mirrors how `--to codex` and `--to claude` are used
|
|
291
|
+
in this command — the CLI's own default is the right default. Pinning
|
|
292
|
+
`--model` ages docs poorly; auto-routing tracks deployed models for you.
|
|
292
293
|
|
|
293
|
-
|
|
294
|
+
Set `--model` explicitly only when you need:
|
|
294
295
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
(`google-gemini/gemini-cli#13561`). By passing `--model` explicitly, we bypass
|
|
300
|
-
this broken behavior and handle retry/fallback ourselves.
|
|
296
|
+
- **Reproducibility** — pinning produces deterministic behavior across runs.
|
|
297
|
+
- **Capability** — a more capable model for a specific task (e.g.,
|
|
298
|
+
`--model gemini-2.5-pro` for a hard review, accepting more 429s).
|
|
299
|
+
- **Debugging** — isolating model behavior from auto-routing changes.
|
|
301
300
|
|
|
302
|
-
###
|
|
301
|
+
### Cache-aware failure for explicit pins
|
|
303
302
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
303
|
+
When you pin a model and it returns a strong 404 (`ModelNotFoundError`),
|
|
304
|
+
PaF caches it as unavailable for 24h at
|
|
305
|
+
`~/.config/phone-a-friend/gemini-models.json` and surfaces a clear error
|
|
306
|
+
that includes the cache path, expiry timestamp, and bypass instructions.
|
|
307
|
+
PaF does **not** auto-substitute another model — explicit pins surface
|
|
308
|
+
explicit failures so the caller decides whether to retry, switch model,
|
|
309
|
+
or omit `--model` and rely on auto-routing.
|
|
309
310
|
|
|
310
|
-
|
|
311
|
-
2. `gemini-2.5-pro` — higher capability but frequently at capacity (429)
|
|
312
|
-
3. `gemini-2.5-flash-lite` — last resort
|
|
313
|
-
4. `gemini-3.1-pro-preview-customtools` — not yet deployed (404 as of 2026-02-22)
|
|
314
|
-
5. `gemini-3.1-pro-preview` — not yet deployed (404 as of 2026-02-22)
|
|
311
|
+
What is and isn't cached:
|
|
315
312
|
|
|
316
|
-
|
|
313
|
+
- **Cached** (24h): strong 404 (`ModelNotFoundError` from gemini-cli's own classifier).
|
|
314
|
+
- **Not cached**: ambiguous 404s (could be a missing project / file, not the model), 429 / RESOURCE_EXHAUSTED, authentication failures, any other error class.
|
|
315
|
+
- **Not consulted**: when `--model` is unset (auto-routing), or during session resume (`--resume`).
|
|
317
316
|
|
|
318
|
-
|
|
319
|
-
capacity errors:
|
|
317
|
+
To bypass the cache (debugging stale entries, testing recovery):
|
|
320
318
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
319
|
+
```bash
|
|
320
|
+
PHONE_A_FRIEND_GEMINI_DEAD_CACHE=false phone-a-friend --to gemini --model X --prompt "..."
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
Or delete `~/.config/phone-a-friend/gemini-models.json` to clear it.
|
|
324
|
+
|
|
325
|
+
### Direct Gemini CLI mode
|
|
326
|
+
|
|
327
|
+
When the orchestrator is calling `gemini` directly (no PaF wrapper), the
|
|
328
|
+
dead-model cache does NOT apply — the orchestrator is responsible for any
|
|
329
|
+
retry. Retry rules in direct mode:
|
|
327
330
|
|
|
328
|
-
|
|
329
|
-
|
|
331
|
+
- **Retry**: HTTP 429, 499, 500, 503, 504; RESOURCE_EXHAUSTED; transient/timeout errors.
|
|
332
|
+
- **Do NOT retry**: authentication failures, invalid arguments, permission errors, model-not-found.
|
|
333
|
+
- **Default**: if an error cannot be confidently classified as transient, surface it immediately.
|
|
330
334
|
|
|
331
|
-
This does NOT apply to `--to codex`.
|
|
335
|
+
This does NOT apply to `--to codex` or `--to claude`.
|
|
332
336
|
|
|
333
337
|
## Notes
|
|
334
338
|
|
package/commands/phone-a-team.md
CHANGED
|
@@ -269,7 +269,7 @@ Resolution matrix:
|
|
|
269
269
|
| Friend backend | Include when |
|
|
270
270
|
|----------------|--------------|
|
|
271
271
|
| `codex` | `command -v codex` AND `codex --version` succeeds |
|
|
272
|
-
| `gemini` | `command -v gemini` succeeds (auth verified at first relay; transient errors handled by Gemini
|
|
272
|
+
| `gemini` | `command -v gemini` succeeds (auth verified at first relay; transient errors handled by Gemini auto-routing) |
|
|
273
273
|
| `ollama` | `curl -sf "${OLLAMA_HOST:-http://localhost:11434}/api/tags"` succeeds AND parsed `models[]` has at least one entry |
|
|
274
274
|
| `claude` | `command -v claude` AND `claude --version` succeeds. Claude is excluded by default when this skill is running inside Claude Code (we are already orchestrating with Claude). Include only when the user explicitly asked for Claude in addition |
|
|
275
275
|
| `opencode` | `command -v opencode` succeeds AND the host is NOT OpenCode (`PHONE_A_FRIEND_HOST=opencode` means we are inside OpenCode; relaying back to opencode is blocked by the recursion guard regardless) |
|
|
@@ -525,7 +525,7 @@ Delegate the task to the backend via the relay. The lead's job is to
|
|
|
525
525
|
"Direct call reference" section. If `--include-diff` is used, run
|
|
526
526
|
`git diff HEAD` and append the output to the template's "Git Diff" section.
|
|
527
527
|
|
|
528
|
-
For gemini,
|
|
528
|
+
For gemini, omit `--model` by default and let auto-routing pick (see "Gemini model selection" section).
|
|
529
529
|
For ollama, always include `--model` / model field using `OLLAMA_SELECTED_MODEL` from preflight.
|
|
530
530
|
- **Both backends**: Relay to each backend (in parallel if using teams,
|
|
531
531
|
sequentially otherwise). You may give them the same task or different
|
|
@@ -804,53 +804,45 @@ happened and whether the result is complete.
|
|
|
804
804
|
targets *unsolicited* repo-content dumps, not user-requested
|
|
805
805
|
diff-scoped reviews.
|
|
806
806
|
|
|
807
|
-
## Gemini
|
|
807
|
+
## Gemini model selection
|
|
808
808
|
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
809
|
+
For `--to gemini` (including the gemini side of `--backend both`), **omit
|
|
810
|
+
`--model` by default** and let Gemini CLI's auto-routing pick. This mirrors
|
|
811
|
+
how `--to codex` and `--to claude` are used in this command — the CLI's own
|
|
812
|
+
default is the right default.
|
|
812
813
|
|
|
813
|
-
|
|
814
|
+
Set `--model` explicitly only when reproducibility, specific capability, or
|
|
815
|
+
debugging requires a pin.
|
|
814
816
|
|
|
815
|
-
|
|
816
|
-
headless/non-interactive mode. `--yolo` (and `--approval-mode yolo`) only
|
|
817
|
-
auto-approve tool calls, not model switch prompts. When Gemini hits a capacity
|
|
818
|
-
error in headless mode, it tries to prompt for consent and fails
|
|
819
|
-
(`google-gemini/gemini-cli#13561`). By passing `--model` explicitly, we bypass
|
|
820
|
-
this broken behavior and handle retry/fallback ourselves.
|
|
817
|
+
### Cache-aware failure for explicit pins
|
|
821
818
|
|
|
822
|
-
|
|
819
|
+
PaF binary mode (`phone-a-friend --to gemini --model X`) caches strong 404s
|
|
820
|
+
(`ModelNotFoundError`) at `~/.config/phone-a-friend/gemini-models.json` for
|
|
821
|
+
24h and surfaces a clear error with the cache path, expiry, and bypass
|
|
822
|
+
instructions. PaF does **not** auto-substitute another model — explicit
|
|
823
|
+
pins surface explicit failures.
|
|
823
824
|
|
|
824
|
-
|
|
825
|
-
deployed) and `gemini-2.5-pro` is perpetually at capacity (429). Based on
|
|
826
|
-
empirical testing across 10+ relay sessions, `gemini-2.5-flash` is the only
|
|
827
|
-
model that reliably works. Lead with what works; fall forward to newer models
|
|
828
|
-
as they become available.
|
|
825
|
+
What is and isn't cached:
|
|
829
826
|
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
4. `gemini-3.1-pro-preview-customtools` — not yet deployed (404 as of 2026-02-22)
|
|
834
|
-
5. `gemini-3.1-pro-preview` — not yet deployed (404 as of 2026-02-22)
|
|
827
|
+
- **Cached** (24h): strong 404 (`ModelNotFoundError` from gemini-cli's own classifier).
|
|
828
|
+
- **Not cached**: ambiguous 404s, 429 / RESOURCE_EXHAUSTED, authentication failures, any other error class.
|
|
829
|
+
- **Not consulted**: when `--model` is unset (auto-routing), or during session resume.
|
|
835
830
|
|
|
836
|
-
|
|
831
|
+
To bypass the cache: `PHONE_A_FRIEND_GEMINI_DEAD_CACHE=false`. Or delete the
|
|
832
|
+
cache file to clear it.
|
|
837
833
|
|
|
838
|
-
|
|
839
|
-
capacity errors:
|
|
834
|
+
### Direct Gemini CLI mode
|
|
840
835
|
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
- **Do NOT retry**: authentication failures, invalid arguments, prompt errors,
|
|
844
|
-
permission errors
|
|
845
|
-
- **Default**: if an error cannot be confidently classified as transient, do
|
|
846
|
-
NOT model-fallback — treat as immediate round failure
|
|
836
|
+
When invoking `gemini` directly (no PaF wrapper), the dead-model cache does
|
|
837
|
+
NOT apply. Orchestrator-level retry rules:
|
|
847
838
|
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
839
|
+
- **Retry**: HTTP 429, 499, 500, 503, 504; RESOURCE_EXHAUSTED; transient/timeout.
|
|
840
|
+
- **Do NOT retry**: auth failures, invalid args, permission errors, model-not-found.
|
|
841
|
+
- **Default**: surface unclassified errors immediately, do not loop.
|
|
851
842
|
|
|
852
|
-
|
|
853
|
-
|
|
843
|
+
Round-level retry: each new round can attempt a different `--model` if the
|
|
844
|
+
prior round failed (see Step 7). When reporting errors in synthesis, list
|
|
845
|
+
the attempted models and each error.
|
|
854
846
|
|
|
855
847
|
This does NOT apply to `--to codex` or `--to ollama`.
|
|
856
848
|
|