diff --git a/packages/tui/package.json b/packages/tui/package.json index 40f1fab7ce..b15608986b 100644 --- a/packages/tui/package.json +++ b/packages/tui/package.json @@ -7,7 +7,8 @@ "license": "MIT", "scripts": { "test": "bun test --timeout 30000 --only-failures", - "typecheck": "tsgo --noEmit" + "typecheck": "tsgo --noEmit", + "screenshots:shortcuts": "bun run script/shortcut-screenshots.ts" }, "exports": { ".": "./src/index.tsx", diff --git a/packages/tui/script/shortcut-screenshots.drive.ts b/packages/tui/script/shortcut-screenshots.drive.ts new file mode 100644 index 0000000000..9cd03ebe3a --- /dev/null +++ b/packages/tui/script/shortcut-screenshots.drive.ts @@ -0,0 +1,71 @@ +import { defineScript, wait, type ScriptUi } from "opencode-drive" + +const settle = () => wait(100) + +async function screenshot(ui: ScriptUi, name: string) { + await settle() + const path = await ui.screenshot(name) + console.log(`${name}: ${path}`) +} + +async function closeDialog(ui: ScriptUi) { + await ui.press("escape") + await ui.waitFor("commands") + await settle() + await ui.waitFor((state) => state.focused.editor) +} + +async function runPalette(ui: ScriptUi, command: string, text: string, name: string) { + await settle() + await ui.press("p", { ctrl: true }) + await ui.waitFor("Commands") + await settle() + await ui.type(command) + await ui.waitFor(command) + await ui.enter() + await ui.waitFor(text) + await screenshot(ui, name) +} + +export default defineScript({ + viewport: { cols: 120, rows: 36 }, + setup({ config }) { + config.autoupdate = false + }, + async run({ ui }) { + await ui.waitFor((state) => state.focused.editor) + await screenshot(ui, "01-home-key-first") + + await ui.type("!") + await ui.waitFor("exit shell mode") + await screenshot(ui, "02-shell-key-first") + await ui.press("escape") + await ui.waitFor("commands") + await ui.waitFor((state) => state.focused.editor) + + await ui.press("p", { ctrl: true }) + await ui.waitFor("Commands") + await screenshot(ui, "03-command-palette") + await closeDialog(ui) + + await runPalette(ui, "Switch model", "Select model", "04-model-actions") + await closeDialog(ui) + + await runPalette(ui, "Help", "Press", "05-help-header-prose") + await closeDialog(ui) + + await runPalette(ui, "View debug info", "Share this", "06-debug-action-first") + await closeDialog(ui) + + await runPalette(ui, "Switch session", "Sessions", "07-session-actions") + await closeDialog(ui) + + await runPalette(ui, "Plugins", "Plugins", "08-plugin-actions") + await closeDialog(ui) + + await runPalette(ui, "Install plugin", "scope:", "09-plugin-install") + await closeDialog(ui) + + await runPalette(ui, "Open diff viewer", "opencode crashed", "10-crash-stacked") + }, +}) diff --git a/packages/tui/script/shortcut-screenshots.ts b/packages/tui/script/shortcut-screenshots.ts new file mode 100644 index 0000000000..152a86ba57 --- /dev/null +++ b/packages/tui/script/shortcut-screenshots.ts @@ -0,0 +1,31 @@ +import { mkdir, rm } from "node:fs/promises" +import { resolve } from "node:path" + +const root = resolve(import.meta.dir, "../../..") +const script = resolve(import.meta.dir, "shortcut-screenshots.drive.ts") +const output = resolve(process.env.OPENCODE_SHORTCUT_SCREENSHOTS_DIR ?? resolve(root, "tmp/tui-shortcut-screenshots")) +const drive = Bun.which("opencode-drive") + +if (!drive) throw new Error("opencode-drive is required: https://github.com/jlongster/opencode-drive") + +await rm(output, { recursive: true, force: true }) +await mkdir(output, { recursive: true }) + +const check = Bun.spawn([drive, "check", script], { + cwd: root, + stdin: "inherit", + stdout: "inherit", + stderr: "inherit", +}) +if ((await check.exited) !== 0) throw new Error("OpenCode Drive script typecheck failed") + +const run = Bun.spawn([drive, "start", "--name", `tui-shortcuts-${process.pid}`, "--dev", root, "--script", script], { + cwd: root, + env: { ...process.env, OPENCODE_DRIVE_MEDIA_DIR: output }, + stdin: "inherit", + stdout: "inherit", + stderr: "inherit", +}) +if ((await run.exited) !== 0) throw new Error("OpenCode Drive screenshot run failed") + +console.log(`Shortcut screenshots: ${output}`) diff --git a/packages/tui/tsconfig.json b/packages/tui/tsconfig.json index ac9f4c63f7..b90a40e89f 100644 --- a/packages/tui/tsconfig.json +++ b/packages/tui/tsconfig.json @@ -6,5 +6,6 @@ "jsxImportSource": "@opentui/solid", "lib": ["ESNext", "DOM", "DOM.Iterable"], "noUncheckedIndexedAccess": false - } + }, + "exclude": ["script/*.drive.ts"] }