Data directory
What lives under ~/.purplemux/, what's safe to delete, and how to back it up.
Every persistent piece of state purplemux keeps — settings, layouts, session history, caches — lives under ~/.purplemux/. Nothing else. No localStorage, no system keychain, no external service.
Layout at a glance
~/.purplemux/
├── config.json # app config (auth, theme, locale, …)
├── workspaces.json # workspace list + sidebar state
├── workspaces/
│ └── {wsId}/
│ ├── layout.json # pane/tab tree
│ ├── message-history.json # input history per workspace
│ └── claude-prompt.md # --append-system-prompt-file content
├── hooks.json # Claude Code hook + statusline config (generated)
├── status-hook.sh # hook script (generated, 0755)
├── statusline.sh # statusline script (generated, 0755)
├── rate-limits.json # latest statusline JSON
├── session-history.json # completed Claude session log (cross-workspace)
├── quick-prompts.json # custom quick prompts + disabled built-ins
├── sidebar-items.json # custom sidebar items + disabled built-ins
├── vapid-keys.json # Web Push VAPID keypair (generated)
├── push-subscriptions.json # Web Push endpoint subscriptions
├── cli-token # CLI auth token (generated)
├── port # current server port
├── pmux.lock # single-instance lock {pid, port, startedAt}
├── logs/ # pino-roll log files
├── uploads/ # images attached via the chat input bar
└── stats/ # Claude usage statistics cache
Files containing secrets (config, tokens, layouts, VAPID keys, lock) are written with mode 0600 via a tmpFile → rename pattern.
Top-level files
| File | What it stores | Safe to delete? |
|---|---|---|
config.json |
scrypt-hashed login password, HMAC session secret, theme, locale, font size, notification toggle, editor URL, network access, custom CSS | Yes — re-runs onboarding |
workspaces.json |
Workspace index, sidebar width / collapsed state, active workspace ID | Yes — wipes all workspaces and tabs |
hooks.json |
Claude Code --settings mapping (event → script) + statusLine.command |
Yes — regenerated on next start |
status-hook.sh, statusline.sh |
POST to /api/status/hook and /api/status/statusline with x-pmux-token |
Yes — regenerated on next start |
rate-limits.json |
Latest Claude statusline JSON: ts, model, five_hour, seven_day, context, cost |
Yes — repopulates as Claude runs |
session-history.json |
Last 200 completed Claude sessions (prompts, results, durations, tools, files) | Yes — clears history |
quick-prompts.json, sidebar-items.json |
{ custom: […], disabledBuiltinIds: […], order: […] } overlays on the built-in lists |
Yes — restores defaults |
vapid-keys.json |
Web Push VAPID keypair, generated on first run | Don't unless you also delete push-subscriptions.json (existing subscriptions break) |
push-subscriptions.json |
Per-browser push endpoints | Yes — re-subscribe on each device |
cli-token |
32-byte hex token for purplemux CLI and hook scripts (x-pmux-token header) |
Yes — regenerated on next start, but any hook script that's already been generated keeps the old token until the server overwrites it |
port |
Plain-text current port, read by hook scripts and the CLI | Yes — regenerated on next start |
pmux.lock |
Single-instance guard { pid, port, startedAt } |
Only if no purplemux process is alive |
Per-workspace directory (workspaces/{wsId}/)
Every workspace gets its own folder, named after the generated workspace ID.
| File | Contents |
|---|---|
layout.json |
Recursive pane/tab tree: leaf pane nodes with tabs[], split nodes with children[] and a ratio. Each tab carries its tmux session name (pt-{wsId}-{paneId}-{tabId}), cached cliState, claudeSessionId, last resume command. |
message-history.json |
Per-workspace Claude input history. Capped at 500 entries. |
claude-prompt.md |
The --append-system-prompt-file content passed to every Claude tab in this workspace. Regenerated on workspace create / rename / directory change. |
Delete a single workspaces/{wsId}/layout.json to reset that workspace's layout to a default pane without touching the others.
logs/
Pino-roll output, one file per UTC day, with a numeric suffix when size limits are exceeded:
logs/purplemux.2026-04-19.1.log
Default level is info. Override with LOG_LEVEL or per-module with LOG_LEVELS — see Ports & env vars.
Logs rotate weekly (7-file limit). Safe to delete at any time.
uploads/
Images attached via the chat input bar (drag, paste, paperclip):
uploads/{wsId}/{tabId}/{timestamp}-{rand}-{name}.{ext}
- Allowed:
image/png,image/jpeg,image/gif,image/webp - Max 10 MB per file, mode
0600 - Auto-cleaned on server start: anything older than 24 hours is removed
- Manual cleanup at Settings → System → Attached Images → Clean now
stats/
Pure cache. Derived from ~/.claude/projects/**/*.jsonl — purplemux only reads that directory.
| File | Contents |
|---|---|
cache.json |
Per-day aggregates: messages, sessions, tool calls, hourly counts, per-model token usage |
uptime-cache.json |
Per-day uptime / active-minutes roll-up |
daily-reports/{YYYY-MM-DD}.json |
AI-generated daily brief |
Delete the whole folder to force a recompute on the next stats request.
Reset matrix
| To reset… | Delete |
|---|---|
| Login password (re-onboard) | config.json |
| All workspaces and tabs | workspaces.json + workspaces/ |
| One workspace's layout | workspaces/{wsId}/layout.json |
| Usage statistics | stats/ |
| Push subscriptions | push-subscriptions.json |
| Stuck "already running" | pmux.lock (only if no process alive) |
| Everything (factory reset) | ~/.purplemux/ |
hooks.json, status-hook.sh, statusline.sh, port, cli-token, and vapid-keys.json are all auto-regenerated on next startup, so deleting them is harmless.
Backups
The whole directory is plain JSON plus a few shell scripts. To back up:
tar czf purplemux-backup.tgz -C ~ .purplemux
To restore on a fresh machine, untar and start purplemux. Hook scripts will be rewritten with the new server's port; everything else (workspaces, history, settings) lifts over as-is.
Wipe everything
rm -rf ~/.purplemux
Make sure no purplemux is running first. Next launch will be the first-run experience again.
What's next
- Ports & env vars — every variable that influences this directory.
- Architecture — how the files connect to the running server.
- Troubleshooting — common issues and fixes.