A local-first AI coding agent for your terminal and desktop.
Governed tools, durable sessions, side-effect recovery, MCP integrations, Agent Skills, and multi-agent workflows - all from a keyboard-driven TUI.
Warning
Azem can read and modify files, run shell commands, and access the network when permitted. Commit or back up important work, and review the security model before enabling permissive policies.
Azem is designed for coding work that needs more than a chat window. It combines model-driven development with explicit approval policies and persistent execution records, so tool calls remain visible, recoverable, and easier to audit.
| Capability | What it provides |
|---|---|
| Terminal and desktop workflows | A fast Bubble Tea TUI plus a Wails desktop workspace with frame-paced streaming output, inline approvals and diffs, Agent inspection, recovery, and role-model settings |
| Governed execution | Prompt, Auto Review, and YOLO approval modes for file, shell, and external actions |
| Durable state | SQLite-backed sessions, runs, approvals, leases, side-effect reconciliation, and Team resume |
| Multiple providers | ChatGPT through Codex-compatible OAuth and Grok through API or CLI-proxy transport |
| Extensible tools | MCP servers over stdio or Streamable HTTP, plus dynamically loaded Agent Skills |
| Multi-agent work | Structured team mode and resumable subagents with optional Git worktree isolation |
Requirements:
- Go 1.25.8 or later; the project recommends the Go 1.25.12 toolchain
- A supported ChatGPT or Grok account or existing credential
- Git when using subagent worktree isolation
git clone https://github.com/Viking602/azem.git
cd azem
make buildTo build the Wails desktop app, install Bun and run:
make gui
open dist/Azem.appThe desktop app and TUI share the same Go runtime, SQLite sessions, approval policy, model routes, Skills, subagents, and recovery state. The React UI receives a bounded event projection; it does not expose arbitrary shell or filesystem bindings.
Desktop text output is presented in frame-paced chunks with a restrained activity cursor. Rendering is capped independently from the display refresh rate, large backlogs catch up automatically, and reduced-motion preferences disable the animation without disabling bounded rendering.
While a desktop turn is running, the composer supports Codex-style Queue and Steer delivery. Queue holds ordered, editable follow-ups for the next turn; Steer injects text or image guidance at the next model boundary without cancelling completed tool work. Cmd+Shift+Enter on macOS or Ctrl+Shift+Enter elsewhere uses the opposite mode for one message. Queues are session-scoped, stay in order, and pause after an interrupted run until explicitly resumed.
The desktop Pull Requests workspace uses the authenticated GitHub CLI for the repository at the workspace root. It lists the current and open pull requests, checks, files, comments, reviews, and merge state; supported mutations include editing, review requests, comments, reviews, draft/ready transitions, close/reopen, merge, and auto-merge. Merge requests are pinned to the displayed head commit so a stale panel cannot merge a newer revision.
Monitor & Fix polls an enabled pull request for failed checks or merge conflicts and starts at most one active governed Azem repair session for each observed failure fingerprint; an interrupted repair is eligible for retry after restart. Repair starts only when the workspace is clean and checked out to the pull request head branch; it never merges the pull request automatically. Missing gh, authentication, repository access, and network failures are reported in the Pull Requests workspace instead of disabling the rest of the desktop app.
The desktop app keeps a durable catalog of projects and restores the most recently opened project. --workspace selects one project for that window without rewriting the user configuration.
cd /path/to/your/project
/path/to/azemYou can also run it directly from the source tree:
go run ./cmd/azemSign in from the TUI:
/login chatgpt
/login grok
Or import credentials from an existing Codex or Grok installation:
/login chatgpt --import-codex
/login grok --import
Azem searches CODEX_HOME (or ~/.codex) for Codex credentials and ~/.grok for Grok credentials. Grok's OAuth-compatible flow is experimental and is not a stable third-party authentication contract provided specifically for Azem.
Enter a request such as:
Inspect this project, fix the failing tests, and explain the changes.
Azem streams progress in the terminal and asks for approval when the selected policy requires it.
- File discovery, reading, searching, patch editing, formatting, testing, and shell execution
- Streaming model output, reasoning state, tool activity, approval decisions, and usage information
- Collapsible, colorized inline diffs with file paths and added/deleted line counts
- Concise tool summaries that avoid flooding the transcript with raw patches or file contents
- Persistent conversations start in a fresh session on every launch; use
/resumeto reopen prior sessions with their context, tool history, and recap - Durable main-agent tool timelines preserve read, search, edit, test, and shell history across cancellation and process restarts; observed file hashes let resumed turns reuse unchanged evidence and target only stale paths
- Durable action attempts and reconciliation of unknown side effects after interruption; Team and eligible Single-Agent runs resume automatically without replaying completed side effects
- Retry handling for transient ChatGPT transport failures before output is emitted
- MCP server discovery, reconnect, concurrency controls, and per-tool policies
- Agent Skills discovery from user, project, configured, and bundled directories
- Planner, Implementer, Reviewer, and Reporter team workflow
- Background subagents with role, persona, model, budget, resume, and cancellation controls
- Independent tool calls dispatch in parallel while shell and subagent runtimes enforce their configured concurrency limits
- Optional detached Git worktrees for isolated subagent changes
Azem keeps review context in the conversation instead of hiding it behind raw tool payloads:
- Approval cards show the requested action and target as a separate lifecycle from the tool execution. Auto Review cards move from reviewing to Allowed, Denied, Timed out, or Review failed, and include risk and rationale when available.
- Inline file diffs turn successful patch edits and newly created files into collapsible transcript blocks. Each block identifies the affected file, reports
+added/-deletedtotals, and colorizes changed lines. - Compact tool activity summarizes file reads, searches, tests, shell commands, edits, and failures. Large patch bodies and complete file contents stay out of routine status messages.
- Subagent visibility applies the same summaries and file-diff presentation when inspecting child-agent activity.
- Context visibility shows startup occupancy before the first model call, then calibrates the total from provider usage. The segmented meter and
/contextbreakdown separate core instructions, Skills, built-in tools, MCP tools, conversation history, and provider framing.
flowchart LR
U[Terminal UI] --> A[Application runtime]
D[Wails desktop UI] --> A
A --> P[ChatGPT or Grok]
A --> G[Approval and tool governance]
G --> T[Files, tests, and shell]
G --> M[MCP servers]
A --> S[(SQLite state)]
A --> C[Teams and subagents]
A --> K[Agent Skills]
Each turn is routed through the application runtime, which selects a provider, assembles the available tools, applies approval policy, persists execution state, and streams events back to the TUI. Structured tool results are projected into readable summaries and file diffs. After a restart, Azem restores durable run projections and surfaces side effects that require reconciliation. Team runs and eligible Single-Agent runs resume automatically; runs requiring side-effect reconciliation remain paused for an explicit decision.
For ChatGPT, Azem retries transient stream-opening and transport failures up to five times when no response output has been emitted. This includes connection resets, temporary network errors, interrupted streams, and selected TLS transport failures. Cancellation, deadlines, invalid requests, and certificate validation errors are not retried. After any output has been emitted, Azem does not replay the request, avoiding duplicate partial responses or tool activity.
azem [-config /path/to/config.yaml]
azem --version
| Option | Description |
|---|---|
-config |
Load a specific YAML configuration file |
--version |
Print the version, current Git short hash, and UTC build time |
Without -config, Azem reads azem/config.yaml from the operating system's user configuration directory. If the file does not exist, built-in defaults are used.
| Shortcut | Action |
|---|---|
Enter |
Submit input or confirm a selection |
Ctrl+J |
Insert a newline |
Esc |
Close a dialog or cancel the active run |
Ctrl+C |
Cancel the active run, or quit while idle |
Ctrl+P |
Open the command palette |
Ctrl+M |
Select a model |
Ctrl+R |
Select reasoning effort |
Ctrl+B |
Inspect subagents |
Shift+Tab |
Cycle the approval mode |
PageUp / PageDown |
Scroll through conversation history |
Ctrl+Home / Ctrl+End |
Jump to the beginning or end |
? |
Open help when the input is empty |
| Command | Description |
|---|---|
/settings |
Configure the plan model, Codex Fast mode, subagent models, concurrency, and interface preferences |
/models |
Search for and select a model |
/model-routing |
Configure models for plan mode, compaction, and each subagent role |
/provider [chatgpt|grok] |
Switch providers |
/reasoning [level] |
Set reasoning effort |
/login [provider] |
Sign in or import provider credentials |
/logout [provider] |
Sign out of a provider account |
/skills [reload] |
Inspect or reload Agent Skills |
/skill <name> [instruction] |
Activate a Skill and run one turn |
/team on|off |
Enable or disable team mode |
/plan [on|off] |
Enable or disable read-only planning mode |
/agents [cancel <id>] |
Inspect or cancel subagents |
/agent-types |
Inspect available subagent types |
/personas |
Inspect subagent personas |
/new |
Create a new session |
/sessions |
List saved sessions |
/resume |
Resume a saved session |
/compact |
Compact the current session context |
/memory [query] |
Search workspace-native memory |
/remember <text> |
Save explicit evidence to workspace memory |
/forget <memory-id> |
Remove one workspace memory |
/recap |
Inspect the current session continuity recap |
/mcp [refresh|reconnect <server>] |
Inspect or update MCP servers |
/status |
Inspect runtime, session, cache, and token diagnostics |
/context |
Inspect the segmented context-window occupancy and individual contributors |
/reconcile <attempt-id> <result> |
Reconcile an unknown side effect |
/cancel |
Cancel the active run |
/help |
Open help |
/quit |
Quit Azem |
Pass a custom configuration file with:
azem -config ./config.yamlAzem rejects unknown fields, unsupported enum values, malformed durations, and invalid MCP settings. Relative workspace and Skill paths are resolved from the configuration file directory.
version: 1
defaults:
provider: chatgpt
model: gpt-5.6-sol
reasoning: high
agent_mode: single # single | team
queue_mode: queue # queue | guide
workspace:
root: .
allow_write: true
shell_policy: prompt # prompt | deny | allow
allow_network: prompt # prompt | deny | allow
shell:
max_context_output_bytes: 65536
max_artifact_output_bytes: 4194304
stop_on_output_limit: true
max_concurrency: 2
auth:
store: keyring # sqlite | keyring | file
import_codex: true
import_grok: true
providers:
chatgpt:
enabled: true
catalog_ttl: 5m
fast_mode: false # supported subscription models only; faster responses use more credits
grok:
enabled: true
catalog_ttl: 5m
experimental_oauth: true
transport: api
retry:
enabled: true
max_retries: 5 # full-engine retries after transport retries are exhausted
base_delay: 500ms # exponential task-retry backoff base
max_delay: 5m # maximum task or server-requested retry delay; 0s disables the cap
agents:
main:
max_tokens: 0 # optional inter-request limit; the final request may overshoot it
max_tool_calls: 0 # optional per-turn limit; 0 means unbounded
max_wall_clock: 0s # optional per-turn limit; 0s means unbounded
team:
max_concurrency: 2
max_ticks: 12
title:
# Lightweight model used for first-turn session titles.
provider: chatgpt
model: gpt-5.6-luna
reasoning: low
plan:
# Empty provider/model inherit the active model and reasoning effort.
provider: ""
model: ""
reasoning: ""
compaction:
# Empty provider/model inherit the active model; empty reasoning uses low.
provider: ""
model: ""
reasoning: ""
context:
enabled: true
background_prepare: true
soft_trigger_ratio: 0.68
hard_trigger_ratio: 0.82
target_ratio: 0.45
safety_margin_ratio: 0.08
reserve_output_tokens: 16384
reserve_reasoning_tokens: 8192
min_reclaim_tokens: 16000
max_summary_tokens: 4096
large_tool_result_tokens: 12000
history_retrieval_tokens: 4096 # private, session-scoped SQLite FTS evidence budget
preserve_full_history: true
subagents:
enabled: true
max_depth: 1
max_concurrency: 2
await_timeout: 10m
auto_wake: true
routes:
explore:
# Remove this entry to inherit the parent agent's model route.
provider: grok
model: grok-4.5
reasoning: low
budget:
max_tokens: 0 # optional inter-request limit; the final request may overshoot it
max_tool_calls: 0 # optional; 0 means unbounded
max_turns: 0 # optional; 0 means unbounded
max_wall_clock: 0s # optional; 0s means unbounded
skills:
enabled: true
trust_project: false # explicitly enable only for repositories you trust
additional_dirs: []
eager: []
disabled: []
mcp:
servers: {}Use Shift+Tab to cycle between modes:
| Mode | Behavior |
|---|---|
| Prompt | Ask the user before governed actions |
| Auto Review | Ask an authenticated reviewer model to assess actions and show its decision, risk, and rationale in the transcript |
| YOLO | Approve actions automatically; use only in trusted environments |
The configured tool effect and approval policy still determine which operations enter the approval flow. Approval cards remain separate from subsequent tool and diff blocks, so a review decision is not mistaken for completed execution.
Azem includes the read-only grep.app MCP server by default, exposed as mcp__grep__searchGitHub. It searches public GitHub repositories for literal code patterns. Override or disable it through mcp.servers.grep in the configuration file.
Azem also supports custom local stdio servers and remote Streamable HTTP servers.
mcp:
servers:
local_tools:
enabled: true
transport: stdio
command: /path/to/mcp-server
args: []
inherit_env: true
connect_timeout: 30s
call_timeout: 60s
max_concurrency: 2
approval: alwaysmcp:
servers:
remote_tools:
enabled: true
transport: streamable_http
url: https://example.com/mcp
headers:
Authorization: env:MCP_AUTHORIZATION
connect_timeout: 30s
call_timeout: 60s
max_concurrency: 2
approval: alwaysSecrets must be references rather than literal values:
env:NAMEreads an environment variable.keyring:NAMEreads an entry from the system keyring.
Remote MCP URLs must use HTTPS. Plain HTTP is accepted only for localhost or loopback addresses.
Azem follows operating-system user-directory conventions and creates an azem subdirectory:
| Data | Location |
|---|---|
| Configuration | azem/config.yaml under the user configuration directory |
| Database | azem/azem.db under the user configuration directory |
| Runtime state | azem/ under the user cache or state directory |
On Linux, XDG_CONFIG_HOME, XDG_DATA_HOME, and XDG_STATE_HOME override the corresponding base directories.
Credentials can be stored in SQLite, the system keyring, or a permission-restricted JSON file. SQLite and file storage rely on filesystem permissions and do not provide application-level encryption at rest. Use the system keyring when stronger local credential protection is required.
Azem's approvals and persistent action boundaries help reduce accidental operations and duplicate side effects. They are governance controls, not an operating-system sandbox.
- In the TUI,
workspace.rootsets the initial shell directory. Desktop windows use the selected project from the SQLite catalog instead. Neither mode is an OS sandbox: shell commands can still access paths outside the project. allow_write: falseremoves built-in write tools but cannot stop an approved shell command from writing files.allow_networkrelies on tools declaring network use and does not enforce OS-level network isolation.shell_policy: allowand YOLO mode remove important confirmation points.- A subagent that explicitly requests worktree isolation fails if the worktree cannot be created; it never falls back to the shared workspace.
For strict isolation, run Azem inside a container, virtual machine, or restricted OS account, and enforce filesystem and network policy outside the application.
cmd/azem/ Terminal application entry point
cmd/azem-gui/ Wails desktop application entry point
frontend/ React desktop interface and Wails bindings
internal/agent/ Tool governance, persistent runs, and team agents
internal/app/ Application orchestration, providers, and subagents
internal/auth/ OAuth, credential import, and credential storage
internal/config/ Configuration, paths, roles, and personas
internal/desktop/ Bounded Wails bridge and desktop lifecycle
internal/githubpr/ GitHub CLI projection, mutations, and PR monitor
internal/mcp/ MCP connection and tool management
internal/provider/ ChatGPT/Codex and Grok drivers
internal/recovery/ Crash recovery and side-effect reconciliation
internal/session/ Session persistence and compaction
internal/skills/ Agent Skills discovery and activation
internal/store/sqlite/ SQLite schema and storage implementation
internal/tui/ Bubble Tea terminal interface
docs/ Maintainer architecture, persistence, and testing guides
.sentrux/ Executable architecture constraints
Maintainer documentation:
Run the complete Go suite against declared module dependencies:
GOWORK=off go test ./...Run frontend and desktop checks:
make test-guiRun the architecture policy gate:
make architecture-checkFormat changed Go files before committing. See Testing for the change-specific verification matrix and real GUI smoke procedure.
gofmt -w path/to/file.goLive provider acceptance tests use the live build tag and require valid credentials plus an explicit environment switch. The standard test suite does not access real accounts.
Azem is available under the MIT License.