Repository navigation
v1.0.277
✨ New: Read a whole turn as one diff
The chat diff viewer only ever answered "what did this tool call do". Reading a turn meant clicking through every call and summing the overlaps by eye. An aggregate toggle now collapses the range into a single diff, built over the shadow snapshot repo from the first call's parent to the newest one.
It is a net diff, and that is the point: a file edited five times appears once, and a file created then deleted inside the range does not appear at all. The count therefore drops — 41 per-call entries can be 12 distinct files — so the header labels the aggregate rather than letting that read as lost data.
A turn that opens with git checkout -b x origin/main used to start the range on a call that rewrote 200 files and 17k lines of other people's commits. Nothing in a snapshot says "this was a branch switch", so size stands in for intent: oversized leading calls are left out of the starting point. That is a guess, so it is never silent — the meta bar states how many calls were dropped and toggles them back in.
Two interaction changes ride along, both about closing the viewer. The header controls move to the left, macOS-window style, since the pointer already lives over the left half of the diff and a ✕ in the far corner charged a full-width trip for the most common action. And the diff column can now be swiped right to dismiss: the gesture draws itself, the column trailing the swipe at half its travel before flying out or springing back.
✨ New: Branch compare counts work you have not committed yet
The history tab's branch compare ran git diff <base> HEAD, so a branch whose work was still in the working tree rendered "no changed files" while a pile of fresh edits sat on disk. Between that view and the status tab, nothing answered "what did this branch change in total" — the question an agent-driven session asks most.
The HEAD pill in the compare header is now a two-segment scope switch:
- worktree — committed + staged + unstaged + untracked (the new default)
- head — committed work only, the GitHub "Files changed" diff
Untracked files are merged in from git status, since git diff never reports them. Both modes now anchor the old side at the merge base; the previous two-dot spelling reported commits made on the base branch since branching as if this branch had reverted them. A project opened at a subdirectory of its repo also read working-tree paths against the wrong root and returned an empty diff.
✨ New: A Bot session says so, wherever it is listed
A Bot session used to be indistinguishable from one a person opened. The mark now rides on chrome that already exists rather than adding a glyph: the number chip keeps its number and changes shape — a robot head, masked over the same status wash — and the running line gets a badge. Detection reads the @name out of the dispatch line once, server-side, and it travels with the payload that already answers which engine.
An @bot line sent from a session that is already sitting in that Bot's directory now runs in place instead of spawning a child. Delegating exists to give a Bot a session whose files are its own; a session that already has that bought a cold start and a second transcript and nothing else. Matching is exact after realpath, so a subdirectory of the Bot does not match and a repo root containing bots/ cannot swallow every @bot line in the project. A delegation with no explicit engine also inherits the engine of the session that asked for it.
🐛 Fix: Ollama runs the model your machine actually has
Ollama ids are whatever the machine pulled, so any id baked into the source is a guess that ollama pull / rm invalidates — and one delegation could produce three separate 404s from Cockpit rather than from the model. Model resolution now happens against the machine: the request's own model (a bare gpt-oss completed to its one installed tag), else the model this session already ran on, else the model the last run used, else the catalog's first entry. An empty or unreachable catalog is now an error naming the server URL and the fix, raised before the run starts rather than landing in a transcript you then throw away.
A new ollama chat opens on the model last used instead of on "Select model", and the picker and the engine read the same resolver, so they cannot answer the question differently.
🐛 Fix: A scheduled task follows its fresh session immediately
When a task's resume target is gone it starts a fresh session, and that session's id used to be written back only after the run finished, and only on the success path. So for the whole turn the task pointed at a session that no longer exists — the board opened an empty transcript while the real one streamed under another id — and a run that timed out left the dead id on disk, which is self-reinforcing: the next round starts yet another from-scratch session, and a from-scratch run is the one most likely to fail again. The task now binds on the id the engine announces seconds in. The per-run deadline also rises to 60 minutes; it is a runaway guard, not a latency budget.
🐛 Fix: Quick instructions can span several lines
The outline editor's record separator is the line break, so a multi-line instruction had no way to spell itself — and the round trip was already lossy, silently tearing such an instruction in two on the next save. Real newlines are now encoded as a literal \n inside the textarea and decoded on the way out, so storage, the API and the send path keep carrying real newlines.
📦 Misc: The cock alias is gone
cock is an English profanity, which makes the short alias awkward in shell history, CI logs, documentation and talks. Cockpit ships a single name now:
cockpit # production server
cockpit-dev # dev serverIf you had cock in a script or an alias, switch it to cockpit — same 237-line implementation, now living in bin/cockpit.mjs. The lockfile carried a stale entry pointing at the deleted file, which would have left npm ci with a dangling symlink.
Engine pins move with this release too: Claude Agent SDK 0.3.268 → 0.3.278, Codex 0.154.0 → 0.155.1.