Angela is a terminal-based AI coding assistant built in Go, forked from Crush. It connects to LLMs and gives them tools to read, write, and execute code in your terminal.
Key capabilities:
- Multi-provider — Anthropic, OpenAI, Gemini, Bedrock, GitHub Copilot, OpenRouter, Ollama, and any OpenAI-compatible API
- Multi-agent — built-in
coder,explore,plan,co-design,deep-researchagents with configurable dispatch, plus sub-agents that can run in the background - LSP integration — uses language servers for code intelligence, just like your editor
- MCP support — extend with Model Context Protocol servers (
stdio,http,sse) - Image input — paste images from clipboard or attach files for vision-capable models
- Hooks — user-defined shell scripts that fire before tool execution for policy enforcement
- Permissions and sandboxing — declarative allow/ask/deny rules, plus optional OS-level isolation (Landlock, Seatbelt)
- Sessions — resume, branch, list, and export conversations from the TUI or the command line
- Agent Skills — reusable instruction packages (Agent Skills standard), with built-in skills for configuring Angela itself
- Cross-platform — macOS, Linux, Windows, Android, FreeBSD, OpenBSD, NetBSD
From GitHub Releases (pre-built binaries for all platforms), or with Go:
go install github.com/NaturalSelect/angela@latestangela upgrade # latest stable release
angela upgrade --pre-release # also consider pre-releases (release candidates)angela upgrade downloads the release from GitHub and verifies the cosign
signature on the release's checksums.txt, which must come from the release
workflow for that tag. It then checks the download against that file and
replaces the running executable. Verification needs access to the Sigstore
trust root at tuf-repo-cdn.sigstore.dev, and a release without a valid
signature is refused.
- No downgrades. Angela only moves to a strictly newer version. A
pre-release build is never rolled back to an older stable release. It moves
on to its own stable release once that is published, or to a newer
pre-release when you pass
--pre-release. - Package managers. If
dpkg,rpm,apkorpacmanowns the executable, the release's package file is installed with that tool, throughsudowhen you are not root, so the package database stays correct. - Go installs and local builds. A build without a release version, such
as one from
go installorgo build, cannot be compared with releases and is not upgraded. Install a release instead, or rungo installagain.
- Run
angelain your project directory. - Press Ctrl+L to open the model picker.
- Choose a provider, paste your API key, and start coding.
Press Ctrl+P for the command palette. Use angela --continue to
resume the most recent session, or angela --session <id> for a specific one.
To take back the last turn, choose Undo Last Turn in the palette once a
session has started. It restores the files the turn edited and removes its
messages, and shows a preview first.
Set API keys via environment variables to skip the manual step:
| Variable | Provider |
|---|---|
ANTHROPIC_API_KEY |
Anthropic |
OPENAI_API_KEY |
OpenAI |
GEMINI_API_KEY |
Google Gemini |
OPENROUTER_API_KEY |
OpenRouter |
AWS_PROFILE |
Amazon Bedrock |
GitHub Copilot uses a device login instead of a key: run angela login copilot.
See the full provider list for all supported variables.
| Command | Purpose |
|---|---|
angela |
Start the interactive UI |
angela run "<prompt>" |
Run one prompt non-interactively and exit |
angela commit |
Generate a commit message for staged changes and commit |
angela session ... |
list, show, last, rename, delete, export |
angela agent ... |
list configured agents, create one from a description |
angela config validate |
Load angela.json and report errors and warnings |
angela models [term] |
List models from known providers |
angela login / logout |
Sign in to or out of a platform (copilot) |
angela logs |
Show the log for the current project |
angela stats |
Show token usage, cost, and activity statistics |
angela vacuum (gc) |
Compact the database and delete temporary files older than an hour (--dry-run previews) |
angela dirs |
Show config directories |
angela projects |
List known project directories |
angela pprof ... |
Export runtime profiles of a running Angela process |
angela acp |
Run as an ACP agent over stdio (see Editor integration) |
angela update-providers |
Refresh the provider catalog |
angela upgrade |
Upgrade Angela to the latest release (see Upgrading) |
Run any command with --help for its flags. These flags work on every
command:
| Flag | Purpose |
|---|---|
-c, --cwd <dir> |
Run as if started in this directory (not accepted by angela acp) |
-D, --data-dir <dir> |
Use a different data directory |
-d, --debug |
Turn on debug logging |
-y, --yolo |
Accept every permission prompt (see Permissions) |
--auto-accept-edits |
Accept file edits only (see Permissions) |
angela run "Explain what this package does"
cat README.md | angela run "make this more glamorous" > GLAMOROUS_README.md
# Save only the final response to a file (stdout still shows the conversation)
angela run --output answer.md "Summarize the open TODOs"
# Pick a model, continue a session, hide the spinner
angela run -m provider/model --continue -q "Follow up"A headless run has nobody to answer a permission prompt, so it refuses
anything it cannot already settle from your rules. Pass --yolo or
--auto-accept-edits (see Permissions) to let it proceed. A
cancelled run exits with an error.
angela commit writes a commit message for your staged changes and commits
them, without opening the interactive UI. It is the command-line counterpart
of /commit: the commit is signed off, repository git hooks are skipped,
and it exits with an error if nothing is staged.
git add -p
angela commitangela acp runs Angela as an Agent Client Protocol
agent over stdin and stdout, so editors such as Zed and Neovim
(CodeCompanion) can drive it. The editor starts the command itself. In Zed,
add this to settings.json:
One process serves one project, named by the first session request. Branch
agents and background agents are not available, and the question tool works
only when the editor supports forms. Permission prompts go to the editor and
offer allow and deny, each either once or for the rest of the session;
--yolo and --auto-accept-edits apply as usual. Editors can load a session
with its history or resume it without the history. Closing a session stops its
work and releases it, but keeps it on disk so it can be opened again; only
deleting it removes it.
Angela connects the MCP servers in its own angela.json and the ones an editor
passes when it opens a session, such as Zed's context servers. Angela declares
HTTP and SSE support, so editors send those servers as well as stdio ones. The
editor's servers last for the life of the process and are never written to
angela.json. Opening a session waits up to five seconds for them to connect.
A slower server keeps connecting in the background, and its tools reach the
agent in later runs, so a session never hangs on a server that is slow or
stuck. A server that failed is tried again the next time a session opens.
Their commands, arguments, URLs and headers are used exactly as the editor
sent them, without $VAR or $(command) expansion.
The editor's servers are shared by every session in the process. If
angela.json already has a server of the same name, its entry wins. If an
earlier session already runs a server of that name with a different config,
that one keeps running and the later one is ignored. Two names that become the
same once characters other than letters, digits and hyphens are replaced keep
only the first. Each ignored server is named in the log with the reason. If no
provider is configured, opening a session fails with a message saying so; set
one up by running angela in a terminal, and the editor's next attempt works
without restarting the agent.
The editor's / menu lists a few built-in commands, your custom commands,
user-invocable skills and MCP prompts, and updates when an MCP server connects
or changes its prompts. Start a prompt with one of them to run it, as in the
terminal UI. A command with one argument takes the rest of the line. A command
with several takes NAME=value pairs, and a value with spaces goes in double
quotes. A skill is attached to the prompt, and any text after its name is sent
alongside it.
The built-in commands are /compact to summarize the conversation, /title
to generate the session title again, /btw <question> to ask a side question
that stays out of the conversation, and /init to have Angela write the
project context file. The first three answer in the chat without starting a
model turn, and session/cancel stops them. Other palette entries, such as
scrolling and themes, only make sense in the terminal, and /undo is left out
because it reverts files without a confirmation step.
When the editor advertises compaction support, a compaction, whether started
by /compact or by Angela when the context fills up, shows as its own entry
that goes from in progress to completed, failed or cancelled, with the summary
attached once it is ready. Other editors see the summary as a thought.
Angela is configured with angela.json. No config is required to get started.
{
"$schema": "https://raw.githubusercontent.com/NaturalSelect/angela/main/schema.json",
"providers": {
"ollama": {
"type": "ollama",
"base_url": "http://localhost:11434/v1"
}
},
"mcp": {
"github": {
"type": "http",
"url": "https://api.githubcopilot.com/mcp/",
"headers": { "Authorization": "Bearer $GH_PAT" }
}
}
}Config files are discovered by walking up from the working directory to the git worktree root. Multiple layers are deep-merged (project overrides global):
| Priority | Path |
|---|---|
| 1 | ./.angela.json |
| 2 | ./angela.json |
| 3 | ~/.config/angela/angela.json ($ANGELA_GLOBAL_CONFIG/angela.json if set) |
| 4 | /etc/angela/angela.json (Unix-like systems only) |
Run angela dirs to see which files were found, and angela config validate
to check them for errors.
Selected string fields (API keys, headers, URLs) support $VAR and $(cmd)
shell expansion.
Angela also reads project instructions from AGENTS.md, ANGELA.md,
CLAUDE.md, GEMINI.md, .cursorrules, and
.github/copilot-instructions.md in the working directory (plus *.local.md
variants), and ~/.config/angela/ANGELA.md or ~/.config/AGENTS.md for
instructions that apply to every project. Change the list with
options.context_paths and options.global_context_paths.
For the full reference, see docs/config/.
Angela uses a multi-agent system. The main coder agent can delegate to
specialized agents:
| Agent | Mode | Purpose |
|---|---|---|
coder |
primary | Primary agent with all tools |
explore |
subagent | Fast read-only codebase search |
general |
subagent | Multi-step tasks with inherited tools |
web-fetch |
subagent | Web search and page fetching |
plan |
branch | Interactive implementation planning |
co-design |
branch | Interactive design of a whole solution, section by section |
deep-research |
branch | Root cause analysis and design |
Sub-agents run on their own and report back. Branch agents fork the conversation and hand control to you until you merge their result back or end the branch.
The coder can start a sub-agent in the background and keep working. Its
result arrives later as a notification that starts a new turn. Open the
Sub-sessions entry in the command palette (Ctrl+P) to look
inside a running sub-agent or stop it.
Custom agents can be defined in angela.json or as markdown files. List the
configured ones with angela agent list. See docs/agents/.
Experimental — no compatibility guarantee; may change or be removed in a future release.
Hooks are shell commands that fire before tool execution. Use them to block dangerous commands, rewrite tool input, inject context, or auto-approve safe operations.
{
"hooks": {
"PreToolUse": [
{ "matcher": "^Bash$", "command": "./hooks/no-rm-rf.sh" }
]
}
}See docs/hooks/ for the full guide.
Angela asks before running tools. Configure allowed tools and declarative
rules in angela.json:
{
"permissions": {
"allowed_tools": ["Read", "LS", "Grep"],
"rules": [
{ "action": "deny", "tool": "read", "pattern": "**/.env", "mode": "path" },
{ "action": "allow", "tool": "Bash", "pattern": "git status*" }
],
"prompt": "ask"
}
}Rules are evaluated deny, then ask, then allow. tool is either an access
category (read, edit, execute, network, mcp, list) or a single
tool name. mode says how pattern is compared and defaults to auto,
which picks by category:
mode |
Compares pattern against |
|---|---|
path |
A filesystem path, where * stops at a separator and ** crosses it |
free |
Free text, where * matches anything |
domain |
The host of a URL, matching that host and any subdomain |
prompt decides what happens when no rule matches: ask (default) or deny.
Use --yolo to skip all prompts (at your own risk). Use
--auto-accept-edits to auto-approve file edits while still being asked
about everything else; it cannot be combined with --yolo. Even in yolo
mode, merging a branch agent's result still asks first. Add --yolo-merge
to auto-approve that too.
Use --sandbox to restrict the process itself with OS-level isolation
(Linux via Landlock, macOS via Seatbelt) instead of relying on approval
prompts. By default it leaves the working directory, Angela's own data
directories, and outbound network access writable/reachable, and makes
the rest of the filesystem read-only:
angela --sandbox
angela run --sandbox "..."
# Add extra directories on top of the defaults (repeatable)
angela run --sandbox --sandbox-rw /extra/writable --sandbox-ro /extra/readable "..."
# Also block outbound network access for commands the agent runs
# (Angela's own provider requests are unaffected; Linux only, refused on macOS)
angela run --sandbox --sandbox-no-network "..."The default set is also widened with any directory an unconditional
filesystem allow rule under permissions.rules (see Permissions
above) already covers, so an edit or read the permission policy already
approves without a prompt doesn't instead run into a confusing sandbox I/O
error.
Inside a Docker or other OCI container Angela treats the container as the
sandbox and does not apply Landlock on top. Pass --no-docker-sandbox to
apply it anyway.
--sandbox is independent from --yolo, and the restriction is irreversible
for the life of the process. Both Linux and macOS restrict the running
process in place and return normally on success, so the interactive
/sandbox command works the same way on both, not just at startup.
--sandbox-no-network is Linux-only: an already-sandboxed macOS process
can't apply a second, tighter profile to just the commands it spawns, so
--sandbox --sandbox-no-network fails at startup on macOS instead of
silently leaving those commands' network access open. macOS enforcement
goes through sandbox_init(3), the same deprecated-but-still-present API
sandbox-exec(1) itself is built on; if a future release removes it,
--sandbox fails at startup instead of silently skipping the restriction.
When Angela runs inside VS Code's integrated terminal with the GitHub
Copilot Chat extension active, an edit-shaped permission prompt also opens
a native VS Code diff tab with Accept/Reject buttons, alongside the usual
terminal dialog — whichever you answer first settles the request. Pass
--no-vscode-diff to always use the terminal dialog only.
Inline image previews need a terminal that supports Kitty graphics protocol
Unicode placeholders. Angela auto-detects kitty, Ghostty, and Rio; VS Code's
integrated terminal and WezTerm answer the basic Kitty query but don't render
placeholders correctly. Override the detection with
--kitty-placeholders/--kitty-placeholders=false (per launch) or
options.tui.kitty_placeholders (persistent, in angela.json).
The built-in ImageGenerate/ImageEdit tools follow the same detection by
default, so they stay hidden in terminals without placeholder support. Pass
--enable-image-tools or set options.enable_image_tools to true to use
them in any terminal. Where inline previews are unsupported, Angela shows no
image in the terminal and instead prints the image ID and size; save the
original with the "Export Image" command. Turn the tools off entirely with
--enable-image-tools=false or options.enable_image_tools: false.
Angela discovers Agent Skills (folders containing a SKILL.md) from these
directories:
| Scope | Directories |
|---|---|
| Project | .agents/skills, .angela/skills, .claude/skills, .cursor/skills |
| Global | ~/.config/angela/skills, ~/.config/agents/skills, ~/.agents/skills, ~/.claude/skills |
Add more with options.skills_paths and hide some with
options.disabled_skills.
A set of skills ships inside the binary, so Angela can help you configure
itself. Ask it to add a provider, MCP server, LSP, hook, or permission rule
and it loads the matching skill (angela-config, angela-mcp,
angela-lsp, angela-hooks, angela-permissions, angela-agents,
angela-sandbox, angela-sessions, angela-shell, angela-skills,
angela-setup, angela-migrate). General-purpose ones cover jq, writing
unit tests, and code walkthroughs. A skill with the same name in your own
skill directories replaces the built-in one.
| Variable | Effect |
|---|---|
ANGELA_GLOBAL_CONFIG |
Directory that holds the global angela.json |
ANGELA_CACHE_DIR |
Directory for the provider catalog cache |
ANGELA_SKILLS_DIR |
Replace the default global skills directories |
ANGELA_AGENTS_DIR |
Replace the default global agent markdown directory |
ANGELA_DISABLE_METRICS |
Same as options.disable_metrics |
ANGELA_DISABLE_PROVIDER_AUTO_UPDATE |
Same as options.disable_provider_auto_update |
ANGELA_DISABLE_DEFAULT_PROVIDERS |
Same as options.disable_default_providers |
DO_NOT_TRACK |
Turns metrics off when set to a true value |
Angela keeps its provider and model list up to date from
Catwalk. To stop the automatic
check, set options.disable_provider_auto_update or
ANGELA_DISABLE_PROVIDER_AUTO_UPDATE. To update by hand:
angela update-providers # from Catwalk
angela update-providers https://example.com/ # from a custom URL
angela update-providers /path/to/providers.json # from a local file
angela update-providers embedded # reset to the bundled listAngela auto-discovers models from Ollama, LM Studio, llama.cpp, and other local providers:
{
"providers": {
"ollama": {
"type": "ollama",
"base_url": "http://localhost:11434/v1/"
}
}
}Logs are stored in logs/angela.log inside the data directory, which is
.angela in the project by default. Change the data directory with
options.data_directory or --data-dir.
angela logs # last 1000 lines
angela logs --tail 200 # last 200 lines
angela logs --follow # real-timeEnable debug logging with --debug or "options": { "debug": true }.
Angela sends pseudonymous usage metrics to a PostHog server run by Charm at
data.charm.land, unless you turn them off. The prompt and response events
record the session ID, provider, model, token counts, and cost, not the text
of your conversation. Every event also carries the operating system, CPU
architecture, TERM value, shell name, Angela and Go versions, and an
identifier derived from a hash of your machine ID. Errors and panics are
reported as well. The code that sends them is in
internal/event.
To opt out, set "options": { "disable_metrics": true }, export
ANGELA_DISABLE_METRICS=1, or export DO_NOT_TRACK=1.
Code inherited from charmbracelet/crush is FSL-1.1-MIT; original work added since is MIT. See LICENSE.md for the exact split.

{ "agent_servers": { "Angela": { "command": "angela", "args": ["acp"] } } }