Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion website/src/content/docs/architecture/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ losing it costs a draft or a scroll position, nothing more:
| `paddock:chatModel:<sessionId \| "new:"+slug>` | Per-chat model selection |
| `paddock:queued:*`, `paddock:queuedts:*`, `paddock:queuedqid:*`, `paddock:queuedatt:*` | Optimistic queued-message mirror: text, timestamp, slot id, staged attachments |
| `paddock:attachments:*` | Attachment refs staged on a composer but not yet sent |
| `paddock:itemHeight`, `paddock:panewidth`, `paddock:pane:*` | Virtualized row heights, sidebar width, per-workspace pane prefs |
| `paddock:itemHeight:*`, `paddock:panewidth:*` | Virtualized row heights; the side-nav and per-project chat-list pane widths |
| `paddock:lastTab:*`, `paddock:theme`, `paddock:fork:*`, `paddock:chatView`, `paddock:chatsCollapsed:*` | Open tab, theme, fork lineage, nested/flat chat list, collapsed subtrees |
| `paddock:area-collapsed:*`, `paddock:home-collapsed:*` | Collapsed sections in the projects grid and on Home |
| `paddock:lastSeen:*` | **Legacy only** — see the caution below |
Expand Down
37 changes: 31 additions & 6 deletions website/src/content/docs/contributing/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ fake claude. `test/e2e/server.mjs` boots `packages/server/dist/index.js` serving

**You must build first**: `npm run build` (server + web), then `npm run test:e2e`.

**The layer is 20 specs across four Playwright projects, against two servers.** The
**The layer is 22 specs across four Playwright projects, against two servers.** The
config (`test/e2e/playwright.config.ts`) declares:

| Project | Specs | Viewport | Server |
Expand All @@ -193,19 +193,44 @@ config (`test/e2e/playwright.config.ts`) declares:
The two servers exist because git-repo detection is cached process-wide, so a
repo-backed and a non-repo run cannot share one. Both ports derive from
**`PADDOCK_E2E_PORT`** (default `4317`; the git server is always that `+ 1`) — override
it if `4317`/`4318` are taken, which is also how you avoid colliding with an orphaned
server from an earlier run. Each server gets its own temp data dir.
it if `4317`/`4318` are taken. Each server gets its own temp data dir.

An orphaned fixture server from a previous run is **no longer the normal reason** to
need that override. Since v0.67 the launcher watches its own ancestry and
self-terminates when the run above it dies, so an aborted run stops leaking a live
server that the next run then attaches to via `reuseExistingServer`. Two facts hold
that fix up, and both are worth knowing before touching `test/e2e/server.mjs`:

- **Watching `process.ppid` alone never fires.** Playwright runs the launcher as
`/bin/sh -c node test/e2e/server.mjs`, and that shell does not `exec` it — the
parent survives indefinitely. The death to detect is the **grandparent's**. (Both
are checked, since a shell that *did* exec would leave the runner as the direct
parent, and both are compared against the pid captured at boot rather than
against `1`, which a container can legitimately be started by.)
- **The server spawn must not be `detached: true`.** Playwright spawns the
`webServer` command detached and kills its own process group on a clean run; a
detached child escapes that kill and survives every ordinary run. Signal handlers
are not a substitute — on the abort path the launcher is never signalled at all.

The `mobile` projects reuse the same Chromium install, so a phone-sized run costs no
extra browser download in CI.

`happy-path.spec.ts` is the original smoke run — create a project (pick an area) → land
in it; send a chat and watch it stream, reload and see history; collapse an area
section; filter by a domain tag; promote a root chat into a project. The 19
section; filter by a domain tag; promote a root chat into a project. The 20
`journey-*` specs are the real coverage: chat, errors, files, git changes, GitHub,
attachments + queue, sub-agents, lifecycle, preload, remount hydration, the root
workspace, tags, theme, turn notices, home attention, project view, landing, and the
two mobile journeys.
workspace, tags, theme, turn notices, home attention, the fleet readout, project
view, landing, and the two mobile journeys.

The twenty-second spec is the odd one out. `orphan-watchdog.spec.ts` runs under
`chromium` like the journeys, but it needs **no port, no build and no browser** — it
uses no `page` at all. It exercises the launcher's orphan watchdog against the real
process topology (launcher → detached `sh -c` → harness → non-detached child), with
a sleeper standing in for the Paddock server, and it reads liveness from
`/proc/<pid>/stat`'s `State:` rather than `process.kill(pid, 0)` — a zombie still
accepts signals, so a `kill(pid, 0)` probe would fail against a watchdog that works
perfectly.

Artifacts (screenshots on failure, traces/videos on retry) go to the run's temp
dir, never the repo. The HTML report lands there too, under `<temp>/report`.
Expand Down
4 changes: 2 additions & 2 deletions website/src/content/docs/reference/self-mcp.md
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ and, when a `repo` is given, a cloned nested checkout — and register its agent
| `status` | enum | no | One of `idea`, `active`, `paused`, `blocked`, `done`, `abandoned`. Default `active`. |

**Returns**
`{ created: true, slug, name, dir, workingDir, managed, repo?, path?, keeperRegistered }`.
`{ created: true, slug, name, dir, workingDir, managed, repo?, path?, agentRegistered }`.
`dir` is the project's metadata directory; `workingDir` is the agent's cwd (the
nested checkout when a `repo` was cloned, otherwise `dir`). `managed` says whether
Paddock curates the project's own files — it replaced the older `repoBacked` flag,
Expand All @@ -473,7 +473,7 @@ Two things this tool guarantees, and one it doesn't:
directory is rolled back on a clone failure, so it is safe to retry with a
corrected URL. Server filesystem paths are stripped from the error before the
agent sees it (a `git clone` failure otherwise surfaces the entire argv).
- **`keeperRegistered: false` is not a failure.** Mirroring the REST route, the
- **`agentRegistered: false` is not a failure.** Mirroring the REST route, the
project *is* created even if agent registration fails — but it is reported,
because a project with no live agent cannot accept a `create_chat` yet.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Creating & organizing projects
description: A hands-on walkthrough — make a new project (notes Paddock curates, or a codebase it doesn't), point one at a directory you already have, promote a notebook to repo-backed in place, fill in its project.yaml, group projects into areas, tune the agent in Settings (models, curation budgets), and promote a root chat into a project.
description: A hands-on walkthrough — import directories you already work in with Discover, make a new project (notes Paddock curates, or a codebase it doesn't), point one at a directory you already have, promote a notebook to repo-backed in place, fill in its project.yaml, group projects into areas, tune the agent in Settings (models, curation budgets), and promote a root chat into a project.
---

Everything you do in Paddock lives inside a **project**. This guide is the
Expand All @@ -12,8 +12,46 @@ By the end you'll know how to create a project of any shape, sort them into
**areas**, set per-project metadata and agent behaviour, and rescue a root chat
by promoting it into a project of its own.

## You may not need the dialog: Discover

If the directory already exists on this machine and you have been running
`claude` in it, the fastest route into Paddock is not the New project dialog at
all. **Discover** reads your Claude Code history, lists the directories you have
actually been working in, and turns the ones you tick into projects — **with
their conversations**, adopted in the same step.

It is **not only a first-run screen**. An empty instance opens on it, but it is
also a permanent **Discover** entry in the sidebar (below Config) and an ordinary
route at `/discover`, because you keep accruing terminal history and there is
always plausibly something new to find. See
[Discover: start from the history you already have](/getting-started/#discover-start-from-the-history-you-already-have)
for what it offers, what it filters out, and the two toggles that relax the
filters — no need to duplicate the rules here.

What matters for *this* page is the shape of what you get. Each imported row
becomes an **unmanaged project with a `path:`** — exactly what the dialog's
**Directory on this machine** field produces, and unmanaged because Paddock
should not be handed leave to rewrite the `CLAUDE.md` of a checkout you already
own. So everything below — areas, `project.yaml`, the Settings tab, promotion —
applies to a discovered project unchanged; see
[Question 2](#question-2--where-does-the-content-live) for what linking a
directory does and does not do.

:::note[Discover, Import, and "Adopt N native chats"]
Three adjacent words that collide here, and they are three different scopes:

- **Discover** — instance-level: *which directories could become projects?*
- **Import** — the button on that screen: bring the ticked ones in, as projects.
- **Adopt N native chats** — per-project and ongoing: a project you *already*
have has accrued more terminal history, and this pulls those conversations in.
See [Adopt your terminal `claude` history](/using/working-in-chats/#adopt-your-terminal-claude-history).
:::

## Create a new project

For a project that does not exist yet — and for anything that needs Paddock to
**clone a repo** for you, which Discover cannot do — the dialog is still the way.

Click **New Project** — the button is in the left sidebar, and again on the
projects home page (top-right, and in the empty state when you have none yet).
That opens the **New project** dialog:
Expand Down