What's New
0.66.1 — Queued messages
Section titled “0.66.1 — Queued messages”- Three ways a queued message could be silently lost are fixed. The queue —
the chip holding what you type while a turn runs — deduped on a timestamp from
your browser, so one fast clock destroyed every later queued message on that
chat. It also drained from only one of the eight places a turn can end, so
anything queued behind a
/compact, a trigger or a background sub-agent sat stranded until a later message flushed it. - A second tab merges instead of overwriting. The queue is one shared slot per chat. Previously a second window replaced the first one’s message, and that client then watched someone else’s text appear as though they had typed it.
- Stop returns your queued message to the composer rather than sending it.
0.66.0 — Config screen, and a new default port
Section titled “0.66.0 — Config screen, and a new default port”- The instance Config screen is now navigable. Forty-seven settings that rendered as one 5,508-pixel column get a section rail with counts and scroll-spy, a live filter, and a Modified only lens. It follows VS Code’s settings screen rather than tabs, and that is the argument: tabs partition, which is exactly what defeats a search. The filter matches labels, keys, help text and environment variable names. Env-overridden settings carry a chip, explained once in a legend rather than beside twenty fields.

- Breaking: the default port moves from 4000 to 7233. Setting
PORT,port:or--portchanges nothing. If you rely on the default, update your reverse proxy,docker run -p, KubernetestargetPortand SSH tunnels — or pinPORT=4000. - Both on-disk formats declare a
schemaVersion. An older build used to drop keys it didn’t recognise and write the file back without them. A config file from the future now refuses to start; a project file is skipped loudly. Nothing on disk changes — the current shape is version 1. - Deleting or reverting a chat stops the turn first.
claudewrites the transcript itself, so unlinking it mid-turn didn’t delete the chat — the live process wrote itself back, stripped of history. Promote lost it from both projects. - The UI says “adopt” rather than “import” — where the transcripts are your
own
~/.claude, the sessions offered are already there and the action only registers them. Your originals are never moved or deleted. - A running sub-agent keeps its place in the bar. Backgrounded sub-agents pair within milliseconds, so one was stamped with a final duration that kept climbing.
- On
driveMode: batchonly, deleting the chat you just finished no longer misfiles your next message into a new session.
0.65 — promote_project over MCP
Section titled “0.65 — promote_project over MCP”- An agent can convert its own notebook project to a repo-backed one. Without
an MCP verb it had to stop and ask, or create a second project and abandon the
first — losing every chat in it.
promote_projectclones, re-points the working directory and re-registers against the existing chat store. A failed clone rolls back.
0.64 — Linked directories, managed and unmanaged
Section titled “0.64 — Linked directories, managed and unmanaged”path:links a directory that already exists, used in place. No copy, no clone: your checkout keeps its history, branches and remotes. Paddock writes nothing into it, and deleting the project never touches it.- Two axes replace one flag. Managed means Paddock curates the project’s own
files; unmanaged means you version-control the content yourself. Whether a git
repo sits behind it is a separate question.
repoBackedis removed from the API response. - The Changes tab reports on the code, not the notes — it had been reading the metadata directory.
0.63 — Host plugins and MCP server fidelity
Section titled “0.63 — Host plugins and MCP server fidelity”- A plugin installed in Claude Code now works here. Sharing instructions brings its commands, agents and skills; sharing MCP servers brings its servers too, each allow-listed automatically — without that they connect and have every call denied with no prompt.
headersandtypeon an inherited MCP server are carried through rather than stripped, which matters because a stored OAuth token is keyed on a hash including both.- On
driveMode: batch, a credential declared inmcpServers:is readable in process arguments by any local user while a turn runs. Paddock can’t fix this from its side, so it warns at startup. The defaultsessionmode is unaffected.
0.62 — Granular host Claude inheritance options
Section titled “0.62 — Granular host Claude inheritance options”Paddock sits next to Claude Code state you already have: transcripts, a login, an
MCP server or two, a curated CLAUDE.md. Until this release it reached all of
that through one lever — which Claude home it pointed at — so moving it for
one reason changed four others. That is how a single week produced data
loss, an invisible macOS
login, and a delete that
destroyed real terminal history.
-
Five independent keys, each answering whose X does this instance use?
claude:transcripts: own # own | host — default owncredentials: host # own | host — default hostinstructions: own # own | host — default ownhooks: own # own | host — default ownmcpServers: own # own | host — default ownownis Paddock’s, isolated inside the data dir;hostis this machine’s Claude Code. Omit the block for full isolation apart from your login. What Paddock touches on your machine states the guarantee in one place. -
⚠️ If you keep a curated
~/.claude/CLAUDE.md, read this one.instructionsdefaults toown, so your user-levelCLAUDE.md,agents/,commands/andplugins/are not loaded; every release before 0.62 bridged them in unconditionally. Setinstructions: hostto keep the old behaviour. Each project’s ownCLAUDE.mdis loaded in every mode and is unaffected. The change bites on the CLI paths — the sweeper, triggers anddriveMode: batch— where those files did still apply. (0.64 raised the startup notice to a warning, so you are now told.) -
Host
settings.jsonhooks no longer run inside Paddock turns. Every hook you had ever configured used to run here with no way to turn it off.hooks: hostrestores them; the rest of that file still applies either way. -
Your own MCP servers can reach Paddock two ways.
claude.mcpServers: hostattaches what is already in your~/.claude.json. A siblingmcpServers:block declares servers to Paddock itself — the answer for a container with nothing to borrow — whereenv:VAR_NAMEreferences keep tokens out of a git-tracked file. -
Deleting a shared chat releases it instead of destroying it. Under
transcripts: hosta Paddock chat and aclaude --resumein the same directory are the same file, so delete no longer meansrm— the transcript is your history, not Paddock’s copy. -
CLAUDE_HOMEand--isolated-claude-homeare removed, replaced by the block above.CLAUDE_CONFIG_DIRstill works as “put Paddock’s home here”, but a value resolving to your~/.claudeis now a startup refusal rather than a silent re-coupling. No migration needed.
0.61.1 — CLI login, and symlinks into your Claude home
Section titled “0.61.1 — CLI login, and symlinks into your Claude home”-
Paddock no longer plants anything in a Claude home it doesn’t own. It used to redirect a directory’s transcripts by replacing
~/.claude/projects/<encoded-dir>with a symlink to the workspace’s.chats/. It skipped directories you already had history in, but not empty ones — which is exactly what--hereis usually pointed at. From then on everyclaudesession in that directory was written into Paddock’s store, so deleting.chats/took real history with it. One person lost 30 transcripts this way. -
On a Mac, your existing Claude Code login works again. Claude Code files its Keychain entry under a name derived from whether
CLAUDE_CONFIG_DIRis set, so once Paddock pointed at its own Claude home a perfectly good login went invisible and every turn failed withNot logged in. A Keychain entry can’t be bridged the way a.credentials.jsoncan, so with no token in your environment the CLI now runs against your own~/.claude. (0.62 removed--isolated-claude-home;claude.credentialsandclaude.transcriptsdecide this now.) -
A first run with no credentials prints a message, not a crash. It used to emit several screens of stack trace containing the whole sweeper system prompt, four times, with the useful line forty lines down.
0.61.0 — Paddock’s own Claude home
Section titled “0.61.0 — Paddock’s own Claude home”-
Transcripts move out of
~/.claudeinto Paddock’s data directory. They were the last state living outside it, reached by planting symlinks into your Claude home — and the code doing that would, on every agent registration, copy your transcripts out and delete the originals, inside a barecatch. Paddock now keeps its own home under the data dir and only ever reads~/.claude. -
Four turn-level fixes. Appending to a queued message no longer discards the addition; Stop works on a
/compact, where slash-command turns had never registered a cancellable id; marking the chat you are reading as unread survives its own turn landing; and the sidebar stops flashing to skeletons twice per turn. -
Paddock is MIT licensed, and the packaging now says so. There was no licence file and no
licensefield, while the publish script defaulted it to MIT — so every release told npm one thing while the source granted another.
0.59.1–0.60 — npx install, --here, and confirmed adoption
Section titled “0.59.1–0.60 — npx install, --here, and confirmed adoption”-
npx @edspencer/paddockstarts an instance in one command — server, web UI and Claude Code runtime, no Docker and no clone. It starts quiet, says where it put your data, and warns up front rather than failing on the first turn. -
--hereopens the directory you are standing in as the workspace, rather than creating a project somewhere else. It creates.paddock/for state and.chats/for transcripts and adds both to your.gitignore; later runs resume with no flag. The model isgit init, with.paddock/as.git. -
Adoption asks before it takes anything. The old button imported everything on one click and could not be undone. It now opens a dialog listing candidate sessions grouped by source directory — the source path being the detail that makes “these are from a scratch copy, not my checkout” visible before you commit — and a successful adoption offers Undo.
-
It stops offering chats that were never yours. Paddock’s own curation runs were being offered as terminal history, and a same-named directory anywhere on disk counted as your checkout; a repo-backed project now requires the git remotes to match.
-
Published with provenance — releases go to npm from CI through OIDC trusted publishing, with a signed attestation tying each version to the commit.
0.58 — CLI output and flags
Section titled “0.58 — CLI output and flags”-
The CLI got quiet and explains its failures. A first run printed about thirty lines of boot logging, scrolling the URL you wanted off the top; it now prints nine, with
--verboseto opt back in.--openlaunches the browser once the server is listening, a port clash is a sentence rather than a stack trace, and--helpsays where your data lives.
0.57 — Environment system prompt
Section titled “0.57 — Environment system prompt”- Paddock tells the agent what it is rendering into. It injected no system
prompt of its own, so Claude ran on its stock preset — written for a terminal.
Nothing said that replies render as Markdown in a browser, that a bare
#123is dead text, or that a tool exists to put an image on screen. An audit of the hundred most recent chats on the dogfooding instance found 4,440 bare#123references against 155 markdown links, and 194 images read with none ever shown to the user. - Two rules, and you can replace or silence them. Show, don’t describe, and
make clickable things clickable. Set
environmentPrompt:to your own text to replace it, or to an empty string to append nothing.
0.56 — npm package
Section titled “0.56 — npm package”npx @edspencer/paddock— no Docker, no clone. The package is synthesised from built output rather than being a workspace package, so no future publish can fire an internal package at the registry. Source maps are stripped, taking it from about 22 MB to 2 MB.- The
claudeCLI was never a prerequisite for chats, whateverCONTRIBUTING.mdsaid — they run through the SDK, which resolves its own bundled binary. Only the sweeper, triggers anddriveMode: batchshell out. PADDOCK_SCRATCH_DIRis gone, and an instance still setting it boots and ignores it. Paddock reads config by name rather than validating a schema, so a removed key is never looked at — and a typo’d key is equally silent.
0.55 — Adopting Claude Code CLI chats
Section titled “0.55 — Adopting Claude Code CLI chats”- Bring the terminal
claudehistory you already have into a project. When a workspace has adoptable sessions, a button appears above its chat list; one click and they arrive, carrying an Adopted badge and their original timestamps, so a conversation from three weeks ago sorts where it belongs rather than collapsing to “today”. Your~/.claudehistory is copied, never moved. The count is live rather than a dismissable prompt, and there is a headless equivalent for when the transcripts and the server don’t share a filesystem.

- Detection is forgiving about where your checkout lives. A repo-backed
project matches any transcript folder whose recorded working directory has the
same checkout name, so history from a clone at a different path still comes
over. The working directory is read out of the transcript rather than decoded
from the folder name, because that encoding is lossy —
/a/b-c,/a-b/cand/a/b/call collapse to one folder. Empty and slash-command-only transcripts are held back as noise and reported separately, so a lower count always has an explanation.
0.54 — The “keeper” rename, and Home’s attention feeds
Section titled “0.54 — The “keeper” rename, and Home’s attention feeds”-
The UI says Claude. Paddock is a thin layer over Claude Code, and the “keeper” persona invented a second actor that does not exist — you were messaging Claude the whole time. The composer says Message Claude…, Settings has a Claude section, and where a sentence didn’t need an actor the word is simply gone.
-
Breaking: the
keepernames are gone from config, env and the API, with no aliases. If you set either of these, rename them:before after PADDOCK_KEEPER_DRIVE_MODEPADDOCK_DRIVE_MODEPADDOCK_KEEPER_NATIVE_PROMPTPADDOCK_NATIVE_PROMPTIn
paddock.yaml,keeperDriveMode→driveMode. An instance still setting the old key falls back to the built-in default quietly, so check yours. OnGET /api/models,keeperDefault→defaultModel. -
Home leads with what needs you: running chats, then unread. It used to open on a list of recent chats — the same list the sidebar already shows — so the front door duplicated the furniture and buried the signal. The root’s Home is fleet-wide; a project’s is scoped to itself. Running state is read from the live session hub rather than guessed from timestamps, which is also what fixed the in-flight badge: watching the running set is now itself a reason to hold a socket open.

OVERVIEW.mdrenders on Home besideCHANGELOG.md, both collapsible. The old Overview card is gone, and the New Project button moved to the sidebar’s Projects header.- Foreground sub-agents stopped duplicating themselves into the transcript, and a live bar above the composer now shows each running sub-agent’s latest step — tapping one scrolls its card into view. Liveness comes from the sub-agent’s own transcript, so a parent finishing its turn no longer makes a working sub-agent look idle.
- A chat can no longer be bound to the curator’s transcript. For a notebook project the sweeper shared a working directory with Claude, and since a sweep is scheduled after every turn the two raced for the same session directory — so curation text could stream back as the reply, and the chat could disappear from the project’s list entirely.
0.53 — Unread badge on the Home link
Section titled “0.53 — Unread badge on the Home link”- The sidebar’s Home link carries the same unread badge as every project row. 0.52 reduced the sidebar to a single Home link, and that link stayed mute — the root is a workspace with chats of its own, yet it was the one row that could never tell you something had come back. It now shows an accent pill counting unread replies, a spinner and count for turns in flight, and nothing at all when quiet, using the same component and accessible labels as a project row. In 0.53 the in-flight half only appeared once you had opened a chat, because nothing held the socket open until then; 0.54 fixed that.
- Home also costs one request less. The project list used to be followed by a second full fetch of the root workspace, from which everything but a few metadata fields was thrown away.
Earlier releases
Section titled “Earlier releases”Everything from 0.52 back to 0.29 lives on What’s New — earlier releases: subtree actions and the one-front-door sidebar, the root becoming a workspace, scratch being retired, driving Paddock from outside over MCP, per-message fork and revert, attachments, streaming, unified triggers, and the rest.
Maintaining this page: add a short, user-facing entry here whenever you cut a release (see RELEASING.md). When this page gets unwieldy, move the oldest entries to the archive page verbatim — the archive is append-only and its entries are never rewritten.