fix(log): show control characters from repository content as visible text #144

Merged
james.maes merged 2 commits from fix/143-visible-control-characters into main 2026-11-10 20:01:00 +00:00
2 Commits
Author SHA1 Message Date
james.maesandClaude Fable 5.2 23d3fdf07b fix(cli): one safe output point; escape by code point and console encoding
Follow-up to the independent review of this branch.

- What reaches a terminal is bytes in the console's code page, and a legacy
  code page turns some printable characters into control bytes (on code
  page 437 a left arrow becomes ESC), after the escaping has passed them.
  The CLI now writes every line through one place, Terminal, which also
  shows any character the console's encoding cannot represent in visible
  form. A test encodes every character of the basic plane for code pages
  437, 850, 1252 and 932 and fails on any control byte.
- That one place replaces the per-call escapes, so the messages the first
  commit missed are covered too: unexpected and usage errors, account,
  organization and target names, the sync summary. A test fails if any
  other CLI file writes to the console.
- DisplayText decides per code point by Unicode category: control, line
  and paragraph separator, and format characters (direction marks and
  overrides including the Arabic letter mark, invisible characters, tag
  characters) and unpaired surrogates become visible; the zero-width
  joiner and non-joiner stay, since emoji and several scripts need them.
- No allocation per escaped character.
- Tests assert the visible form with its backslash. The threat model says
  what is covered (log and CLI) and what is not (the desktop app's own
  surfaces, look-alike text).

Refs #143

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Signed-off-by: James Maes <james@kof22.com>
2026-11-10 14:00:22 -06:00
james.maesandClaude Fable 5.2 9c42165334 fix(log): show control characters from repository content as visible text
Text that comes from a repository reaches the activity log and, in the
CLI's text modes, the terminal. A file path in a git tree may contain a
newline, an escape sequence or a text-direction override, and such a path
is exactly what gclo reports when it cannot be created on Windows. A
newline started what read as a new log entry, and an escape sequence was
obeyed by the terminal.

- New DisplayText.Escape turns control characters, line and paragraph
  separators and direction marks, embeddings, overrides and isolates into
  visible \uXXXX text; ordinary text comes back as the same string.
- FileActivityLog writes the message on one line, and an exception's
  lines indented under their entry, so no line of it can start like an
  entry (the Log window's error filter groups lines by that prefix).
- CLI text output (progress and failure lines, path notes, dry run, the
  repos and orgs listings) prints repository-provided text through it.
  The JSON modes are unchanged: the JSON encoder already escapes.

Threat model: T15 added. docs/CLI.md describes the log format.

Closes #143

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Signed-off-by: James Maes <james@kof22.com>
2026-11-10 13:37:37 -06:00