Persistence
What MadoHub saves, where it saves it, and how.
MadoHub persists your workspace state to disk so everything is restored when you relaunch the app. All persisted workspace data is stored locally on your machine.
Storage location
All files are stored in ~/.madohub/:
~/.madohub/
├── canvas-state.json # Full canvas state
├── config.json # App configuration
├── chat-history.json # Chat message history
├── memory-policies.json # Memory auto-inject policies
├── templates/
│ └── <slug>.json # One per saved workspace template
├── flows/
│ └── <id>.json # One per saved flow
├── logs/
│ └── madohub.log # Application logs
├── notifications/ # Stop-hook completion markers
└── orchestrator/ # Orchestrator mode stateWhat's saved
Canvas state (canvas-state.json)
| Data | Details |
|---|---|
| Tiles | Type, position, size, z-index, file paths, working directory |
| Frames | Workspace paths, colors, positions |
| Viewport | Pan offset (X/Y) and zoom level |
| Connections | All routing connections with trigger/transform config |
| Settings | API provider, key, model; notification hook state |
| Max z-index | For stacking order of new tiles |
| Dismissed sessions | Hidden tmux sessions |
App config (config.json)
| Data | Details |
|---|---|
| Hooks state | Whether Claude Code notification hooks are enabled |
| Workspaces (legacy, inactive) | The config schema still defines a list of registered project directories and an active workspace ID, but no frontend code path calls the save/load functions for them, so they're dead. The live concept for per-project state is frames, stored in canvas-state.json. |
How saving works
- Auto-save: Triggers on any canvas, connection, or settings change.
- Debounced: 500ms delay to batch rapid changes.
- Atomic writes: Data is written to a unique sibling file (
<name>.tmp.<pid>.<seq>), then renamed into place. This prevents corruption if the app crashes mid-write. - Corruption recovery: If a file fails to parse as JSON on load, its bytes are quarantined to a content-addressed
<name>.corrupt.<hash>sibling (stable across restarts) and loading falls back to defaults instead of failing.
What's NOT saved
- Terminal session content (PTY output is ephemeral)
- Clipboard contents