Module Map

Layer-level ownership map for the workspace crates and the agentty application layers.

This guide maps the workspace crates and the agentty application layers to their responsibilities so contributors can quickly choose the correct module when implementing changes.

For file-level detail, read the module docstrings directly.

Workspace Crates🔗

  • crates/ag-clipboard/: Read-only clipboard support crate with the narrow text, file-list, and RGBA image read surface used by prompt image capture. Platform backends own macOS pasteboard access, X11 selection reads, Wayland wl-paste reads, and unsupported-backend reporting.
  • crates/ag-agent/: Shared agent backend library crate with provider model metadata, prompt templates, provider-neutral channel contracts, the injectable OneShotClient submission boundary, provider availability probes, and crate-private CLI/app-server transport wiring.
  • crates/ag-forge/: Shared forge review-request library crate with normalized review-request and comment-thread types, GitHub/GitLab remote detection, thread reply/resolution, and the gh/glab adapters and project-scoped assigned GitHub issue list/detail loading behind the ReviewRequestClient and ForgeCommandRunner boundaries.
  • crates/ag-git/: Shared git library crate with worktree creation, repository metadata, commit/diff/push/pull sync, rebase/conflict handling, and squash-merge workflows behind the GitClient boundary.
  • crates/ag-protocol/: Shared structured response protocol library crate with transport-neutral response models, schema generation, parser diagnostics, protocol prompt envelopes, repair prompts, review-comment outcomes, and turn prompt payload helpers.
  • crates/ag-tui-text/: Shared Ratatui text-rendering library crate with markdown parsing/styling, bounded mermaid-to-terminal diagram rendering, and terminal-width wrapping/truncation helpers. Host applications inject semantic palette and cache version settings at the render boundary.
  • crates/agentty/: Main TUI application crate with composition root, application, domain, infrastructure, runtime, and UI layers.
  • crates/testty/: Rust-native TUI end-to-end testing framework with PTY-driven semantic assertions and VHS visual capture. Also ships the language-agnostic testty command-line binary for non-Rust projects.
  • crates/ag-xtask/: Workspace maintenance commands, including the SQL migration numbering check.

Application Layers (crates/agentty/src/)🔗

  • main.rs / lib.rs: Composition root — database bootstrap, App construction, runtime launch, and public module exports.
  • app/: Orchestration layer. Owns the App state, the AppEvent reducer, project and settings persistence manager, the merge queue, the sync orchestrator, branch publish, review, typed prompt workflow requests and outcomes, and the session module (app/session/) with its per-session worker queues and workflow steps (lifecycle, turn, post_turn, merge, task, worker). Prompt composers, slash-menu state, and mode navigation remain presentation-owned. No direct process, filesystem, or clock calls — everything external goes through infra/ traits.
  • domain/: Pure business entities and logic — sessions and statuses, projects, settings keys, themes, structured questions, typed transcript messages, explicit transient-message slots and lifecycles, prompt-composer logic, the shared InputState command and undo/redo model, stable input-revision and character-offset identities used to bind prompt attachments to exact placeholder occurrences and history states, and thin re-export modules for ag-agent provider models plus shared protocol question and turn prompt payloads. No I/O.
  • infra/: External integrations behind traits — Agentty data-root resolution, SQLite persistence (infra/db/ repositories), git (GitClient, backed by ag-git), filesystem (FsClient), tmux, clipboard images, version checks, project discovery, and file indexing. Clipboard image capture delegates host clipboard reads to ag-clipboard, then owns temp-file persistence and attachment metadata. Agentty imports the curated ag-agent crate-root API; provider registry, router, parser, and transport internals stay private to crates/ag-agent/.
  • runtime/: Terminal lifecycle and the event loop — terminal setup, the event-reader thread, key dispatch, mode-focused handlers under runtime/mode/, and shared handlers for common interactions such as issue/review detail navigation, session-output metrics, transcript scrolling, KeyEvent mapping to domain input commands, and session review-comment selection and agent-resolution shortcuts. Runtime owns PresentationState, including the shared RenderCacheStore used by input metrics and frame rendering.
  • presentation.rs and presentation/: Frontend-neutral interaction state shared by runtime input and UI output. They expose mode, help-action, prompt, settings-screen actions, editor, scroll, viewport, and semantic list-selection contracts without importing Ratatui or ui/ formatting. presentation/settings.rs owns settings row selection, selectors, launch-configuration editing through the shared InputState, and render-ready settings snapshots; it returns typed persistence operations to app/setting.rs.
  • ui/: Rendering — frame composition, mode-to-page routing, pages under ui/page/, reusable widgets under ui/component/, application-to-frame projection in ui/app_render.rs, Agentty theme adapters for ag-tui-text, plus diff, layout, review-comment formatting, the split session review-comment page, and theme helpers. ui/session_output_assembly.rs owns the pure transcript-to-display-line projection; the SessionOutput component retains layout caching, scrollbar metrics, loader effects, and Ratatui painting.

Layer Rules🔗

  • Workflow and state transitions live in app/, not in UI rendering modules.
  • App does not render terminal frames or own concrete render caches; runtime passes its presentation cache into the UI projection boundary.
  • App::view_snapshot() creates the immutable borrowed application view consumed by frontends. ui/app_render.rs receives that snapshot plus runtime-owned Ratatui state and does not access the concrete App, services, or managers directly.
  • Application managers retain semantic selected-row indexes through domain::selection::SelectionState; runtime owns Ratatui table viewport state and synchronizes selection at the frame projection boundary.
  • app/ must not import runtime mode handlers. Shared interaction calculations belong in domain/ or presentation.rs, while application task registries belong in app/.
  • Runtime converts presentation-owned prompt state into typed app requests, then applies returned navigation and composer effects. app/ must not inspect or mutate AppMode.
  • Business entities and enums live in domain/.
  • External side effects live in infra/ behind mockable traits; see Testability Boundaries.
  • module.rs files paired with a module/ directory stay router-only.
  • Change-path guidance for common scenarios lives in Change Recipes.