Scratch Workspaces
Throwaway, app-managed workspaces for one-off agent tasks: nameable, persistent, searchable in the project switcher, and cleaned up on their own when abandoned.
What a Scratch Workspace Is
A scratch workspace is a throwaway, app-managed folder for one-off work — a quick experiment, a script you want an
agent to write once, a place to paste something and look at it. Daintree creates the folder for you under userData/scratches/<uuid>/, outside any of your project directories, so you can put an agent
somewhere disposable without registering a project first.
A scratch is a sibling of a project, not a kind of project. It has its own record, its own switch path, and its own lifecycle. The practical differences:
| Project | Scratch workspace | |
|---|---|---|
| Folder | Yours, anywhere on disk | App-managed, under userData/scratches/ |
| Git | Optional, and git init is one click away | Not a repository unless you make it one |
| Worktrees | Yes | No — the workspace root is the only place to work |
| Project settings | Its own settings tab | None |
| Lifetime | Until you remove it | Auto-cleaned once abandoned for 30 days |
Creating and Naming
Open the project switcher (Option-Command-P Control-Alt-P Control-Alt-P , or click the workspace pill in the toolbar),
expand the collapsible Scratch section, and click New scratch workspace. The button
opens a name field seeded with a timestamped default like Scratch 2026-08-18 14:30. Type over it, press Enter, and the workspace is created and switched to. Leave it as-is and you get the default name.
The name is the workspace's identity from then on. It shows in the toolbar's workspace pill — hovering it reads the name with "Scratch workspace" underneath — and on the row in the project switcher. Rename it at any time from the row's context menu with Rename scratch.
The Scratch section starts collapsed when you have none, so it is discoverable without being noise, and expands once you do. When empty it reads "No scratch workspaces yet. Create one for a quick one-off task."
The First-Run Launcher
A fresh scratch opens on the same empty-canvas launcher a worktree does, not on the onboarding Welcome screen. A scratch is somewhere to launch into, so it gets the launcher's affordances: the resume line, the agent quick-action chips, New terminal, Browse files, and the Search agents & panels… button that opens the panel palette.
What it does not get are the parts only a project can honor: the project settings gear, the rotating tips (they talk about worktrees and the project tree), and the recipe section. Everything you need to put an agent to work in the folder is one click from the canvas.
Persistence
Scratch workspaces persist and restore their panel grid. A scratch keeps its own durable panel state, exactly as a project does, so an eviction under memory pressure or an app restart returns you to the panels you left rather than stranding running PTYs behind a workspace that comes back empty.
This matters more in a scratch than in a project, because a scratch is where you are most likely to have a single long-running agent and nothing else. Losing the grid would have meant losing the only view of it.
Working in a Scratch
Terminals, agents and panels behave the same way they do in a project, resolved against the workspace root instead of a worktree path:
- The file browser opens scratch folders, not just git worktrees. Files outside every worktree — a scratch folder among them — still get a live change signal, so the listing reflects what is on disk rather than what was there when the panel opened.
- Save as project… in the row's context menu copies the scratch folder somewhere you choose and registers it as a project. It copies rather than moves, so a failed registration leaves the scratch intact; the destination has to be an empty or new folder outside the scratch itself. Afterwards Daintree asks whether to Delete scratch or Keep scratch now that the work has a permanent home.
- Previous-project navigation works from a scratch. Entering a scratch records the project you came from, so Option-Command-= Control-Alt-= Control-Alt-= takes you back to it instead of finding an empty history.
Finding a Scratch
Scratch workspaces are searchable in the project switcher. Typing a query ranks them into the main result list alongside projects, with "· Scratch" trailing the name so the origin is clear; the collapsible section is a browse affordance and hides itself while you search. Scratches deliberately stay out of the project frecency ranking, and the section sorts purely by when each was last opened.
Scratch rows carry the same agent-activity status line project rows get: how many agents need input, how many are blocked, how long the oldest has been waiting, and whether finished work is waiting for review. A scratch is where an agent is easiest to forget about, so the row says what is happening in it before you open it.
Scratches in Pilot
Pilot (Option-Command-O Control-Alt-O Control-Alt-O ) lists every agent run across every workspace, and groups scratches beside projects rather than omitting them. A scratch group carries a neutral tile and a document glyph instead of a project's emoji and color, because it has neither. Opening a run from Pilot switches into the scratch and focuses the panel, the same way it does for a project.
Deleting a Scratch
Delete scratch… in a row's context menu asks first. The confirmation names the workspace, states the consequence — "Its terminals will be closed and its folder deleted from disk" — and prints the full path. While the delete runs it reports progress, and says "Still working…" if it takes long enough to be worth saying.
Deleting a scratch kills its agent terminals rather than leaving them running against a folder that no longer exists. Those sessions are journaled on the way out, so the conversations stay resumable from the session list. If Daintree cannot confirm the terminals stopped, it keeps the scratch instead of orphaning them, and tells you to try again.
Deleting every scratch
A visible Delete all scratch workspaces button sits under the create button, and the same action is on the section header's context menu. Its confirmation names every workspace rather than counting them: the whole list is rendered, scrolling if it has to, because a count is not something you can meaningfully consent to when the button is one click from "New scratch workspace". The count in the title is frozen when you open the dialog, so it keeps naming the number you agreed to even as rows disappear during the run.
Auto-Cleanup
A scratch becomes a cleanup candidate 30 days after it was last opened, so opening one resets the clock. A countdown appears on the row only once you are within 7 days: "Auto-cleanup in 5 days", then "Auto-cleanup tomorrow" and "Auto-cleanup today" as the date closes in.
Being stale is not enough to be deleted. Before a candidate is removed, Daintree inspects the folder for signs of live work — uncommitted, untracked or unpushed git state, or recent filesystem activity — and only removes one it can positively prove abandoned. Anything it cannot read, or any git check that errors or times out, counts as protected. Uncertainty never resolves to deletion.
Removal is also two-phase. The sweep first tombstones a candidate, which takes it out of the switcher immediately; the folder itself is not removed until a later sweep, at least a day afterwards. No directory is destroyed in the same pass that first found it stale, and the scratch you are currently in is never a candidate at all.
userData/scratches/. It never touches your project
folders. If a scratch is turning into real work, use Save as project… and it leaves the cleanup
schedule entirely.