Files
hermes-agent/ui-tui/packages
ethernet 6832b910c2 fix(tui): account for paddingLeft when mapping click col to source col
Reported by ethie:

    ```mermaid
    graph LR
        user[ethie] -->|asks| packet[packet >w<]
    ```

Double-click "ethie" inside the fence → copied "hie]". Selection
shifted right by 2 at the start AND extended past `]` at the end.

Root cause: code fences (and tables / lists / blockquotes) render their
content inside a `<Box paddingLeft={2}>` nested inside the
`<CopySource>` Box. The hit-test walked up the DOM looking for a
copyRangeId and reported visualLine/col relative to THAT outer Box,
which has rect.x=0. The visual col (which includes the +2 padding) was
passed through to `simpleOffsetFor` unchanged — but simpleOffsetFor
treats col as a source col, so every char shifted +2 in source space.

Also: code fences register no per-fragment source data, so the focus
point falls through to the no-fragment path in toCopyText where the
cell-INCLUSIVE col was treated as a byte-EXCLUSIVE slice end. Last char
got dropped.

Fix (two parts):

1. copyPointHitTest tracks the deepest non-rangeId rect's X during the
   walk-up and reports col relative to that (when present). visualLine
   stays relative to the rangeId Box's rect.y — that's the coordinate
   system the registered rowStarts / visualLineCount were measured in
   (rows counted from block start, not from any sub-text element).
   Inline content w/o an indented wrapper sees no change.

2. buildCopyTextFromDom now bumps the focus point's col by +1 when the
   hit-test returned no sourceOffset (the fallback path). This handles
   the cell-INCLUSIVE → byte-EXCLUSIVE conversion for blocks that don't
   carry per-fragment source data. The fragment path already does this
   bump internally via the endpoint='end' arg.

Tests:
- packages/hermes-ink/src/ink/copyPointHitTest.test.ts: new test asserts
  visualLine/col reporting respects an inner padded Box's rect.x while
  preserving the rangeId Box's rect.y for visualLine.
- ui-tui/src/lib/copySource/__tests__/codeFencePadding.test.ts: end-to-end
  regression test reproducing ethie's exact mermaid example and
  asserting the copied string is 'ethie' (not 'hie]').
2026-05-19 23:26:00 -04:00
..