Z²ᴱ logo

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
PathRoleLOC
cmd/z2e-terminal/main.goEntry point~20
internal/agent/runtime.goCore agent loop~303
internal/agent/tools.goTool definitions + execution~435
internal/agent/policy.goCommand policy~19
internal/agent/prompt.goSystem prompt loader~27
internal/agent/session_debug.goDebug snapshots~237
internal/agent/types.goShared types~53
internal/agent/prompts/Embedded system prompt
internal/config/Env config loader + tests
internal/executor/runner.goShell 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

  1. just fmt — Format code (gofmt -w ./cmd ./internal)
  2. just vet — Static analysis
  3. just test — Run tests
  4. just build — Ensure compilation
  5. just run — Manual smoke test

Code Style

  • gofmt only — do not hand-align spacing
  • Error handling: early returns, wrap errors with %w
  • Prefer typed structs over map[string]any for internal logic
  • Use JSON tags only on serialized payloads
  • Bubble Tea: Model struct with Init(), Update(), View() pattern
  • Agent runtime: explicit step loop with guard checks, no goroutine races
  • Never leak AI_GATEWAY_API_KEY, Authorization headers, 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/Msg channel.
  • Single executor path: bash -lc is the only audited shell-crossing point.

Tests

Two test files currently exist:

  • internal/config/gateway_test.go
  • internal/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 — the appVersion constant (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.md in the repo root documents architecture, guards, and conventions for agentic contributors

Contact

On this page