A local AI agent harness with its own execution engine. Not a wrapper around someone else's.
Providence Core runs its own from-scratch agentic loop directly on the Anthropic SDK (and OpenAI Codex, and OpenRouter), with ~30 native Go tools, a 7-step permission chain, and a flame-themed terminal UI that renders charts in your terminal. When you actually want to drive Claude Code or Codex instead, it wraps those too, in headless mode. One interface, your engine of choice.
Named after Providence, the Profaned Goddess from Terraria's Calamity mod. The theme runs deep.
Most AI coding tools are a TUI bolted onto a single vendor's CLI. Providence is the other thing: a real harness. It owns the call-stream-execute-repeat cycle itself, runs its own tools written in Go, gates every tool through a permission model ported from Claude Code, manages its own context window with a five-stage compaction engine, and persists every session to a local SQLite database with full-text search.
It speaks to three LLM backends through one shared agent loop:
- Anthropic (Messages API, native streaming, prompt caching, live token counting)
- OpenAI Codex via ChatGPT OAuth, no API key needed. Full PKCE flow: localhost callback server, CSRF state validation, JWT account-id extraction, tokens stored at 0600, refreshed 8 minutes before expiry, with mid-turn 401 self-heal.
- OpenRouter for any OpenAI-compatible model. For
anthropic/*models it does prompt-cache passthrough: detects the model id and injectscache_control:ephemeralon the last cacheable system block so caching survives the proxy.
And when you'd rather drive an existing harness, it wraps them as subprocesses:
- Claude Code over
stream-jsonNDJSON - Codex over
codex exec --json
Same UI, same session store, same permission surface, no matter which engine is underneath. Compaction is provider-agnostic too: three compact.Provider implementations (Anthropic, Codex, OpenRouter) each serialize their own native history and summarize with a cheap fast-tier model, none ever orphaning a tool result.
Requires Go 1.25+.
Build from source:
git clone https://github.com/gravitrone/providence-core.git
cd providence-core
make setup
make install-binThen run it:
providencePick your engine with --engine direct|claude|codex_headless|openai (where openai maps to the Codex backend), or set it in ~/.providence/config.toml. Auth is ANTHROPIC_API_KEY, OPENROUTER_API_KEY, /auth (ChatGPT OAuth for Codex), or an api_key_helper shell command.
Every AI coding agent ships its own mediocre TUI locked to one vendor. Providence is one harness that drives Anthropic, Codex, and OpenRouter through a single agent loop, wraps Claude Code and Codex headlessly when you want them, and keeps one shared session store and permission model across all of it. The direct engine isn't a thin client either: it does read-parallel / write-serial tool scheduling, exact token accounting, cache-break forensics, and a multi-class retry ladder that most "harnesses" never bother building. The Codex path talks to ChatGPT over a real PKCE OAuth flow with zero API key, which is the kind of thing nobody else bothers wiring up.
And it looks like it's on fire while doing it.
This is the heart of the project: a hand-rolled streaming agent loop, not a subprocess wrapper.
- Native streaming loop on the Anthropic SDK - accumulates the message, translates every stream event into a unified event model, extracts
tool_useblocks, and loops until the model stops. From scratch. - Read-parallel / write-serial tool queue - read-only tools (and dynamically-detected read-only Bash) run concurrently under a semaphore; writes block until reads drain, then run serially. A failed Bash command fires a sibling-cancel that aborts its concurrent batch.
- Streaming-overlapped tool pre-execution - the moment a read-only
tool_useblock closes mid-stream, that tool starts running, overlapping tool I/O with model generation. Results are reused when the turn ends. - Live token counting - hits Anthropic's
count_tokensendpoint for exact input counts, backed by a 256-entry SHA256-keyed LRU cache, with a char heuristic fallback (Anthropic models only; Codex and OpenRouter use a crude char-based estimate). - Cache-break forensics - every call fingerprints model + system blocks + per-tool schema/description hashes, and writes a timestamped diff to
~/.providence/cache-breaks/whenever the prompt-cache prefix drifts. - Multi-class resilience - distinct handling for 429 rate-limit (Retry-After parsing), 529 overload (capped backoff), 500-503 with fast-model fallback, connection-reset (client rebuild), auth-401 (OAuth refresh + retry), and a stream-idle watchdog that cancels stalled streams.
- Max-output-token recovery ladder - escalates
max_tokensfrom 16k to 64k, then falls through to up to 3 resume turns telling the model to pick up mid-thought. - Mid-turn steering - send a message while the model is working; it gets wrapped as a system reminder telling the model to finish the current task then address you.
- Stuck-loop detection - a ring buffer hashes recent tool calls; 3 identical calls in a row injects a "try a different approach" nudge.
- Ember autonomous tick loop - after each completed turn the TUI fires a self-prompting
<tick>back into the engine when ember is active, with focus-state tracking and a 5-minute timeout, so the agent keeps working unattended. Toggle and status from the agent tab. - Unattended mode -
PROVIDENCE_UNATTENDED_RETRYenables indefinite 429/529 retry with 5min max backoff, 30s heartbeats, and a 6hr wall-clock cap for long-running headless agents.
~30 tools written in Go, all behind one Tool interface, all gated by permissions. Highlights:
- File ops with a real safety stack - Read (line-numbered, image-resize, PDF, notebooks, encoding-aware), Write/Edit with read-before-write enforcement, mtime stale detection, atomic temp-and-rename, byte-encoding preservation (BOM/CRLF/Latin-1/CP1252), config-file parse validation, and a secret-pattern write guard that blocks OpenAI/Anthropic/AWS/GitHub/Stripe keys and PEM blocks from hitting disk via Write/Edit.
- FileHistory - Write and Edit auto-snapshot every overwrite as a gzipped blob under
~/.providence/history(20 deep / 7 days), with one-call restore so the model can undo a bad edit without leaving the harness. - Sandboxed Bash (macOS) -
sandbox-execjail denying network +/Systemwrites (config can allow-list specific outbound hosts and writable subpaths), persistent cwd across calls, process-group SIGKILL on timeout, background PIDs, and oversized-output spill-to-disk. - Bash security guard - pre-execution analysis blocks
sed -i, dangerous zsh builtins,eval, process substitution,/devand/proc/*/environaccess,rm -rfat root, andsedbacktick injection. - Hardened WebFetch - https-only upgrade, DNS preflight, cross-host redirect refusal, 5MiB body cap, HTML-to-text, binary spill, 15-minute LRU cache. Plus WebSearch via Exa with domain filtering.
- Agentic tools - Agent/Task (spawn subagents), SendMessage (inter-agent messaging + broadcast), TodoWrite, plan mode, Skill, Brief, AskUserQuestion, ToolSearch, StructuredOutput.
A Swift-first desktop bridge with automatic shell fallback. It spawns a real compiled native binary (bridge/swift-mac) as a long-lived subprocess and talks to it over NDJSON-RPC on stdio, with a warm ScreenCaptureKit pipeline kept hot for the session. Strongest "not a wrapper" evidence in the repo.
- Semantic UI control -
DesktopFindElement/DesktopClickElement/DesktopReadScreenquery the Accessibility tree by role/title/text with fuzzy/substring/exact matching and stable element IDs (with focus-change invalidation, so handles don't go stale). Click by meaning, not pixels, with coordinate fallback for canvases and games. - ScreenDiff - perceptual-hash (dHash) comparison returning changed-region deltas of a few dozen bytes instead of a 1MB screenshot.
- DesktopActionBatch - multi-step GUI automation (click + type + verify_ax + read_value) executed server-side in one bridge round trip, with AX-based verification and focus-changed abort.
- Plus Screenshot, DesktopClick, DesktopType, DesktopApps, Clipboard. All gated to darwin.
A separate overlay companion (/overlay) runs a Unix-domain-socket server, spawns its GUI helper with a TCC-disclaiming posix_spawn (the same technique Chrome and Slack use so the child owns its own privacy identity), ring-buffers screenshot frames for vision attachment, and tracks injected-token cost against a daily budget breaker.
A five-stage compaction engine runs before every API call. Four passes are zero-API-cost; the fifth is provider-agnostic.
- Snip old message pairs beyond a window
- Budget - enforce a 100KB tool-result cap, oldest truncated first
- Microcompact - clear old tool results over 2000 chars, keeping the last few
- Collapse - summarize consecutive old tool-result groups inline
- LLM summarization - an async orchestrator with a phase state machine and a 3-failure circuit breaker, plus a separate synchronous reactive path that recovers from
413 prompt_too_longmid-turn
None of these passes ever orphan a tool_result from its originating tool_use. Session memory, when present, is read first and fenced above the generated summary so the durable record survives restores.
A 7-step ordered decision chain, ported from Claude Code, runs on every tool call: deny rules, ask rules, per-tool checker, safety asks, bypass, allow rules, mode defaults.
- Bypass-immune safety checks - touching
.git/,.claude/, or shell configs (.bashrc,.zshrc,.zprofile...) always forces a prompt, even in bypass mode. - Shadowed-rule detection - static analysis flags rules that can never fire because an earlier rule subsumes both their pattern and behavior. Surfaced in
/permissionsand logged at load. - Session denial tracking - LRU-deduped denial history, surfaced in the UI.
- Read-only auto-mode - session-scoped auto-approval limited to Read/Grep/Glob, never overriding safety paths.
- Crash-safe persistence - rules written via tempfile + fsync + rename, keyed by
sha256(projectPath).
Flame-themed and animated, built on Bubble Tea v2 / lipgloss v2.
- Charts in your terminal - the model emits fenced
providence-vizJSON blocks; the UI renders 12 types (bar, table, sparkline, tree, list, progress, gauge, heatmap, timeline, kv, stat, diff) with flame gradients. Streaming-aware: unclosed fences show a spinner, closed ones render live, all surviving the markdown pipeline via placeholder tokens. - Spring-physics agent sidebar - harmonica damped springs slide it in, status icons pulse to a global animation frame, finished agents auto-evict. Expand any agent for a full transcript view.
- Animated gradient borders - per-character flame gradient rotating on box borders while streaming, plus per-character shimmer and ember breathing.
- Fuzzy file picker -
@triggers a finder overgit ls-fileswith a hand-written subsequence scorer and git-index mtime auto-refresh. - 41 slash commands, including
/permissions,/auth,/plan,/bridge, and/overlay.
- MCP - a from-scratch Go MCP client (no SDK): stdio JSON-RPC 2.0,
initializehandshake, tool discovery, and the samemcp__server__toolnamespacing as Claude Code. Self-healing transport auto-respawns a server after 3 consecutive errors. Resources, prompts, and server-initiated elicitation are wired at the client layer but not yet consumable from the UI (see Roadmap). Reads both./.mcp.jsonand~/.providence/mcp.json. - Lifecycle hooks - shell or HTTP webhooks on lifecycle events.
PreToolUseexit-code-2 genuinely blocks the tool mid-flight (not just observed). Async hooks feed results back via a sequenced TTL drain queue. HTTP hooks pass through an SSRF guard with a full IPv4/IPv6 private-range + cloud-metadata blocklist. Reads native TOML and Claude Code's.claude/settings.json. - Skills, output styles, custom tools - markdown skills with frontmatter from project/user dirs, including conditional path-triggered activation (touch a file matching a skill's
path_globs, its instructions inject into the next turn). Output styles inject into the system prompt. - Subagents - 7 built-in agent types with tool allowlists (general-purpose, Explore, Plan, Verification, Code-Reviewer, Implementer, Spec-Reviewer), plus custom agents from
.providence/agents. Real git-worktree isolation per agent (auto-cleanup if no changes, branch hand-back if changes exist), three-scope per-agent-type memory injection, and an inter-agent inbox (message by id/name or broadcast).
- Pure-Go SQLite (
modernc.org/sqlite, zero cgo) at~/.providence/sessions.db- WAL, tuned pragmas, idempotent migrations. Sessions + messages with FTS5 full-text search (ranked,<mark>snippets) and a typed event-log side table (file snapshots, content replacements, worktree state, tool-call ids) backing session resume. Nil-safe throughout: a failed DB open degrades gracefully instead of crashing. - 5-level config merge - user global, project
.providence/config.toml, local override,.claude/config.toml, enterprise managed-settings (read, enforcement pending), with env-var expansion and JSON-to-TOML auto-migration. - Security-hardened sandbox config - rejects wildcard network rules (
*:*,0.0.0.0) and bare-$HOME/ filesystem-root write paths before they can widen the sandbox.
Providence can be driven by other tooling in a Claude-Code-compatible NDJSON protocol (--headless or the --output-format stream-json alias). It emits an enriched system/init (tools, slash commands, permission mode, cwd, engine id), handles control_request subtypes (initialize, interrupt, set_model, set_permission_mode, get_context_usage, end_session, and more), runs a keep-alive ticker, tracks session_state_changed, and attaches human-readable tool-call summaries. Anything already built around Claude Code's headless mode can drive Providence as a drop-in.
Adding a new engine is one RegisterFactory call in an init() - the factory registry feature-detects capabilities (history restore, compaction, session bus) by interface, so a minimal engine implements only what it actually supports.
Where this is going, honestly labeled because half of it isn't wired yet:
- Wiring the plugin manager and custom-tools loader into the running app (the libraries are built and tested, the runtime registration isn't).
- A real dashboard panel stack (collapsible APPROVALS/AGENTS/TOKENS/TASKS/FILES/ERRORS panels exist and are tested, but the live UI shows the sidebar instead).
- Ember crash recovery + task queue (
.providence/tasks.yaml, checkpointing) and coordinator mode - implemented and tested, not yet exposed to a user trigger (the basic tick loop is live; these deeper parts aren't). - Team coordination beyond create/delete: there's no add-member/join tool yet and mailbox messaging isn't wired to a user trigger.
- Background watcher agents (adversarial Red-Team-Advisor, context-enriching Smart-Pre-processor) - built on the SessionBus, no activation flow yet.
- MCP resources/prompts browsing UI, elicitation UI wiring, and HTTP/SSE MCP transport (stdio-only today).
- Linux/Windows computer-use (the desktop bridge is darwin-only) and broader OpenCode engine support (currently a stub).
- Per-session cost/token accounting persisted to the store.