devpit

The model

Seven objects. If something is not one of these, it does not get in.

devpit is built from seven objects. If something is not one of these, it does not get in. Once you know them, the rest of the app follows: every screen is one of these objects, or a view onto several of them.

project ──┬── target terminal   (one, and only one)
          ├── board ── column ──┬── card ── run*
          │                     └── step?
          └── session*

Project

A git repository and its preferences. The axis of parallelism is the project, not the branch. The hard part is not producing five versions of one feature; it is not losing the thread when you switch projects and come back two days later. See Projects.

Terminal, the target

One per project. devpit draws the layout, not tmux: a tmux split would show every pane in a single client and fight the layout devpit keeps. Output is read without an attached client, because recognising what a terminal is doing has to work when it is not on screen, or a notification could never fire. See The terminal.

Board and column

A project's columns, in the order they appear. Columns are data, not code. You create, rename, reorder and delete them, and you decide whether a column runs a step and which kind. The board a new project starts with is a starting point, and nothing in devpit assumes its column names. See Columns and cards.

Card

The unit of work: a title, a markdown description, and the column it sits in.

The card is the trigger, not the record. That is what keeps it from going stale. A board that merely describes what happens elsewhere is out of date by the first busy day. If moving the card is what starts the work, it has no way to lie.

Step

A column's rule: on arrival here, run this. A step is one of three kinds.

Agent Session Command
Takes a terminal no yes — the card's terminal tab no
Good for refine, review, verify implementing tests, builds, deploys
Returns schema-validated JSON a session you drive streamed output and an exit code
At once several several, one attached several

A command step receives its context only through environment variables, never interpolated into the command string: a branch name containing a space or a ; becomes a variable's value rather than shell syntax. Its output streams while it runs, so a test suite that takes twenty minutes shows its first line immediately. See Steps.

Run

One execution of a step, and what it cost: how it ended, the output as it came, a command's exit code, an agent turn's spend and duration, the lane it was sent from, the folder it ran in. A card shows its runs, which is how "the agent is doing something" becomes a sentence with numbers in it. The circumstances are recorded before the command starts, so a green row can answer green on which code.

Exit code zero is not a pass: a runner that matched no test files exits zero having checked nothing. So a run carries three answers rather than one, and a run that left nothing devpit can read reports no result rather than a green tick. See Runs and cost and Reading a check.

Secrets devpit handed out are taken out of a run's output before it is stored: a profile's environment, the account token, the hook secret. This is not detection. A secret the command read from a file or fetched itself passes through.

Session

An agent session, running in a terminal you can watch — usually tied to a card and its worktree, sometimes only to a project's folder. devpit does not own session state. The agent CLI already answers whether a session is busy or idle, and keeping that in a database would create a second truth that drifts from the first. devpit stores only the link: which card, which worktree.

What a session you drove yourself cost is not read back, so a card says what its runs cost and is quiet about the rest. See Sessions that outlive the window.

And an orchestrator?

Not an eighth object. An orchestrator is a chat you drive, with a folder of its own, and everything it does it does through these seven: it reads boards, writes cards, and starts sessions on them. It never moves a card into a column that runs a step, so the card stays the trigger.

What is not an object

Open files, tabs, panes, window layout. That is interface state, and it lives with the interface. Promoting it to a domain object is how a workspace for agents turns into an IDE.