Files
stablyai--orca/tests/e2e/capture-opencode-tui-repro.mjs
2026-07-13 13:05:33 +08:00

147 lines
3.8 KiB
JavaScript

#!/usr/bin/env node
// Repro setup:
// git clone https://github.com/anomalyco/opencode.git .tmp/opencode
// node tests/e2e/capture-opencode-tui-repro.mjs
// Then run the captured replay test documented in terminal-foreground-redraw-freeze.spec.ts.
import { createRequire } from 'node:module'
import { createWriteStream, existsSync, mkdirSync, writeFileSync } from 'node:fs'
import path from 'node:path'
const require = createRequire(import.meta.url)
const pty = require('node-pty')
const scriptDir = import.meta.dirname
const repoRoot = path.resolve(scriptDir, '..', '..')
function readOption(name, fallback) {
const index = process.argv.indexOf(name)
if (index === -1) {
return fallback
}
const value = process.argv[index + 1]
if (!value || value.startsWith('--')) {
throw new Error(`Missing value for ${name}`)
}
return value
}
const opencodePackagePath = path.resolve(
readOption('--opencode-path', path.join(repoRoot, '.tmp', 'opencode', 'packages', 'opencode'))
)
const outputPath = path.resolve(
readOption('--output', path.join(repoRoot, '.tmp', 'opencode-tui-capture.txt'))
)
if (!existsSync(path.join(opencodePackagePath, 'package.json'))) {
throw new Error(
`OpenCode package not found at ${opencodePackagePath}. Clone https://github.com/anomalyco/opencode.git into .tmp/opencode first.`
)
}
const harnessPath = path.join(opencodePackagePath, 'orca-opencode-tui-repro.tsx')
const harnessSource = String.raw`import { BoxRenderable, createCliRenderer, RGBA, TextRenderable } from "@opentui/core"
import { SpinnerRenderable } from "opentui-spinner"
import { createColors, createFrames } from "./src/cli/cmd/tui/ui/spinner"
const renderer = await createCliRenderer({
externalOutputMode: "passthrough",
targetFps: 60,
gatherStats: false,
exitOnCtrlC: false,
useKittyKeyboard: {},
autoFocus: false,
openConsoleOnError: false,
useMouse: false,
})
const root = renderer.root
const ctx = root.ctx
const color = RGBA.fromHex("#ff8a00")
const frames = createFrames({
color,
style: "blocks",
inactiveFactor: 0.6,
minAlpha: 0.3,
})
const colors = createColors({
color,
style: "blocks",
inactiveFactor: 0.6,
minAlpha: 0.3,
})
const panel = new BoxRenderable(ctx, {
width: "100%",
height: "100%",
flexDirection: "column",
paddingLeft: 2,
paddingTop: 1,
gap: 1,
})
root.add(panel)
const header = new BoxRenderable(ctx, { flexDirection: "row", gap: 1, height: 1 })
panel.add(header)
header.add(new SpinnerRenderable(ctx, { frames, interval: 40, color: colors }))
header.add(
new TextRenderable(ctx, {
content: "OpenCode synthetic active TUI redraw",
fg: "#ff8a00",
}),
)
for (let index = 0; index < 28; index++) {
const row = new BoxRenderable(ctx, { flexDirection: "row", gap: 1, height: 1 })
panel.add(row)
row.add(
new TextRenderable(ctx, {
content: String(index + 1).padStart(2, "0"),
fg: index % 2 === 0 ? "#ff8a00" : "#6aa9ff",
width: 2,
}),
)
row.add(
new TextRenderable(ctx, {
content: "#".repeat(36) + " " + "opencode".repeat(10),
fg: "#e7edf7",
}),
)
}
renderer.requestRender()
setTimeout(() => {
renderer.destroy()
}, 5000)
`
mkdirSync(path.dirname(outputPath), { recursive: true })
writeFileSync(harnessPath, harnessSource)
const out = createWriteStream(outputPath)
const command = process.platform === 'win32' ? 'bun.exe' : 'bun'
const child = pty.spawn(command, ['run', './orca-opencode-tui-repro.tsx'], {
cwd: opencodePackagePath,
cols: 120,
rows: 40,
name: 'xterm-256color',
env: {
...process.env,
FORCE_COLOR: '1',
TERM: 'xterm-256color'
}
})
child.onData((data) => {
out.write(data)
})
child.onExit(({ exitCode }) => {
out.end(() => {
console.log(`wrote OpenCode/OpenTUI PTY capture to ${outputPath}`)
process.exitCode = exitCode
})
})