Fix four root causes in the desktop preview pipeline, surfaced when the
model writes the files the user pointed it at:
- Output chips guessed paths from prose and could point at a missing file.
They are now reconciled against the turn's real changed files: a bare
`index.html` resolves to the `todo-app/index.html` actually written, and
mentions the turn never changed are dropped.
- A standalone single-page index.html got no browser preview (mistaken for a
Vite template). It is now only routed to the source view when a
package.json/vite.config ships in the same change-set.
- Files written outside the session workdir (another folder, or another drive
on Windows) failed to preview with 'Path is outside workspace'. The turn's
changed-file directories are registered as filesystem access roots; html
serves via /local-file and other files via a workdir-relaxed read.
- The visual-selection prompt leaked as a raw bubble on Windows because the
server-appended '[Image source: ...]' line broke replay dedupe. Replay text
is now metadata-normalized before comparison (affects any image message).
Adds unit tests for each: htmlPreviewPolicy, assistantOutputTargets
reconciliation, replay dedupe + stripGeneratedImageMetadataLines, filesystem
access roots, and workspace outside-workdir reads.