walid@portfolio:~/lab/angela-cli-architecture$
cd../lab
02ideaOct 2026

Inside an AI shell assistant: the Angela CLI blueprint

How a Gemini-powered terminal assistant is designed to fit together: shell hooks, a context engine, a request pipeline, a five-level risk classifier, adaptive confirmation and a rollback log. The design is worth borrowing; the project behind it is an unfinished prototype, and the checks say exactly where. Checked against the project’s own code

Angela is an AI assistant that lives in your shell. You type what you want in plain English; it works out the command, scores how sure it is, rates how risky it is, previews it, asks before anything destructive, runs it, and can roll it back. That loop is a clean blueprint for any AI that acts on a real machine, built from textbook parts: shell hooks that watch what you do, a context engine, a dispatcher, a five-level risk ladder, confirmation in proportion to risk, and a transaction log for undo. This is the blueprint, with each part checked against the code. The honest finding: the architecture is worth borrowing, the project is not something to rely on. It is an alpha prototype, untouched since May 2025, pinned to a Gemini model Google has since shut down, and several of the pieces the design describes are missing or broken.

AI shellArchitectureGeminiPythonDesign patternsSafetyangela-cli (GitHub) ↗Typer ↗Rich ↗Pydantic ↗Google Gen AI SDK ↗
i
What this is

A design reference, not an install guide. Angela CLI is an open-source Python tool that sits inside Bash or Zsh and turns plain-English requests into shell commands through Google’s Gemini API, wrapped in context gathering, risk checks, confirmation and undo. The architecture it describes is a good map for building any agent that executes commands on a real machine. The code is a useful place to see that map partly built, and to learn from where it isn’t.

!
Not “AGI”, and not finished

The project bills itself as the world’s first command-line AGI. Its own README says “(will be)” and “ANGELA IS NOT COMPLETE YET”, and its package metadata says Alpha, version 0.1.0. Technically it is a Typer command-line app that calls Gemini. One developer, three stars, last commit 25 May 2025, and no licence file despite the MIT badge.

Checked, not copied

What held up, on 2 October 2026

Checked against the angela-cli repository at its latest commit (aafda64, 25 May 2025), by reading the code and running it, plus Google’s Gemini deprecation notices.

ClaimWhat the code says
The stackMostly right: Python 3.9+, Typer, Rich, Pydantic, asyncio (in 50 files) and Gemini. Click is only Typer’s own dependency, not Angela’s. The Gemini SDK it uses, google-generativeai, is deprecated; Google ended support on 30 November 2025.
The modelHard-coded to gemini-2.5-pro-preview-05-06, which Google shut down on 2 December 2025. AI calls fail until that line in constants.py changes.
The module layoutAccurate. All 14 component packages exist: about 77,700 lines of Python in 121 files, 4,659 of them in the orchestrator alone.
Shell hooksReal, but not where described. The plain angela.bash and angela.zsh are thin wrappers marked “implemented in a future phase”. The preexec and precmd hooks live in angela_enhanced.zsh, and angela_enhanced.bash fakes them with a DEBUG trap plus PROMPT_COMMAND.
The named componentsMixed. GeminiClient, ConfidenceScorer, ErrorAnalyzer, CommandRiskClassifier, RollbackManager, ErrorRecoveryManager and all four toolchain adapters exist as classes. PromptBuilder, ResponseParser and AdaptiveConfirmation are plain functions, PreviewGenerator is called CommandPreviewGenerator, and CommandValidator doesn’t exist, so the code that imports it fails.
Five risk levelsCorrect: SAFE, LOW, MEDIUM, HIGH and CRITICAL, scored 0 to 4, with confirmation from MEDIUM up. An unrecognised command defaults to MEDIUM.
The seven-stage pipelineIdealised. The orchestrator is a dispatcher: regular expressions sort a request into one of 16 types, and each type has its own handler. Planning only happens for multi-step requests, and four request types point at handlers that were never written.
Relevance-filtered contextMostly not. Ordinary requests send fixed slices: the first five frameworks, dependencies and files. Only code generation ranks files against a token budget, and that loop passes file paths instead of file contents.
“All operations are verified”There are holes. In a test run the validator passed rm -rf / (its pattern catches -r or -f, not the two together), though the risk classifier still rated it HIGH and asked first. Trusting a command trusts its first word, so trusting rm once lets every later rm skip confirmation. Gemini’s own content filters are switched off by default.
A working toolNot as shipped. There is no CI (the “build passing” and “87% coverage” badges are static images), the test suite gives 3 passes and 18 errors, and without an API key every command crashes at import, including angela init, the command meant to set the key.
The idea

Ambient intelligence in the shell

Traditional command lines make you memorise syntax and flags. Chat assistants understand plain language but can’t see your machine. Angela’s design puts the model inside the shell, where it can see your project, the commands you just ran and the files you are working on, and act right there. The ambition is an assistant you can talk to at any level, from “show disk usage” to “set this project up for Docker”, that adapts to how you work over time.

The five design principles

✓Contextual understanding: a model of the project, its frameworks and dependencies, and your recent activity✓Any level of abstraction: from a single command to a high-level goal✓Progressive disclosure: simple stays simple, power unfolds when needed✓Safety first: classify, preview, confirm, and keep a way back✓Learning over time: trust and preferences built from your own history
The architecture

Six subsystems

As designed, with what the code actually contains.

01·SHELL

Shell integration

Zsh preexec and precmd hooks (a DEBUG trap in Bash) report every command, its exit code, its duration and any change of directory to Angela in the background, so the terminal never waits. A tmux file adds a status indicator and key bindings.

02·CONTEXT

Context management

Project-type inference, recent-file tracking, command history and session state, gathered lazily so only what a request needs is computed. In practice, ordinary requests get fixed-size slices of it, not a relevance-ranked selection.

03·PIPELINE

Request handling

An orchestrator classifies each request into one of 16 types (command, multi-step, file content, workflow, code generation, toolchain and so on) and hands it to that type’s handler.

04·AI

Gemini integration

A GeminiClient wrapper, prompt-building functions with few-shot examples, a parser that pulls JSON out of the reply, a nine-factor confidence scorer, and an error analyser that suggests fixes when a command fails.

05·SAFETY

Safety layer

A five-level risk classifier, regex checks for dangerous patterns, per-command impact previews, confirmation that adapts to risk and to your history, and a rollback manager that records changes as undoable transactions.

06·TOOLS

Toolchain adapters

Git, Docker, package managers and a universal translator for arbitrary command-line tools, each behind its own adapter class, plus CI/CD and test-framework integrations.

How it watches

The hook that makes it ambient

From angela_enhanced.zsh. Every notification runs in a background subshell, which is the trick that keeps a context-gathering assistant from slowing the prompt down.

angela_enhanced.zsh20 lines
# Pre-command execution hook (before command runs)
angela_preexec() {
    # Capture the command
    ANGELA_LAST_COMMAND="$1"
    ANGELA_COMMAND_START_TIME=$(date +%s)

    # Send notification to Angela's monitoring system
    if [[ ! "$ANGELA_LAST_COMMAND" =~ ^angela ]]; then
        # Only track non-angela commands to avoid recursion
        (angela --notify pre_exec "$ANGELA_LAST_COMMAND" &>/dev/null &)
    fi
}

# … angela_precmd() reports the exit code, the duration and any
#   change of directory the same way, in the background

# Register the hooks with Zsh
autoload -Uz add-zsh-hook
add-zsh-hook preexec angela_preexec
add-zsh-hook precmd angela_precmd
One request, end to end

The single-command path

What the orchestrator actually does with “find all Python files in this project”.

1

Gather context

Refresh what it knows about the working directory and project, and resolve any file the request mentions by name.

2

Classify the request

Pattern-match the text into one of the 16 request types. A plain command request takes this path; multi-step goals take another.

3

Ask Gemini for a command

Send system instructions, the context, few-shot examples and a strict JSON response format, then parse the reply into intent, command and explanation.

4

Score confidence

Rate the suggestion on history, similarity, syntax, flags and context. Below 0.6, ask a clarifying question instead of guessing.

5

Rate the risk and preview it

Place the command on the five-level ladder and generate a preview of what it would touch.

6

Confirm in proportion

SAFE and LOW run without asking. Above that, skip the question for a command you’ve trusted, or one with a long record of succeeding at a level you allow; otherwise ask simply at MEDIUM and show a detailed confirmation at HIGH and CRITICAL.

7

Run, log, learn

Execute, record the outcome in history, and offer to trust a command you keep approving. On failure, analyse the error and suggest a fix.

The contract with the model

Structured output, every time

The last thing every command prompt contains before the user’s request. Forcing JSON is what lets the rest of the pipeline treat the model’s answer as data rather than prose.

prompts.py · response format8 lines
Expected response format (valid JSON):
{
    "intent": "the_classified_intent",
    "command": "the_suggested_command",
    "explanation": "explanation of what the command does",
    "confidence": 0.85, /* Optional confidence score from 0.0 to 1.0 */
    "additional_info": "any additional information (optional)"
}
The safety layer

The risk ladder

LevelCoversConfirmation
0 · SAFECoversReading operations, info commandsConfirmationNone
1 · LOWCoversDirectory creation, simple file operationsConfirmationNone
2 · MEDIUMCoversFile content changes, non-critical configuration; also any command it doesn’t recogniseConfirmationAsks first, unless you’ve trusted the command
3 · HIGHCoversSystem configuration, package installationConfirmationDetailed confirmation
4 · CRITICALCoversDestructive operations, security-sensitive changesConfirmationDetailed confirmation, with a warning

The ladder, as code

angela/constants.py17 lines
# Safety
RISK_LEVELS = {
    "SAFE": 0,            # Reading operations, info commands
    "LOW": 1,             # Directory creation, simple file operations
    "MEDIUM": 2,          # File content changes, non-critical configurations
    "HIGH": 3,            # System configuration, package installation
    "CRITICAL": 4,        # Destructive operations, security-sensitive changes
}

# Default confirmation requirements by risk level
DEFAULT_CONFIRMATION_REQUIREMENTS = {
    0: False,  # SAFE: No confirmation needed
    1: False,  # LOW: No confirmation needed
    2: True,   # MEDIUM: Confirmation needed
    3: True,   # HIGH: Confirmation needed
    4: True,   # CRITICAL: Confirmation needed with warning
}

Undo, as transactions

The part most worth copying is the rollback manager. Each logical action, say a five-step plan, opens a transaction; every file change and command inside it is recorded with what is needed to reverse it, either a backup or a compensating command; and rollback replays those in reverse order, newest first. Transactions are saved as JSON, so they survive the session. It isn’t atomic in the database sense, but it turns “the AI broke my project” into one command.

When a step fails, an error-recovery manager chooses between retrying, modifying the command, trying an alternative, preparing the environment, reverting, skipping or aborting.

Under the hood

The patterns it is built on

PatternWhere it shows up
Service registrycore/registry.py: a thread-safe singleton that components are fetched from by name and created on first use. In practice a service locator; nothing arrives through constructors.
Event buscore/events.py: 46 lines of publish and subscribe. It matches event names exactly, so a subscriber to “monitoring:*” never receives “monitoring:git_status”.
CommandOperations recorded with their undo inside rollback transactions.
DispatcherThe orchestrator’s request types, each routed to its own handler.
AdapterOne class per external tool (Git, Docker, package managers, any CLI) behind a common shape.
ObserverShell hooks and background monitors publishing what happens, for context to pick up.
Lessons from the code

What to fix before you borrow it

✗Match dangerous commands on parsed flags, not raw strings: -rf slipped past a -r|-f regex✗Trust a whole command shape, never just its first word✗Leave the model provider’s safety filters on unless you have a reason✗Read the model name from config, so a retired model is a one-line change✗Don’t build the API client at import time; setup commands must run without a key✗Keep the API key in the OS keychain or an environment variable, not a plain-text config file✗Give wildcard event subscriptions a matcher, or they silently receive nothing✗Put the test suite in CI, so a refactor that breaks every import gets noticed

The roadmap, and where things stand

The design’s roadmap lists deeper multi-tool orchestration, local models for privacy, customisable learning, multi-agent collaboration, visual feedback and team features. None of it has landed: the code has one model client, Gemini’s, and no commit since 25 May 2025.

If you want to read it running

Explore the code safely

For study, not daily use. Use --suggest-only (or --dry-run) so nothing executes, and remember its safety layer has the gaps above.

explore-angela15 lines
git clone https://github.com/CarterPerez-dev/angela-cli.git
cd angela-cli
python3 -m venv .venv && source .venv/bin/activate

# editable install only: a regular install leaves most of the package out
pip install -e .

# set the key first: without one, every command crashes at import
export GEMINI_API_KEY=your_key_here

# angela/constants.py pins gemini-2.5-pro-preview-05-06, which Google has
# shut down; point GEMINI_MODEL at a current model before asking anything

python -m angela --help
python -m angela request --suggest-only "find all Python files in this project"
i
The takeaway

The shape is right: watch the shell, gather context lazily, turn language into a structured suggestion, score it, rate its risk, preview it, confirm in proportion to the risk, run it inside something you can undo, and learn from what happens. Build that loop with real validation, the provider’s filters left on and nothing hard-coded, and it is a solid blueprint for any agent that touches a real machine.