• v1.13.19-html-artifact-panes: pane-based artifact viewer with on-request HTML

    indifferentketchup released this 2026-05-23 12:43:13 +00:00

    Every assistant message gets an "Open in pane" affordance that opens the
    message in the workspace splitter — Markdown pane (Copy + Download .md) by
    default; HTML pane (Download .html only) when the model emits a self-contained

    or fenced ```html artifact. BOOCHAT.md rule keeps Markdown

    default at every length; HTML opt-in on explicit user request.

    Backend: services/artifacts.ts (slug derivation + write helpers with
    symlink-escape guard via realpath-after-mkdir), routes/artifacts.ts (POST
    download + GET stream with nosniff + CSP sandbox defense-in-depth), HTML
    detection in finalizeCompletion writing a new message_parts.kind='html_artifact'
    row (schema CHECK extended via v1.13.13 pattern), graceful 1MB cap via the
    pure decideHtmlArtifactWrite helper. PartKind union extended.

    Frontend: MarkdownRenderer.tsx extracted from MessageBubble's inline
    MarkdownBody for reuse; MarkdownArtifactPane.tsx + HtmlArtifactPane.tsx with
    loading/error states; pane state is reference-only ({chat_id, message_id,
    title}) — content fetched on mount to keep workspace_panes jsonb small and
    avoid 1MB blobs riding session_workspace_updated frames. iframe sandbox
    locked to allow-scripts allow-clipboard-write allow-downloads with no
    allow-same-origin, srcDoc not src. openInPane discriminates 404 (expected
    fallback) from real errors (toast + bail). PanelRightOpen icon button with
    mobile 44px tap-target.

    31 new server unit tests including a real-symlink filesystem case; 332/332
    server tests passing, tsc clean both sides, pnpm -C apps/web build green.
    Smoke deferred to first deploy.

    Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com

    Downloads