jackin'
Behind jackin' — InternalsGetting Oriented

Codebase Map

Where the source lives, how the modules fit together, and where to start reading

This page is a contributor's map of the jackin' source tree. It is written for people who want to understand how jackin' is built, debug its internals, or work on the project itself. If you only want to use jackin', start at Concepts and the Operator Guide — you do not need this page.

This page is the canonical module map for jackin'. When module structure changes, this page is updated in the same PR — see the "Code ↔ Docs Cross-Reference" table in PROJECT_STRUCTURE.md. PROJECT_STRUCTURE.md itself is a short, agent-facing pointer that covers the multi-repo ecosystem and the per-PR docs contract; it sends readers here for the actual module-level detail.

Repository layout

PathWhat lives there
src/Rust CLI binary — every command jackin' implements
docker/construct/Source for the shared base Docker image (projectjackin/construct:trixie)
docker/runtime/entrypoint.shLightweight shell bridge injected into every derived image at /jackin/runtime/entrypoint.sh; it calls Rust runtime setup, sources role hooks, and execs the selected agent
crates/jackin-capsule/src/runtime_setup.rsIn-container Rust setup for git/GitHub initialization, trailer hook installation, agent home seeding, auth handoff copies, and Claude MCP registration
docs/This documentation site (Fumadocs on TanStack Start)
.github/workflows/CI for jackin', the construct image, and the docs site
tests/End-to-end and integration tests

Workspace crate structure

The Cargo workspace is a tiered DAG — dependencies point only downward. A higher tier may name a lower tier; never the reverse.

Tier 0  jackin-core        vocabulary + traits + manifest types + JackinPaths +
                           env_model (reserved-name policy) + op_types + constants
        jackin-protocol    capsule↔client wire protocol
        ──  no tokio · no docker · no filesystem (except std::fs in paths)  ──

Tier 1  jackin-tui         ratatui widgets + theme + ansi_text + prune_output formatting → core
        jackin-diagnostics RunDiagnostics JSONL + debug_log! macro +
                           terminal-ownership state                 → core, tui
        jackin-docker      BollardDockerClient + ShellRunner + net  → core, diagnostics

Tier 2  jackin-config      AppConfig · WorkspaceConfig · ConfigEditor · migration engine ·
                           planner · mount/workspace validation + resolution  → core

Tier 3  jackin-manifest    manifest validation + migrations + repo_contract + repo → core, config, diagnostics
        jackin-env         operator_env + env_resolver + host_claude + token_setup → core, config, diagnostics

Tier 4  jackin-image       derived_image + agent_binary + capsule_binary +
                           binary_artifact + version_check  → core, config, manifest, docker, diagnostics
                           (agent_binary and capsule_binary repair cached executable bits before redownloading)
        jackin-runtime     runtime + instance + isolation  → core, config, env, manifest, docker, image, diagnostics
        jackin-console     console product state, input/update planning, view composition,
                           components, effects-as-data   → core, config, tui, diagnostics, env, protocol
                           (screens/editor, screens/settings, screens/workspaces, auth panel,
                            op picker, mount display, workspace helpers, launch dispatch)
                           jackin (Tier 5) provides the side-effect adapter shell in
                           crates/jackin/src/console/ — Docker/runtime/config IO execution,
                           terminal ownership, event loop. NOT a duplicate, a complement.
        jackin-launch      launch progress UI                     → protocol, tui
        jackin-capsule     in-container TUI (its own binary)      → core, tui, protocol
        jackin-term        owned terminal model (vte parser + DamageGrid + GridSnapshot) → (no workspace deps)
        jackin-xtask       workspace automation binary (cargo xtask; construct image + dev fixtures)
                           → (no workspace deps; see Workspace Automation page)

Tier 5  jackin (binary)    cli/ + app/ + console adapter shell (effects.rs, services.rs,
                           tui/run.rs) + role_authoring + host tui/ + main.rs + bin/role.rs
                           → all of the above. THE ONLY BINARY. No root src/.

Ownership rules per tier: jackin-core is types + traits only — no tokio, no subprocess, no docker. pub(crate) by default; pub only on what the next crate up imports. Heavy dependencies (tokio, bollard) live only in the tiers annotated above.

Extraction ledger (2026-06-19 — Phase 5 end state). The console extraction is at the adapter-shell end state. crates/jackin/src/ now contains 94 Rust files / 21,382 LOC; crates/jackin/src/console/ is down to 9 files / ~6,200 LOC (from 80 files / 34,407 LOC — 89% file reduction, 82% LOC reduction), while crates/jackin-console/src/ is at 185 files / 84,712 LOC. The root console/ module tree is now a thin adapter shell: console.rs (type bindings + inline terminal adapter), effects.rs (typed effect interpreter), services.rs (Docker/runtime/config IO adapters), tui.rs (inline type aliases + adapter modules), tui/run.rs (event loop), plus 4 test files that require root IO infrastructure. All console product state, input planning, view composition, components, and pure business rules live in jackin-console. Root retains only the side-effect execution layer (Docker, runtime, host config), the terminal ownership adapter, and the CLI-facing entrypoint.

Where to start reading

Different contribution shapes have different natural entry points.

"I want to add or change a CLI flag"

Start at crates/jackin/src/cli.rs — the top-level Cli and Command enum. Each subcommand has its own clap module:

Command dispatch lives in crates/jackin/src/app/. Every clap subcommand has a match arm in crates/jackin/src/app.rs (run) that calls into the relevant domain module (workspace/, runtime/, config/, etc.). When you add a flag, also update the matching docs page under docs/content/docs/commands/.

"I want to change container lifecycle behaviour"

The container lifecycle lives in src/runtime/:

Instance-local state helpers live in src/instance/:

The end-to-end shape of "what happens when you run jackin load" is described in Architecture → Container lifecycle. The detailed contract for instance names, manifests, lookup indexes, restore decisions, cleanup guards, and parallel sessions lives in Runtime Instance Model.

"I want to change workspace or mount behaviour"

The workspace model is in src/workspace/:

Per-mount isolation (worktree / clone) lives in a separate module because it has its own materialization lifecycle:

"I want to change a config-file shape"

The TOML config model lives in src/config/:

Whenever a config field changes, also update Configuration File so the schema reference stays accurate.

"I want to change role-manifest behaviour"

The jackin.role.toml schema, validator, migration chain, and role-authoring entrypoints live across a small set of files:

Whenever the manifest schema changes, also update Role Manifest.

"I want to change the operator console (TUI)"

The interactive console is split between root integration code in src/console/ and extracted surface code in crates/jackin-console/:

  • crates/jackin/src/console.rs and crates/jackin/src/console/tui/run.rs — root integration for the run_console entrypoint, runtime/config prompts, launch prompt agent-choice lookup, and instance actions. The run loop lives under the root TUI boundary while it still executes typed effects through the service adapters below; startup op CLI availability is probed before entering the TUI loop and passed in as a visible-state fact.
  • crates/jackin/src/console/services.rs and crates/jackin/src/console/services/ — root-console side-effect adapters that still depend on the root application crate: browser launch, config persistence for role/workspace/settings saves, Docker-backed instance discovery and instance-refresh snapshots, mount inspection, 1Password probing/read validation, op-picker metadata loading/cache invalidation, role repository registration, agent resolution, Claude token minting, and workspace-save drift/cleanup workers. crates/jackin/src/console.rs owns root-bound console product rules such as role-source resolution with debug logging, launch provider derivation from operator environment, and the instance-refresh snapshot shape. crates/jackin/src/console.rs binds the jackin-console terminal lifecycle to root crate host debug-buffering globals.
  • crates/jackin-console/src/tui/app.rs, crates/jackin-console/src/tui/auth.rs, crates/jackin-console/src/tui/auth_config.rs, crates/jackin-console/src/tui/update.rs, crates/jackin-console/src/tui/run.rs, crates/jackin-console/src/tui/terminal.rs, and crates/jackin-console/src/tui/debug.rs — extracted generic top-level console app model, top-level input dispatch precedence, stage modal fact derivation, manager-stage pending token-generation request draining, manager-stage pending role-load, op-commit, drift-check, isolation-cleanup, and active-animation tick routes, create-prelude model state/transitions including modal-step classification, file-browser outcome routing, destination text-input, workdir-picker, and workspace-name text-input routing, generic modal vocabulary including list/shared scroll-target classification, list-modal key-target classification, modal letter-input classification, and base-surface modal-blocking policy, auth kind/mode vocabulary, surface auth-kind ordering, modal scroll-target classification for top-level and settings modals, non-modal mouse-wheel axis/fallback planning, plus credential-requirement policy and Claude token-generate eligibility for editor/settings auth forms, event-loop shell helpers, global quit/Q-intercept policy, letter-consumption policy, Claude token-generate status wording plus in-place instance-action busy/failure wording, mouse telemetry filters, global clickability policy, modal mouse-consumption and modal mouse-layer dismissal planning, debug-chip activation policy, pointer hand policy, debug-bar rendering, debug key-name formatting, modal debug-name vocabulary, and terminal lifecycle abstractions used by the root integration layer.
  • crates/jackin-console/src/services/launch.rs — pure workspace-choice, launch-dispatch, committed-role launch, and provider-follow-up workspace resolution helpers shared by the root console adapter.
  • crates/jackin-console/src/tui/app.rs — root type aliases and constructors that bind the generic console app model to root workspace-manager state, launch input, role selector, and 1Password cache types.
  • Workspace/settings save-preview line builders, collapse rows, snapshots, reusable preview rows, environment snapshots, role-auth relevance, detail line composition, and their tests live in crates/jackin-console/src/tui/components/save_preview.rs.
  • Sidebar inline-picker active-state policy lives in crates/jackin-console/src/tui/sidebar_layout.rs, with the root console adapter supplying concrete role-picker and agent-picker open facts.
  • crates/jackin/src/console/tui/ — the remaining root workspace-manager TUI subsystem. The root TUI model lives in crates/jackin/src/console/tui.rs with concrete manager-stage, editor-state, and settings-state aliases backed by crates/jackin-console/src/tui/app.rs, crates/jackin-console/src/tui/screens/editor/model.rs, and crates/jackin-console/src/tui/screens/settings/model.rs, including root-bound editor dirty/count/isolation helpers and editor auth/secret row adapters that bind root workspace/config data to generic editor row derivation in crates/jackin-console; launch-dispatch state mutation lives in crates/jackin-console/src/tui/launch.rs, agent/role prompt flow with crate-owned role-resolution, no-eligible-launch, and workspace-list instance and instance-refresh index popup wording lives in crates/jackin-console/src/tui/prompts.rs, debug-log stage facts live in crates/jackin-console/src/tui/app.rs and crates/jackin-console/src/tui/debug.rs, while crates/jackin-console/src/tui/debug.rs maps root state to the generic formatter, footer hint adapters for root-bound modal and workspace facts live under crates/jackin-console/src/tui/screens/workspaces/view/footer.rs and crates/jackin/src/console/tui/components/footer/, editor frame rendering, footer-height stabilization, tab-strip, tab-body rendering, and contextual editor footer routing lives in crates/jackin-console/src/tui/screens/editor/view.rs, settings frame rendering, footer-height stabilization, tab-strip, tab-body, modal rendering, modal-priority planning, and non-modal settings footer routing lives in crates/jackin-console/src/tui/screens/settings/view.rs, workspace-list body/name/instance/provider-picker display adapters live in crates/jackin-console/src/tui/screens/workspaces/view/list.rs and delegate list/preview column splitting to crates/jackin-console/src/tui/list_geometry.rs and list-name sidebar render and focus-ownership planning to crates/jackin-console/src/tui/screens/workspaces/view.rs, pre-render cache and geometry preparation lives in crates/jackin-console/src/tui/layout.rs and delegates settings geometry, workspace-list frame geometry, active-stage footer-height facts, modal prepare areas, and config-backed sidebar layout math to crates/jackin-console/src/tui/screens/settings/model.rs, crates/jackin-console/src/tui/app.rs, crates/jackin-console/src/tui/view.rs, and crates/jackin-console/src/tui/sidebar_layout.rs, the root update boundary lives in crates/jackin-console/src/tui/message.rs (ManagerMessage alias + update_manager), root aliases for typed effect requests live in crates/jackin/src/console/tui.rs, backed by crate-owned effect vocabulary in crates/jackin-console/src/tui/effect.rs, and crates/jackin/src/console/effects.rs owns root-only effect execution and background polling outside the TUI boundary. Root frame render functions are pure (immutable model) and live under crates/jackin/src/console/tui/view/; extracted screen and widget render functions live in crates/jackin-console/src/tui/; input handlers under crates/jackin/src/console/tui/input/ translate terminal events into ManagerMessage variants and route external work through the console service adapters above. The manager model stores concrete pending subscription receivers through crate-owned pending-worker carriers in crates/jackin-console/src/tui/subscriptions.rs and render-safe snapshots, while crate-owned app/run helpers own token-generate request take semantics, token-generate visible status wording, and in-place instance-action busy/failure wording; reusable settings-row construction plus mount-row display formatting and width/height math live in crates/jackin-console/src/tui/screens/settings/model.rs and crates/jackin-console/src/tui/mount_display.rs with root adapters supplying config/workspace data and mount-info labels where root types still block extraction. Instance refresh, mount inspection, browser opening, Debug info OSC52 clipboard writes, settings persistence, auth-form op read validation, agent-choice resolution, workspace-save writes, workspace-save drift checks, workspace-save cleanup workers, and other background worker creation are executed by service/effect code outside the model.
  • Screen modules under crates/jackin-console/src/tui/screens.rs, including model.rs, message.rs, update.rs, effect.rs, and view.rs files under crates/jackin-console/src/tui/screens/workspaces.rs, crates/jackin-console/src/tui/screens/editor.rs, and crates/jackin-console/src/tui/screens/settings.rs — extracted console screen TUI model/message/effect/helper code that no longer depends on the root application crate. Workspaces update.rs owns reusable instance action/status acceptance planning, selected-instance action/error planning, selected-instance purge-confirm open/error planning, instance-action empty-state message selection, preview-pane focused key and action routing, preview-focus and preview-pane cursor plan application, workspace-list horizontal/vertical scroll plan application, workspace delete and instance purge confirm stage planning, workspace-list mouse scroll-focus routing, list mouse seam/click planning, pointer clickability routing, workspace-list hover row hit-testing, list tree arrow ownership policy, workspace-list top-level key precedence, new-session open-picker/missing-instance follow-up planning, edit/delete/settings row planning, workspace-list GitHub-open planning, horizontal/vertical scroll-target planning, tree-disclosure plan application, list-selection plan application and picker-clearing policy, destructive-confirm outcome planning, and workspace delete / instance purge key payload planning, and workspaces view.rs owns reusable create-prelude destination/name text-input, mount-destination choice, workdir-picker state helpers, list-name row/block/scrollbar rendering, current-directory/new-workspace/instance row display defaults and list-width labels, live-pane default agent label, workspace environment row mapping, picker sidebar title formatting, global-mount title formatting, role-global-mount title formatting, instance-detail pane rendering, running-instance summary rendering, instance session empty/error wording, the new-workspace description pane, the provider/role/agent picker sidebar widgets, and General/Mounts/Global-mounts/Environments/Roles subpanel rendering plus config mount and role subpanel adapters; editor model.rs owns selected-mount removal and isolation cycling, state-aware selection-bounds assembly, pending role-load polling, field-selection key planning, row-focus application, hover-state application, tab-bar focus application, tab-navigation key planning, immediate editor action key planning, focused secret op-ref detection, focused Secrets/Auth role-header expansion planning, role-header expansion key routing, focused Auth-kind lookup, focused Auth Enter planning, focused Mounts/Roles add-row selection, focused mount GitHub-open planning, and editor save-mode classification, editor update.rs owns General-tab field modal routing, reusable tab cell hit-testing, tab/mount-row hover target planning, Auth-row mouse hit planning, tab-move reset planning, direct tab-select planning, auth-kind entry/clear focus planning, field-selection row/scroll planning, primitive editor selection-bounds routing, auth-generate scope classification, tab-specific max-row policy, inert row derivation for Secrets/Auth selection, Mounts-tab visual-row to mount-index hit-testing, Auth-tab visual-row to focusable-auth-index hit-testing, plus secret row lookup/mutation, unmask-target planning, and label-free row action/Enter planning, while editor view.rs owns reusable secret delete/role-trust/isolated-save confirm state, editor name/secret value/new-secret value/secret key/role-load/mount-destination text-input state, editor secret new-key/empty-key labels and duplicate-key derivation, secret source-picker/scope-picker, role-picker default/launch confirm labels, and mount-destination choice state, frame/body layout, General/Mounts/Roles/Secrets/Auth-tab line composition, row-width primitives, and viewport scroll clamping; settings model.rs owns shared auth-form target kind access, settings stage state, settings tab move/select application, tab-bar focus application, hover-state application, global-mount/environment/trust selection application, Trust row-select application, settings horizontal-scroll application, settings subpanel save refs, post-event error/exit aggregation, settings global-mount state including modal-dismiss add-draft cleanup, add-draft start state, add-row close mutation, remove-row selection mutation, settings-env pending key, picker scratch, value mutation, selected-row deletion, pending picker target, and modal pending-key/target cleanup, settings auth state including error, token-generation, save refs, modal slot, modal-open lookup, selected-row clamp, modal-stack, selected-kind, selected-kind query, selection-movement, scroll offset, pending op-commit, and row/env commit and clear lifecycle, settings environment state, settings trust error lifecycle, settings environment/auth/global-mount modal vocabulary, config-backed settings construction, environment flat-row derivation, tab content-height rules, and global-mount scroll-frame clamping, and settings update.rs owns reusable tab cell hit-testing, tab/Trust-row hover target planning, tab-move focus planning, direct tab-select planning, settings shell/tab key routing, top-level shell/header/delegate key precedence, General/Environment/Trust-tab key routing, environment selected-key matching, selected-key op-ref predicate, selected op-ref/delete-key lookup, selected header expand/collapse routing, environment delete-target routing, selected-row deletion, selected-row mask toggling and maskability policy, selected add/picker target routing, selected Enter planning, role-picker choices/open planning, global-mount role-picker choices/open/commit planning, modal-open fact aggregation, auth-row selection planning, global-mount selection/scroll planning, global-mount non-modal key routing, GitHub-open planning, and sensitive-save branch routing, global-mount confirm outcome and commit planning, global-mount text commit/normalization, edit-row mutation, add-draft mutation, scope-picker choice, and add-finalize planning, settings-env text commit/source-picker commit/op-picker target/scope-picker commit/role-picker commit planning, environment-row selection/scroll planning, trust-row selection/scroll planning and Trust-tab mouse row hit-testing, Settings Trust clickability routing, auth-kind entry/clear focus planning, environment row lookup/mutation, label-free row action/Enter planning, mask toggling, and delete-row mutation, while settings view.rs owns reusable global-mount confirm/scope-picker/role-picker default/launch confirm labels/text-input state and add-cancel error wording, global-mount text-target labels/edit-initial-value mapping and selected edit-text planning, settings-env key text, plain-value text, and value-edit text planning, settings-env source/scope-picker/delete-confirm state plus role-picker default/launch confirm labels, settings error-popup title, sensitive-path abort wording, settings-env key/value text-input construction and settings-env value-edit, new-key, and empty-key labels, frame/screen geometry such as the shared settings frame areas, settings modal widget dispatch, non-modal settings footer mode routing, and General/Mounts/Environment/Auth/Trust-tab line composition. Root adapters pass only root data, global overlay facts, concrete action/status facts, clickability hit facts, modal mouse facts, debug-chip facts, preview pane sessions, confirm outcomes, labels, root action mappings, payload effects, error-popup display, content dimensions, and narrow mutation-trait implementations for root-owned workspace-list storage. Sidebar layout helpers, including the generic sidebar input fact shape, config-backed sidebar layout and scroll-area derivation, and scroll-area liveness checks, live in crates/jackin-console/src/tui/sidebar_layout.rs.
  • Settings Auth-tab top-level key routing lives in crates/jackin-console/src/tui/screens/settings/update.rs; the root input adapter applies the resulting plan to concrete settings state mutation and modal construction.
  • Settings General selection/toggle, global-mount selected readonly toggling, environment role expansion, and Trust toggle application live in crates/jackin-console/src/tui/screens/settings/model.rs; root message handling delegates those mutations to the shared settings state.
  • Editor pending role-load, op-commit, drift-check, and isolation-cleanup polling live in crates/jackin-console/src/tui/screens/editor/model.rs; settings auth pending op-commit polling lives in crates/jackin-console/src/tui/screens/settings/model.rs. Manager-stage routing lives in crates/jackin-console/src/tui/app.rs; the root effect loop only executes the resulting service completions.
  • Editor top-level key routing and tab-action key precedence live in crates/jackin-console/src/tui/screens/editor/model.rs; the root input adapter applies the resulting plans to config-backed payload lookup, concrete editor state mutation, and effect requests.
  • Editor General toggles, selected-mount readonly toggles, role expansion, and secret mask toggles live in crates/jackin-console/src/tui/screens/editor/model.rs; root message handling delegates those mutations to the shared editor state.
  • Editor and Settings scroll-focus plan application lives in crates/jackin-console/src/tui/screens/editor/model.rs and crates/jackin-console/src/tui/screens/settings/model.rs; root mouse handling computes facts and delegates focus-owner mutation.
  • ContainerInfo modal rectangle classification lives in crates/jackin-console/src/tui/app.rs; root input adapters apply the resulting area to concrete hover, scroll, key, and clipboard-copy effects.
  • Modal render adapters use the crate-owned modal rect specs in crates/jackin-console/src/tui/components/modal_rects.rs directly; crates/jackin-console/src/tui/components/modal_rects.rs owns root-modal widget dispatch for the frame view.
  • Incremental extraction note: editor secret lookup, secret text-editability, focused unmask target derivation, focused secret Enter/delete/add target planning, focused secret op-ref detection, focused Secrets/Auth role-header expansion planning, role-header expansion key routing, focused Auth-kind lookup, focused Auth Enter planning, focused Mounts/Roles add-row selection, focused mount GitHub-open planning, horizontal-scroll key planning and application, workspace mount content-width planning and shared-mount append mutation, role override eligibility, allowed-role toggling, default-role toggling, Auth-tab role override eligibility, Auth-tab form prefill/source-folder derivation, Auth-tab form persistence/reset mutation, Auth-tab role expansion, Auth-tab clear-row mutation, field-selection key planning and application, tab-navigation key planning, tab move/select and tab-bar focus application, immediate editor action key planning, Roles-tab action key planning, Mounts-tab action key planning, Secrets-tab action key planning, Auth-tab action key planning, Auth-kind entry/clear application, modal-chain clearing, tab-action precedence planning, Enter-key planning, Escape-key planning, and Save-key planning now live with the shared editor state in crates/jackin-console/src/tui/screens/editor/model.rs; shared auth clear-layer helpers and Auth-form generate eligibility in crates/jackin-console/src/tui/auth_config.rs, crates/jackin-console/src/tui/app.rs, and crates/jackin-console/src/tui/screens/editor/model.rs also own env-only key cleanup, modal/editor-level generate gating, editor footer token-generate gating, Auth-token generate scope classification, Auth-token generate modal transition, Auth source-picker open transition, Auth source-folder browser transition, Auth op-picker open transition, Auth op-ref commit transition, Auth plain-source text-input transition, Auth plain-text/folder commit transitions, and Auth side-modal restore transition; root input code only builds concrete modal/message adapters.
  • crates/jackin-console/src/tui/components.rs — promoted host-console visual components, including modal rect modes/specs in crates/jackin-console/src/tui/components/modal_rects.rs, status popup state construction and in-place instance-action busy wording in crates/jackin-console/src/tui/components/status_popup.rs, role-load, editor-action, GitHub-preview, save, 1Password-read, workspace-list instance, instance-refresh index, and in-place instance-action error-popup state construction in crates/jackin-console/src/tui/components/error_popup.rs, shared editor/settings row display helpers and auth-source display derivation in crates/jackin-console/src/tui/components/editor_rows.rs, auth source-picker state, credential text-input state, auth-form mode cycling, mode-to-next-focus planning, and full auth-form key/focus planning helpers in crates/jackin-console/src/tui/components/auth_panel.rs, workspace/global mount row rendering in crates/jackin-console/src/tui/components/mount_rows.rs, provider-picker state and key/outcome planning in crates/jackin-console/src/tui/components/provider_picker.rs, GitHub picker state, key handling, scroll selection, and open-vs-pick routing in crates/jackin-console/src/tui/components/github_picker.rs, mount-row, workspace-list, create-prelude, destructive-confirm, editor/settings row, secret/env footer hint blocks, editor/settings contextual row-mode planning, workspace-list footer fact assembly, workspace-screen footer route planning, Open-in-GitHub row visibility policy, and footer-mode planning, modal footer mode vocabulary, Debug-info dialog overflow-aware footer routing, and op-picker modal footer-mode routing in crates/jackin-console/src/tui/components/footer_hints.rs, workspace/settings save-preview line rendering plus workspace mount-summary formatting from typed preview rows in crates/jackin-console/src/tui/components/save_preview.rs, and the file-browser state/input/render pieces under crates/jackin-console/src/tui/components/file_browser.rs, including pointer-position scroll gating when the Git prompt is closed and listing page-row derivation from shared modal geometry. File-browser Git URL lookup leaves input as ManagerEffect::ResolveFileBrowserGitUrl, while directory navigation and commit validation leave input as ManagerEffect::ApplyFileBrowserOutcome; crates/jackin/src/console/effects.rs executes those effects outside the TUI boundary through crates/jackin-console/src/services/file_browser.rs. Browser launches and workspace deletes leave input as ManagerEffect::OpenUrl and ManagerEffect::RemoveWorkspace; crates/jackin/src/console/effects.rs executes both outside the TUI boundary. crates/jackin-console/src/tui/screens/workspaces/view/list.rs binds root workspace/config data to crate-owned workspace-list name/instance/picker/sidebar display rows. The op-picker display metadata structs, naming text-input state helpers, query/filter helpers, render trait and renderer, selected-index routing, naming-stage input routing, filter-reset selection routing, pane-refresh planning, account/vault/item/field load-completion planning, concealed-first field-load sorting policy, account-stage navigation planning, vault-stage navigation planning, item-stage navigation planning, field-back navigation planning, field-stage commit routing, field-label commit routing, existing-field commit routing, section-stage navigation planning, section-collapse routing, naming-stage transition planning, naming text-input state construction, field-row derivation, and session cache type now live with the surface-local op-picker component in crates/jackin-console/src/tui/components/op_picker.rs; crates/jackin-console/src/tui/op_picker.rs remains the root-console transitional binding for root commit types, service execution, and the root state adapter that implements the crate-owned render trait.
  • crates/jackin-console/src/tui/components/env_value.rs — shared EnvValue to secret-display mapping used by editor/settings display adapters.
  • crates/jackin-console/src/tui/components/error_popup.rs, crates/jackin-console/src/tui/components/status_popup.rs, crates/jackin-console/src/tui/components/container_info.rs, and crates/jackin-console/src/tui/components/save_discard.rs — console-local state constructors for shared popup widgets; root adapters pass title/message/run facts instead of constructing shared popup state inline.
  • Console op-picker pending-load requests use the generic carrier in crates/jackin-console/src/tui/components/op_picker.rs; crates/jackin-console/src/tui/op_picker.rs still binds it to jackin-env result and runner types while crates/jackin/src/console/services.rs executes op metadata loads outside the TUI boundary.
  • Console route-to-screen mapping, plain-main-screen route detection, global quit/Q-intercept policy, quit-confirm outcome policy, modal letter-input route assignment, modal letter-consumption policy, base-surface modal-blocking policy, startup-error dismissal policy, modal mouse-layer dismissal/consumption planning, and confirm-state construction now live in crates/jackin-console/src/tui/run.rs; crates/jackin/src/console/tui/run.rs maps root stage/modal facts and concrete modal rectangles into QuitInterceptState, LetterInputState, ModalBlockState, and ConsoleModalMouseLayerFacts.
  • crates/jackin-console/src/tui/message.rs, crates/jackin-console/src/tui/update.rs, crates/jackin-console/src/tui/effect.rs, crates/jackin-console/src/tui/subscriptions.rs, crates/jackin-console/src/tui/focus.rs, crates/jackin-console/src/tui/list_geometry.rs, crates/jackin-console/src/tui/layout.rs, crates/jackin-console/src/tui/mount_display.rs, crates/jackin-console/src/tui/op_breadcrumb.rs, crates/jackin-console/src/tui/split.rs, and crates/jackin-console/src/tui/view.rs — host-console top-level TUI message/update/effect/subscription carriers, generic pending-worker carriers, generic input, modal, prompt outcome, mount-info refresh result vocabulary, and mount-info refresh source-selection/de-duplication planning, generic manager effect vocabulary, file-browser effect context, workspace-save effect and write-mode vocabulary, focus/selection/cursor-scroll helpers, term-width horizontal scroll planning, generic selection and unclamped scroll planning, list row sizing helpers, mount-display and op:// breadcrumb display models, split/drag primitives, config-backed global-mount row selection, split/mouse geometry helpers, seam hit-region helpers, mouse-wheel step policy, non-modal mouse-wheel axis/fallback planning, list body, visual-row, and bordered-content hit-testing helpers, rectangle hit-testing, mouse-wheel scroll application, pointer-gated selection-scroll dispatch, scrollbar drag offset and drag-apply helpers, tab-strip hit-testing, tabbed content-area geometry, footer-height calculation, workspace-screen frame geometry, top-level main-frame route planning, top-level pre-render route planning, top-level modal-render route planning, reserved-footer height route planning, modal-overlay visibility facts, route-scoped list-modal overlay-state policy, modal backdrop rendering, destructive-confirm modal placement, settings-error modal placement, status-overlay placement, status-overlay open/dismiss planning and application, list-modal open/dismiss planning and application, list-modal GitHub/role/popup outcome routing, file-browser modal outcome routing, mount-destination choice routing, save-discard/confirm-save modal outcome routing, scope/source-picker outcome routing, editor/settings browse-mode op-picker outcome routing, settings auth source/text/op-picker outcome routing, settings auth source-folder picker outcome routing, create-mode token op-picker outcome routing, editor/settings text-input outcome routing, editor/settings bool-confirm outcome routing, settings error-popup dismissal routing, editor workdir/error-popup outcome routing, editor/settings role-picker outcome routing, inline-picker dismissal planning and application, inline-picker shell key policy, inline role/agent/session picker outcome routing, provider follow-up planning, inline new-session picker open application, and inline provider-picker open application, launch-prompt agent-probe and pending/error outcome policy, list focus/pre-render focus-liveness/pre-render scroll-reset/drag/split shell-state planning and application, and frame composition helpers. Root console product-specific message/update still lives in crates/jackin-console/src/tui/message.rs while root dependencies move behind service/domain boundaries.
  • Shared tokens and primitive components live in crates/jackin-tui/src/components.rs. The confirm dialog in crates/jackin-tui/src/components/confirm_dialog.rs owns only generic Yes/No prompt, detail-row, and note-row rendering; product-specific role-trust text and standalone prompt-context styling are assembled by console/launch surface TUI code.
  • crates/jackin-tui/src/runtime.rs — small shared runtime contracts such as Dirty and UpdateResult, used by host and launch update functions.
  • crates/jackin-tui-lookbook/src/stories.rs — renderable component stories used by the tui-lookbook generator to produce the TUI Lookbook SVG previews.
  • crates/jackin-tui/src/components/tab_strip.rs — shared Ratatui tab chrome used by the console editor/settings screens and the in-container multiplexer status bar.

Pure pull-request render snapshots live in crates/jackin-capsule/src/pull_request.rs. Capsule visible TUI model vocabulary lives in crates/jackin-capsule/src/tui/app.rs (mux mode, hover targets, pointer shape, visible agent state, visible agent-label formatting, visible pane layout snapshots and derivation, visible tab auto-label derivation, drag-resize state, mux-mode derivation, chrome-hover priority, pointer-shape derivation, and cursor-visibility derivation), visible pane tree/tab geometry, content-row and content-rect derivation, split-spawn sizing, main-view hint row reservations, and pane-local mouse coordinate mapping in crates/jackin-capsule/src/tui/layout.rs, terminal input parsing, tab double-click timing, escape-time defaults, SGR passive-motion vocabulary, mouse protocol gating/encoding, and key-binding data/parsing in crates/jackin-capsule/src/tui/input.rs, semantic action vocabulary plus parsed-input and prefix-command action mapping in crates/jackin-capsule/src/tui/message.rs, visible redraw/update vocabulary, hover redraw policy, dialog copy-feedback timing, partial-frame invalidation policy, and drag-resize ratio math in crates/jackin-capsule/src/tui/update.rs, attach-client effect and subscription vocabulary plus capsule tick intervals in crates/jackin-capsule/src/tui/effect.rs and crates/jackin-capsule/src/tui/subscriptions.rs (including initial attach-frame labels), interactive attach-loop wiring in crates/jackin-capsule/src/tui/run.rs, attach-client raw-mode, reset handling, terminal size normalization, and OSC 22 pointer-shape encoding in crates/jackin-capsule/src/tui/terminal.rs, pure fact-based outer-terminal title, pane-title, and pane-agent-label helpers in crates/jackin-capsule/src/tui/title.rs, full Ratatui frame composition (status bar, pane chrome, pane body, dialogs, selection, bottom chrome, spawn-failure banner) and visible message formatting in crates/jackin-capsule/src/tui/view.rs, status-bar prefix-mode mapping and supplied visible identity-label storage in crates/jackin-capsule/src/tui/components/status_bar.rs, dialog state construction defaults, Debug info diagnostics display snapshots, provider-choice display snapshots, and GitHub-context branch/PR loading display mapping in crates/jackin-capsule/src/tui/components/dialog.rs, mouse text-selection state, start, motion, and copy helpers in crates/jackin-capsule/src/tui/selection.rs, git-context utilities in crates/jackin-capsule/src/git_context.rs, and process/command utilities in crates/jackin-capsule/src/util.rs. The services module at crates/jackin-capsule/src/services.rs owns non-TUI adapters such as crates/jackin-capsule/src/services/input_bindings.rs, which resolves env/logging into the TUI-owned binding type. Capsule TUI modules are rooted at crates/jackin-capsule/src/tui.rs, with local visual components under crates/jackin-capsule/src/tui/components.rs and crates/jackin-capsule/src/tui/components/; callers use canonical tui:: module paths instead of flat root aliases. crates/jackin-capsule/src/daemon.rs still owns protocol/session authority, maps it into visible frame data, and calls into TUI composition for rendering.

  • Capsule attach-spawn, spawn-capacity, and spawn-failure agent-label wording lives with visible spawn-failure formatting in crates/jackin-capsule/src/tui/view.rs. The daemon still enforces the tab/session limits, allocates PTYs, and sends the banner frame.
  • Capsule branch-context bar rendering, hit-testing, and default-branch visibility filtering live in crates/jackin-capsule/src/tui/components/branch_context_bar.rs. The daemon supplies Git/default-branch facts and executes GitHub/container actions.

crates/jackin-term/ is the owned terminal model used by jackin-capsule. It implements the vte → DamageGrid → GridView/GridSnapshot → PaneBodyWidget → Ratatui → SocketBackend → ClientWriter pipeline. Dirty rows tell the capsule that a frame is needed and give tests/future tooling an observation API; they do not form a second client emit path:

  • crates/jackin-term/src/grid.rsDamageGrid: vte::Perform implementation backed by ring-style row stores and a shared RowArena; cells use CompactString for inline storage (no heap alloc for ≤24 byte graphemes). The grid exposes jackin' terminal-model API: process(bytes), cell(row, col), size()/set_size(), alternate_screen(), set_scrollback(), dirty_spans(), dump_dirty_patch() for observation, clear_scrollback(), mouse-mode enums.
  • crates/jackin-term/src/damage.rsDirtyTracker + DirtySpans: records which rows changed during process() calls. Concept from Zellij's OutputBuffer (MIT).
  • crates/jackin-term/src/cell.rsCell, Attrs, Color: the coupling-surface cell type.
  • crates/jackin-term/src/passthrough.rsPassthroughBuffer + PassthroughEvent: captures OSC/title/clipboard/CWD events so the capsule can forward them.
  • crates/jackin-term/src/snapshot.rsGridPatch, GridView, GridSnapshot, and SnapCell: borrowed dirty-row patches for observation and test assertions, borrowed scrollback/live views for Ratatui body rendering, and owned dumps for acceptance tests and terminal observation.
  • crates/jackin-term/tests/conformance.rs — conformance replay harness comparing one-shot and byte-split DamageGrid processing over the committed corpus.
  • crates/jackin-term/fuzz/src/damage_grid_process.rscargo-fuzz target for zero-panic and one-shot/byte-split determinism on arbitrary byte input.
  • crates/jackin-term/README.md — the required self-contained engineering record (problem → analysis → build rationale → borrow ledger → correctness strategy).

jackin-term has no workspace dependencies — it is a pure-Rust library with vte, compact_str, and unicode-width as its only production dependencies.

General terminal-UI helpers (palette, intro/outro animation, prompt helpers) are split out into src/tui/.

Cross-cutting helpers

A handful of files at the crate root own concerns that don't cluster into a single module:

FileOwns
crates/jackin/src/env_model.rsReserved-runtime-env list, is_reserved, interpolation reference extraction, topological env order with cycle detection.
crates/jackin/src/env_resolver.rsRuntime env resolution — interpolation, interactive prompts.
crates/jackin/src/selector.rsRole-selector parsing (agent-smith, chainargos/backend-engineer, …).
crates/jackin/src/repo.rsRole-repo validation — required files, path-traversal checks.
crates/jackin/src/repo_contract.rsEnforces that role Dockerfiles extend the construct base.
crates/jackin-image/src/derived_image.rsGenerates the derived Dockerfile from the role's repo + the construct base.
crates/jackin/src/docker.rsDocker command builder — CommandRunner trait (run, capture, capture_secret) and ShellRunner. capture_secret suppresses stdout from the debug stream and omits stderr from error messages; use it for commands whose output is a credential.
crates/jackin-docker/src/docker_client.rsBollard-based Docker API client — DockerApi trait (container/network/image/exec operations), BollardDockerClient (production), FakeDockerClient (tests), and ContainerState enum (all 9 Docker lifecycle states). BollardDockerClient::connect() honors a non-empty DOCKER_HOST (matching Docker CLI's empty-as-unset semantics); otherwise it asks docker context inspect for the active CLI context endpoint (passing any DOCKER_CONTEXT override explicitly) and caches the result in a process-wide OnceLock so typed API calls and remaining Docker CLI calls target the same daemon without re-spawning the subprocess on every connect. This path supports local-socket and plain HTTP/TCP contexts; SSH and TLS contexts fail clearly instead of dropping Docker CLI transport/TLS settings that this Bollard build cannot mirror. Replaces Docker CLI string-matching for lifecycle, cleanup, and inspect paths. CLI stays CLI for docker build (no parsing risk, streaming context complexity), docker exec -it / docker run -it (TTY-bound; bollard exposes the raw stream but the Docker CLI manages raw-terminal mode, Ctrl-C signal forwarding, and SIGWINCH for free), and docker run --rm one-shot commands (fire-and-forget captured stdout; no parsing risk).
crates/jackin-diagnostics/src/run.rsRun-scoped JSONL diagnostics under ~/.jackin/data/diagnostics/runs/; every command gets a run ID, compact launch breadcrumbs are always written, and detailed debug lines are written only when --debug / JACKIN_DEBUG=1 is active.
crates/jackin-core/src/paths.rsXDG-compliant data and config directory resolution (JackinPaths).
crates/jackin-docker/src/net.rsShared HTTP for binary acquisition — the reqwest text-GET client (http_client / get_text / fetch_text, with connect + request timeouts and a jackin/<version> User-Agent so GitHub's API edge does not 403 UA-less requests before any auth or rate-limit logic runs) and the fast-down parallel chunked download_parallel (work-stealing across DOWNLOAD_CONCURRENCY connections, mmap writes, overall DOWNLOAD_TIMEOUT + abort, same UA).
crates/jackin-image/src/agent_binary.rsAgent runtime binary resolver/cache — resolves Claude Code, Codex, Amp, Kimi, OpenCode, and Grok release metadata, persists fresh latest.json plus per-version sidecars, downloads verified binaries into ~/.jackin/cache/agent-binaries/ through the shared fast-down path, offloads cache scans and archive/chmod work from async launch workers, returns the newest cached executable when current metadata or download URLs fail, and lets the derived Dockerfile use the official upstream installer only when jackin' cannot resolve/download the hard-coded binary path and has no usable cached executable.
crates/jackin-image/src/binary_artifact.rsPost-download artifact helpers shared by agent_binary / capsule_binarycontainer_arch, chmod_executable, is_executable_file, hash_file_sha256, parse_sha256_hex, and the tar.gz member extractor. The network transfer lives in crates/jackin-docker/src/net.rs; this owns the bytes once on disk.

Code ↔ docs cross-reference

When a code change affects user-visible behaviour, the matching docs page must change in the same PR. The full table lives at the bottom of PROJECT_STRUCTURE.md; the most common pairings are:

Code change inUpdate docs in
src/cli/**Commands
src/workspace/** (mount logic)Workspaces, Mounts
src/config/**Configuration File
src/runtime/**Architecture, Runtime Instance Model
src/instance/**Runtime Instance Model
src/isolation/**Workspaces (per-mount isolation), Architecture (materialization + finalizer), Configuration File
src/manifest/**Role Manifest
crates/jackin-runtime/src/instance/auth.rsAuthentication, Security Model
crates/jackin-image/src/derived_image.rsConstruct Image
docker/construct/DockerfileConstruct Image

Docs site source

The docs site (this site) is a Fumadocs on TanStack Start project under docs/. Bun is the only supported package manager.

PathPurpose
docs/source.config.tsMDX source configuration and processing
docs/content/docs/**/meta.jsonSidebar/page-tree order, titles, and grouping
docs/content/docs/All MDX content — file path maps to URL
docs/src/components/chrome/Shared header chrome used by the Fumadocs layout
docs/src/routes/index.tsxLanding route — a TanStack route outside the Fumadocs content tree

To run the site locally:

cd docs
bun ci
bun run dev   # http://localhost:3000/

Contributor entry points

If you have not contributed before, these files are worth reading first:

  • AGENTS.md — house rules (apply equally to humans and agents).
  • CONTRIBUTING.md — contribution flow, DCO sign-off, branch naming, merge policy, and Conventional Commits format.
  • TESTING.md — how to run the test suite.
  • PROJECT_STRUCTURE.md — agent-facing pointer covering the multi-repo ecosystem and the per-PR docs contract; the detailed module map this page surfaces is the source of truth.

The Roadmap is the catalogue of in-flight and planned design work. When picking up a task, the matching roadmap entry usually has the problem statement, the chosen approach, and the related source files.

On this page