ee627aff
docs: record muxweb mouse selection
a73x 2026-08-18 12:27
Commit message
docs/decisions.md
| Old | New | ||
|---|---|---|---|
| @@ -3680,3 +3680,67 @@ retry. | |||
| 3680 | copy will use the correlated Reply family and the shared selection | 3680 | copy will use the correlated Reply family and the shared selection |
| 3681 | architecture. They will not add a web-only protocol parser alongside the | 3681 | architecture. They will not add a web-only protocol parser alongside the |
| 3682 | shared client semantics. | 3682 | shared client semantics. |
| 3683 | |||
| 3684 | ## 2026-08-16 (muxweb mouse selection and scrollback copy) | ||
| 3685 | |||
| 3686 | **The daemon owns selection truth; the browser owns the interaction.** A | ||
| 3687 | `selection_req` carries two screen-row coordinates and a client-local request | ||
| 3688 | ID. The daemon extracts against its authoritative terminal screen and sends | ||
| 3689 | the `selection_reply` only to the requesting client, so another attached | ||
| 3690 | client cannot observe either the reply or its text. Successful replies are | ||
| 3691 | valid UTF-8 and at most 1 MiB; extraction is all-or-nothing, with explicit | ||
| 3692 | `invalid`, `too_large`, and `unavailable` statuses rather than truncated text. | ||
| 3693 | Ghostty's selection and plain screen-formatter machinery decides soft-wrap, | ||
| 3694 | hard-break, wide-cell, history, and trimming semantics instead of duplicating | ||
| 3695 | terminal rules in JavaScript. | ||
| 3696 | |||
| 3697 | **The Reply lane keeps CLI and web architecture aligned.** The portable | ||
| 3698 | `ClientCore` owns the one-pending-request correlation rule and rejects stale | ||
| 3699 | or malformed replies. The native client and WASM adapter consume the same | ||
| 3700 | semantic result family; the CLI currently has no selection requester, while | ||
| 3701 | the WASM ABI exposes only the correlated result to muxweb. That is a framework | ||
| 3702 | for future request/reply actions without growing a second browser protocol | ||
| 3703 | parser, not a claim that native keyboard copy mode or terminal mouse-mode | ||
| 3704 | mirroring shipped here. | ||
| 3705 | |||
| 3706 | **Visible selection is optimistic; copyability is authoritative.** Pointer | ||
| 3707 | dragging immediately paints a canvas highlight in retained screen-row | ||
| 3708 | coordinates, but copy remains unavailable until the matching daemon reply has | ||
| 3709 | been decoded and copied out of the borrowed WASM buffer. Edge dragging uses | ||
| 3710 | one scrollback request in flight at a time. Its endpoint advances only through | ||
| 3711 | coordinates belonging to the viewport actually painted after a matching | ||
| 3712 | history response; failure restores the last painted view, preventing a fast | ||
| 3713 | pointer from selecting rows the user never saw. | ||
| 3714 | |||
| 3715 | **Copy chords are selection-sensitive.** With an authoritative retained | ||
| 3716 | selection, `Ctrl+C`, `Ctrl+Shift+C`, and macOS `Cmd+C` are consumed for an | ||
| 3717 | explicit clipboard write and send no PTY bytes. Without one, `Ctrl+C` falls | ||
| 3718 | through to the terminal keymap and `Ctrl+Shift+C` is not prevented, preserving | ||
| 3719 | Firefox's Web Inspector shortcut. Input, paste, composition, plain click, and | ||
| 3720 | unzoom invalidate the retained selection; a copy attempt alone does not. | ||
| 3721 | |||
| 3722 | **Clipboard completion has one accepted browser-owned edge.** The UI is | ||
| 3723 | versioned latest-wins, so stale completions cannot restore stale buttons or | ||
| 3724 | selection state. An already-issued Clipboard API promise cannot be cancelled, | ||
| 3725 | however: if explicit selection copy overlaps an OSC 52 automatic write that | ||
| 3726 | has already entered the browser, the browser owns the external clipboard's | ||
| 3727 | completion ordering. The UI still converges on the latest action, but the | ||
| 3728 | external clipboard ordering needs real-browser validation and is not claimed | ||
| 3729 | from the deterministic harness. | ||
| 3730 | |||
| 3731 | **Validation is split honestly.** At commit `6bf0466`, the full `make test` | ||
| 3732 | and `make build` gates were green. After the interaction-race hardening at | ||
| 3733 | `03ef53f`, the browser verifier reports 602/602 checks passing. The full make | ||
| 3734 | gates could not be rerun after that commit because the approval usage limit | ||
| 3735 | blocked the shared Zig cache required by the sandbox; that is an unavailable | ||
| 3736 | rerun, not a failed gate. The ten-case manual Firefox interaction matrix — | ||
| 3737 | including soft wraps, hard breaks, wide characters, history auto-scroll, | ||
| 3738 | clipboard permissions, and Inspector-shortcut preservation — remains | ||
| 3739 | outstanding. | ||
| 3740 | |||
| 3741 | **Tracker mapping, without tracker mutation.** `063cec67` now has concrete | ||
| 3742 | implementation evidence for muxweb mouse-drag selection and scrollback copy, | ||
| 3743 | while its native CLI copy-mode scope remains open and separate. `7c777ec6` | ||
| 3744 | maps to the OSC 52 browser clipboard path, and `ee062dd9` to the shared mode | ||
| 3745 | semantics and DEC 2004 browser paste path; the mouse-mirroring half of the | ||
| 3746 | latter remains separate. No issue is closed by this record. | ||
docs/roadmap.md
| Old | New | ||
|---|---|---|---|
| @@ -409,22 +409,23 @@ grid and not its neighbour's. `--diff-since` is still owed. | |||
| 409 | Shipped 2026-08-16. The three discovery issues are now accounted for: | 409 | Shipped 2026-08-16. The three discovery issues are now accounted for: |
| 410 | `7c777ec6`'s OSC 52 **set** reaches the host clipboard (the query direction | 410 | `7c777ec6`'s OSC 52 **set** reaches the host clipboard (the query direction |
| 411 | is deliberately refused, with a 64 KiB cap); `ee062dd9`'s bracketed-paste | 411 | is deliberately refused, with a 64 KiB cap); `ee062dd9`'s bracketed-paste |
| 412 | half is mirrored; and `063cec67` remains the deliberately separate | 412 | half is mirrored; and `063cec67` now has implementation evidence for its |
| 413 | copy-mode problem. Window-title state and bells rode the same delivery | 413 | **muxweb** half: mouse-drag selection reaches daemon scrollback and explicit |
| 414 | mechanisms. | 414 | copy. Native CLI keyboard copy mode remains a separate problem. Window-title |
| 415 | 415 | state and bells rode the same delivery mechanisms. | |
| 416 | What remains banked is intentionally narrower: mouse mirroring, whose | 416 | |
| 417 | terminal-side reporting would take away native drag selection until | 417 | What remains banked is intentionally narrower: terminal mouse-mode mirroring, |
| 418 | copy-mode exists; mouse-drag selection and scrollback copy (Slice 2); and | 418 | whose reporting would take away native drag selection until the CLI has its |
| 419 | OSC 10/11 colour queries. Browser copy/paste shipped 2026-08-16: the CLI and | 419 | own copy mode; that native CLI copy mode itself; and OSC 10/11 colour queries. |
| 420 | Browser copy/paste and mouse selection shipped 2026-08-16: the CLI and | ||
| 420 | web/WASM consume one shared semantic decoder, browser paste follows the | 421 | web/WASM consume one shared semantic decoder, browser paste follows the |
| 421 | sampled DEC mode 2004 state, and accepted OSC 52 payloads that decode as valid | 422 | sampled DEC mode 2004 state, accepted OSC 52 payloads reach a guarded |
| 422 | UTF-8 text first try the Clipboard API then offer one latest-wins explicit | 423 | Clipboard API path, and mouse dragging paints immediately while daemon-owned |
| 423 | Copy fallback. Only the zoomed tile may act on either clipboard path. | 424 | selection extraction decides what is copyable across live rows and |
| 424 | Automated coverage pins those semantics; interactive Firefox clipboard | 425 | scrollback. Only the zoomed tile may act on either clipboard path. Automated |
| 425 | acceptance remains manual. The cross-version gate now also proves, over | 426 | coverage pins those semantics; the real Firefox interaction matrix remains |
| 426 | socket and QUIC, that a real v0.0.1-5 client ignores the new daemon-to-client | 427 | manual. The cross-version gate also proves, over socket and QUIC, that a real |
| 427 | frames and keeps parsing. | 428 | v0.0.1-5 client ignores the new daemon-to-client frames and keeps parsing. |
| 428 | 429 | ||
| 429 | ## M16 candidates — and still outranked by trial feedback | 430 | ## M16 candidates — and still outranked by trial feedback |
| 430 | 431 | ||