Overview
Autonomous AI agent TUI for penetration testing and CTF challenges.
z2e-terminal is an autonomous AI agent TUI built with Go and Bubble Tea. It accepts natural-language missions, plans and executes multi-step CLI actions autonomously, observes output, reasons, and iterates until the objective is reached or runtime limits are hit.
Current Version
v0.2.4
Core Architecture
| Layer | Package | Responsibility |
|---|---|---|
| TUI | internal/ui/ | Terminal UI: transcript, composer, status bar, model picker, streaming |
| Agent | internal/agent/ | Core loop: LLM turns, tool execution, policy, debug snapshots |
| LLM | internal/llm/gateway/ | OpenCode Go SSE streaming client, model catalog, retry with backoff |
| Executor | internal/executor/ | bash -lc shell runner with timeout, output capture, truncation |
| Config | internal/config/ | Environment config loader for API keys and model settings |
Agent Loop
The core loop is Plan → Execute → Observe → Replan:
- LLM Turn: Send conversation to the model via SSE streaming (up to 3 total attempts per step)
- Aggregate: Collect tool_calls from stream fragments
- Emit: Stream assistant response to TUI
- Execute: Run each tool call via
bash -lc - Observe: Package output as
z2e.tool_observation.v1and append to chat - Replan: Repeat until final answer, max steps (30), doom-loop, empty-turn, or error
Safety Guards
- Max tool steps: 30
- Doom-loop detection: 3 identical command signatures in a row
- Max empty turns: 2
- Max LLM retries: 2 per step
- Command timeout: 60s default, 10 min max
- Output cap: 64KB
Features
- Autonomous agent loop: Plan → Execute → Observe → Replan
- Tool execution: bash / run_command tools (pure pass-through policy)
- Streaming output: Real-time SSE streaming from OpenCode Go gateway
- Markdown rendering: glamour for terminal markdown display
- Runtime model switching:
/modelcommand - LLM retry with backoff: Up to 2 retries per step, exponential backoff with jitter at the gateway level
- Security-oriented system prompt: Built-in pentesting and CTF persona
- Session debug snapshots:
/tmp/z2e-terminal/session.json
Model Catalog
8 models available through the OpenCode Go gateway, configured in internal/llm/gateway/models.json:
| Model ID | Provider |
|---|---|
opencode-go/deepseek-v4-pro | DeepSeek (default) |
opencode-go/deepseek-v4-flash | DeepSeek |
opencode-go/glm-5.1 | GLM |
opencode-go/glm-5.2 | GLM |
opencode-go/kimi-k2.6 | Moonshot |
opencode-go/kimi-k2.7-code | Moonshot |
opencode-go/mimo-v2.5 | Mimo |
opencode-go/mimo-v2.5-pro | Mimo |
Default model: opencode-go/deepseek-v4-pro
Environment
| Variable | Required | Default | Description |
|---|---|---|---|
AI_GATEWAY_API_KEY | Yes | — | OpenCode Go API key |
AI_GATEWAY_BASE_URL | No | https://opencode.ai/zen/go/v1 | Gateway endpoint |
AI_GATEWAY_MODEL | No | opencode-go/deepseek-v4-pro | Model override |
Codebase
- Go: ~3,200 LOC across
cmd/+internal/ - Dependencies: bubbletea, bubbles, glamour, lipgloss, godotenv