Skip to content

chore: version packages - #800

Merged
edspencer merged 1 commit into
mainfrom
changeset-release/main
Aug 10, 2026
Merged

chore: version packages#800
edspencer merged 1 commit into
mainfrom
changeset-release/main

Conversation

@github-actions

@github-actions github-actions Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

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 75b8a05 Thanks @edspencer! - Discover: a read-only API that finds directories on this machine with existing
    Claude 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/discover enumerates <claudeHome>/projects/*, recovers each folder's
    recorded 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 can
    expand 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 /,
    ~/Downloads and /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 the
    as-written spelling), temp root, inside Paddock's own directories, $HOME
    itself, outside $HOME, overlapping an existing project, no .git, no
    surviving sessions — so the ~150 die on string comparisons before anything reads
    a transcript. includeNonGit=1 and includeOutsideHome=1 relax the two soft
    rules; excluded reports what each rule ate, so a container that legitimately
    finds 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 a sourceCwd its project does
    not 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: repo is mutable and unvalidated — relocates workingDir to a nonexistent dir and bricks the project #718PATCH /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 5cd3c5a Thanks @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), a systemd --user unit
    on Linux (~/.config/systemd/user/paddock.service). install writes the unit and starts
    it, uninstall stops and removes it, status reads real state back out of launchctl 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 LaunchDaemon has no such
    session — so claude.credentials: host and boot-time start are mutually exclusive. On
    Linux, install prints the loginctl enable-linger you need to survive logout rather
    than running it for you.

    The generated unit sets no PADDOCK_DATA_DIR, so the service and a paddock typed
    into a terminal are the same ~/.paddock instance reached two ways; invokes node
    explicitly by absolute path (launchd's stub PATH cannot find the bin's
    #!/usr/bin/env node); restarts on crash but not on a clean exit; sits in
    <data-dir>/service rather than $HOME; and carries PATH and nothing else in its
    environment. 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 start is now an explicit synonym for the default, and the CLI parses a
    leading verb before its flags. Bare paddock is unchanged, flags parse the same in every
    position, and an unrecognised leading token is still an unknown option error.

  • #803 7536505 Thanks @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).

    --here opened the directory you were standing in as the workspace, with its own
    data dir at <dir>/.paddock. Discover (Discover: find directories with existing Claude Code sessions and import them as projects (UI-first; replaces paddock scan) #745) does the job it was built for from
    one 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 agent
    hosts exactly one instance and three --here directories 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. So
    on any machine where paddock had ever run bare, a later bare run from $HOME
    matched isHereWorkspace($HOME), resumed the entire home directory as the
    workspace, wrote a ~/.gitignore and created ~/.chats. An explicit --data-dir
    was honoured and did not help — PADDOCK_PROJECTS_DIR = cwd was set
    independently — 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 any
    directory: PADDOCK_PROJECTS_DIR was only ever set here, and is now left to the
    server's own default of <dataDir>/projects. It remains a supported environment
    variable. The startup line names the data dir rather than a workspace, and
    --data-dir is 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 --here is gone too — both halves of it were the problem. The
    first-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, its
    state is the .paddock/ and .chats/ folders inside it — add the directory
    through Discover to bring its conversations across, then delete those two folders
    and the two lines --here added to your .gitignore.

@paddock/web@0.68.0

Minor Changes

  • #802 69c9eb6 Thanks @edspencer! - Discover: the view (Discover: find directories with existing Claude Code sessions and import them as projects (UI-first; replaces paddock scan) #745, web half). A route, /discover, that lists the
    directories 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 Discover entry joins Config in
    the 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/sessions only when opened, so a collapsed table costs
    nothing. Everything is ticked by default. The two soft rules (no git, outside $HOME) are offered as toggles, but only when relaxing one would actually reveal
    something; scanned: 0 says there is no history at all and names the Claude home
    to 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/projects then
    POST …/adopt-chats — run sequentially from the client, with no new streaming
    protocol. 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. skipped reasons are surfaced per row rather than rounded away. On
    completion 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 Checkbox primitive gained an indeterminate prop (a DOM
    property with no attribute, so it cannot be set from JSX), which sets
    aria-checked="mixed" with it.

Patch Changes

  • #801 323cddd Thanks @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. --surface and --surface-raised are back to the pre-token UI's measured
    values (#141210, #28221a), sampled from a screenshot of it rather than
    recovered 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 minimum
    that clears 4.5:1 against every dark surface — 14%, giving #cd7758. The
    raw 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/10 composited
    over the page, and only an sRGB mix lands on that same pixel (#251a14).
    resolveColor in lib/color.ts gains in srgb support so the contrast suite
    can evaluate those tokens.

    All 79 contrast pairs still pass in both modes. Light mode is untouched.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Aug 9, 2026

Copy link
Copy Markdown

Deploying paddock with  Cloudflare Pages  Cloudflare Pages

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

View logs

@github-actions
github-actions Bot force-pushed the changeset-release/main branch 3 times, most recently from 28d2f85 to 74ce9b7 Compare August 10, 2026 01:48
@github-actions
github-actions Bot force-pushed the changeset-release/main branch from 74ce9b7 to 645ad7a Compare August 10, 2026 01:56
@edspencer
edspencer merged commit a0efd9b into main Aug 10, 2026
5 checks passed
@edspencer
edspencer deleted the changeset-release/main branch August 10, 2026 02:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant