Skip to content

fix(brain): use plain-text time in collapsed-run range label#1388

Merged
vivekchand merged 1 commit into
mainfrom
auto/issue-1222-plain-time-rangelabel
May 16, 2026
Merged

fix(brain): use plain-text time in collapsed-run range label#1388
vivekchand merged 1 commit into
mainfrom
auto/issue-1222-plain-time-rangelabel

Conversation

@vivekchand

Copy link
Copy Markdown
Owner

Closes #1222

Summary

  • formatBrainTime() returns HTML (a <span> wrapping the date prefix for opacity styling), making rangeLabel in the collapsed-run path an HTML string that must not be passed through escHtml() — a fragile invariant that already caused one regression (PR fix(brain): collapsed-run time range rendered HTML as literal text #1215 double-escaped it, rendering markup as literal text).
  • Adds _formatBrainTimePlain(isoStr) returning plain text ("Today 14:23:45"), no HTML tags.
  • Switches the two formatBrainTime() calls in the collapsed-run rangeLabel path to _formatBrainTimePlain; rangeLabel is now a plain string safely wrapped with escHtml(), and the "do NOT escHtml or the markup renders as text" warning comment is gone.

All existing formatBrainTime() callers (the <span class="brain-time"> rows) are unchanged. Minor visual: date prefix in the collapsed-range badge loses its reduced-opacity span — acceptable in a summary badge.

Test plan

  • node tests/test_appjs_units.js — 89 passed, 0 failed
  • node --check clawmetry/static/js/app.js — JS syntax OK
  • make lint — Python syntax OK (pre-existing ruff warnings in other files, none introduced by this change)

Generated by Claude Code

formatBrainTime() returns HTML (a <span> wrapping the date prefix for
opacity styling), making rangeLabel an HTML string that must NOT be
passed through escHtml() — a fragile invariant that already caused
one regression (PR #1215 double-escaped it).

Add _formatBrainTimePlain() that returns "Today 14:23:45" as plain
text. Switch the two formatBrainTime() calls in the collapsed-run
rangeLabel path to use it; the range label can now be safely escaped
with escHtml() and the warning comment explaining why not to escape
is gone.

No change to existing formatBrainTime() callers — the styled brain-time
spans are unaffected. Minor visual: date prefix in collapsed-range badge
no longer has reduced opacity, which is acceptable in a summary badge.

Closes #1222

Co-Authored-By: Claude <[email protected]>
@vivekchand
vivekchand merged commit f6ba742 into main May 16, 2026
10 checks passed
@vivekchand
vivekchand deleted the auto/issue-1222-plain-time-rangelabel branch May 16, 2026 03:34
@vivekchand

Copy link
Copy Markdown
Owner Author

UX review

  • 🟡 P1 — Visual regression acknowledged in the PR body: the date prefix in the collapsed-range badge loses its reduced-opacity span ("Today 14:23:45" is now uniform text instead of dimmed-prefix + bold-time). Two adjacent badge styles in the Brain panel are now inconsistent. Next action: replicate the opacity treatment via CSS — wrap the prefix in a span inside _formatBrainTimePlain only when caller opts in, OR add a .brain-collapsed-range time-prefix regex-styled rule so the visual hierarchy survives.
  • 🟢 nit — Two near-identical functions (formatBrainTime HTML + _formatBrainTimePlain text) are a footgun: future edits to the time-format logic must be made twice or they drift. Next action: refactor so formatBrainTime(iso, {html: true}) is the single source and the HTML variant wraps the plain output.
  • 🟢 nit — _formatBrainTimePlain returns isoStr || '' on parse failure (raw ISO string surfaced to user). For a "today 14:23" sibling that's jarring. Next action: fall back to '-' instead — matches the convention used in the cron timeline.

@vivekchand

Copy link
Copy Markdown
Owner Author

Product review

  • 🟢 nit — Pure correctness fix preventing markup-as-text rendering in the Brain panel's collapsed-run range label. No conversion-funnel implication. Next action: none required; consider adding a node tests/test_appjs_units.js case that pipes a known ISO through both formatBrainTime and _formatBrainTimePlain and asserts the plain output contains no </> characters — locks the invariant for future contributors.
  • 🟢 nit — The recurrence of "string-with-HTML mistaken for plain string" bugs (PR fix(brain): collapsed-run time range rendered HTML as literal text #1215 → this PR) suggests a small typesystem affordance is warranted. Next action: prefix all HTML-returning helpers in app.js with _html_ (e.g. _html_formatBrainTime) so call-sites visibly flag the escape hazard.

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.

[Product P0 from PR #1215] Migrate renderBrainStream off raw HTML string-concat

2 participants