# snowtema/drift architecture

> Architecture diagram of the GitHub repository snowtema/drift, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-21). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/snowtema/drift
- Repository: https://github.com/snowtema/drift

## Overview

1. **Repository shape**
   - `drift` is a single Go binary that offers both a terminal TUI and a CLI.
   - The architecture is intentionally **local-first** and **file-based**: project state lives in JSON files on disk, not in a server or database.

2. **Top-level execution flow**
   - `cmd/main.go` is the entrypoint.
   - It hands off to `internal/commands/cli.go`, which routes between:
     - interactive TUI mode
     - one-off CLI commands such as init, list, status, note, goal, scan, and open

3. **Protocol layer as the core boundary**
   - `internal/protocol/*` is the most important architectural boundary.
   - It defines the shared data model, config, and file I/O for the on-disk protocol:
     - per-project `.drift/project.json`
     - global `~/.drift/registry.json`
     - user config in `~/.drift/config.json`
   - This layer is what both the CLI and TUI consume, so the protocol is effectively the product contract.

4. **Data model and persisted state**
   - The project record appears to hold metadata such as description, status, progress, tags, links, goals, and notes.
   - The registry is the global index of tracked projects.
   - The docs and schemas in `docs/protocol.md` and `docs/schema/*.json` formalize this contract for compatibility with other tools.

5. **TUI subsystem**
   - `internal/ui/*` implements the interactive terminal interface.
   - The package structure suggests a classic model/update/view split:
     - `model.go` for UI state
     - `update.go` for handling input and state transitions
     - `view.go` for rendering
     - `styles.go` and `helpers.go` for presentation and utility code
   - The TUI is the user-facing orchestration layer over the protocol.

6. **List/detail workspace**
   - The TUI centers on a dual-panel project browser:
     - a list view for navigating tracked projects
     - a detail view for editing goals, notes, descriptions, and status
   - User actions in the TUI write back to the same `.drift` files used by the CLI, so the interface is just another client of the protocol.

7. **Scanning and project discovery**
   - `internal/ui/scan.go` supports directory browsing and batch discovery/init from inside the TUI.
   - The README also exposes `drift scan` in the CLI, so scanning is a shared capability across both interfaces.
   - This subsystem bridges the filesystem and the registry by finding candidate project folders and optionally initializing them.

8. **Configuration and personalization**
   - User preferences such as theme, tree/flat view, sort order, and banner state are persisted in `~/.drift/config.json`.
   - This is separate from project data, which keeps UI preferences distinct from the tracked-project protocol.

9. **Claude Code integration boundary**
   - The repo includes explicit integration with Claude Code:
     - launching Claude from the TUI
     - writing a `CLAUDE.md` section during init for auto-sync behavior
     - a reusable skill under `skills/drift/SKILL.md`
   - Architecturally, this is an external-agent integration layer that sits beside the core tracker, not inside it.

10. **Documentation and compatibility assets**
   - `docs/protocol.md`, the JSON schemas, and the `.ajtbd` notes define and analyze the data model and workflow.
   - These files matter because the project is designed to be **open protocol** rather than just one app; other tools can interoperate by reading/writing the same JSON.

11. **Release and packaging**
   - `.goreleaser.yaml` and `.github/workflows/release.yaml` indicate the binary is built and published as a standalone release artifact.
   - This supports the “single binary, zero dependencies” distribution model described in the README.

12. **Mental model for an architecture diagram**
   - A good diagram would show:
     - **User** interacting with either **CLI** or **TUI**
     - both calling into the **protocol layer**
     - which reads/writes **project JSON**, **registry JSON**, and **user config**
     - plus a side integration to **Claude Code**
     - with **scanning/discovery** feeding new projects into the same persistent store

Main entry points: [`internal/commands/cli.go`](https://github.com/snowtema/drift/blob/main/internal/commands/cli.go) (CLI router), [`internal/protocol/io.go`](https://github.com/snowtema/drift/blob/main/internal/protocol/io.go) (File I/O), [`internal/protocol/types.go`](https://github.com/snowtema/drift/blob/main/internal/protocol/types.go) (Data model), [`internal/ui/model.go`](https://github.com/snowtema/drift/blob/main/internal/ui/model.go) (UI state)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_grp_runtime["Runtime"]
  node_node_cmd_main["main<br/>entrypoint<br/>[main.go]"]
  node_node_cli["CLI router<br/>command router<br/>[cli.go]"]
end

subgraph group_grp_protocol["Protocol"]
  node_node_protocol_types["Data model<br/>protocol model<br/>[types.go]"]
  node_node_protocol_io["File I/O<br/>protocol storage<br/>[io.go]"]
  node_node_protocol_config["Config<br/>user prefs<br/>[config.go]"]
end

subgraph group_grp_tui["TUI"]
  node_node_ui_model["UI state<br/>tui model<br/>[model.go]"]
  node_node_ui_update["Update loop<br/>tui controller<br/>[update.go]"]
  node_node_ui_view["Renderer<br/>tui view<br/>[view.go]"]
  node_node_ui_styles["Styles<br/>tui styling<br/>[styles.go]"]
  node_node_ui_helpers["Helpers<br/>tui util<br/>[helpers.go]"]
end

subgraph group_grp_integration["Integration"]
  node_node_ui_scan["Scanner<br/>discovery<br/>[scan.go]"]
  node_node_claude["Claude Code<br/>agent integration<br/>[SKILL.md]"]
  node_node_release["Release<br/>packaging<br/>[.goreleaser.yaml]"]
end

subgraph group_grp_docs["Docs"]
  node_node_project_schema["Project schema<br/>json schema"]
  node_node_registry_schema["Registry schema<br/>json schema"]
  node_node_protocol_doc["Protocol doc<br/>specification<br/>[protocol.md]"]
end

node_node_cmd_main -->|"starts"| node_node_cli
node_node_cli -->|"uses"| node_node_protocol_types
node_node_cli -->|"reads/writes"| node_node_protocol_io
node_node_cli -->|"loads"| node_node_protocol_config
node_node_cli -->|"launches"| node_node_ui_model
node_node_ui_model -->|"binds"| node_node_protocol_types
node_node_ui_update -->|"mutates"| node_node_ui_model
node_node_ui_view -->|"renders"| node_node_ui_model
node_node_ui_view -->|"uses"| node_node_ui_styles
node_node_ui_update -->|"persists"| node_node_protocol_io
node_node_ui_scan -->|"discovers"| node_node_protocol_io
node_node_ui_scan -->|"indexes"| node_node_protocol_types
node_node_protocol_io -->|"serializes"| node_node_protocol_types
node_node_protocol_config -.->|"separates"| node_node_protocol_types
node_node_protocol_doc -->|"formalizes"| node_node_project_schema
node_node_protocol_doc -->|"formalizes"| node_node_registry_schema
node_node_claude -.->|"syncs"| node_node_protocol_io
node_node_claude -.->|"extends"| node_node_cli
node_node_release -->|"packages"| node_node_cmd_main

click node_node_cmd_main "https://github.com/snowtema/drift/blob/main/cmd/main.go"
click node_node_cli "https://github.com/snowtema/drift/blob/main/internal/commands/cli.go"
click node_node_protocol_types "https://github.com/snowtema/drift/blob/main/internal/protocol/types.go"
click node_node_protocol_io "https://github.com/snowtema/drift/blob/main/internal/protocol/io.go"
click node_node_protocol_config "https://github.com/snowtema/drift/blob/main/internal/protocol/config.go"
click node_node_ui_model "https://github.com/snowtema/drift/blob/main/internal/ui/model.go"
click node_node_ui_update "https://github.com/snowtema/drift/blob/main/internal/ui/update.go"
click node_node_ui_view "https://github.com/snowtema/drift/blob/main/internal/ui/view.go"
click node_node_ui_styles "https://github.com/snowtema/drift/blob/main/internal/ui/styles.go"
click node_node_ui_helpers "https://github.com/snowtema/drift/blob/main/internal/ui/helpers.go"
click node_node_ui_scan "https://github.com/snowtema/drift/blob/main/internal/ui/scan.go"
click node_node_claude "https://github.com/snowtema/drift/blob/main/skills/drift/SKILL.md"
click node_node_project_schema "https://github.com/snowtema/drift/blob/main/docs/schema/project.schema.json"
click node_node_registry_schema "https://github.com/snowtema/drift/blob/main/docs/schema/registry.schema.json"
click node_node_protocol_doc "https://github.com/snowtema/drift/blob/main/docs/protocol.md"
click node_node_release "https://github.com/snowtema/drift/blob/main/.goreleaser.yaml"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_node_cmd_main,node_node_cli toneBlue
class node_node_protocol_types,node_node_protocol_io,node_node_protocol_config toneAmber
class node_node_ui_model,node_node_ui_update,node_node_ui_view,node_node_ui_styles,node_node_ui_helpers toneMint
class node_node_ui_scan,node_node_claude,node_node_release toneRose
class node_node_project_schema,node_node_registry_schema,node_node_protocol_doc toneIndigo
```

## Components

### Runtime

Entry and command routing

- [main](https://github.com/snowtema/drift/blob/main/cmd/main.go): entrypoint · Binary entrypoint · `cmd/main.go`
- [CLI router](https://github.com/snowtema/drift/blob/main/internal/commands/cli.go): command router · Dispatches CLI and TUI modes · `internal/commands/cli.go`

### Protocol

Shared data model and file I/O

- [Data model](https://github.com/snowtema/drift/blob/main/internal/protocol/types.go): protocol model · Project, registry, and config types · `internal/protocol/types.go`
- [File I/O](https://github.com/snowtema/drift/blob/main/internal/protocol/io.go): protocol storage · Reads and writes JSON protocol files · `internal/protocol/io.go`
- [Config](https://github.com/snowtema/drift/blob/main/internal/protocol/config.go): user prefs · User configuration and preferences · `internal/protocol/config.go`

### TUI

Interactive terminal interface

- [UI state](https://github.com/snowtema/drift/blob/main/internal/ui/model.go): tui model · List and detail workspace state · `internal/ui/model.go`
- [Update loop](https://github.com/snowtema/drift/blob/main/internal/ui/update.go): tui controller · Handles input and state transitions · `internal/ui/update.go`
- [Renderer](https://github.com/snowtema/drift/blob/main/internal/ui/view.go): tui view · Renders the terminal interface · `internal/ui/view.go`
- [Styles](https://github.com/snowtema/drift/blob/main/internal/ui/styles.go): tui styling · Presentation and theming · `internal/ui/styles.go`
- [Helpers](https://github.com/snowtema/drift/blob/main/internal/ui/helpers.go): tui util · Shared UI utilities · `internal/ui/helpers.go`

### Integration

External agent and discovery flows

- [Scanner](https://github.com/snowtema/drift/blob/main/internal/ui/scan.go): discovery · Project discovery and init from directories · `internal/ui/scan.go`
- [Claude Code](https://github.com/snowtema/drift/blob/main/skills/drift/SKILL.md): agent integration · Launch and sync integration boundary · `skills/drift/SKILL.md`
- [Release](https://github.com/snowtema/drift/blob/main/.goreleaser.yaml): packaging · Build and publish workflow · `.goreleaser.yaml`

### Docs

Compatibility and schema assets

- [Project schema](https://github.com/snowtema/drift/blob/main/docs/schema/project.schema.json): json schema · Project protocol contract · `docs/schema/project.schema.json`
- [Registry schema](https://github.com/snowtema/drift/blob/main/docs/schema/registry.schema.json): json schema · Global tracked-project index contract · `docs/schema/registry.schema.json`
- [Protocol doc](https://github.com/snowtema/drift/blob/main/docs/protocol.md): specification · Human-readable protocol definition · `docs/protocol.md`

## Connections

- main → CLI router: starts · Entrypoint hands off to command routing
- CLI router → Data model: uses · Commands operate on shared protocol data
- CLI router → File I/O: reads/writes · CLI mutates on-disk project state
- CLI router → Config: loads · CLI consumes user preferences
- CLI router → UI state: launches · Interactive mode enters the TUI workspace
- UI state → Data model: binds · UI state mirrors protocol entities
- Update loop → UI state: mutates · Input drives state transitions
- Renderer → UI state: renders · View reads current UI state
- Renderer → Styles: uses · Renderer applies styling
- Update loop → File I/O: persists · Edits write back to JSON files
- Scanner → File I/O: discovers · Finds and initializes tracked projects
- Scanner → Data model: indexes · Discovery feeds project records
- File I/O → Data model: serializes · Storage layer encodes protocol objects
- Config → Data model: separates · User prefs are distinct from project records
- Protocol doc → Project schema: formalizes · Documentation aligns with schema contracts
- Protocol doc → Registry schema: formalizes · Documentation aligns with registry contract
- Claude Code → File I/O: syncs · External agent integration uses the same files
- Claude Code → CLI router: extends · CLI and TUI expose Claude Code workflows
- Release → main: packages · Builds the standalone binary
