feat(web): shiki syntax highlighting for code surfaces
One highlighter for the client: a synchronous fine-grained shiki core (JS regex engine, no WASM) in ui-primitives with an explicit grammar allowlist (typescript, shellscript, json — aliases resolve, unknown languages take a geometry-identical plain arm). The shared CodeBlock component owns both arms; markdown fences, the run_code expanded program body (typescript), and the details panel Input (json) all route through it. Token colors live in a new ui-theme shiki.css sheet as --shiki-* custom properties (light/dark blocks), wired through the shell's base.css chain — tokens-only styling holds; shiki's generated span tree is the sanctioned innerHTML path (static output, no user HTML). jsdom specs pin token spans, aliases, both fallbacks, and the fence route; the built-bundle snapshot asserts the highlighted program under the code row.
This commit is contained in:
@@ -152,7 +152,7 @@ describe('run_code sub-calls through the real chat machinery', () => {
|
||||
expect(view.getByText('Tool call')).toBeTruthy()
|
||||
})
|
||||
|
||||
it('expanding the code row reveals the program body verbatim', async () => {
|
||||
it('expanding the code row reveals the program body verbatim (shiki-tokenized)', async () => {
|
||||
const parent = 'call-64'
|
||||
const b = await bench(snapshotWith([codeResult(10, parent)], new Map()))
|
||||
const view = mountApp(b.slots)
|
||||
@@ -160,7 +160,12 @@ describe('run_code sub-calls through the real chat machinery', () => {
|
||||
const toggle = view.container.querySelector('[data-variant="code"] button[aria-expanded]')
|
||||
expect(toggle).not.toBeNull()
|
||||
fireEvent.click(toggle!)
|
||||
expect(view.getByText(/const listing = await tools\.bash/)).toBeTruthy()
|
||||
// Shiki splits the program into token spans inside one <pre class="shiki">:
|
||||
// assert the whole text and the highlighted tree rather than one node.
|
||||
const pre = view.container.querySelector('pre.shiki')
|
||||
expect(pre).not.toBeNull()
|
||||
expect(pre!.textContent).toContain('const listing = await tools.bash')
|
||||
expect(pre!.querySelectorAll('span[style]').length).toBeGreaterThan(3)
|
||||
})
|
||||
|
||||
it('an isError sub-call renders the error state dot exactly like a failed native row', async () => {
|
||||
|
||||
Reference in New Issue
Block a user