chore: version packages - #800
Merged
Merged
Conversation
Deploying paddock with
|
| Latest commit: |
645ad7a
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://18548afb.paddock-7u2.pages.dev |
| Branch Preview URL: | https://changeset-release-main.paddock-7u2.pages.dev |
github-actions
Bot
force-pushed
the
changeset-release/main
branch
3 times, most recently
from
August 10, 2026 01:48
28d2f85 to
74ce9b7
Compare
github-actions
Bot
force-pushed
the
changeset-release/main
branch
from
August 10, 2026 01:56
74ce9b7 to
645ad7a
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and publish to npm yourself or setup this action to publish automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.
Releases
@paddock/server@0.68.0
Minor Changes
#799
75b8a05Thanks @edspencer! - Discover: a read-only API that finds directories on this machine with existingClaude Code history and proposes them as projects (Discover: find directories with existing Claude Code sessions and import them as projects (UI-first; replaces
paddock scan) #745, server half).GET /api/discoverenumerates<claudeHome>/projects/*, recovers each folder'srecorded cwd from a transcript (never by inverting the lossy encoded folder
name), and returns the directories a human would actually recognise as a
project, ranked by how many non-noise sessions each holds.
GET /api/discover/sessions?dir=…lists one directory's sessions so a client canexpand a row lazily and tick sessions individually.
The heuristic is the feature: a naive scan surfaces ~166 transcript folders on a
real developer machine, ~150 of them ephemeral temp-dir sessions, plus
/,~/Downloadsand/tmp. Rules run cheap-to-expensive — no recorded cwd,missing, system path (
/and the validatePath() has no system-path floor — a project can be linked at /, /etc or /dev (and managed:true writes CLAUDE.md there) #720 denylist, on both the resolved and theas-written spelling), temp root, inside Paddock's own directories,
$HOMEitself, outside
$HOME, overlapping an existing project, no.git, nosurviving sessions — so the ~150 die on string comparisons before anything reads
a transcript.
includeNonGit=1andincludeOutsideHome=1relax the two softrules;
excludedreports what each rule ate, so a container that legitimatelyfinds nothing can say why instead of rendering a blank page.
This is a NEW, instance-level endpoint rather than a loosening of
POST …/adopt-chats, which deliberately refuses asourceCwdits project doesnot offer. Its own containment: the only paths it will read are ones a transcript
folder already records and that clear the same path floor a linked project must
(PATCH /api/projects/:slug:
repois mutable and unvalidated — relocates workingDir to a nonexistent dir and bricks the project #718–PATCH /api/projects/:slug persists arbitrary unknown body keys verbatim into project.yaml (unbounded) #721), so?dir=is a lookup into a computed set, not a path parameter.No UI yet.
#804
5cd3c5aThanks @edspencer! -paddock service install | uninstall | status— keep Paddock running in the background (CLI:paddock service install— run Paddock as a per-user background service (launchd / systemd --user) #796)Registers Paddock as a per-user background service: a launchd LaunchAgent on
macOS (
~/Library/LaunchAgents/net.edspencer.paddock.plist), asystemd --useruniton Linux (
~/.config/systemd/user/paddock.service).installwrites the unit and startsit,
uninstallstops and removes it,statusreads real state back out oflaunchctl print/systemctl is-active— including the port the unit was actually installed with.It starts at login, not at boot, and every surface says so. That is not a limitation
to be worked around: on macOS your Claude login is a Keychain item, the login keychain is
unlocked by your account password at login, and a boot-time
LaunchDaemonhas no suchsession — so
claude.credentials: hostand boot-time start are mutually exclusive. OnLinux,
installprints theloginctl enable-lingeryou need to survive logout ratherthan running it for you.
The generated unit sets no
PADDOCK_DATA_DIR, so the service and apaddocktypedinto a terminal are the same
~/.paddockinstance reached two ways; invokesnodeexplicitly by absolute path (launchd's stub
PATHcannot find the bin's#!/usr/bin/env node); restarts on crash but not on a clean exit; sits in<data-dir>/servicerather than$HOME; and carriesPATHand nothing else in itsenvironment. Installing from an npx cache path is refused — those are hash-keyed and
prunable, so the unit would rot silently at some future login.
Also:
paddock startis now an explicit synonym for the default, and the CLI parses aleading verb before its flags. Bare
paddockis unchanged, flags parse the same in everyposition, and an unrecognised leading token is still an
unknown optionerror.#803
7536505Thanks @edspencer! - Remove--here, and with it the per-directory instance (Remove--here— the per-directory instance model is incompatible with running as a service (and silently adopts $HOME) #798).--hereopened the directory you were standing in as the workspace, with its owndata dir at
<dir>/.paddock. Discover (Discover: find directories with existing Claude Code sessions and import them as projects (UI-first; replacespaddock scan) #745) does the job it was built for fromone instance with as many linked directories as you like — which is also the
only shape that can run as a background service (CLI:
paddock service install— run Paddock as a per-user background service (launchd / systemd --user) #796), since a launchd agenthosts exactly one instance and three
--heredirectories were three instances.It also deletes a live bug. The marker for "this directory is a workspace" was
a
.paddock/folder — the same name as the default data dir at~/.paddock. Soon any machine where paddock had ever run bare, a later bare run from
$HOMEmatched
isHereWorkspace($HOME), resumed the entire home directory as theworkspace, wrote a
~/.gitignoreand created~/.chats. An explicit--data-dirwas honoured and did not help —
PADDOCK_PROJECTS_DIR = cwdwas setindependently — and because it read as a resume rather than a first open, the
consent announcement was skipped. The only tell was the word
(resumed).The CLI no longer reads
process.cwd()at all, and no longer writes into anydirectory:
PADDOCK_PROJECTS_DIRwas only ever set here, and is now left to theserver's own default of
<dataDir>/projects. It remains a supported environmentvariable. The startup line names the data dir rather than a workspace, and
--data-diris the only thing that picks which instance you get.The bare-run hint that counted the current directory's Claude Code sessions and
suggested
paddock --hereis gone too — both halves of it were the problem. Thefirst-run welcome now points at the app, where Discover reads the whole history
rather than one directory and can show it with tick-boxes.
No migration: there were no users. If you did open a directory with
--here, itsstate is the
.paddock/and.chats/folders inside it — add the directorythrough Discover to bring its conversations across, then delete those two folders
and the two lines
--hereadded to your.gitignore.@paddock/web@0.68.0
Minor Changes
#802
69c9eb6Thanks @edspencer! - Discover: the view (Discover: find directories with existing Claude Code sessions and import them as projects (UI-first; replacespaddock scan) #745, web half). A route,/discover, that lists thedirectories on this machine with existing Claude Code history and imports the
ones you tick as projects — and the empty instance's Home, which renders the same
component inline.
One component, two mount points. Not a dialog: a fresh instance whose Home is
Discovery has nothing to dismiss, so there is no "don't ask again" flag to get
wrong, and a first-run screen you can link to and refresh is the one that
survives being booted from launchd with nobody at a terminal (CLI:
paddock service install— run Paddock as a per-user background service (launchd / systemd --user) #796). "Empty"means zero non-root projects and zero root-workspace chats — the root always
exists, so it cannot be what makes an instance non-empty, but a conversation
started in it means the instance is in use. A
Discoverentry joinsConfiginthe sidebar footer.
The table is one row per candidate: path, git remote, conversation count, how
many the noise filter withheld, and the newest session's date. Tickboxes are
tri-state — a directory with only some conversations ticked shows
indeterminate — and rows expand lazily, fetching
GET /api/discover/sessionsonly when opened, so a collapsed table costsnothing. Everything is ticked by default. The two soft rules (
no git,outside $HOME) are offered as toggles, but only when relaxing one would actually revealsomething;
scanned: 0says there is no history at all and names the Claude hometo bind-mount, rather than rendering an empty table that looks broken; and a
candidate whose transcripts record a different spelling of its path is warned
about up front, that being how an import silently comes back empty.
Importing is two existing calls per row —
POST /api/projectsthenPOST …/adopt-chats— run sequentially from the client, with no new streamingprotocol. Submit disables on submit, and each row colours itself as its own calls
resolve. Failures are per row and carry their own sentence: create-failed is
red, and the one that matters — created-but-import-failed, which leaves a real
empty project behind — is amber and says so, as is a clean run that imported
nothing.
skippedreasons are surfaced per row rather than rounded away. Oncompletion a success panel offers Get started, which refreshes the project
list and returns to Home — no longer empty, so it renders the ordinary workspace.
Also: the shared
Checkboxprimitive gained anindeterminateprop (a DOMproperty with no attribute, so it cannot be set from JSX), which sets
aria-checked="mixed"with it.Patch Changes
#801
323cdddThanks @edspencer! - Restore the dark theme's warmth. The token pass neutralised the dark ground —the assistant prose card's chroma fell from 0.017 to 0.0075 at hue 88 rather
than the old ramp's 67–77 — so a palette that read as brown started reading as
grey.
--surfaceand--surface-raisedare back to the pre-token UI's measuredvalues (
#141210,#28221a), sampled from a screenshot of it rather thanrecovered from the config, and verified against rendered pixels.
Accent text in dark mode was being lifted 26% toward white, turning the
terracotta into a salmon (
#c2603c→#d58a6f). The lift is now the minimumthat clears 4.5:1 against every dark surface — 14%, giving
#cd7758. Theraw accent cannot be restored as text: it measures 3.77:1 on the prose card and
3.5:1 on the active surface, so a literal restoration would have made contrast
worse, not better.
Accent fills and borders are restored exactly, which required mixing them in
sRGB rather than OKLab: the old sub-agent strip was
bg-accent/10compositedover the page, and only an sRGB mix lands on that same pixel (
#251a14).resolveColorinlib/color.tsgainsin srgbsupport so the contrast suitecan evaluate those tokens.
All 79 contrast pairs still pass in both modes. Light mode is untouched.