← All Skills

snappy-shell

v1.0.0
5 files, 42.4 KB ~1,708 words · 7 min read Updated 2026-09-09

snappy-shell skill

30 of 34 checks pass
What does not pass yet
$ npx snappy-skills install snappy-shell
zip ↓
Documents
AGENTS.md

snappy-shell — Fallback Runner#

The resilience lever. When Claude Code quota dies, Anthropic has an outage, or you simply want to run a snappy workflow on OpenAI or Gemini instead of Claude, snappy-shell boots pi with the full snappy kernel loaded as the system prompt — same skills, same conventions, different brain.

This is NOT the cheap-labor lever (snappy-dispatch is that — fire-and-return sub-agent calls for mechanical work). snappy-shell is a peer runner: an interactive or one-shot session that behaves like a Claude Code session, with the kernel, but talks to whichever provider you pick.

The two patterns, side by side#

snappy-dispatch snappy-shell
Purpose Fire-and-return grunt work from an orchestrator Full interactive session as a Claude Code substitute
Mode One-shot only, captured stdout REPL or one-shot
System prompt Pi default coding assistant Snappy kernel (always-inject skills + global CLAUDE.md)
Use when The orchestrator wants a task done Claude Code is unavailable or you want a second opinion from a different brain
Default model gemini (cheap) auto (OpenAI → OpenRouter → Anthropic, whichever has a key)

API#

typescriptimport { runShell, buildKernelPrompt } from "../snappy-shell/api.ts";

// One-shot
const r = await runShell({
  prompt: "Read ~/.claude/logs/dispatches.ndjson and summarize the last 10 runs.",
  model: "gpt-4o",                // default: "auto"
  tools: ["read", "bash", "grep"],
});

// Interactive (no prompt → REPL mode, inherits stdio)
await runShell({ model: "gemini-pro" });

Returns { ok, output, stderr, durationMs, provider, model, exitCode, kernelPromptBytes, error? }.

CLI#

bash# Interactive, auto-pick provider (OpenAI if key set, else OpenRouter)
snappy-shell

# Interactive on a specific model
snappy-shell --model gpt-4o
snappy-shell -m gemini-pro

# One-shot
snappy-shell -m gemini "count snappy-* skills under ~/.claude/skills"

# Inject an extra skill beyond always-inject
snappy-shell --skill snappy-inbox-sweep --model gpt-4o

# Or via npx if not yet symlinked
npx tsx ~/.claude/skills/snappy-shell/api.ts --model gpt-4o

Model aliases#

Alias Provider Model Notes
auto Default. Picks OpenAI → OpenRouter → Anthropic based on which key is in .env.cache.
gpt-4o openai gpt-4o Safe known-good OpenAI default.
gpt-5 openai gpt-5 Use if available on your account.
gpt-5.4 openai gpt-5.4 Use if available on your account.
gemini openrouter google/gemini-2.5-flash Cheap, fast.
gemini-pro openrouter google/gemini-2.5-pro Hard reasoning.
gemini-3 openrouter google/gemini-3-pro Latest if OpenRouter has it listed.
llama openrouter meta-llama/llama-3.3-70b-instruct OSS path.
qwen openrouter qwen/qwen-2.5-72b-instruct OSS alt.
deepseek openrouter deepseek/deepseek-chat Very cheap.
sonnet anthropic claude-sonnet-4-6 Only if ANTHROPIC_API_KEY is set in .env.cache (empty by default inside Claude Code).

Full provider/model-id strings also work (e.g. openai/gpt-4o-mini, openrouter/mistralai/mistral-large).

How the kernel gets loaded#

  1. Read ~/.claude/CLAUDE.md (global bootstrap).
  2. Read ~/.claude/hooks/always-inject.txt and concatenate every listed skill's AGENTS.md.
  3. Append extra skills from the --skill flag (repeatable).
  4. Append fallback reminders (MCP/subagent limits, credential location, api.ts preference, Robert reviews before posting).
  5. Write to a temp file and pass via pi --append-system-prompt <file>.
  6. pi is invoked with --no-skills --no-extensions --no-prompt-templates so the only source of truth is the kernel prompt we built.

The built kernel is typically 15–40 KB. Every provider in use supports that comfortably.

Portability caveats (from the 2026-04-13 audit)#

  • ~39/64 snappy-* skills are portable as-is — content, channels, clients, corpus, most of the day-to-day workflow surface.
  • ~25/64 have Claude-Code-specific dependencies — mostly mcp__* tool references (database, browse, analytics, pipeline) or subagent spawning. Those will fail on a fallback runner until reworked.
  • When snappy-shell encounters one of these, the kernel footer instructs the runner to fall back to calling api.ts directly or to bash equivalents, rather than MCP tools it doesn't have.

Logging and comparison#

Every shell run appends one ndjson line to ~/.claude/logs/agent-runs.ndjson:

json{"ts":"2026-04-13T...","runner":"snappy-shell","mode":"repl","provider":"openai","model":"gpt-4o","durationMs":42731,"ok":true,"kernelPromptBytes":28314,...}

snappy-dispatch writes into a separate log (~/.claude/logs/dispatches.ndjson) for now. Over time we'll unify or cross-query these to compare shell (full kernel) vs dispatch (minimal prompt) vs inline Claude Code orchestrator on the same task shapes.

Gotchas#

  • Credentials: needs at least one of OPENAI_API_KEY / OPENROUTER_API_KEY / ANTHROPIC_API_KEY in .env.cache. auto picks the first non-empty one.
  • Interactive mode inherits stdio: you'll see pi's TUI directly. Exit with Ctrl+D or whatever pi expects.
  • Temp prompt file: kernel prompt is written to $TMPDIR/snappy-shell-kernel-<pid>-<ts>.md every run. Short-lived; cleaned up by the OS.
  • Session persistence: pass --session ~/path/to/session.jsonl to resume later with pi --session <path> --continue or equivalent.
  • This is a fallback, not a replacement. Anything that depends on Claude Code's Agent/Task/WebFetch/mcp tools won't work here. Use the portable skills.

<!-- SKILL-INDEX-START -->

[snappy-shell Index]|root: ~/.claude/skills/snappy-shell|IMPORTANT: Prefer these files over pre-training assumptions for this domain. Read the relevant file when the AGENTS.md summary is insufficient.|root:{SKILL.md}

<!-- SKILL-INDEX-END -->

Used by#

Nothing in the collection names this skill.

<!-- SNAPPY-CONTRACT-VERBS-START -->

Contract verbs#

Generated from api.ts HAND_CONTRACT. Do not hand-edit this block.

This skill declares no executable verbs. Its instruction-only label is intentional.

Show the result#

When an answer carries face_hint, show it with one snappy_present(<answer>) call.

See /snappy-faces for face selection. Human-facing images must crop to the

element, render at 2x on Retina, and fill the destination channel instead of

placing a small card in a full-page screenshot.

<!-- SNAPPY-CONTRACT-VERBS-END -->

---
name: snappy-shell
role: Kernel-loaded fallback runner for when Claude Code is unavailable
loaded-by: preload-skill-context hook
---

# snappy-shell — Fallback Runner

**The resilience lever.** When Claude Code quota dies, Anthropic has an outage, or you simply want to run a snappy workflow on OpenAI or Gemini instead of Claude, `snappy-shell` boots `pi` with the full snappy kernel loaded as the system prompt — same skills, same conventions, different brain.

This is NOT the cheap-labor lever (`snappy-dispatch` is that — fire-and-return sub-agent calls for mechanical work). `snappy-shell` is a **peer runner**: an interactive or one-shot session that behaves like a Claude Code session, with the kernel, but talks to whichever provider you pick.

## The two patterns, side by side

| | `snappy-dispatch` | `snappy-shell` |
|---|---|---|
| Purpose | Fire-and-return grunt work from an orchestrator | Full interactive session as a Claude Code substitute |
| Mode | One-shot only, captured stdout | REPL or one-shot |
| System prompt | Pi default coding assistant | Snappy kernel (always-inject skills + global CLAUDE.md) |
| Use when | The orchestrator wants a task done | Claude Code is unavailable or you want a second opinion from a different brain |
| Default model | `gemini` (cheap) | `auto` (OpenAI → OpenRouter → Anthropic, whichever has a key) |

## API

```typescript
import { runShell, buildKernelPrompt } from "../snappy-shell/api.ts";

// One-shot
const r = await runShell({
  prompt: "Read ~/.claude/logs/dispatches.ndjson and summarize the last 10 runs.",
  model: "gpt-4o",                // default: "auto"
  tools: ["read", "bash", "grep"],
});

// Interactive (no prompt → REPL mode, inherits stdio)
await runShell({ model: "gemini-pro" });
```

Returns `{ ok, output, stderr, durationMs, provider, model, exitCode, kernelPromptBytes, error? }`.

## CLI

```bash
# Interactive, auto-pick provider (OpenAI if key set, else OpenRouter)
snappy-shell

# Interactive on a specific model
snappy-shell --model gpt-4o
snappy-shell -m gemini-pro

# One-shot
snappy-shell -m gemini "count snappy-* skills under ~/.claude/skills"

# Inject an extra skill beyond always-inject
snappy-shell --skill snappy-inbox-sweep --model gpt-4o

# Or via npx if not yet symlinked
npx tsx ~/.claude/skills/snappy-shell/api.ts --model gpt-4o
```

## Model aliases

| Alias       | Provider   | Model                                  | Notes |
|-------------|-----------|----------------------------------------|-------|
| `auto`      | —         | —                                      | **Default.** Picks OpenAI → OpenRouter → Anthropic based on which key is in `.env.cache`. |
| `gpt-4o`    | openai    | gpt-4o                                 | Safe known-good OpenAI default. |
| `gpt-5`     | openai    | gpt-5                                  | Use if available on your account. |
| `gpt-5.4`   | openai    | gpt-5.4                                | Use if available on your account. |
| `gemini`    | openrouter| google/gemini-2.5-flash                | Cheap, fast. |
| `gemini-pro`| openrouter| google/gemini-2.5-pro                  | Hard reasoning. |
| `gemini-3`  | openrouter| google/gemini-3-pro                    | Latest if OpenRouter has it listed. |
| `llama`     | openrouter| meta-llama/llama-3.3-70b-instruct      | OSS path. |
| `qwen`      | openrouter| qwen/qwen-2.5-72b-instruct             | OSS alt. |
| `deepseek`  | openrouter| deepseek/deepseek-chat                 | Very cheap. |
| `sonnet`    | anthropic | claude-sonnet-4-6                      | Only if `ANTHROPIC_API_KEY` is set in `.env.cache` (empty by default inside Claude Code). |

Full `provider/model-id` strings also work (e.g. `openai/gpt-4o-mini`, `openrouter/mistralai/mistral-large`).

## How the kernel gets loaded

1. Read `~/.claude/CLAUDE.md` (global bootstrap).
2. Read `~/.claude/hooks/always-inject.txt` and concatenate every listed skill's `AGENTS.md`.
3. Append extra skills from the `--skill` flag (repeatable).
4. Append fallback reminders (MCP/subagent limits, credential location, `api.ts` preference, Robert reviews before posting).
5. Write to a temp file and pass via `pi --append-system-prompt <file>`.
6. `pi` is invoked with `--no-skills --no-extensions --no-prompt-templates` so the only source of truth is the kernel prompt we built.

The built kernel is typically 15–40 KB. Every provider in use supports that comfortably.

## Portability caveats (from the 2026-04-13 audit)

- **~39/64 snappy-* skills are portable as-is** — content, channels, clients, corpus, most of the day-to-day workflow surface.
- **~25/64 have Claude-Code-specific dependencies** — mostly `mcp__*` tool references (database, browse, analytics, pipeline) or subagent spawning. Those will fail on a fallback runner until reworked.
- When `snappy-shell` encounters one of these, the kernel footer instructs the runner to fall back to calling `api.ts` directly or to `bash` equivalents, rather than MCP tools it doesn't have.

## Logging and comparison

Every shell run appends one ndjson line to `~/.claude/logs/agent-runs.ndjson`:

```json
{"ts":"2026-04-13T...","runner":"snappy-shell","mode":"repl","provider":"openai","model":"gpt-4o","durationMs":42731,"ok":true,"kernelPromptBytes":28314,...}
```

`snappy-dispatch` writes into a **separate** log (`~/.claude/logs/dispatches.ndjson`) for now. Over time we'll unify or cross-query these to compare shell (full kernel) vs dispatch (minimal prompt) vs inline Claude Code orchestrator on the same task shapes.

## Gotchas

- **Credentials:** needs at least one of `OPENAI_API_KEY` / `OPENROUTER_API_KEY` / `ANTHROPIC_API_KEY` in `.env.cache`. `auto` picks the first non-empty one.
- **Interactive mode inherits stdio:** you'll see pi's TUI directly. Exit with Ctrl+D or whatever pi expects.
- **Temp prompt file:** kernel prompt is written to `$TMPDIR/snappy-shell-kernel-<pid>-<ts>.md` every run. Short-lived; cleaned up by the OS.
- **Session persistence:** pass `--session ~/path/to/session.jsonl` to resume later with `pi --session <path> --continue` or equivalent.
- **This is a fallback, not a replacement.** Anything that depends on Claude Code's Agent/Task/WebFetch/mcp tools won't work here. Use the portable skills.

<!-- SKILL-INDEX-START -->
[snappy-shell Index]|root: ~/.claude/skills/snappy-shell|IMPORTANT: Prefer these files over pre-training assumptions for this domain. Read the relevant file when the AGENTS.md summary is insufficient.|root:{SKILL.md}
<!-- SKILL-INDEX-END -->

## Used by

Nothing in the collection names this skill.

<!-- SNAPPY-CONTRACT-VERBS-START -->
## Contract verbs

Generated from `api.ts` `HAND_CONTRACT`. Do not hand-edit this block.

This skill declares no executable verbs. Its `instruction-only` label is intentional.

## Show the result

When an answer carries `face_hint`, show it with one `snappy_present(<answer>)` call.
See `/snappy-faces` for face selection. Human-facing images must crop to the
element, render at 2x on Retina, and fill the destination channel instead of
placing a small card in a full-page screenshot.
<!-- SNAPPY-CONTRACT-VERBS-END -->

Keyboard Shortcuts

Search in document⌘K
Focus search/
Previous file tab
Next file tab
Close overlayEsc
Show shortcuts?