Skip to content

feat(logs): opt-in soft-wrap mode (w) and → truncation indicator in /ps:logs - #92

Merged
aliou merged 1 commit into
debug/programmatic-process-controlfrom
fix/log-viewer-line-wrapping
Aug 22, 2026
Merged

feat(logs): opt-in soft-wrap mode (w) and → truncation indicator in /ps:logs#92
aliou merged 1 commit into
debug/programmatic-process-controlfrom
fix/log-viewer-line-wrapping

Conversation

@378-kaiabot

@378-kaiabot 378-kaiabot Bot commented Aug 17, 2026

Copy link
Copy Markdown

Note

Automated pull request by Pi, model aperture/hf:zai-org/GLM-5.2. Implemented and validated empirically against
aliou/pi-processes. The bug was confirmed on main by the #75 repro; the fix is verified on
this branch. See the local run log for the full investigation.

Problem

In the /ps:logs overlay (and the /ps preview and dock, which share the renderer), any log line
wider than the viewport was hard-clipped to the row width with no way to see the rest and no
indication that content was lost. renderLogLine called truncateToWidth(text, textWidth, "", true)
— an empty ellipsis — and LogFileViewer.render() mapped exactly one log line to one display row,
so content beyond the viewport width was silently dropped (#75).

Confirmed before the fix: rendering the quick brown fox jumps over the lazy dog at width 10 in a
LogFileViewer produced a single row where lazy was invisible, with no marker that the line was
clipped.

Changes

  • extensions/shared/truncate.ts — add wrapToWidth(text, maxWidth, contIndent = 0), a
    grapheme-aware soft-wrap sibling of truncateToWidth. Walks graphemes with the same
    Intl.Segmenter + readAnsiSequence machinery, expands tabs to 3-column stops, never splits a
    wide character across a row boundary, and carries open SGR state across wrapped chunks (each
    chunk re-opens accumulated SGR, each open chunk ends with a reset). With contIndent > 0, the
    first row wraps to maxWidth and continuation rows to maxWidth - contIndent, mirroring less.
  • extensions/shared/log-line.ts — add renderLogLineWrap(line, options): same sanitize + tone
    pipeline as renderLogLine but returns string[] of display rows, prefixing every continuation
    row with a dim marker so wrapped chunks are visually distinct from new log lines. Change
    renderLogLine's ellipsis from "" to "→" so truncated lines (wrap off) are visibly marked in
    all three surfaces.
  • extensions/processes-logs/components/log-file-viewer.ts — add wrapEnabled state with
    toggleWrap()/isWrapEnabled(). When wrapping, render() builds a flat display-row list from
    the visible logical lines (each row tagged with its source line for emphasis), and the viewport —
    anchorEnd, scrollBy, scrollToTop/Bottom, search jumps, and the L<end>/<total> status —
    operates on display rows via totalDisplayRows(). A wrap indicator is shown in the status bar;
    the toggle persists across tab round-trips through the existing viewer cache.
  • extensions/processes-logs/components/log-overlay-component.ts — wire the w key to
    toggleWrap() and show w: wrap (accent when on) in the footer key hints.
  • .changeset/log-viewer-line-wrapping.md — minor-version changeset.

Truncation remains the default for the /ps preview, the dock, and the logs overlay — wrap is
opt-in per viewer, exactly as #75 specifies.

Verification

  • pnpm typecheck
  • pnpm lint
  • pnpm test ✅ (605 passed, 59 files)

Closes #75
Stacked on #93 — merge that first.


Run host: golden-hugo-lefevre · Session: 01a00f8d-2ec0-7125-b9b7-8f0cb1c0c50f · Model: aperture/hf:zai-org/GLM-5.2

@378-kaiabot
378-kaiabot Bot force-pushed the fix/log-viewer-line-wrapping branch from bd6f0de to 4ecaca5 Compare August 17, 2026 14:15
@378-kaiabot 378-kaiabot Bot changed the title feat(logs): add opt-in soft-wrap mode (w toggle) to /ps:logs overlay feat(logs): opt-in soft-wrap mode (w) and → truncation indicator in /ps:logs Aug 17, 2026
Issue #75: long log lines were hard-clipped with no way to see the full
content and no indication that content was lost.

- Add grapheme-aware wrapToWidth alongside truncateToWidth: walks
  graphemes, expands tabs to 3-column stops, never splits wide
  characters across row boundaries, and carries open SGR state across
  wrapped chunks so colours survive wrapping. Continuation rows wrap to
  a narrowed width when a continuation indent is set.
- Add renderLogLineWrap in shared log-line.ts: wraps instead of
  truncating, applies the same sanitization and stream/match emphasis,
  and prefixes every continuation row with a dim ↳ marker so wrapped
  chunks are visually distinct from new log lines.
- Show a → indicator when a line is truncated (wrap off) so clipped
  output is visible in /ps preview, dock, and /ps:logs.
- Wire a w-key toggle into LogFileViewer and the /ps:logs overlay:
  viewport (scroll, anchor, search jumps, status bar) operates on
  display rows when wrapping; wrap state persists across tab
  round-trips via the viewer cache. Truncation remains the default.

Closes #75
@378-kaiabot
378-kaiabot Bot force-pushed the fix/log-viewer-line-wrapping branch from 4ecaca5 to 9e9e1f7 Compare August 17, 2026 14:26
@378-kaiabot
378-kaiabot Bot changed the base branch from fix/intentional-stop-context-notification to debug/programmatic-process-control August 17, 2026 14:27
@378-kaiabot
378-kaiabot Bot force-pushed the fix/log-viewer-line-wrapping branch from 9e9e1f7 to 545874a Compare August 17, 2026 16:48
@aliou
aliou marked this pull request as ready for review August 18, 2026 18:39
@aliou
aliou merged commit 2eff528 into main Aug 22, 2026
2 checks passed
@aliou
aliou deleted the fix/log-viewer-line-wrapping branch August 22, 2026 11:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

/ps:logs long log lines are invisible past the viewport width (no wrap, no horizontal scroll)

2 participants