Skip to content

TUI: type OpenTUI intrinsics + fix code/markdown/split-diff render bugs (#212 P0, phase 1) #466

@windoliver

Description

@windoliver

Phase 1 of the #212 OpenTUI adoption plan. Design spec: docs/superpowers/specs/2026-05-30-tui-opentui-adoption-design.md (branch feat/212-opentui-adoption-plan).

Keystone phase — unblocks typed JSX for all later phases and fixes three confirmed silent render bugs found by verifying against installed @opentui/core@0.1.87.

Root cause

OpenTUI registers lowercase tags at runtime but ships no JSX.IntrinsicElements augmentation, so Grove uses untyped React.createElement("tag" as string, …) — which hides wrong props.

Scope

  • Expand src/tui/opentui.d.ts: declare JSX.IntrinsicElements for diff, code, markdown, scrollbox, select, input, textarea, span, line-number, ascii-font, tab-select with real option props; declare/confirm SyntaxStyle, RGBA, mouse prop types, hooks useOnResize, useTimeline.
  • Replace every React.createElement("<tag>" as string, …) with typed JSX (audit artifact-preview.tsx, split-diff.tsx, detail.tsx, vfs-browser.tsx, others).

Bug fixes (silent render failures)

  1. <code> uses language= + children → must be filetype= + content= (syntax highlighting currently does nothing).
  2. <markdown> passes children → must be content= (renders nothing).
  3. split-diff.tsx (via compare-view.tsx) uses oldContent/newContent/mode<diff> takes a unified diff string + view="split" only. Share one computeUnifiedDiff util with artifact-preview.tsx.

Note (per OpenTUI gotchas): the unified diff string needs a valid @@ hunk header or <diff> won't parse it.

Acceptance

  • tsc --noEmit passes with zero as string intrinsic casts in src/tui.
  • Artifact code/markdown/diff and compare-view render real content in a TUI smoke.
  • Render tests assert code highlighting / markdown / split diff emit non-empty styled output.

Version: stays on 0.1.87. Part of #212.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions