Skip to content

fix(terminal-core): replace clackNote with own box rendering to prevent path splitting#94741

Closed
bowenluo718 wants to merge 1 commit into
openclaw:mainfrom
bowenluo718:fix/issue-94730-doctor-copy-sensitive-paths-g
Closed

fix(terminal-core): replace clackNote with own box rendering to prevent path splitting#94741
bowenluo718 wants to merge 1 commit into
openclaw:mainfrom
bowenluo718:fix/issue-94730-doctor-copy-sensitive-paths-g

Conversation

@bowenluo718

Copy link
Copy Markdown

Summary

openclaw doctor mangles long file paths inside note(...) boxes because the downstream clackNote() call re-wraps text that wrapNoteMessage() already correctly preserved. The fix replaces the @clack/prompts note box rendering with an OpenClaw-owned box renderer so copy-sensitive tokens (paths, URLs) stay intact.

Fixes #94730

Root cause

wrapNoteMessage in packages/terminal-core/src/note.ts correctly identifies copy-sensitive tokens (paths starting with /, ~/, ./, URLs, Windows drives, etc.) and allows them to overflow the wrap width rather than being broken mid-token. However, note() then calls clackNote() which performs its own width-based wrapping via fast-wrap-ansi, unaware of the copy-sensitive semantics. The double-wrap causes the path to be split at the box border, breaking file extensions like .jsonl.lock into .js + onl.lock.

Fix

Remove the clackNote() call and build the bordered note box directly in renderNoteBox(). The new renderer:

  • Uses the output of wrapNoteMessage() as-is (no re-wrapping)
  • Allows lines containing copy-sensitive tokens to overflow the box right border
  • Renders the same visual format (◇ Title ─╮, │ content │, ╰───╯)
  • Supports rich (colored) and plain terminal output via the existing theme/isRich helpers

Real behavior proof

Behavior addressed: Copy-sensitive file paths were split mid-extension inside openclaw doctor note boxes

Real setup tested:

  • Runtime: Node 22.19+, Linux
  • Environment: 80-column terminal (COLUMNS=80)

Exact steps or command run after fix:

pnpm test packages/terminal-core/src/note.test.ts

After-fix evidence:

✓ |unit| packages/terminal-core/src/note.test.ts (9 tests) 151ms
  ✓ wrapNoteMessage (3)
    ✓ preserves a copy-sensitive path that exceeds the wrap width
    ✓ preserves a URL that exceeds the wrap width
    ✓ wraps long non-copy-sensitive words at the wrap width
  ✓ note box rendering (4)
    ✓ renders a note box with title and message
    ✓ renders content lines with proper box borders
    ✓ does not re-wrap a copy-sensitive path inside the box
    ✓ allows a copy-sensitive line to overflow the box right border
  ✓ note suppression (2)
    ✓ suppresses output when OPENCLAW_SUPPRESS_NOTES is set
    ✓ suppresses output inside withSuppressedNotes callback

Observed result after the fix: All 9 tests pass. The .jsonl.lock path remains unbroken in the box. Copy-sensitive overflow lines extend past the right border without being split. No regressions in wrapNoteMessage or note suppression behavior.

What was not tested: Full end-to-end openclaw doctor run with a real gateway session lock. The box rendering is verified via unit tests that exercise the exact same code path used by src/commands/doctor-session-locks.ts.

Tests and validation

  • New test file: packages/terminal-core/src/note.test.ts (9 tests)
    • 3 tests for wrapNoteMessage (path, URL, long-word wrapping)
    • 4 tests for note() box rendering (title, borders, path preservation, overflow)
    • 2 tests for note suppression (env var, AsyncLocalStorage)
  • TypeScript: pnpm tsgo — no errors related to note.ts
  • Regression: All existing terminal-core tests pass

Risk checklist

Did user-visible behavior change? Yes — copy-sensitive paths inside note boxes are no longer split; they overflow the right border instead.

Did config, environment, or migration behavior change? No

Did security, auth, secrets, network, or tool execution behavior change? No

What is the highest-risk area?

  • Visual rendering of note boxes may differ slightly from @clack/prompts in edge cases (e.g., very narrow terminals, right-to-left text).

How is that risk mitigated?

  • The box format uses the same Unicode characters and layout measurements as @clack/prompts.
  • Test coverage validates title, content, borders, and overflow behavior.
  • The note() function signature is unchanged; callers are unaffected.

Current review state

  • Maintainer review

…nt path splitting

wrapNoteMessage correctly preserves copy-sensitive tokens (paths, URLs)
by allowing them to overflow the wrap width, but the downstream clackNote
call would re-wrap them at the box border, splitting file extensions mid-token.
Build the note box directly in renderNoteBox() so OpenClaw owns wrapping
decisions end-to-end. Lines with copy-sensitive overflow are allowed to
extend past the right border instead of being broken.

Fixes openclaw#94730
@openclaw-barnacle openclaw-barnacle Bot added size: M proof: supplied External PR includes structured after-fix real behavior proof. labels Jun 19, 2026
@clawsweeper

clawsweeper Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Thanks for the context here. I swept through the related work, and this is now duplicate or superseded.

Close as superseded: the same doctor note-wrapping bug is already covered by a cleaner open landing path with positive real behavior proof, while this branch has a lint failure and only unit-test proof.

Root-cause cluster
Relationship: superseded
Canonical: #94738
Summary: The same source-reproducible doctor note wrapping issue has multiple open candidate PRs; the narrower proof-positive PR is the best canonical landing path for cleanup.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Canonical path: Use #94738 as the current canonical landing path for #94730, then let the issue close when that fix merges.

So I’m closing this here and keeping the remaining discussion on #94738 and #94730.

Review details

Best possible solution:

Use #94738 as the current canonical landing path for #94730, then let the issue close when that fix merges.

Do we have a high-confidence way to reproduce the issue?

Yes: the source path is clear because session lock doctor output reaches the shared note() helper, and pinned Clack 1.4.0 performs a hard second wrap inside the note renderer. I did not run a live openclaw doctor scenario in this read-only review.

Is this the best way to solve the issue?

No: this PR is a plausible shared-renderer fix, but it is not the best current cleanup target while #94738 is a narrower open candidate with positive real behavior proof and clean lint/type checks.

Security review:

Security review cleared: The diff changes terminal rendering code and tests only; it adds no dependency, workflow, secret, network, package, or code-execution surface.

AGENTS.md: found and applied where relevant.

What I checked:

Likely related people:

  • vincentkoc: Current blame and history point to the current packages/terminal-core/src/note.ts helper, adjacent wrap tests, and doctor-session-locks note caller being introduced together on main. (role: recent area contributor; confidence: high; commits: 2c7fe6a39c0f; files: packages/terminal-core/src/note.ts, packages/terminal-core/src/table.test.ts, src/commands/doctor-session-locks.ts)
  • steipete: Older history shows this person authored the earlier Clack-backed note wrapping helper that established the terminal note behavior lineage. (role: terminal note history contributor; confidence: medium; commits: 29884f8d6f2c; files: src/terminal/note.ts)
  • vignesh07: History for isCopySensitiveToken points to prior work preserving copy-sensitive long tokens in terminal/TUI formatting, which is the invariant involved here. (role: adjacent copy-sensitive wrapping contributor; confidence: medium; commits: 69418cca2091; files: src/terminal/note.ts, src/tui/tui-formatters.ts, src/tui/tui-formatters.test.ts)

Codex review notes: model internal, reasoning high; reviewed against 2ef0589b760d.

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal backlog priority with limited blast radius. labels Jun 19, 2026
@clawsweeper

clawsweeper Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper applied the proposed close for this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

P2 Normal backlog priority with limited blast radius. proof: supplied External PR includes structured after-fix real behavior proof. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: M status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

doctor: copy-sensitive paths get re-wrapped by clack note box, splitting file extensions

1 participant