hermes-agent/ui-opentui/scripts/demo.tsx
alt-glitch 338b5275be opentui(v6): syntax highlighting for 10 more languages (vendored tree-sitter grammars)
@opentui/core@0.4.0 bundles only 5 grammars (ts/js/markdown/markdown_inline/
zig) and Hermes registered none of its own — Python/Rust/Go/bash/JSON/C/HTML/
CSS/YAML/TOML tool bodies and fences rendered plain text (never a regression:
no addDefaultParsers existed anywhere in branch history).

Now: parsers/manifest.json curates the 10 grammars (cpp deliberately dropped —
3.28MB alone); scripts/update-parsers.mjs vendors wasm+highlights.scm with
magic/content validation (plain Node fetch — core's update-assets generator is
Bun-flavored and its import-module won't bundle under esbuild, so registration
skips it and points at the vendored files by runtime-resolved path instead);
boundary/parsers.ts registers via the public addDefaultParsers() at entry
module load, before the first <code>/<markdown> mount initializes the global
tree-sitter client. ~4MB vendored, committed (build inputs, offline-safe).

Markdown fence injections need no infoStringMap: fence labels resolve as
filetype ids and core's ext maps already normalize py→python, zsh→bash, h→c.
Live-smoked in a real renderer: python tool body draws 6 distinct token
colors; ```python and ```yaml fences inside markdown highlight too. 6 new
tests pin the wiring (vendored assets valid, registration set, filetype
routing); visuals stay live-smoke territory per codeBlock.tsx.
2026-06-12 13:26:17 +05:30

56 lines
2.2 KiB
TypeScript

/**
* DEV DEMO — NOT a test, NOT production. Renders the bench fixture (lorem-ipsum +
* fat tool-turns from ./fixture.ts) in a REAL CliRenderer so you can attach over
* tmux, scroll, and eyeball the transcript + the rolling-cap truncation notice.
* No gateway is spawned (purely the fixture seeded into the store via the resume
* path), so typing won't reach a backend — it's for viewing/scrolling.
*
* Run (Node 26 — needs the esbuild/Solid transform, then --experimental-ffi):
* node scripts/build.mjs scripts/demo.tsx .demo
* node --experimental-ffi --no-warnings .demo/demo.js # inside tmux (needs a TTY)
* DEMO_TOTAL=200 fixture messages to seed (default 200)
* HERMES_TUI_MAX_MESSAGES=80 cap → the "⤒ N earlier messages" notice fires
* Quit: Ctrl+C.
*/
import { createCliRenderer } from '@opentui/core'
import { render } from '@opentui/solid'
import { installMultiClickSelection } from '../src/boundary/multiClickSelect.ts'
import { registerVendoredParsers } from '../src/boundary/parsers.ts'
import { createSessionStore } from '../src/logic/store.ts'
import { App } from '../src/view/App.tsx'
import { ThemeProvider } from '../src/view/theme.tsx'
import { materialize } from './fixture.ts'
// Same grammar registration as the live entry so fixture code blocks highlight.
registerVendoredParsers()
const TOTAL = Number.parseInt(process.env.DEMO_TOTAL ?? '', 10) || 200
const store = createSessionStore()
store.apply({ type: 'gateway.ready' })
store.setSessionId('demo-fixture-20260609')
// Seed via the resume path so the cap slices + the `dropped` counter is set
// (drives the truncation notice) exactly as a real `session.resume` would.
store.beginBuffer()
store.commitSnapshot(materialize(TOTAL))
const renderer = await createCliRenderer({
externalOutputMode: 'passthrough',
targetFps: 60,
exitOnCtrlC: true,
useKittyKeyboard: {},
useMouse: true
})
// Same seam the live entry installs (boundary/renderer.ts) so the demo smokes
// double-click word / triple-click line / drag-extend too.
installMultiClickSelection(renderer)
void render(
() => (
<ThemeProvider theme={() => store.state.theme}>
<App store={store} />
</ThemeProvider>
),
renderer
)