@worktango/tango-pi
v0.5.0
Published
WorkTango's pi launcher: bundles our pi extensions, finds wt-tooling skills, resolves provider credentials, and falls back across models until a run succeeds.
Readme
@worktango/tango-pi
WorkTango's launcher for pi. It runs pi with our extensions, our skills, and whatever credentials you already have, then gets out of the way.
npx @worktango/tango-pi # interactive
npx @worktango/tango-pi -p "what changed?" # one-shotEvery argument is forwarded to pi, so anything in pi --help works here too.
What it does before pi starts
Finds your skills. It looks for a wt-tooling checkout — TANGO_PI_WT_TOOLING, then the directory you are standing in, then the usual spots under $HOME — and passes projects/ and packages/orca/skills to pi as --skill roots. It also walks up from the cwd to the enclosing repo root, picking up every .claude/skills, .pi/skills, and .agent/skills it finds along the way — so a session started deep in kazoo-web/d2c-apps/constellation sees both that folder's skills and any higher up. No checkout, no skills, no error.
Loads our extensions. The eight in extensions/ ship with the package: todo, sub-agents, plan mode, self-review, system prompt budget, memory, skill dedupe, and Claude usage. They are passed explicitly alongside --no-extensions, so you get exactly this set. Without that flag, anyone who also has these installed in ~/.pi/agent/extensions would register every command twice.
Sorts out credentials. It looks for these, in order, and hands whatever it finds to pi under the name pi actually reads:
| Provider | Checked |
|---|---|
| Anthropic | ~/.pi/agent/auth.json (a /login session), ANTHROPIC_AUTH_TOKEN, ANTHROPIC_OAUTH_TOKEN, CLAUDE_CODE_OAUTH_TOKEN, ANTHROPIC_API_KEY, CLAUDE_API_KEY |
| OpenAI | OPENAI_API_KEY, OPENAI_KEY |
| Gemini | GEMINI_API_KEY, GOOGLE_GENAI_API_KEY, GOOGLE_API_KEY |
| Vertex | GOOGLE_CLOUD_API_KEY, GOOGLE_APPLICATION_CREDENTIALS, gcloud ADC, with GOOGLE_CLOUD_PROJECT |
Aliases matter here. CLAUDE_CODE_OAUTH_TOKEN is exported by Claude Code and pi has never read that name, so tango passes it along as ANTHROPIC_OAUTH_TOKEN. Vertex ADC without a project id is reported rather than silently skipped.
Choosing a model
Interactive sessions are left alone: pi has a model picker and a login flow, so tango passes credentials through and hands over.
With -p (or --mode json/--mode rpc) there is nobody to answer a prompt, so tango picks. It reads pi --list-models, ranks what each credential can reach — newest generation first, strongest family within it, skipping dated snapshots and chat-tuned variants — and works down the list until a run produces a response. A credential rejected with a 401 is dropped immediately rather than retried on three more models. Pinning --model or --provider yourself short-circuits all of this.
If nothing works you get an exit code of 1 and a breakdown on stderr of every variable checked, every attempt made, and what to set. It never falls back to silence.
Environment
| Variable | Effect |
|---|---|
| TANGO_PI_WT_TOOLING | Path to wt-tooling, skipping discovery (WT_TOOLING_DIR also works) |
| TANGO_PI_BIN | Use a specific pi binary instead of the bundled one |
| TANGO_PI_NO_UPDATE=1 | Skip the daily pi update check |
| TANGO_PI_QUIET=1 | Suppress tango's own stderr notes |
| TANGO_PI_SKILL_DIRS | Set by tango for the skill-dedupe extension; not something you set |
Development
yarn workspace @worktango/tango-pi check # typecheck, run testsThe source is plain JavaScript typed with JSDoc, checked by tsc --checkJs --noEmit. There is no build step, which is what keeps npx instant.
src/cli.e2e.test.js runs the real CLI as a subprocess against a stub pi, so fallback, diagnostics, and argument assembly are covered without touching a provider.
