detached 71431fb

chore: remove useless docs

commit
71431fb4084d754365cb1b0b1c86437e700a880f
author
brice · · 2026-07-15 15:38 UTC
parent
cb4ef6c
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
1 file · +0 -40
D docs/superpowers/specs/2026-07-04-clipboard-image-transfer-design.md +0 -40
@@ -1,40 +0,0 @@
1-# Clipboard image transfer (local → remote pane)
2-
3-Date: 2026-07-04 · Status: approved (approach A)
4-
5-## Problem
6-
7-When attached to a remote session, pasting an image for a TUI coding agent (pi, claude) is impossible: the agent's Ctrl+V handler reads the *remote* clipboard, which doesn't exist on a headless host (pi's chain — `wl-paste` → `xclip` → native — returns null in every branch without `WAYLAND_DISPLAY`/`DISPLAY`; no OSC 52 image path exists). The image lives on the laptop.
8-
9-## Approach
10-
11-Replicate the *end state* of pi's local Ctrl+V, which is: write the image to a temp file and insert the literal file path as text at the editor cursor (pi-mono `interactive-mode.ts:2536-2555`). vev does the same across the wire:
12-
13-1. **Client (remote attach only):** intercept `0x16` (Ctrl+V) on stdin. Run `wl-paste --list-types` (1s timeout). If an `image/*` type is present, pick by preference `png > jpeg > webp > gif` (same order as pi), read it with `wl-paste --type <mime> --no-newline`, and send one `ImagePush` frame. If no image / wl-paste missing / any error: forward `0x16` verbatim (today's behavior).
14-2. **Daemon:** on `ImagePush`, write the bytes to `os.TempDir()/vev-clip-<unixts>.<ext>` with mode 0600, remember the path on the session, and inject the path text into the focused pane's PTY — wrapped in `\x1b[200~…\x1b[201~` iff the pane's `Screen.BracketedPasteMode()` is true (first production use of the mode-2004 tracking), bare text otherwise. Injection goes through the same write path as regular input (`writeToPane`).
15-3. **Cleanup:** files recorded on the session are removed when the session ends (same lifecycle as the session teardown path). Best-effort; `/tmp` is the backstop.
16-
17-## Wire protocol
18-
19-- New client-originated message `MsgImagePush` (next free type in the 1–15 range) in `internal/ports`: `{ Mime string, Data []byte }`, hand-marshalled big-endian like the rest of `wire.go`.
20-- Bump `ProtocolVersion` (strict-equality negotiation; `Hello.Version` stays first field).
21-- Byte-for-byte golden tests + truncated-prefix / trailing-garbage invariants in `wire_test.go`, per repo protocol rules.
22-- Caps: client refuses images > 10 MiB (notifies via stderr/status); frame limit is 16 MiB so one frame always suffices. Daemon independently rejects > 10 MiB payloads (defense against old/foreign clients).
23-
24-## Scope decisions
25-
26-- **Remote attaches only.** On local attach, `0x16` passes through untouched — the agent reads the local clipboard natively and its own temp-file flow works.
27-- **Wayland only** on the client side (user's environment). The clipboard read sits behind a small client-side seam (interface in the client package or `ports` if it must cross layers) so `xclip`/OSC-52 backends can be added later without protocol changes.
28-- **No image conversion.** Bytes are transferred as-is; unsupported exotic formats are the agent's problem (pi converts BMP itself locally; that path simply isn't reachable here).
29-- **Known caveat:** while an image is on the local clipboard, Ctrl+V won't reach remote pane apps that bind it themselves (e.g. vim visual block). Text/empty clipboard → passthrough unchanged.
30-
31-## Testing
32-
33-- Client: fake clipboard runner (seam above) — image present → one ImagePush frame, no `0x16` forwarded; no image → `0x16` forwarded; oversized → refused + `0x16` not swallowed silently.
34-- Ports: golden wire tests as above.
35-- Daemon: ImagePush → file created 0600 with exact bytes, path injected with/without bracketed-paste wrapping depending on pane mode; session end removes the file; oversized rejected.
36-- Manual: end-to-end against the scratchpad harness (fake-ssh `_stdio` path) with a real PNG.
37-
38-## Out of scope
39-
40-Remote→local image transfer, multi-image batching, X11 client support, progress UI for large images.
@@ -1,40 +0,0 @@
1-# Clipboard image transfer (local → remote pane)
2-
3-Date: 2026-07-04 · Status: approved (approach A)
4-
5-## Problem
6-
7-When attached to a remote session, pasting an image for a TUI coding agent (pi, claude) is impossible: the agent's Ctrl+V handler reads the *remote* clipboard, which doesn't exist on a headless host (pi's chain — `wl-paste` → `xclip` → native — returns null in every branch without `WAYLAND_DISPLAY`/`DISPLAY`; no OSC 52 image path exists). The image lives on the laptop.
8-
9-## Approach
10-
11-Replicate the *end state* of pi's local Ctrl+V, which is: write the image to a temp file and insert the literal file path as text at the editor cursor (pi-mono `interactive-mode.ts:2536-2555`). vev does the same across the wire:
12-
13-1. **Client (remote attach only):** intercept `0x16` (Ctrl+V) on stdin. Run `wl-paste --list-types` (1s timeout). If an `image/*` type is present, pick by preference `png > jpeg > webp > gif` (same order as pi), read it with `wl-paste --type <mime> --no-newline`, and send one `ImagePush` frame. If no image / wl-paste missing / any error: forward `0x16` verbatim (today's behavior).
14-2. **Daemon:** on `ImagePush`, write the bytes to `os.TempDir()/vev-clip-<unixts>.<ext>` with mode 0600, remember the path on the session, and inject the path text into the focused pane's PTY — wrapped in `\x1b[200~…\x1b[201~` iff the pane's `Screen.BracketedPasteMode()` is true (first production use of the mode-2004 tracking), bare text otherwise. Injection goes through the same write path as regular input (`writeToPane`).
15-3. **Cleanup:** files recorded on the session are removed when the session ends (same lifecycle as the session teardown path). Best-effort; `/tmp` is the backstop.
16-
17-## Wire protocol
18-
19-- New client-originated message `MsgImagePush` (next free type in the 1–15 range) in `internal/ports`: `{ Mime string, Data []byte }`, hand-marshalled big-endian like the rest of `wire.go`.
20-- Bump `ProtocolVersion` (strict-equality negotiation; `Hello.Version` stays first field).
21-- Byte-for-byte golden tests + truncated-prefix / trailing-garbage invariants in `wire_test.go`, per repo protocol rules.
22-- Caps: client refuses images > 10 MiB (notifies via stderr/status); frame limit is 16 MiB so one frame always suffices. Daemon independently rejects > 10 MiB payloads (defense against old/foreign clients).
23-
24-## Scope decisions
25-
26-- **Remote attaches only.** On local attach, `0x16` passes through untouched — the agent reads the local clipboard natively and its own temp-file flow works.
27-- **Wayland only** on the client side (user's environment). The clipboard read sits behind a small client-side seam (interface in the client package or `ports` if it must cross layers) so `xclip`/OSC-52 backends can be added later without protocol changes.
28-- **No image conversion.** Bytes are transferred as-is; unsupported exotic formats are the agent's problem (pi converts BMP itself locally; that path simply isn't reachable here).
29-- **Known caveat:** while an image is on the local clipboard, Ctrl+V won't reach remote pane apps that bind it themselves (e.g. vim visual block). Text/empty clipboard → passthrough unchanged.
30-
31-## Testing
32-
33-- Client: fake clipboard runner (seam above) — image present → one ImagePush frame, no `0x16` forwarded; no image → `0x16` forwarded; oversized → refused + `0x16` not swallowed silently.
34-- Ports: golden wire tests as above.
35-- Daemon: ImagePush → file created 0600 with exact bytes, path injected with/without bracketed-paste wrapping depending on pane mode; session end removes the file; oversized rejected.
36-- Manual: end-to-end against the scratchpad harness (fake-ssh `_stdio` path) with a real PNG.
37-
38-## Out of scope
39-
40-Remote→local image transfer, multi-image batching, X11 client support, progress UI for large images.

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 12

Tags 11

↑↓ moveenter openesc close