fix(chat): refuse Markdown image paths the parser may have glued
Review fixes on top of the local-image renderer. Correctness. CommonMark drops `\` before ASCII punctuation, so a Windows destination loses the separator in front of every punctuation-initial segment: `C:\repo\shots\.preview.png` parses as `C:\repo\shots.preview.png`. That is not merely a path that fails to load — the glued form is still inside the root, so a `shots.preview.png` that happens to exist rendered under the alt text of the file the agent actually named. `[Image blocked: …]` had no such failure mode, so refusing is the floor for replacing it. `remarkLocalImages` now refuses a destination when `\` + ASCII punctuation occurs anywhere from the earliest possible start of the destination (past the first `](` or `]:`) to the end of the node's source. Starting the region early only refuses more, so no label-end guess is needed — which is what `remarkRestoreWindowsPaths` deliberately avoids for images. The label is excluded, so `` still resolves. Wiring. `canvas-conversation-surface` and `live-transcript-view` now pass the cwd they already hold. Both fell back to the folder path derived from persisted detail, which a canvas draft's first reply does not have yet and a delegation child's scratch folder row is missing from (created closed, with no `folder://changed` broadcast). A derived test asserts every `<MessageListView` mount makes the decision. Robustness. The sanitize allow-list carried only the camelCased hast property names, which match only because Streamdown runs `rehype-raw` ahead of sanitize; both spellings are now listed. A `data-codeg-local-image` with no value is left as the plain span it is, and `resolveLocalImage` takes its MIME from the extension it already validated. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
X
xintaofei committed
049ef608b1c3b246819355e9f9a34155fb34cb7e
Parent: 402d8b0