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
| Path | What 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.sh | Lightweight 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.rs | In-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:
| Subcommand | Module |
|---|---|
load / hardline / console | crates/jackin/src/cli/role.rs |
role | crates/jackin/src/cli/role.rs and crates/jackin/src/role_authoring.rs |
eject / purge | crates/jackin/src/cli/cleanup.rs |
prune | crates/jackin/src/cli/prune.rs |
workspace | crates/jackin/src/cli/workspace.rs |
config | crates/jackin/src/cli/config.rs |
diagnostics | crates/jackin/src/cli/diagnostics.rs |
exile (unit variant) | crates/jackin/src/cli.rs |
Bare jackin / console dispatch | crates/jackin/src/cli/dispatch.rs |
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/:
crates/jackin-runtime/src/runtime/launch.rs— the load path: clone/update role repo, validate the contract, generate a derived Dockerfile, build the image on the host Docker engine, start the DinD sidecar and the agent container, attach. It emits structured launch progress stages rather than writing raw status directly to the terminal.crates/jackin-launch/src/progress.rs— launch progress event vocabulary plus rich, compact, non-interactive, and test rendering support. The rich launch cockpit model, update, subscriptions, terminal checks, and Ratatui model/message/update/effect/run/view live undercrates/jackin-launch/src/tui.rs,crates/jackin-launch/src/tui/terminal.rs,crates/jackin-launch/src/tui/run.rs, andcrates/jackin-launch/src/tui/view.rs, with launch-local visual components undercrates/jackin-launch/src/tui/components.rs. The view derives hyperlink-overlay bytes from model state;tui/run.rsemits those bytes at the terminal edge after drawing.crates/jackin-runtime/src/runtime/attach.rs— the attach + reconnect path (hardline).crates/jackin-runtime/src/runtime/cleanup.rs—eject,exile,purge,prune(roles/cache/images/instances), and orphan GC.crates/jackin-runtime/src/runtime/image.rs—docker buildinvocation.crates/jackin-runtime/src/runtime/repo_cache.rs— the role-repo cache lock- fetch logic.
crates/jackin-runtime/src/runtime/caffeinate.rs— the macOS keep-awake reconciler.
Instance-local state helpers live in src/instance/:
crates/jackin/src/instance.rs— role state preparation and auth materialization re-exports.crates/jackin-runtime/src/instance/auth.rs— Claude, Codex, Amp, Kimi, OpenCode, and GitHub auth file provisioning.crates/jackin-runtime/src/instance/naming.rs— DNS-safe container name generation (jk-{id}-{workspace?}-{role}), instance-ID extraction, and role-family matching. Image tag derivation (jk_…) lives incrates/jackin-runtime/src/runtime/naming.rs.crates/jackin-runtime/src/instance/manifest.rs— per-instanceinstance.jsonidentity records, lifecycle status, and the rebuildableinstances.jsonlookup index.
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/:
crates/jackin/src/workspace.rs— types and re-exports.crates/jackin/src/workspace/mounts.rs— mount parsing and validation.crates/jackin/src/workspace/planner.rs—plan_create,plan_edit,plan_collapse(the redundant-mount invariant).crates/jackin/src/workspace/resolve.rs— runtime resolution from workspace + ad-hoc + global mounts.crates/jackin/src/workspace/sensitive.rs— sensitive-mount detection for the warn-and-confirm gate.
Per-mount isolation (worktree / clone) lives in a separate module because it has its own materialization lifecycle:
crates/jackin-runtime/src/isolation/materialize.rs— worktree and clone materialization +MaterializedWorkspace.crates/jackin-runtime/src/isolation/state.rs—isolation.jsonIO.crates/jackin-runtime/src/isolation/finalize.rs— the post-attach finalizer that decides between preserve / clean / return-to-agent.
"I want to change a config-file shape"
The TOML config model lives in src/config/:
crates/jackin/src/config.rs— compatibility re-exports for config model types.crates/jackin-config/src/app_config_persist.rs—AppConfig::load_or_init(config-load + builtin sync).crates/jackin-config/src/editor.rs—ConfigEditor(the save path used by every CLI mutator).crates/jackin-config/src/app_config_workspaces.rs— workspace CRUD plus therequire_workspacehelper.crates/jackin-config/src/app_config_mounts.rs,crates/jackin-config/src/app_config_roles.rs— CRUD and resolution per area (global mounts; builtin sync, trust, and auth-forward).
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:
crates/jackin/src/manifest.rs— schema structs,load,display_name.crates/jackin/src/manifest/validate.rs—RoleManifest::validateandvalidate_agent_consistency.crates/jackin/src/manifest/migrations.rs— manifest version registry and file migration.crates/jackin/src/repo.rs— role-repo contract validation shared by local commands and runtime repo resolution.crates/jackin/src/role_authoring.rs— desktop role-authoring commands for creating, validating, and migrating local role repositories.crates/jackin/src/bin/role.rs— standalone role-focused validation and migration binary used by GitHub Actions and future Renovate-style automation.
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.rsandcrates/jackin/src/console/tui/run.rs— root integration for therun_consoleentrypoint, 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; startupopCLI availability is probed before entering the TUI loop and passed in as a visible-state fact.crates/jackin/src/console/services.rsandcrates/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.rsowns 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.rsbinds thejackin-consoleterminal 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, andcrates/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 incrates/jackin/src/console/tui.rswith concrete manager-stage, editor-state, and settings-state aliases backed bycrates/jackin-console/src/tui/app.rs,crates/jackin-console/src/tui/screens/editor/model.rs, andcrates/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 incrates/jackin-console; launch-dispatch state mutation lives incrates/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 incrates/jackin-console/src/tui/prompts.rs, debug-log stage facts live incrates/jackin-console/src/tui/app.rsandcrates/jackin-console/src/tui/debug.rs, whilecrates/jackin-console/src/tui/debug.rsmaps root state to the generic formatter, footer hint adapters for root-bound modal and workspace facts live undercrates/jackin-console/src/tui/screens/workspaces/view/footer.rsandcrates/jackin/src/console/tui/components/footer/, editor frame rendering, footer-height stabilization, tab-strip, tab-body rendering, and contextual editor footer routing lives incrates/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 incrates/jackin-console/src/tui/screens/settings/view.rs, workspace-list body/name/instance/provider-picker display adapters live incrates/jackin-console/src/tui/screens/workspaces/view/list.rsand delegate list/preview column splitting tocrates/jackin-console/src/tui/list_geometry.rsand list-name sidebar render and focus-ownership planning tocrates/jackin-console/src/tui/screens/workspaces/view.rs, pre-render cache and geometry preparation lives incrates/jackin-console/src/tui/layout.rsand delegates settings geometry, workspace-list frame geometry, active-stage footer-height facts, modal prepare areas, and config-backed sidebar layout math tocrates/jackin-console/src/tui/screens/settings/model.rs,crates/jackin-console/src/tui/app.rs,crates/jackin-console/src/tui/view.rs, andcrates/jackin-console/src/tui/sidebar_layout.rs, the root update boundary lives incrates/jackin-console/src/tui/message.rs(ManagerMessagealias +update_manager), root aliases for typed effect requests live incrates/jackin/src/console/tui.rs, backed by crate-owned effect vocabulary incrates/jackin-console/src/tui/effect.rs, andcrates/jackin/src/console/effects.rsowns root-only effect execution and background polling outside the TUI boundary. Root frame render functions are pure (immutable model) and live undercrates/jackin/src/console/tui/view/; extracted screen and widget render functions live incrates/jackin-console/src/tui/; input handlers undercrates/jackin/src/console/tui/input/translate terminal events intoManagerMessagevariants and route external work through the console service adapters above. The manager model stores concrete pending subscription receivers through crate-owned pending-worker carriers incrates/jackin-console/src/tui/subscriptions.rsand 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 incrates/jackin-console/src/tui/screens/settings/model.rsandcrates/jackin-console/src/tui/mount_display.rswith 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-formopread 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, includingmodel.rs,message.rs,update.rs,effect.rs, andview.rsfiles undercrates/jackin-console/src/tui/screens/workspaces.rs,crates/jackin-console/src/tui/screens/editor.rs, andcrates/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. Workspacesupdate.rsowns 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 workspacesview.rsowns 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; editormodel.rsowns 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, editorupdate.rsowns 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 editorview.rsowns 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; settingsmodel.rsowns 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 settingsupdate.rsowns 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 settingsview.rsowns 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 incrates/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 incrates/jackin-console/src/tui/screens/settings/model.rs. Manager-stage routing lives incrates/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.rsandcrates/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.rsdirectly;crates/jackin-console/src/tui/components/modal_rects.rsowns 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 incrates/jackin-console/src/tui/auth_config.rs,crates/jackin-console/src/tui/app.rs, andcrates/jackin-console/src/tui/screens/editor/model.rsalso 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 incrates/jackin-console/src/tui/components/modal_rects.rs, status popup state construction and in-place instance-action busy wording incrates/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 incrates/jackin-console/src/tui/components/error_popup.rs, shared editor/settings row display helpers and auth-source display derivation incrates/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 incrates/jackin-console/src/tui/components/auth_panel.rs, workspace/global mount row rendering incrates/jackin-console/src/tui/components/mount_rows.rs, provider-picker state and key/outcome planning incrates/jackin-console/src/tui/components/provider_picker.rs, GitHub picker state, key handling, scroll selection, and open-vs-pick routing incrates/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 incrates/jackin-console/src/tui/components/footer_hints.rs, workspace/settings save-preview line rendering plus workspace mount-summary formatting from typed preview rows incrates/jackin-console/src/tui/components/save_preview.rs, and the file-browser state/input/render pieces undercrates/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 asManagerEffect::ResolveFileBrowserGitUrl, while directory navigation and commit validation leave input asManagerEffect::ApplyFileBrowserOutcome;crates/jackin/src/console/effects.rsexecutes those effects outside the TUI boundary throughcrates/jackin-console/src/services/file_browser.rs. Browser launches and workspace deletes leave input asManagerEffect::OpenUrlandManagerEffect::RemoveWorkspace;crates/jackin/src/console/effects.rsexecutes both outside the TUI boundary.crates/jackin-console/src/tui/screens/workspaces/view/list.rsbinds 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 incrates/jackin-console/src/tui/components/op_picker.rs;crates/jackin-console/src/tui/op_picker.rsremains 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— sharedEnvValueto 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, andcrates/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.rsstill binds it tojackin-envresult and runner types whilecrates/jackin/src/console/services.rsexecutesopmetadata 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.rsmaps root stage/modal facts and concrete modal rectangles intoQuitInterceptState,LetterInputState,ModalBlockState, andConsoleModalMouseLayerFacts. 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, andcrates/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 andop://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 incrates/jackin-console/src/tui/message.rswhile root dependencies move behind service/domain boundaries.- Shared tokens and primitive components live in
crates/jackin-tui/src/components.rs. The confirm dialog incrates/jackin-tui/src/components/confirm_dialog.rsowns 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 asDirtyandUpdateResult, used by host and launch update functions.crates/jackin-tui-lookbook/src/stories.rs— renderable component stories used by thetui-lookbookgenerator 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.rs—DamageGrid:vte::Performimplementation backed by ring-style row stores and a sharedRowArena; cells useCompactStringfor 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.rs—DirtyTracker+DirtySpans: records which rows changed duringprocess()calls. Concept from Zellij'sOutputBuffer(MIT).crates/jackin-term/src/cell.rs—Cell,Attrs,Color: the coupling-surface cell type.crates/jackin-term/src/passthrough.rs—PassthroughBuffer+PassthroughEvent: captures OSC/title/clipboard/CWD events so the capsule can forward them.crates/jackin-term/src/snapshot.rs—GridPatch,GridView,GridSnapshot, andSnapCell: 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-splitDamageGridprocessing over the committed corpus.crates/jackin-term/fuzz/src/damage_grid_process.rs—cargo-fuzztarget 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:
| File | Owns |
|---|---|
crates/jackin/src/env_model.rs | Reserved-runtime-env list, is_reserved, interpolation reference extraction, topological env order with cycle detection. |
crates/jackin/src/env_resolver.rs | Runtime env resolution — interpolation, interactive prompts. |
crates/jackin/src/selector.rs | Role-selector parsing (agent-smith, chainargos/backend-engineer, …). |
crates/jackin/src/repo.rs | Role-repo validation — required files, path-traversal checks. |
crates/jackin/src/repo_contract.rs | Enforces that role Dockerfiles extend the construct base. |
crates/jackin-image/src/derived_image.rs | Generates the derived Dockerfile from the role's repo + the construct base. |
crates/jackin/src/docker.rs | Docker 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.rs | Bollard-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.rs | Run-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.rs | XDG-compliant data and config directory resolution (JackinPaths). |
crates/jackin-docker/src/net.rs | Shared 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.rs | Agent 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.rs | Post-download artifact helpers shared by agent_binary / capsule_binary — container_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 in | Update 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.rs | Authentication, Security Model |
crates/jackin-image/src/derived_image.rs | Construct Image |
docker/construct/Dockerfile | Construct 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.
| Path | Purpose |
|---|---|
docs/source.config.ts | MDX source configuration and processing |
docs/content/docs/**/meta.json | Sidebar/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.tsx | Landing 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.