Core Concepts
The operator
Section titled “The operator”You are the operator. You sit outside every container and control what gets loaded into each one. In jackin’, you decide:
- Which agent to load
- Which directories to mount (and whether they’re read-only)
- Which workspace configuration to use
- When to eject (stop) an agent
The operator never enters the container. You drive jackin’ from your host machine through two surfaces: the operator console (jackin console) — an interactive TUI that is the simplest and most-used way to work day-to-day — and the CLI (jackin load, jackin workspace, …) for advanced, scripted, or non-interactive flows.
Agents
Section titled “Agents”An agent is an AI coding runtime (Claude Code, Codex, Amp, Kimi, or OpenCode today) running inside an isolated Docker container. Each agent:
- Has its own filesystem, network, and process space
- Runs at full speed inside the container — whatever “no permission prompts” mode the runtime ships (
Claude Code’s--dangerously-skip-permissions,Codex’s YOLO, etc.) — because the boundary is the container, not the prompts - Can only access directories you explicitly mount
- Can build and run its own containers (
Docker-in-Docker), without touching your host’sDockerdaemon - Persists its state between sessions (conversation history, runtime settings,
GitHub CLIauth/config, plugins)
An agent role is a reusable tool profile for creating agent containers. It’s defined by a GitHub repository that contains a Dockerfile and a manifest file. For example:
agent-smith— the default rolethe-architect— an agent with the full Rust toolchain (used for jackin’ development)chainargos/backend-engineer— a namespaced role for backend work in the chainargos organization
The name agent-smith is just a project-specific example. In practice, role names can reflect the job they are designed for:
frontend-engineerbackend-engineerinfra-operatordocs-writersecurity-reviewer
When you run jackin load agent-smith, jackin’ clones the jackin-agent-smith repository, builds a Docker image from it, and launches a container.
Think of a role as answering: “What kind of agent is this?”
- Which language toolchains are installed?
- Which shell setup or helper scripts are present?
- Which
Claude Codeplugins (or equivalent extensions for other runtimes) are installed? - Which defaults should this agent start with?
One project may intentionally use several roles. That is not redundancy. It is how you keep the agent’s world focused. A frontend-oriented role can carry UI tooling and plugins, while a backend-oriented role can carry server tooling and database clients, even if both point at the same workspace. The smaller and more relevant that environment is, the less out-of-scope context the agent has to inspect.
Agent instances
Section titled “Agent instances”A single role can have multiple running instances. Each instance is a separate container with its own state. This lets you run the same agent type against the same workspace or against different workspaces simultaneously.
An instance can also contain more than one agent session when the role supports multiple runtimes. For example, you can start Claude Code to implement a change, then start Codex inside the same running instance to review the same branch and run tests. For day-to-day workflows, see Parallel Agents.
The jackin’ Capsule
Section titled “The jackin’ Capsule”Every running instance has a jackin’ Capsule inside it. The Capsule is the small control process that starts first in the container and stays there while the instance is alive.
From an operator’s point of view, the Capsule is what makes a running instance feel like a persistent agent workspace instead of a one-shot docker run:
- It owns the in-container multiplexer: tabs, split panes, the status bar, the command palette, and the identity strip at the top of the terminal.
- It keeps agent sessions running after your terminal disconnects, so closing a terminal tab detaches from the instance instead of killing the agent.
- It lets you reconnect with
jackin hardline, start another agent tab withjackin hardline --new, or open a shell tab withjackin hardline --shell. - It reports live session inventory back to
jackin consoleandjackin hardline --inspect, including which agent tabs exist and which one is focused. - It performs container-local setup before an agent starts, such as preparing the durable agent home and applying the auth handoff that jackin’ already decided at launch.
The visible result is the two-line jackin’ chrome at the top of an attached terminal. The first line identifies the session and tabs; the second line shows the running instance identity and opens Container info when clicked. The rest of the terminal belongs to the focused agent or shell pane. Agent shortcuts, editors, full-screen TUIs, bracketed paste, mouse reporting, wheel scrolling, and normal terminal output still go to the focused pane unless the Capsule UI is explicitly active. Normal-screen panes use jackin’ scrollback and scroll chrome only when terminal history exists, including rows preserved before normal-screen clear/redraw; empty-history wheel gestures stay local to jackin’ instead of becoming prompt cursor keys. Full-screen TUIs that opt into mouse reporting receive pane-local mouse events.
That means one running instance can hold a small working room:
- one tab running
Claude Codeto implement a change - another tab running
Codexto review it - a shell tab for inspection or one-off commands
- split panes when you want multiple views visible at once
All of those tabs share the same mounted files, branch, role tooling, forwarded credentials, and private Docker-in-Docker sidecar. They do not share conversation context: each agent runtime still owns its own prompt history and state.
The Capsule is not another agent and it is not a separate container. It is jackin’-owned runtime plumbing inside the role container. You normally interact with it through jackin load, jackin console, and jackin hardline, not by running jackin-capsule yourself.
The construct
Section titled “The construct”The construct is the shared base Docker image that every agent starts from. It carries the operating system and the tools every agent is expected to have on day one — Debian, the Docker CLI, git, GitHub CLI, mise, ripgrep, fd, fzf, zsh with Oh My Zsh, and the Starship prompt.
Role repos extend the construct with their own tools. For example, a role for Rust development would add the Rust toolchain on top of the construct.
You don’t pull or maintain the construct yourself — jackin load does it for you the first time it is needed.
Docker-in-Docker
Section titled “Docker-in-Docker”Each agent gets its own private Docker daemon. From the agent’s point of view that means it can run docker build, docker run, and docker compose inside its own container, without ever talking to your host Docker daemon.
The practical consequence: an agent can build and run containers as part of its work, but those containers cannot escape into your host’s Docker engine.
Workspaces
Section titled “Workspaces”A workspace defines how your project directories are mounted into an agent container. It specifies:
- workdir — the working directory inside the container
- mounts — which host directories to mount, where, and with what permissions
- allowed roles — optionally restrict which roles can use this workspace
- default role — which role to highlight first in the console picker, and which role CLI context loading can use automatically
Think of a workspace as answering: “Which project files can this agent see, and where do they appear in the container?”
This is why roles and workspaces are separate instead of being one concept.
- role = the environment
- workspace = the accessible files
That separation gives you two kinds of control. You can keep the same project boundary while changing the agent’s tool profile, or keep the same tool profile while changing the project boundary.
Example: one monorepo workspace can be shared by two different roles.
chainargos/frontend-engineersees the monorepo files and has Node, Playwright, and UI pluginschainargos/backend-engineersees the same monorepo files but has Rust, Postgres tools, and backend-specific plugins
That keeps tool and plugin scope small even when the project scope is shared.
Workspaces can be:
-
Current-directory workspace — the current directory, mounted at the same path. This is what you get with
jackin load agent-smithfrom any directory. -
Saved — named configurations you create in the operator console (or with
jackin workspace createfrom the CLI). Saved workspaces are useful when you want to reuse the same project boundary across sessions, launch from anywhere, preserve a multi-mount layout, or keep a preferred/default agent attached to that project.
State persistence
Section titled “State persistence”Each agent keeps its own session state — conversation history, login state for tools you authenticated inside the container (such as gh), and any plugins the role installed. When you stop and restart an agent, it picks up where it left off.
To wipe an agent’s persisted state and start fresh, run jackin purge <role>.
Putting it all together
Section titled “Putting it all together”When you run jackin load agent-smith ~/Projects/my-app, jackin’ takes care of every step needed to launch a usable agent — from your point of view, that looks like:
- Pick the role — fetch and validate the role repo.
- Build the agent image — extending the
constructwith the role’s tools and the agent runtime. Subsequent loads reuseDocker’s layer cache. - Mount your project files — at the path the workspace says.
- Start the container in isolation — on its own
Dockernetwork, with its own privateDockerdaemon for any containers the agent itself needs to build. - Drop you inside —
Claude Code(or another supported runtime —Codex,Amp,Kimi, orOpenCode) starts with full permissions inside that boundary.
That whole sequence is one command. If you want to read the full,
under-the-hood account — derived Dockerfiles, networking, isolated
worktrees, the post-attach finalizer — see
Architecture in the internals section.