Contributing
How to contribute to z2e-terminal development.
Project Structure
main.go
runtime.go
tools.go
policy.go
prompt.go
session_debug.go
types.go
justfile
VERSION
.env.example
| Path | Role | LOC |
|---|---|---|
cmd/z2e-terminal/main.go | Entry point | ~20 |
internal/agent/runtime.go | Core agent loop | ~303 |
internal/agent/tools.go | Tool definitions + execution | ~435 |
internal/agent/policy.go | Command policy | ~19 |
internal/agent/prompt.go | System prompt loader | ~27 |
internal/agent/session_debug.go | Debug snapshots | ~237 |
internal/agent/types.go | Shared types | ~53 |
internal/agent/prompts/ | Embedded system prompt | — |
internal/config/ | Env config loader + tests | — |
internal/executor/runner.go | Shell command runner | ~141 |
internal/llm/gateway/ | SSE streaming client + model catalog + tests | — |
internal/ui/ | Bubble Tea TUI (model.go, stream.go) | ~1,333 |
Total: ~3,200 LOC of Go across a 5-layer architecture.
Build & Test
just recipes are canonical. Raw Go equivalents work but lack version ldflags and pre-commit ordering.
# Full pre-commit check (fmt → vet → test → build)
just check
# Individual recipes
just build # build to ./bin/z2e-terminal with version ldflags
just fmt # gofmt -w ./cmd ./internal
just vet # go vet ./cmd/... ./internal/...
just test # go test ./cmd/... ./internal/...Note: gofmt scope is ./cmd ./internal, not ./....
Pre-commit Checklist
just fmt— Format code (gofmt -w ./cmd ./internal)just vet— Static analysisjust test— Run testsjust build— Ensure compilationjust run— Manual smoke test
Code Style
gofmtonly — do not hand-align spacing- Error handling: early returns, wrap errors with
%w - Prefer typed structs over
map[string]anyfor internal logic - Use JSON tags only on serialized payloads
- Bubble Tea:
Modelstruct withInit(),Update(),View()pattern - Agent runtime: explicit step loop with guard checks, no goroutine races
- Never leak
AI_GATEWAY_API_KEY,Authorizationheaders, or raw tokens into traces or observations
Key Design Decisions
- Pure pass-through policy: No deny-list, no allowlist. The system prompt guides behavior.
- SSE streaming: LLM responses streamed through a 6-stage pipeline to the terminal.
- No goroutine sharing: All mutable state flows through Bubble Tea's
Cmd/Msgchannel. - Single executor path:
bash -lcis the only audited shell-crossing point.
Tests
Two test files currently exist:
internal/config/gateway_test.gointernal/llm/gateway/client_test.go
Tests should be deterministic (no timing-sensitive flakes) and placed alongside the package they cover. Use table-driven tests with t.Parallel() for independent cases.
Version Sync
When bumping the version, update all of these in the same commit:
VERSION(plain text, e.g.v0.2.4)internal/ui/model.go— theappVersionconstant (shown in TUI title bar)README.md— the "Current version" section
Use short, one-line commit messages for version bumps.
Documentation
- Update docs in
www/content/docs/(this Fumadocs site) AGENTS.mdin the repo root documents architecture, guards, and conventions for agentic contributors
Contact
- GitHub: Z2E-Agent