Codebase map
A map of cmd/ and internal/: what each package does, where to start reading, and how a message travels from a chat to the model and back.
On this page
Habakkuk is one Go module, github.com/MayorScript/habakkuk. The binary is cmd/habakkuk; everything else is under internal/, grouped by area. The desktop app (apps/desktop) is a separate module. For the design behind this layout, read Architecture.
Top level#
| Path | What is there |
|---|---|
cmd/habakkuk/ |
The CLI. main.go holds the usage text and the command switch; each command group has its own file (board.go, sessions.go, setup.go, update.go, security.go ...) |
internal/ |
The packages below |
apps/desktop/ |
Habakkuk Desktop, its own Go module (Wails v3, CGO) |
apps/website/ |
The website and docs site |
docs/ |
This documentation |
scripts/install.sh |
The release installer |
assets/brand/ |
Logo, icons and social card |
Dockerfile |
The container image, with an optional browser target |
.github/workflows/ |
CI (ci.yml) and releases (release.yml) |
internal/#
Dependencies point downward: agent uses llm, tools and core/session; core/jobs knows nothing about agents; core/store knows nothing above it. Only app sees everything.
app#
Wires configuration, storage, models, tools, channels and workers together. app.Open builds an App from $HABAKKUK_HOME; App.Pools returns the worker pools for each job kind. Files are split by area (models.go, platforms.go, media.go, board.go, nodes.go, telemetry.go ...). The CLI commands call into it.
agent#
The turn loop and prompt assembly. Runner.HandleTurn (loop.go) is the handler for turn jobs: it loads and repairs the transcript, calls the model, runs tools, appends results, and repeats. Also here: compaction (compact.go), delegation (delegate.go, subturns.go), identity and the first-chat welcome (identity.go), per-session overrides (overlay.go), structured output (schema.go), taint tracking (taint.go), titles, tool search and git worktrees for sub-agents.
llm#
Provider-neutral types (types.go: Provider, Request, Response, Block), error classification (errors.go) and the Router (router.go) that retries, rotates keys and falls back. Adapters: anthropic, openai (Chat Completions and Responses), gemini, bedrock. auth holds subscription logins; usage records tokens and prices them.
tools#
The tool Registry, toolsets, permission modes and the policy (tools.go), built-in core tools (builtin.go, exec.go, patch.go, search.go, process*.go), the hardline command blocklist, the SSRF guard and taint. Sub-packages are toolsets and helpers:
| Package | What it does |
|---|---|
tools/browser |
Browser toolset over the Chrome DevTools Protocol, with the URL guard |
tools/computer |
Computer toolset: screenshots, mouse and keyboard through OS commands |
tools/meeting |
Meeting attendance through a dedicated Chrome and live captions |
tools/homeassistant |
Home Assistant tools and event triggers |
tools/media |
Attachment type detection, speech-to-text |
tools/mediatools |
Text-to-speech, images, video, view_image, read_document, web_search |
tools/voice |
habakkuk talk: microphone, voice activity detection, wake phrases, playback |
tools/review |
The LLM approval reviewer |
tools/sandbox |
Docker and SSH command backends |
channel#
The Gateway (gateway.go) decides who may talk, maps conversations to agents and sessions, handles chat commands (commands.go, session_commands.go), approvals and clarify questions, and delivers replies. The Supervisor (supervisor.go) restarts adapters and watches their heartbeat. channel.go defines the Adapter interface and its optional extras. One sub-package per platform: telegram, slack, whatsapp, whatsappagent, whatsappcloud, discord, signal, matrix, email, sms, msteams, googlechat, bluebubbles, line, mattermost, irc, ntfy, messenger (also Instagram), feishu, dingtalk, wecom, zulip, rocketchat, nextcloudtalk, twitch. Shared helpers: metagraph (Meta Graph API), apptoken (cached app access tokens), jwt (RS256 tokens for Bot Framework and Google), upload (multipart bodies).
channel/web is the HTTP surface: the chat page, the JSON API and Server-Sent Events, the dashboard's API, webhooks and the OpenAI-compatible API. The dashboard's front end is in channel/web/ui.
core#
| Package | What it does |
|---|---|
core/jobs |
The durable queue: Enqueue, Claim with a lease, Heartbeat, Complete, serial keys, retries, reclaiming jobs of dead processes; Pool runs handlers |
core/session |
Sessions and append-only transcripts, crash repair, full-text search |
core/state |
Small per-session state: overrides, goals, steering, task lists, progress drafts |
core/store |
Opens and migrates the SQLite databases; the blob store; atomic file writes |
core/checkpoint |
Workspace snapshots in a shadow git repository |
core/events |
The in-process event bus that streams turn activity to clients |
core/frontmatter |
YAML frontmatter for Markdown files |
knowledge#
| Package | What it does |
|---|---|
knowledge/memory |
Memory notes, the FTS5 and embedding index, memory tools, the user profile; memory/consolidate runs background review and the nightly pass |
knowledge/skills |
SKILL.md discovery, precedence, skill tools, the curator |
knowledge/hub |
Installs skills and plugins: sources, safe unpacking, scan, tree hash, lock file, backups |
knowledge/plugins |
habakkuk-plugin.yaml packages: loading, describing, script commands |
protocols#
| Package | What it does |
|---|---|
protocols/mcp |
MCP client: server connections, tools, OAuth, the catalog |
protocols/mcpserver |
Habakkuk as an MCP server |
protocols/a2a |
Agent2Agent server and client |
protocols/acp |
Agent Client Protocol server for editors |
protocols/nodes |
Device nodes: pairing, connections, capabilities |
work, ops, config, tui#
| Package | What it does |
|---|---|
work/schedule |
Scheduled prompts and scripts with at-most-once slots |
work/board |
The task board and its dispatcher |
ops/hooks |
User commands run on events |
ops/i18n |
Message catalogs (YAML per locale in locales/) |
ops/logs |
Log rotation, redaction and reading |
ops/secrets |
Secret manager sources |
ops/security |
habakkuk security audit |
ops/telemetry |
Metrics and OTLP traces |
config |
Strict YAML config: types, defaults, validation, provider presets, the starter config |
tui |
The full-screen terminal UI (Bubble Tea) over a narrow Backend interface |
Main flows#
A chat message#
platform ──> adapter ──> supervisor ──> gateway ──> turn job ──> agent
^ │
└──────── delivery job <────────────────┘
- An adapter (
internal/channel/<type>) receives a message and hands it to the inbox; theSupervisorkeeps the adapter running. Gateway.Handlechecks the sender (allowlist or pairing), whether a group message is addressed to the bot, and handles commands. Otherwise it picks the agent and session, appends the message and enqueues aturnjob whose ID derives from the platform message ID.- A worker in a
jobs.Poolclaims the job with a lease.Gateway.HandleTurnwrapsagent.Runner.HandleTurn, which runs the loop:llm.Router.Sendstreams the model call,tools.Registry.Executeruns tool calls under the permission policy, and every append checks the lease. - When the turn finishes, the gateway enqueues a delivery job;
Gateway.HandleDeliverformats the reply, splits it into chunks, and records each chunk sent so a retry resumes where it stopped.
Other entry points#
- CLI and TUI (
habakkuk chat,run,tui) create a session and run the same turn jobs in-process (Runner.Ask,Begin,Await), following live events fromcore/events. - HTTP (
channel/web): the web chat is an ordinary adapter; webhooks, the OpenAI-compatible API, A2A and MCP over HTTP start turns through the same runner. - Schedules and the board (
work/) enqueue jobs whose IDs derive from the slot or the card attempt, so each runs at most once. - Delegation enqueues
subturnjobs that run in their own pool.
Crash recovery#
On start, jobs.Queue.ReleaseDead frees jobs whose owner process is gone; they are claimed again and the turn loop repairs the transcript (a tool call without a result gets an "interrupted" result) before going on.
Where to start reading#
internal/core/jobs/queue.goandworker.go: the queue everything runs on.internal/agent/loop.go: one turn.internal/channel/gateway.go: from a chat message to a turn and back.internal/app/app.go: how it is all put together.cmd/habakkuk/main.go: the commands.
Tests sit beside the code (*_test.go); adapters are tested against fake platform servers, and the job queue and turn loop include crash and retry cases.