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/managed-runtime 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 behind theReviewRequestClientandForgeCommandRunnerboundaries.crates/ag-git/: Shared git library crate with worktree creation, repository metadata, commit/diff/push/pull sync, merge-conflict preflights, rebase/conflict handling, and squash-merge workflows behind theGitClientboundary.crates/ag-harness/: Application-facing LLM harness crate with the provider-neutral object-safeModelboundary, itsModelClientimplementation, the built-in provider catalog and environment-backed configuration, private Qwen, Kimi, and Muse policies, a shared Chat Completions backend with JSON Object and JSON Schema modes, backend-neutral request-duration telemetry, and a deny-by-defaultHarnessloop with closed built-inreadandwritecapabilities. It also provides completed-turn-only SQLite chat persistence with embedded migrations and bounded whole-turn reloads. Thereadtool provides bounded worktree reads, path listing, literal search, host-bound diffs, and base/HEAD file inspection; stale-safe patch writes and file reads use the injectableFileSystemboundary. Application binaries own prompts, tool permissions, and telemetry setup; the v0 read tool owns its fixedmaincomparison base.crates/ag-harness-cli/: Interactiveag-harnesscommand-line application and its process-level tests. It derives provider parsing and help fromag-harness, then owns command-line defaults, application prompts, bounded repository permission selection, terminal-safe output, and in-memory chat input handling.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-session/: Frontend-neutral session library with stable identity, lifecycle, orchestration, project, personality, review-link, setting, clarification, and transcript models; complete session aggregates; pure policy and parsing helpers; and the object-safeSessionBackendport exposed through the owned, cloneableSessionServicefor creation, lookup, messaging, structured question answers, durable coordinator submissions, cancellation, merge, and review-request workflows.crates/ag-store/: Reusable persistence library with narrow repository contracts, SQLite adapters, WAL/foreign-key connection setup, offline SQLx query metadata, and embedded migrations. Host applications may inject aTimestampSourcewhile the default constructors use the system clock.crates/ag-tui-text/: Shared Ratatui text-rendering library crate with Markdown parsing/styling, forge HTML normalization, 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 project sync orchestrator, durable campaign planning, managed-worker capability routing, the multi-session orchestration coordinator, branch publish, review, generation-matched background full-diff requests, typed prompt workflow requests and outcomes, thesession_api.rsadapter forag-session, the boundedsession_runtime.rscommand actor, 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 Agentty-specific business entities and logic — render/runtime session snapshots, themes, clarification input progress, 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, session action-eligibility and list-ordering policies, and fuzzy file-entry ranking shared by runtime selection and UI suggestions. Thin compatibility modules re-exportag-agentprovider models,ag-sessionsession and session-adjacent models, and shared protocol turn prompt payloads. No I/O.infra/: External integrations behind traits — Agentty data-root resolution andag-storecomposition, git (GitClient, backed byag-git), filesystem (FsClient), the session-worktree-only personality catalog, 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 review-request detail navigation, session-output metrics, transcript scrolling,KeyEventmapping to domain input commands, and session review-comment navigation, address/deny marking, and batch submission. 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, semantic list-selection contracts, and one coherentFrameTimevalue per render pass without importing Ratatui orui/formatting.presentation/review_comment.rsowns review comment group ordering and headings while preserving forge-thread selection and batch actions across grouped snapshot refreshes.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 unified Diff Files/Comments workspace, 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. The snapshot resolves the injected clock once intoFrameTime, including Unix seconds, milliseconds, and the clock-provided UTC offset used by deterministic timers, loaders, and activity-day projections. Fixed clocks own both their timestamp and offset, so render projections do not depend on the host timezone.- Session activity persistence stores timestamps supplied by the injected
Clock. Session loading retrieves those immutable timestamps and applies the clock-provided offset for each event before aggregating local-day counts; SQLite does not read the host clock or timezone for this projection. - 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. - Frontend-neutral session entities, enums, and policies live in
ag-session; keep only Agentty-specific entities and interaction state indomain/. - Persistence contracts, SQLite repositories, offline query metadata, and migrations live in
ag-store; Agentty'sinfra/db.rsowns only application-specific database location and timestamp-source composition. - 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.