diff --git a/docs/plans/2026-03-29-settings-design.md b/docs/plans/2026-03-29-settings-design.md new file mode 100644 index 0000000..1fc51c4 --- /dev/null +++ b/docs/plans/2026-03-29-settings-design.md @@ -0,0 +1,211 @@ +# Settings Panel & New Session Design + +## Goal + +Add a Settings panel and New Session feature to muxplex, removing the command palette (now redundant with the sidebar). + +## Background + +The command palette was the original mechanism for session switching, but the sidebar + hover preview + click-to-navigate flow now covers the same functionality. The header space freed by removing the palette is better used for settings access and session creation — two features muxplex currently lacks. + +Settings need to live in two places: per-device preferences (font size, notifications) in localStorage, and per-user configuration (session defaults, templates) in a server-side file that persists across devices. + +## Approach + +- **Settings** as a modal dialog (desktop) / bottom sheet (mobile), triggered by a gear icon in the header. Controls apply immediately with debounced persistence — no Save button. +- **New Session** as an inline name input that replaces the `+` button on click. A configurable command template in settings controls what actually runs on the server. +- **Command palette removal** — delete all palette HTML, CSS, and JS. + +--- + +## Architecture + +### Settings Access + +Gear icon (⚙) in the header, right side, next to a `+` (new session) button and connection status indicator. Same position in both dashboard and expanded terminal views. + +Keyboard shortcut: `,` (comma, VS Code convention). + +### Desktop Layout (≥600px) + +Centered modal dialog — same pattern as the now-removed command palette (backdrop, escape-to-close, centered panel): +- Width: `min(600px, 90vw)` +- Height: `min(480px, 80vh)` +- Left tab list: 140px fixed width +- Active tab: `color: var(--accent)` with 2px left border in `var(--accent)` + +Tabs: **Display**, **Sessions**, **Notifications**, **New Session**. + +### Mobile Layout (<600px) + +Bottom half-sheet (slides up from bottom, drag-to-dismiss downward): +- Same gear icon trigger +- 48px minimum touch targets for all controls +- Dim overlay behind +- Max height ~85vh + +### Storage Split + +**localStorage (per-device):** Font size, grid columns, hover preview delay, bell sound, desktop notification permission. + +**Server (`~/.config/muxplex/settings.json`):** Default session, sort order, hidden sessions, window-size largest, auto-open created sessions, new session command template. + +No sync between the two. If localStorage is cleared, the user gets defaults. Server settings persist across devices via the API. + +### Controls Behavior + +All controls apply immediately — no Save button. Each change debounces 500ms then persists (PATCH to server or localStorage write). A subtle toast confirms the save. This matches developer tool conventions (VS Code, terminal settings). + +--- + +## Components + +### API Endpoints + +| Method | Path | Description | +|--------|------|-------------| +| `GET` | `/api/settings` | Returns server-side `settings.json` contents | +| `PATCH` | `/api/settings` | Partial update — merges single-field saves | +| `POST` | `/api/sessions` | Creates a new session (`{"name": "my-project"}`) | + +### Server-Side Settings File + +`~/.config/muxplex/settings.json`: + +```json +{ + "default_session": null, + "sort_order": "manual", + "hidden_sessions": [], + "window_size_largest": false, + "auto_open_created": true, + "new_session_template": "tmux new-session -d -s {name}" +} +``` + +### localStorage Key + +`muxplex.display` — single JSON blob: + +```json +{ + "fontSize": 14, + "hoverPreviewDelay": 1500, + "gridColumns": "auto", + "bellSound": false, + "notificationPermission": "default" +} +``` + +--- + +## Settings Categories & Fields + +### Display Tab (localStorage) + +| Field | Control | Default | +|---|---|---| +| Font size | `` (Off, 1s, 1.5s, 2s, 3s) | 1.5s | +| Grid columns | `` (None + current session list) | None | +| Sort order | `