A preview was distinguished only by the chip and a dashed ring, both easy to
miss, and the sidebar's hover reused the neutral surface — so a hovered row
said nothing about what the content pane was showing.
Adds a `--preview` token family on a hue of its own, deliberately not the
accent: the accent means "this is the one you picked", which a preview is not.
The previewed pane's titlebar, the chip, the throwaway tab, the previewed
sidebar row and hover all carry it. Palettes whose accent is already violet
(periwinkle, orchid) move the hue via `--preview-h`.
Replaces the inline activity dot with a coloured bar positioned inside
each row's own indent gutter, per the updated docs/SIDEBAR.md contract.
Active breathes, awaiting-input blinks, error flashes; idle stays
solid. prefers-reduced-motion leaves every state static.
Graphite replaces the signal-green accent as the default web palette;
data-palette on <html> selects ice-cyan, periwinkle, amber-phosphor,
ember or orchid (each with dark + light token sets), picked from a new
sidebar-footer dropdown and persisted in localStorage.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The header carried only the brand and a session tally; app actions had
already moved to the sidebar footer. The mobile ☰ it hosted moves to the
pane header (replacing the redundant back arrow) and to the welcome
state, so the session drawer stays reachable without a swipe. The DEV
`?kit` link moves to the sidebar footer.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The draft pane covers every field the modal had; the modal was a second
code path for the same job. The header Spawn button, sidebar empty state,
welcome button, and ?mock&spawn now open a draft pane via
MultiView.openDraft — reusing an empty focused pane, else splitting it.
"Spawn similar" seeds a draft with the session's cwd + command.
Modal-only CSS (backdrop, sheet/dialog chrome, keyframes) is deleted;
.modal-body form styling folds into .spawn-form, which also picks up the
select styling the worktree branch picker was borrowing from the modal.
Session tree nests by working directory only; the daemon chips in the
header become a session tally, and the spawn form loses its host picker.
API calls move from /api/daemons/:id/* to /api/dirs, /api/recent-dirs,
/api/gitroot, and /api/info.
Replace the freeform `metadata.label` session grouping with nesting derived
from each session's working directory. The daemon's activity watcher already
polls each tmux pane every tick, so it now also captures
`#{pane_current_path}` and surfaces it as a new `Session.current_cwd`
(serde-default, back-compat); `cwd` stays the spawn dir for worktree
inference, spawn-similar, and recents.
Web catalog builds the tree from `current_cwd ?? cwd`, collapses the home
dir to `~`, and folds single-child folder chains so `~/git/maestro` reads as
one node. CLI swaps its LABEL column for an abbreviated DIR; the spawn forms
(web + TUI) and `--label` flag are removed.
The pane format stays space-delimited (parser splits the first three tokens
and keeps the remainder as the path) so a cwd containing spaces survives.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Web: rename the per-row clone affordance to "Spawn similar" — it reopens the
revamped spawn form pre-seeded from the session's host, dir, command (matched
back to a preset by the form), and label, but with a freshly generated name
since it's a new session. Built entirely on the existing prefill machinery; the
custom event is renamed `catalog-spawn-similar`.
e2e (maestro-e2e): against real tmux + git, spawn into a git repo dir and assert
(1) the daemon's recent-dirs endpoint surfaces that dir with its command — what
#27's recents picker reads on the next form open — proving the durable
spawn-history write, and (2) gitroot infers the enclosing repo as the worktree
base_repo.
Closes#28
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Live-review iteration on the browser SPA, driven by crit feedback.
Sidebar / session tree
- Compact single-line leaf rows; status shown as a faint "alive" row wash
instead of per-row dots (exited rows dim + keep the "exited" badge).
- Host is now the first level of nesting (host → label path → session); the
inline @daemon is dropped from rows.
- Flush, borderless search input spanning the sidebar; drag-to-resize grip on
the sidebar edge (width persisted to localStorage); narrower default.
- Per-row clone action (opens the spawn modal prefilled); right-pointing
chevron when collapsed.
Chrome / layout
- Buttons swapped to a bracket terminal style ([ + Spawn ]); ghost/icon drop
the brackets. Old filled styles removed.
- Squared corners globally (radius tokens) and tighter, denser spacing.
- Session tally + daemon chips moved into the centered app header.
- Shorter control height; shared --bar-h aligns the search and attach bars.
Attach / terminal
- Useful attach title (name · command @ host) over a bare UUID.
- Robust fit: compute columns from the viewport's scrollbar-excluded
clientWidth (fixes mobile under-fit and desktop overflow); ResizeObserver +
font-load refit; full-bleed terminal on mobile.
Spawn / empty states
- Spawn modal accepts a prefill (clone); real "+ Spawn" buttons in welcome and
no-sessions empty states.
Dev
- New ?kit design-kit page (kit.ts/kit.css, DEV-only) showcasing components.
- Richer ?mock fixture with deeper label nesting.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>