Commit graph

5 commits

Author SHA1 Message Date
83d8932c98 Add MCP server (v1 read-only): toggle, per-pane gate, panel UI 2026-05-25 21:31:49 +01:00
872fb0e80e Add SSH connections: saved hosts manager and hierarchical shell picker 2026-05-25 19:47:37 +01:00
d9ddf52699 Replace idle toasts with pane border + titlebar badge
Old behaviour: every pane fired orch.notify("X is idle") after 5s of
silence, stacking up to N toasts that took ages to dismiss.

New behaviour:
- LeafPane tracks its own isIdle state locally and reports up via
  orch.reportLeafIdle(leafId, idle).
- App aggregates into a Set<NodeId> and renders "N idle" in red after
  the "N panes" count in the titlebar (hidden when zero).
- The pane itself gets a red border (.leaf.idle) — but active and
  broadcasting borders still take precedence, so the focus indicator
  isn't masked by idle status.
- The pane's "alive" status text in the toolbar swaps to red "idle"
  while it's quiet (reverts to "alive" the moment output arrives).
- Idle clears immediately on the next byte of output (no 1-second lag)
  AND when the pane unmounts (cleanup effect).

No more flood of toasts.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 19:54:20 +01:00
c93ebddfa5 Drag a pane's toolbar onto another pane to swap them
New interaction: click-and-drag any pane's toolbar onto another pane
to swap their positions in the tree. The shells / scrollback stay
intact (each leaf keeps its data; only the tree slot it occupies
changes).

Implementation:
- tree.ts: `swapLeaves(root, idA, idB)` walks the tree once,
  substituting one leaf for the other at each occurrence. The leaf
  objects themselves carry their id/distro/cwd/label/broadcast across,
  so React preserves the LeafPane instances via the flat-list keying.

- orchestration.tsx: add drag lifecycle to the context —
  dragSourceId / dragOverId (reactive) plus beginHeaderDrag,
  setHeaderDragOver, endHeaderDrag (stable methods).

- App.tsx: implement those methods. endHeaderDrag(true) swaps if
  source and over are different leaves.

- LeafPane.tsx: pointerdown on .pane-toolbar (skipped if the target
  is a button/input). 5px movement threshold before drag commits to
  prevent accidental swaps when clicking a chip etc. Pointer-capture
  the toolbar so we keep getting move events even outside it. Use
  document.elementFromPoint to find the leaf under the cursor.

- CSS: source pane fades to 40% opacity during drag; target pane
  shows a 3px dashed blue outline; toolbar shows grab/grabbing
  cursors.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 19:47:06 +01:00
774b8633dc Migrate frontend from Svelte 5 to React 18
After hours of fighting Svelte 5's prop-reactivity through the
recursive Pane → SplitNode → LeafPane chain (props captured at
mount, never updated; context+getter pattern crashed; DOM-direct
workarounds created zombie-split click-intercept bugs), we
checkpointed the Svelte version (branch svelte-archive at e9015b2,
tarball at D:\archives\tiletopia-svelte-2026-05-22.tar.gz) and
rewrote the frontend in React.

Kept verbatim:
- All of src-tauri/ (Rust backend, Tauri config, icons)
- scripts/ (make-icon.py, release.sh)
- README.md, CLAUDE.md, memory.md
- src/lib/layout/tree.ts (pure TS — 43 tests still pass)
- src/ipc.ts (Tauri command wrappers)

Rewrote in React:
- src/App.tsx (top-level state via useState, OrchestrationProvider
  for descendants via React.Context)
- src/lib/layout/orchestration.tsx (React Context API for shared
  state — known-reliable reactivity, no Svelte 5 wall)
- src/lib/layout/Pane.tsx (recursive dispatcher)
- src/lib/layout/SplitNode.tsx (draggable gutter, local ratio state)
- src/lib/layout/LeafPane.tsx (toolbar + XtermPane)
- src/components/XtermPane.tsx (xterm.js wrapper, refs for callbacks)
- src/components/Notifications.tsx, Palette.tsx

Build: Vite + @vitejs/plugin-react. TypeScript strict. Same Tauri 2
config. Verified: pnpm check (clean), pnpm test (43/43 pass).
Not yet verified: pnpm tauri dev — that requires the Windows host.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 18:05:05 +01:00