Session log: SSH, links, promote, help, MCP v1

This commit is contained in:
megaproxy 2026-05-25 21:43:57 +01:00
parent 112d7dd5b5
commit d667e18c0c

View file

@ -51,6 +51,27 @@ Durable memory for this project. Read at session start, update before session en
## Session log
### 2026-05-25 — SSH + clickable links + promote + help + MCP v1
Big session, ~12 commits. Headlines:
- **PowerShell** as a third shell kind alongside WSL distros, then refactored to an explicit `shellKind: "wsl" | "powershell" | "ssh"` discriminator on `LeafNode` with migration on deserialize (legacy `distro:"PowerShell"``shellKind:"powershell"`).
- **Backend SpawnSpec enum** (serde-tagged) replaces the old `distro: Option<String>` model. `pty.rs::spawn` dispatches; SSH builds `ssh.exe -t [-l user] [-p port] [-i id] [-J jump] -- host` with `TERM=xterm-256color`. Token validation rejects leading `-` and control chars (CVE-2023-51385).
- **Clickable URLs** via `@xterm/addon-web-links` routed through `@tauri-apps/plugin-opener`. Needed scoped `opener:allow-open-url` permission with `http/https/mailto` allow list, not the bare identifier.
- **Saved SSH hosts** with manager modal (label/host/user/port/identityFile/jumpHost/extraArgs), stored in `hosts.json`. Hierarchical per-pane dropdown: WSL distros → PowerShell → SSH hosts → "Manage hosts…".
- **Saved passwords** in Windows Credential Manager via `keyring-core` 1.0 + `windows-native-keyring-store` 1.0 (keyring-rs 4.x is sample code only now; the lib was split). Reader thread autotypes the password when ssh prompts (`password:`/`passphrase` regex, 30s window, one-shot). Passwords never on disk, never in IPC events, never in MCP.
- **Promote-out gesture**: first tried drag-past-sibling (75% then 50% threshold), but the inner gutter is too easy to miss — xterm canvas hit-testing felt unreliable. Ripped all the drag-armed/preview logic, replaced with **Ctrl+Shift+P keyboard shortcut** that calls `promoteLeaf(tree, activeLeafId)` (self-inverse).
- **Help overlay**: titlebar `?` button + F1, sourced from a single `src/lib/shortcuts.ts` SoT (sections + tips).
- **MCP server v1 (read-only)** via `rmcp` 1.7.0 Streamable HTTP on 127.0.0.1, bearer-token auth, OS-picked port. Per-pane `mcpAllow` flag (default-deny) gates what's mirrored to the backend. Resources: `tiletopia://layout`, `tiletopia://panes`, `tiletopia://hosts`. Tools: `read_pane(leaf_id, last_lines, after_seq)` + `wait_for_idle(leaf_id, idle_ms, timeout_ms)`. 256 KB per-pane scrollback ring populated by the PTY reader thread. Titlebar 🤖 toggle opens an `McpPanel` with URL + token + ready-to-paste Claude config snippet.
- **WSL → Windows networking gotcha**: WSL2 default NAT mode hides Windows `127.0.0.1`. User needs `networkingMode=mirrored` in `%UserProfile%\.wslconfig` (Win 11 22H2+) then `wsl --shutdown` to reconnect. Documented in McpPanel + README + help overlay.
- **Tree-helper data model** also gained: `setLeafShell` (replaces `changeDistro` for shell switches; id-swap forces respawn), `promoteLeaf`, `toggleMcpAllow`. `reshapeToPreset` carries new fields. 72 vitest cases, all green.
Open follow-ups specific to this session:
- **MCP v2**`write_pane`, `spawn_pane`, `connect_host`, `close_pane`, `apply_preset`, `promote_pane`, `set_label`, `swap_panes`, `add_host`. Spawned panes should auto-set `mcpAllow=true` (per user). Still skip `set_host_password` from MCP.
- **MCP write surface should require a confirmation** for `write_pane` on SSH panes (footgun avoidance).
- **`.mcpb` bundle** as a one-click Claude Desktop install path.
- **Per-pane MCP audit log** in the panel — show last N tool calls so the user can spot Claude doing surprising things.
### 2026-05-22 — M5 ship infrastructure
- New icon: `scripts/make-icon.py` (Pillow) draws a 1024×1024 dark rounded square with a 2×2 grid — one tile in the active-blue, one in the broadcast-orange, two muted. Mirrors the in-app `.leaf.active` / `.leaf.broadcasting` colors so the brand is consistent end-to-end.