Oompa / Get started
Set up Oompa
Find the admitted CLI and this candidate's installation limits, then follow the first-run path only when artifact admission and rollout prerequisites are satisfied.
Checked · Read as Markdown ↗
1. Install and check the CLI
test "$(unset BUN_OPTIONS NODE_OPTIONS LD_AUDIT LD_LIBRARY_PATH LD_ORIGIN_PATH LD_PRELOAD DYLD_FALLBACK_FRAMEWORK_PATH DYLD_FALLBACK_LIBRARY_PATH DYLD_FRAMEWORK_PATH DYLD_IMAGE_SUFFIX DYLD_INSERT_LIBRARIES DYLD_LIBRARY_PATH DYLD_ROOT_PATH DYLD_VERSIONED_FRAMEWORK_PATH DYLD_VERSIONED_LIBRARY_PATH && curl -fsSL --connect-timeout 10 --max-time 60 --max-filesize 524288 --retry 3 --retry-delay 1 --retry-max-time 60 --proto '=https' --tlsv1.2 https://raw.githubusercontent.com/hraness/oompa/v0.8.0/src/install-preflight-runtime.ts | command bun --no-env-file --config=/dev/null -e 'const n=["BUN_OPTIONS","NODE_OPTIONS","LD_AUDIT","LD_LIBRARY_PATH","LD_ORIGIN_PATH","LD_PRELOAD","DYLD_FALLBACK_FRAMEWORK_PATH","DYLD_FALLBACK_LIBRARY_PATH","DYLD_FRAMEWORK_PATH","DYLD_IMAGE_SUFFIX","DYLD_INSERT_LIBRARIES","DYLD_LIBRARY_PATH","DYLD_ROOT_PATH","DYLD_VERSIONED_FRAMEWORK_PATH","DYLD_VERSIONED_LIBRARY_PATH"],x=process.execArgv;const c=x.filter(v=>v==="-c"||v.startsWith("--config"));if(n.some(k=>process.env[k]!==undefined)||x.filter(v=>v==="--no-env-file").length!==1||c.length!==1||c[0]!=="--config=/dev/null"||x.some(v=>v.startsWith("-r")||v==="--preload"||v.startsWith("--preload=")||v==="--require"||v.startsWith("--require=")||v==="--import"||v.startsWith("--import=")||v==="--env-file"||v.startsWith("--env-file=")))throw new Error("The tagged Oompa preflight requires a neutral Bun stage zero.");const[a,h]=process.argv.slice(1);const r=Bun.stdin.stream().getReader(),q=[];let z=0;try{for(;;){const o=await r.read();if(o.done)break;z+=o.value.byteLength;if(z>524288)throw new Error("The tagged Oompa preflight exceeds its byte limit.");q.push(o.value)}}finally{r.releaseLock()}const b=new Uint8Array(z);let p=0;for(const v of q){b.set(v,p);p+=v.byteLength}const d=new Bun.CryptoHasher("sha256").update(b).digest("hex");if(d!==h)throw new Error("The tagged Oompa preflight digest is invalid.");const j=new Bun.Transpiler({loader:"ts",target:"bun"}).transformSync(b);const u=URL.createObjectURL(new Blob([j],{type:"text/javascript"}));try{const m=await import(u);await m.installOompaRelease(a);process.stdout.write(`${m.OOMPA_INSTALL_SUCCESS}\n`);}finally{URL.revokeObjectURL(u)}' -- https://github.com/hraness/oompa/releases/download/v0.8.0/hraness-oompa-0.8.0.tgz a0d9ad996437922619bdf88c7474dff87659ee401689c95724f019412c13d3d9)" = hra-install-safe
Only after exact artifact admission, use macOS or Linux with Bun 1.3.14 and curl to install v0.8.0. The installer verifies the immutable release before replacing the Oompa command. It does not start the daemon.
oompa --version
oompa doctor --offline
Already using Oompa? Follow the update runbook before changing a daemon or restoring local state. Do not apply first-run instructions to an existing installation.
2. Connect a provider account
After the rollout prerequisites are satisfied, run these as separate commands in a foreground terminal. Initialization sets up local state and uses your Documents directory as the default workspace. Name your profile, then let Codex complete its own device-code sign-in.
oompa init --yes
oompa account add personal
oompa account login personal --provider codex --device-code
For Claude Code on Linux, use oompa account login personal --provider claude instead. Claude owns its terminal prompts and browser handoff. Managed Claude login and execution are not available on macOS, and Claude has no Oompa browser-linking flow.
Provider login is a one-shot command, not a command inside Oompa's persistent shell. Oompa never asks you to paste a provider credential. Account status and login recovery cover an interrupted sign-in.
3. Start a conversation
With setup complete and your provider signed in, start a session. Keep the session ID returned by the first command. Open Oompa's shell and select that exact session before writing your request.
If you signed in to Claude Code, replace the first command below with oompa session start personal --provider claude --preset fable-max. The remaining shell steps are the same.
oompa session start personal --provider codex
oompa
/account personal
/session <session-id>
Review this project and summarize its current state.
Type /exit to leave the shell. The daemon keeps the session running. Return later, select the same account and session, and continue.
To use a specific repository, register it with oompa project add --path <directory> --name <name> and select it with oompa project use <project> before starting the session.
4. Add the web app when you want it
You can stay local, or connect your Oompa identity and approve a browser to see sessions away from the terminal. The web app guide walks through email sign-in, device approval, and the session grid.
Detailed reference
Exact commands, recovery steps, and compatibility details for this guide.
First account
oompa account add personal
oompa account login personal --provider codex --device-code
oompa account usage personal --refresh
oompa account usage-history personal --limit 50 --json
Account login is always a dedicated one-shot invocation, including while the persistent shell is running. For Codex, use oompa account login personal --provider codex --device-code in a foreground TTY for app-server's device-code path. That terminal displays the code and verification URL directly. An opted-in registered machine can also receive a versioned web request that always selects device-code mode; Oompa accepts only the pinned Codex device URL and a separate closed code, encrypts them to the account key, and lets only the requesting browser read the handoff once before its five-minute hosted expiry. Oompa keeps the resulting provider state inside that profile's isolated CODEX_HOME without copying auth.json.
On Linux, oompa account login personal --provider claude launches a realpath-resolved Claude Code executable only after its exact self-reported version matches Oompa's pin, in the foreground inside that profile's isolated CLAUDE_CONFIG_DIR. Claude owns its prompts and browser handoff. Oompa gives it the terminal, joins the exact child, and reports only whether Claude says it is signed in; Oompa never opens or copies a Claude credential. Claude exposes no Oompa device-code, handoff-file, or web-linking protocol. New Claude effects are refused on macOS pending authenticated isolated-Keychain and detached-read acceptance.
For a Codex login, JSON and noninteractive callers must create an empty mode-0600 file under a canonical current-user-owned mode-0700 directory, then pass its absolute canonical path:
oompa account login personal --device-code --handoff-file /absolute/private/login.json --json
Oompa opens and holds the parent and file, resolves the account selector to one exact local account ID, and dispatches login only for that authority. It validates the returned account, state, cancellation command, URL, and device-code shape, writes one versioned login document through the held descriptor, verifies it with fsync and readback, and closes both descriptors before returning only the path and cleanup disposition on stdout. The caller reads the file through its protected boundary and removes it after login. A same-key replay never claims or rewrites a handoff. While login is pending it reports that one-time instructions are unavailable; after completion or cancellation it reports the terminal account state.
If the first pending-login handoff is lost or the daemon restarts before completion, oompa account show personal --provider codex reports the pending attempt. Then run oompa account login-cancel personal --provider codex. A caller that retained the idempotency key may retry it without redispatching. A still-pending local replay cannot recover the one-time code or URL; a completed or canceled replay returns terminal signed-in or signed-out evidence instead of stale pending state. Oompa cancels only that profile's exact current-generation provider login before allowing a fresh login. Verification URLs and user codes never enter local durable Oompa state, logs, or ordinary command output. A protected handoff file may retain them for its local caller; the web path instead retains only an account-key-encrypted, one-read hosted result until consumption or five-minute expiry.
If a Claude foreground parent or daemon fails after launch, oompa account show personal --provider claude retains the one-child fence even if Claude reports signed in. After confirming that original child has exited, use the exact attempt, generation, and idempotency key in the reported acknowledged oompa account login-cancel command to release only the local fence. That recovery does not stop Claude or read, change, or delete a credential.
oompa account list --provider codex or oompa account list --provider claude --json reads cached provider order, default marker, readiness and observation times. It does not refresh providers or change account selection. Unknown observation times stay unknown; cached readiness is not current sign-in proof or quota freshness. The read verifies at most 10,000 live profiles and returns at most 10,000 accounts within a separate 3 MiB JSON limit, refusing oversized or inconsistent results without truncation. Unqualified oompa account list keeps the existing profile listing.
oompa account usage is Codex-only and keeps the latest snapshot and 1-, 5-, and 15-minute observed token velocity. oompa account usage-history <profile> reads the retained 24-hour local ledger in durable source order. Use UTC RFC3339 --from and --through bounds plus the returned opaque cursor for later pages; a cursor freezes that account and range and expires after five minutes. History rows contain only derived token observations or closed poll-failure codes; raw provider payloads are never returned.
oompa usage auto status [codex|claude] reads local automatic-policy configuration and its revision. Without a provider, on|off changes the inherited default, not a global kill switch. A provider's explicit on override remains enabled when that default is off; inherit <codex|claude> restores inheritance. Every change requires --revision <n> from status and a caller-owned --idempotency-key <uuid>. After a lost response, replay the exact command with the same key and revision. Its saved receipt is not the current configuration; read status again for that. These controls do not refresh providers, move accounts or sessions, or enable unavailable runtime capabilities. Devin has no automatic usage policy.
When effective Codex automatic policy is enabled, Oompa automatically spends one available earned Codex rate-limit reset when a fresh read shows the exact seven-day Codex window at 99 percent used or higher. It records a private idempotency key before dispatch, retries only that key after an uncertain response, and rereads limits after every closed outcome. Disabling suppresses new automatic reset dispatches, including retries, while retaining uncertain attempts under their original keys. A later disable does not cancel an already admitted operation or skip settlement and rereading after a closed outcome. A successful redemption is latched to that weekly window, so a stale usage snapshot cannot spend another credit. Rate-limit notifications wake a coalesced authoritative read; the staggered 50-to-70-second poll remains the fallback. oompa account usage reports the most recent local reset attempt with its source weekly-window boundary and suppresses a prior identity's snapshot after an account change. Credit IDs, descriptions, private keys, and account fingerprints never enter that reset status or its cloud projection.
Automatic account movement is not exposed yet. The adopted provider-usage boundary permits only a managed Codex session to follow a durable account decision after reset handling and fresh exact source and target reads. Explicit sessions and work tasks stay pinned to the account you selected. Claude and Devin accounts never rotate automatically, and Oompa never replays a failed or ambiguous turn under another account.
Oompa cloud identity is separate from every Codex or Claude Code account. Use the email-code flow below only after a hosted or self-managed Convex deployment has been configured.
First session
Only after the rollout prerequisite is satisfied, complete initialization and the first provider login before this walkthrough. Account login remains a dedicated one-shot command, and the session-start command returns the new session ID.
Human terminal
Create an idle session, open the persistent shell, select the account and exact returned session ID, then type a request as an ordinary line. Oompa sends that line to the selected session and shows safe live updates. /exit leaves the daemon running.
oompa session start personal --provider codex
oompa
/account personal
/session <session-id>
Review this project and summarize its current state.
Agent caller
Read data.session.id from the start response. Before sending, call status and read data.eventStream.cursor from its version-2 result. Start watch from that exact cursor so the atomic local snapshot and subsequent event stream are contiguous. Keep watch as a long-running subprocess, consume its two output streams independently, and use the exact ID instead of a mutable title in automation.
oompa session start personal --provider codex --json
oompa session status <session-id> --json
oompa session send <session-id> -- "Review this project and summarize its current state."
oompa session watch <session-id> --cursor <status-cursor> --jsonl
oompa session interactions <session-id> --pending --json
If the event stream reports a blocking interaction, read its exact ID and revision, inspect the live authority through the protected path, and resolve only the interaction kind you received. Keep following while a separate one-shot invocation handles the approval, question, permission grant, or supported MCP form. The protected interaction commands and input documents are defined below.
Devin support has been removed because its supported CLI integration cannot provide verified remaining account quota and reset times. Existing Devin history is read-only and provider-owned credentials are preserved. Retired-provider compatibility and local login-fence cleanup remain documented; no new Devin login or session can start.
Claude Code and provider switching
Start directly with Claude Code by selecting its provider and reviewed preset, or move an idle session between providers. A switch seeds a fresh provider-native runtime from the latest retained tail of Oompa's provider-neutral conversation record; it does not move a provider-native thread. From the point the v0.6 daemon begins recording a session, that record covers accepted direct, queued, Work and scheduled automation, autorespond, and provider-switch handoff messages with actor provenance. It does not backfill provider history from before a personal-home session was admitted or user turns from before a v0.5 installation was upgraded, and those origin gaps do not set the current retention-gap field. Attachments are represented only by byte-free manifests containing bounded names, media types, sizes, and digests. Retention is capped at 50,000 events, 64 MiB, and seven days; when pruning has occurred, switch seeds and exports state the retention reason and leave the unavailable older count unknown. A switch refuses an active turn, an unsettled provider effect, an unsigned target profile, or a preset that belongs to another provider. If a Claude controller is no longer available, Oompa can recover the exact conversation with --resume only after prior-process exit or an already-completed exact process release is proven. Ambiguous custody stays fenced in recovery without launching another process.
oompa session start personal --provider claude --preset fable-max --json
oompa session switch <session-id> --provider claude --preset fable-max
oompa session export <session-id> --format json
Scheduled work in the same conversation
Attach a recurring whole-minute interval to an existing session with oompa session task. Each run returns to that exact Oompa conversation. A task cannot independently retarget its account, provider, project, model, or execution environment; later explicit changes to the session apply to future runs. Missed intervals coalesce into one queued turn. Use the returned task ID and revision for later edits or deletion; Oompa never creates a replacement provider conversation or writes a provider's private automation registry.
oompa session task create <session-id> --name daily-review --every-minutes 1440 -- "Review the release queue."
oompa session task list <session-id>
oompa session task show <session-id> <task-id>
oompa session task edit <session-id> <task-id> --revision <revision> --pause
oompa session task edit <session-id> <task-id> --revision <revision> --resume
oompa session task delete <session-id> <task-id> --revision <revision>