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, Waylandwl-pastereads, and unsupported-backend reporting.crates/ag-agent/: Shared agent backend library crate with provider model metadata, prompt templates, provider-neutral channel contracts, the injectableOneShotClientsubmission 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 thegh/glabadapters and project-scoped assigned GitHub issue list/detail loading behind theReviewRequestClientandForgeCommandRunnerboundaries.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 theGitClientboundary.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-agnostictesttycommand-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,Appconstruction, runtime launch, and public module exports.app/: Orchestration layer. Owns theAppstate, theAppEventreducer, 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 throughinfra/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 sharedInputStatecommand 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 forag-agentprovider 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 byag-git), filesystem (FsClient), tmux, clipboard images, version checks, project discovery, and file indexing. Clipboard image capture delegates host clipboard reads toag-clipboard, then owns temp-file persistence and attachment metadata. Agentty imports the curatedag-agentcrate-root API; provider registry, router, parser, and transport internals stay private tocrates/ag-agent/.runtime/: Terminal lifecycle and the event loop — terminal setup, the event-reader thread, key dispatch, mode-focused handlers underruntime/mode/, and shared handlers for common interactions such as issue/review detail navigation, session-output metrics, transcript scrolling,KeyEventmapping to domain input commands, and session review-comment selection and agent-resolution shortcuts. Runtime ownsPresentationState, including the sharedRenderCacheStoreused by input metrics and frame rendering.presentation.rsandpresentation/: 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 orui/formatting.presentation/settings.rsowns settings row selection, selectors, launch-configuration editing through the sharedInputState, and render-ready settings snapshots; it returns typed persistence operations toapp/setting.rs.ui/: Rendering — frame composition, mode-to-page routing, pages underui/page/, reusable widgets underui/component/, application-to-frame projection inui/app_render.rs, Agentty theme adapters forag-tui-text, plus diff, layout, review-comment formatting, the split session review-comment page, and theme helpers.ui/session_output_assembly.rsowns the pure transcript-to-display-line projection; theSessionOutputcomponent retains layout caching, scrollbar metrics, loader effects, and Ratatui painting.
Layer Rules🔗
- Workflow and state transitions live in
app/, not in UI rendering modules. Appdoes 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.rsreceives that snapshot plus runtime-owned Ratatui state and does not access the concreteApp, 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 indomain/orpresentation.rs, while application task registries belong inapp/.- Runtime converts presentation-owned prompt state into typed app requests, then applies returned navigation and composer effects.
app/must not inspect or mutateAppMode. - Business entities and enums live in
domain/. - External side effects live in
infra/behind mockable traits; see Testability Boundaries. module.rsfiles paired with amodule/directory stay router-only.- Change-path guidance for common scenarios lives in Change Recipes.