Commit Graph
78 Commits
Author SHA1 Message Date
Miguel PalhasandClaude Opus 5 8dde63a2ab feat(maestro): add the web ctrl-k command bar
The overlay, the query line and the session half of the results
(docs/COMMAND-BAR.md): an empty query lists sessions most recently
focused first, typing ranks through `matchAndRank` with the winning
field's ranges highlighted, and results render under kind headers
ordered by their best-scoring member.

Enter dispatches `SESSION_SELECT_EVENT`, the path the sidebar's click
and the hash router already share, so a bar attach cannot leave the
layout in a state a click could not produce.

The global key listener moves to the capture phase, which #148 left
alone: an attached xterm swallows every keystroke it is given, so
ctrl-k has to be seen ahead of the terminal.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-03 14:28:42 +01:00
Miguel Palhas 46a000aa68 docs(maestro): correct the row-transition comment after the fill change
ci / web (push) Failing after 6s
ci / flake (push) Successful in 3m9s
ci / rust (push) Successful in 7m0s
2026-09-03 14:08:37 +01:00
Miguel Palhas b46ba9dd26 Merge remote-tracking branch 'origin/main' into dominant 2026-09-03 14:06:58 +01:00
Miguel Palhas cd37ac5d6d fix(maestro): say preview with a fill, not a ring
The previewed row and the keyboard cursor both drew a 2px inset ring, which
read as a border on hover rather than as a colour. Rows now carry the preview
hue as a fill: a light wash under the pointer or the cursor, deepening to an
opaque `--preview-tint` once the preview lands.

That leaves `.is-active`'s ring as the only one in the session list, where it
now means exactly one thing — open in a pane. The pane's titlebar drops its
hairline for the same reason; the dashed edges that remain belong to the
canvas and the throwaway tab.
2026-09-03 13:46:49 +01:00
Miguel PalhasandClaude Opus 5 6075a177f5 perf(maestro): drop the sidebar preview delay
The pane waited 150 ms on hover and 60 ms on a keyboard step before
following the sidebar highlight, so every preview paid for the fast walk
it might have been. Replace both with a leading-edge 120 ms gap: the
first move shows at once, a burst is coalesced to its start and its end.

The row's own hover no longer eases either — `background` was on a 120 ms
transition, which is what read as lag on the row itself.

The sidebar also rebuilt its whole tree on every `SessionUpdated`, a
couple of times a minute per live session, dropping `:hover` from the row
under the pointer. Refreshes that change nothing structural now patch the
activity rail and meta line into the standing rows instead.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-03 13:36:51 +01:00
Miguel Palhas 7a3287f231 feat(maestro): colour the previewed pane and its sidebar row
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`.
2026-09-03 13:35:55 +01:00
Miguel Palhas 2319b4e47b fix(maestro): keep the keyboard in the list while previewing
Two mounts were taking focus out of the sidebar mid-walk: the render that
put the multi-view on screen before the preview applied, and the render
that restores the previous pane when a preview ends. Both now mount
without focusing, so j/k keeps walking. Also marks the preview with a
badge on the canvas and drops the close button from its tab.
2026-09-03 10:52:43 +01:00
Miguel Palhas f6b2cf3ab4 feat(maestro): preview the highlighted session in the web pane
Moving the sidebar highlight (keyboard or hover) now shows that session in
the content pane without opening it: its own tab comes forward, or a
throwaway tab carries it. The layout, the saved layout and the daemon's
focus report are all left untouched, and the keyboard stays in the list.

Contract in docs/PREVIEW.md.
2026-09-03 10:42:53 +01:00
Miguel Palhas f669ebbddd fix(maestro): full-screen spawn dialog on mobile
ci / web (push) Failing after 6s
ci / flake (push) Successful in 3m8s
ci / rust (push) Successful in 6m20s
The dialog capped at 92vh and scrolled its whole body, so the Spawn button
sat below the fold on a phone. Below 600px it now fills the viewport, the
pickers drop their own scroll caps, and the actions row sticks to the bottom
edge.
2026-09-02 21:53:26 +01:00
Miguel Palhas 6173c86694 feat(maestro): web spawn form stops naming sessions
The name field starts empty and the reroll is gone; the worktree branch keeps
a default by borrowing one handle from /api/names. A card whose name the
daemon generated renders dimmed until a first prompt settles it.

Refs #131
2026-09-02 18:00:03 +01:00
Miguel Palhas acb84b91ef fix(maestro): pin activity rail to left edge, drop active-state pulse
Rail now spans full row height flush to the left edge with square
corners, instead of a depth-shifted inset bar. Active state stays
solid green since colour alone already signals it; blink/flash stay
for awaiting-input/error.
2026-09-02 17:18:00 +01:00
naps62 21fc20b30a Merge pull request 'docs(maestro): replace the sidebar's activity dot with a rail' (#130) from indicators into main
ci / web (push) Successful in 3m40s
ci / rust (push) Successful in 5m49s
ci / flake (push) Successful in 6m12s
Reviewed-on: #130
2026-09-02 17:00:58 +01:00
Miguel Palhas 1d18e21420 feat(maestro): web sidebar activity rail
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.
2026-09-02 16:47:47 +01:00
Miguel Palhas adbf57fc49 Merge remote-tracking branch 'origin/main' into colors
ci / web (push) Successful in 37s
ci / rust (push) Successful in 4m19s
ci / flake (push) Successful in 7m3s
# Conflicts:
#	web/src/catalog.ts
#	web/src/styles.css
2026-09-02 16:31:58 +01:00
Miguel PalhasandClaude Fable 5 7935663ed7 feat(maestro): graphite web default + palette picker
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>
2026-09-02 16:14:12 +01:00
Miguel Palhas 3ce1a6f331 feat(maestro): add paging and symbol keys to the mobile key bar
ci / web (push) Successful in 1m22s
ci / rust (push) Successful in 7m24s
ci / flake (push) Successful in 8m50s
PgUp/PgDn and the `- / | ~` symbols the soft keyboard buries behind a page
switch join the bar, in an 8-column grid that keeps the cursor inverted-T.
Columns hold a thumb's width, so a narrow phone scrolls the bar sideways
instead of shrinking the caps.

Closes #7
2026-09-02 16:01:08 +01:00
Miguel PalhasandClaude Opus 5 4d7e368d31 feat(maestro): daemon status indicator and restart overlay on web
The sidebar footer gains a status dot beside the spawn button: green while the
daemon answers, amber while reconnecting, red while it is gone. Hovering it
shows the release the daemon is running — commit hash and commit date.

When the events socket drops, `DaemonLink` starts polling `GET /api/info`. Past
a 1200 ms grace window an overlay blocks the UI (and swallows the app's
shortcuts) until the daemon answers again. If it comes back on a different
commit the page reloads, so a tab never drives new server code from the bundle
that was just replaced; a plain restart just unlocks.

docs/RESTART.md is the contract.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-02 15:45:50 +01:00
Miguel PalhasandClaude Opus 5 6be0dba74e feat(maestro): spawn form back in a modal on web
Draft panes are gone: an empty pane is a placeholder again, and every
spawn affordance opens a dialog around the shared spawn form. Escape,
Cancel, the ✕ and a backdrop click dismiss it; a successful submit puts
the session in a new tab (Spawn similar and the fast-forward fallback
keep placing it beside the pane they acted on).

Removes the per-leaf draft state, its persistence strip, and the form
reuse/teardown machinery the panes needed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-02 14:44:55 +01:00
Miguel Palhas 766eabbcb6 fix(maestro): bind terminal touch scroll to .xterm
ci / web (push) Successful in 38s
ci / rust (push) Successful in 4m8s
ci / flake (push) Successful in 6m39s
The touch handlers sat on `.xterm-viewport`, but xterm appends the
absolutely-positioned viewport before the `position: relative` screen, so
`.xterm-screen` paints over it and takes every touch. The viewport is not an
ancestor of the screen, so the listeners never fired and mobile drags did
nothing. Moves them, and `touch-action: none`, to `.xterm`.
2026-09-01 13:10:18 +01:00
Miguel Palhas c67fa2bd4e feat(maestro): force-kill prompt in the web client
ci / web (push) Successful in 35s
ci / rust (push) Successful in 4m1s
ci / flake (push) Successful in 6m55s
The kill button now sends the unforced DELETE immediately instead of
asking first. Only the daemon's guard refusal raises a prompt, and it is
a real dialog rather than confirm(), so it can offer the override the
daemon already implements.

The API error envelope is decoded into ApiRequestError, keeping the code
and the unsaved-work breakdown so the dialog names what is in the way.
2026-09-01 11:51:45 +01:00
Miguel Palhas 9fc21b4306 Merge remote-tracking branch 'origin/main' into moderato-motif
ci / flake (push) Has been cancelled
ci / web (push) Has been cancelled
ci / rust (push) Has been cancelled
2026-09-01 10:00:32 +01:00
Miguel PalhasandClaude Opus 5 2fcfc06c3c feat(maestro): drop the global app header
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>
2026-09-01 09:51:22 +01:00
Miguel Palhas d304171d7c feat(maestro): hide tab bar when a single tab
The bar has nothing to switch between with one tab, so it is pure chrome. It reappears as soon as a second tab exists; spawn already opens its own tab, so the "+" button stays reachable.
2026-09-01 09:48:15 +01:00
Miguel PalhasandClaude Opus 5 80af2e6816 feat(maestro): one pane, one tab on mobile
Below 860px the layout no longer grows a second navigation surface. The
pane pill strip is gone, the tab bar stays collapsed however many tabs
exist, and opening or spawning takes over the current pane instead of
splitting beside it or opening a tab. The sidebar drawer is the only way
to move between sessions.

The tree itself is untouched, so a desktop-built layout comes back when
the window widens again.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-31 22:14:42 +01:00
Miguel Palhas eb5d28d3a6 Merge branch 'dolce-sonata'
ci / web (push) Successful in 1m7s
ci / flake (push) Failing after 2m45s
ci / rust (push) Successful in 3m48s
2026-08-31 15:32:45 +01:00
Miguel PalhasandClaude Sonnet 5 511ee3be4e fix(maestro): show tool icon in attach header instead of raw command
Session header used to print the raw command line ("claude"); mirror
the sidebar's icon-for-program treatment so both agree.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-31 15:31:00 +01:00
Miguel Palhas a92202302a Merge remote-tracking branch 'origin/main' into largo-lute
ci / web (push) Successful in 53s
ci / flake (push) Failing after 3m19s
ci / rust (push) Successful in 4m1s
2026-08-31 15:30:51 +01:00
Miguel Palhas 44c67fcee7 feat(maestro): move header actions to the sidebar footer
Help, theme toggle, and Spawn now live pinned to the bottom of the
sidebar instead of the top-right app header, keeping them next to the
session list they act on.
2026-08-31 15:30:19 +01:00
Miguel Palhas d8d26d181a Merge remote-tracking branch 'origin/feroce-violin'
ci / web (push) Successful in 1m50s
ci / flake (push) Failing after 2m7s
ci / rust (push) Successful in 4m1s
2026-08-31 15:25:50 +01:00
Miguel PalhasandClaude Sonnet 5 aec7f4cae6 fix(maestro): swap focus rings for background tints on web
ci / web (push) Successful in 41s
ci / flake (push) Failing after 3m8s
ci / rust (push) Failing after 3m10s
Focused sidebar rows and multiview panes drew a green border/ring.
Swap to a background tint on the row and the pane titlebar instead,
so focus stays borderless.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-31 15:24:56 +01:00
Miguel Palhas 7f3d450f63 Merge remote-tracking branch 'origin/main' into feroce-violin 2026-08-31 15:24:32 +01:00
Miguel PalhasandClaude Sonnet 5 0d088c2581 fix(maestro): remove horizontal margin on sidebar session rows
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-31 15:24:29 +01:00
Miguel Palhas 1257ec6eba feat(maestro): self-host JetBrains Mono for web terminal
ci / web (push) Successful in 34s
ci / flake (push) Failing after 1m37s
ci / rust (push) Successful in 3m30s
Sets it as the primary --font-mono/xterm font, system stack kept as
fallback.
2026-08-31 15:19:51 +01:00
Miguel Palhas 39e8239a7d Merge remote-tracking branch 'origin/main' into sostenuto-bassoon 2026-08-31 15:04:28 +01:00
Miguel Palhas 1afe079ca0 feat(maestro): keyboard navigation for the web sidebar
Ctrl+Shift+H moves the keyboard between the session list and the pane;
j/k walk the cards, Enter opens, Escape hands the pane back. The walk
skips expanded folder headers and stops on collapsed ones, matching the
TUI.
2026-08-31 15:04:02 +01:00
Miguel Palhas 8cf9bd0586 Merge remote-tracking branch 'origin/main' into tranquillo-nocturne
ci / web (pull_request) Successful in 46s
ci / rust (pull_request) Successful in 4m16s
ci / flake (pull_request) Successful in 8m45s
2026-08-31 14:58:51 +01:00
Miguel Palhas 1589d58ca0 feat(maestro): sidebar cards show diff stats and tool icons
Line 2 of a session card spelled out its blocked work ("1 uncommitted
file") and its command ("claude"). Both now render as marks: the
breakdown as diff notation, and the command's leading program as its
tool's icon in the web client.

The probe carries the line delta of the tracked changes — staged and
unstaged together, against HEAD — so `git add` never makes the counter
drop. Untracked files stay a file count; counting their lines means
reading every one off disk. A tracked change with no line delta falls
back to `~N` rather than claiming `+0 -0`.

The TUI keeps its command as text: a terminal cannot be assumed to have
a font carrying tool glyphs.
2026-08-31 14:54:54 +01:00
Miguel Palhas a503ec7c2b refactor(maestro): drop per-session colour and pane glow
ci / web (push) Successful in 49s
ci / rust (push) Successful in 4m47s
ci / flake (push) Successful in 7m31s
The sidebar row dot, the pane top strip and the mobile pill dot all
painted a hashed per-session colour; the focused pane added an outer
accent glow on top of its ring. Removes the colour concept entirely
along with the glow, leaving the flat accent ring as the only focus mark.
2026-08-31 14:51:24 +01:00
Miguel Palhas f0851a62ed feat(maestro): keyboard shortcut overlay on web
ci / web (push) Successful in 37s
ci / rust (push) Successful in 4m13s
ci / flake (push) Successful in 8m48s
`?` toggles a dialog listing every web binding, mirroring the TUI's help
overlay. A `?` button in the header covers pointer-only clients, and the
welcome screen points at the key.

One registry (SHORTCUTS) drives the rendering, so a binding added without
an entry reads as missing. main.ts and the overlay now share one
isTypingTarget guard instead of two copies.
2026-08-31 14:37:53 +01:00
Miguel PalhasandClaude Opus 5 d39fbdbbfc feat(maestro): drop retained worktrees and header debug toggle
Removes the retained-worktree store end to end: the daemon's state-dir
store, GET/DELETE /api/worktrees, `maestro worktrees list|reclaim`, the
TUI overlay behind `w`, and the web `#/worktrees` view and header link.

The kill guard stays. A forced kill and a dirty natural exit now leave
the worktree on disk untouched instead of parking it in a store, so
removing one is an ordinary `git worktree remove`. A pristine tree is
still removed on exit. DELETE /api/sessions/:id always answers 204.

The header's debug button also goes; Ctrl+Shift+D and `?hud` still
toggle the HUD.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-31 09:00:52 +01:00
Miguel PalhasandClaude Opus 5 43b90ccf0a feat(maestro): rename a session from the web sidebar
ci / web (push) Successful in 31s
ci / rust (push) Successful in 5m26s
ci / flake (push) Successful in 8m13s
Right-clicking a card opens a custom context menu (rename, spawn similar,
kill). Rename swaps the name for an inline field; Enter commits, Escape and
blur cancel. The tree stops rebuilding while the field is open, so a catalog
delta cannot replace what is being typed into.

Refs #125

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 11:32:20 +01:00
Miguel Palhas c9d089534b enable session scrolling across clients
ci / web (push) Successful in 59s
ci / rust (push) Successful in 6m8s
ci / flake (push) Successful in 9m52s
2026-08-25 18:46:26 +01:00
Miguel Palhas a1816a0838 fix(maestro): preserve fixed card trailing fragments 2026-08-25 13:18:24 +01:00
Miguel Palhas 10a25e5b83 feat(maestro): keep web session cards two lines 2026-08-25 13:06:23 +01:00
Miguel Palhas c24a2133d4 feat(maestro): render agent-reported detail on web session cards 2026-08-24 22:13:59 +01:00
Miguel Palhas 5be3e33c94 feat(maestro): render sidebar sessions as two-line cards per docs/SIDEBAR.md 2026-08-24 19:50:24 +01:00
Miguel Palhas cd66dbf7d8 Merge remote-tracking branch 'origin/blitz/spawn-v2' into spawn-v2/93-collapse-worktree
# Conflicts:
#	web/src/spawnForm.ts
2026-08-24 15:22:16 +01:00
Miguel Palhas 5de04af36a feat(maestro): collapse the spawn form worktree section by default (#93)
Closed by default behind a disclosure reusing the sidebar folder-header
affordance (catalog.ts), since most spawns take the default target and
the section was the largest block in the form. The collapsed header
states whether a worktree will be created, so #91's off-by-default for
a worktree row stays visible without expanding.

Fixes a latent [hidden] + display:flex bug for the new .wt-collapsible
element (author CSS beats the UA [hidden] rule at equal specificity);
.wt-body has the same bug pre-existing and is out of scope here.
2026-08-24 15:15:47 +01:00
Miguel Palhas 2c89902829 feat(maestro): pick a project, then its worktree
The working-directory picker was a flat list mixing repositories with
their worktrees, each row repeating the project name as an abbreviated
path. It is now two steps: a grid of project boxes carrying the full
unabbreviated path, then — only once a project is picked — that
repository's worktrees with "+ new" as the default.

"+ new" creates a worktree; picking an existing one runs in it and
leaves the create-worktree toggle off, since the daemon never adopts
(docs/WORKTREES.md). That is #91's rule, now an explicit choice rather
than an inference from which row was clicked.

Also fixes `.raw-wrap[hidden]`: `display: flex` outranked the UA sheet's
`[hidden]`, so the free-text cwd input showed even when hidden.

The interaction rules are listed in spawnForm.ts for the TUI mirror (#96)
to follow.

Refs #95
2026-08-24 15:08:05 +01:00
Miguel Palhas 73e9ecfc85 fix(maestro): cap and centre the spawn form's width
The form filled the full pane width, so on a 4K display every input
stretched thousands of pixels wide. Bound it to 60ch (in line with the
48ch/42ch precedents already in the type scale) and centre it with
margin auto; panes narrower than the cap still fill edge to edge.
2026-08-24 14:48:19 +01:00