# Internals ## Layout ``` cmd/codey flag parsing, wiring, REPL internal/llm Messages API: types, HTTP, SSE, pricing internal/agent turn loop, conversation state, compaction, sessions internal/tools the tool registry and the tools internal/diag language servers and linters, and what they say about an edit internal/skills discovery and parsing of SKILL.md, Codey's own and Claude Code's internal/websearch the search command, the URL jail, HTML to text internal/mcp MCP client: starts the configured servers, offers their tools internal/config saved defaults: model, effort, approvals, web search, theme, diagnostics internal/approval allow / deny / ask, with shell analysis and Claude Code's permission rules internal/ccsettings Claude Code's permission rules and CLAUDE.md, and who may grant what internal/ask questions the agent puts to you mid-task, and the tool for it internal/hooks the lifecycle, published: fan-out, and the config's commands internal/herdr reporting agent state to the herdr pane Codey is running in internal/attach pictures pasted into a prompt: clipboard, files, markers internal/metrics JSONL event log internal/ui line-based terminal rendering internal/acp Agent Client Protocol: the wire, and its vocabulary internal/serve Codey as an agent another program drives, over ACP internal/tui full-screen Bubble Tea front end, and the setup wizard evals task suite and runner ``` Two rules hold the shape: `agent` never imports `ui` or `tui`, so the eval runner and the ACP front end can drive the loop headless; and every tool returns `(string, error)` where the error is text the model reads, not an exception Codey swallows. A failed edit is a normal event in the transcript. The TUI obeys the first rule through two one-way hatches. Events reach it via `agent.Observe`, forwarded into the Bubble Tea loop with `Program.Send`, which is safe from the agent's goroutine. Approvals go out the same way and then block the agent on a reply channel until a key arrives, and questions take the same hatch with an answer on the way back. Those channels are buffered and the wait honours the turn's context, so neither side can strand the other. ## Evals ```bash ./evals/selftest.sh # no API calls: checks the tasks measure something go run ./evals -n 3 # the real thing ``` Ten tasks, a fresh temp directory per run, full transcripts under `evals/runs//`. See [METRICS.md](../../METRICS.md).