Kaynağa Gözat

test(tui): add theme screenshot gallery

James Long 1 ay önce
ebeveyn
işleme
4885c3a5d3
100 değiştirilmiş dosya ile 1240 ekleme ve 0 silme
  1. 37 0
      packages/tui/test/theme/gallery/README.md
  2. 79 0
      packages/tui/test/theme/gallery/run.ts
  3. 123 0
      packages/tui/test/theme/gallery/scenario.ts
  4. BIN
      packages/tui/test/theme/gallery/screenshots/candy-pop-dark-dark-01-home.png
  5. BIN
      packages/tui/test/theme/gallery/screenshots/candy-pop-dark-dark-02-markdown.png
  6. BIN
      packages/tui/test/theme/gallery/screenshots/candy-pop-dark-dark-03-permission.png
  7. BIN
      packages/tui/test/theme/gallery/screenshots/candy-pop-dark-dark-04-form.png
  8. BIN
      packages/tui/test/theme/gallery/screenshots/candy-pop-dark-dark-05-session-switcher.png
  9. BIN
      packages/tui/test/theme/gallery/screenshots/candy-pop-dark-light-01-home.png
  10. BIN
      packages/tui/test/theme/gallery/screenshots/candy-pop-dark-light-02-markdown.png
  11. BIN
      packages/tui/test/theme/gallery/screenshots/candy-pop-dark-light-03-permission.png
  12. BIN
      packages/tui/test/theme/gallery/screenshots/candy-pop-dark-light-04-form.png
  13. BIN
      packages/tui/test/theme/gallery/screenshots/candy-pop-dark-light-05-session-switcher.png
  14. BIN
      packages/tui/test/theme/gallery/screenshots/candy-pop-light-dark-01-home.png
  15. BIN
      packages/tui/test/theme/gallery/screenshots/candy-pop-light-dark-02-markdown.png
  16. BIN
      packages/tui/test/theme/gallery/screenshots/candy-pop-light-dark-03-permission.png
  17. BIN
      packages/tui/test/theme/gallery/screenshots/candy-pop-light-dark-04-form.png
  18. BIN
      packages/tui/test/theme/gallery/screenshots/candy-pop-light-dark-05-session-switcher.png
  19. BIN
      packages/tui/test/theme/gallery/screenshots/candy-pop-light-light-01-home.png
  20. BIN
      packages/tui/test/theme/gallery/screenshots/candy-pop-light-light-02-markdown.png
  21. BIN
      packages/tui/test/theme/gallery/screenshots/candy-pop-light-light-03-permission.png
  22. BIN
      packages/tui/test/theme/gallery/screenshots/candy-pop-light-light-04-form.png
  23. BIN
      packages/tui/test/theme/gallery/screenshots/candy-pop-light-light-05-session-switcher.png
  24. BIN
      packages/tui/test/theme/gallery/screenshots/matchalk-dark-01-home.png
  25. BIN
      packages/tui/test/theme/gallery/screenshots/matchalk-dark-02-markdown.png
  26. BIN
      packages/tui/test/theme/gallery/screenshots/matchalk-dark-03-permission.png
  27. BIN
      packages/tui/test/theme/gallery/screenshots/matchalk-dark-04-form.png
  28. BIN
      packages/tui/test/theme/gallery/screenshots/matchalk-dark-05-session-switcher.png
  29. BIN
      packages/tui/test/theme/gallery/screenshots/matchalk-light-01-home.png
  30. BIN
      packages/tui/test/theme/gallery/screenshots/matchalk-light-02-markdown.png
  31. BIN
      packages/tui/test/theme/gallery/screenshots/matchalk-light-03-permission.png
  32. BIN
      packages/tui/test/theme/gallery/screenshots/matchalk-light-04-form.png
  33. BIN
      packages/tui/test/theme/gallery/screenshots/matchalk-light-05-session-switcher.png
  34. BIN
      packages/tui/test/theme/gallery/screenshots/nightowl-dark-01-home.png
  35. BIN
      packages/tui/test/theme/gallery/screenshots/nightowl-dark-02-markdown.png
  36. BIN
      packages/tui/test/theme/gallery/screenshots/nightowl-dark-03-permission.png
  37. BIN
      packages/tui/test/theme/gallery/screenshots/nightowl-dark-04-form.png
  38. BIN
      packages/tui/test/theme/gallery/screenshots/nightowl-dark-05-session-switcher.png
  39. BIN
      packages/tui/test/theme/gallery/screenshots/nightowl-light-01-home.png
  40. BIN
      packages/tui/test/theme/gallery/screenshots/nightowl-light-02-markdown.png
  41. BIN
      packages/tui/test/theme/gallery/screenshots/nightowl-light-03-permission.png
  42. BIN
      packages/tui/test/theme/gallery/screenshots/nightowl-light-04-form.png
  43. BIN
      packages/tui/test/theme/gallery/screenshots/nightowl-light-05-session-switcher.png
  44. BIN
      packages/tui/test/theme/gallery/screenshots/opencode-dark-01-home.png
  45. BIN
      packages/tui/test/theme/gallery/screenshots/opencode-dark-02-markdown.png
  46. BIN
      packages/tui/test/theme/gallery/screenshots/opencode-dark-03-permission.png
  47. BIN
      packages/tui/test/theme/gallery/screenshots/opencode-dark-04-form.png
  48. BIN
      packages/tui/test/theme/gallery/screenshots/opencode-dark-05-session-switcher.png
  49. BIN
      packages/tui/test/theme/gallery/screenshots/opencode-light-01-home.png
  50. BIN
      packages/tui/test/theme/gallery/screenshots/opencode-light-02-markdown.png
  51. BIN
      packages/tui/test/theme/gallery/screenshots/opencode-light-03-permission.png
  52. BIN
      packages/tui/test/theme/gallery/screenshots/opencode-light-04-form.png
  53. BIN
      packages/tui/test/theme/gallery/screenshots/opencode-light-05-session-switcher.png
  54. BIN
      packages/tui/test/theme/gallery/screenshots/poimandres-dark-01-home.png
  55. BIN
      packages/tui/test/theme/gallery/screenshots/poimandres-dark-02-markdown.png
  56. BIN
      packages/tui/test/theme/gallery/screenshots/poimandres-dark-03-permission.png
  57. BIN
      packages/tui/test/theme/gallery/screenshots/poimandres-dark-04-form.png
  58. BIN
      packages/tui/test/theme/gallery/screenshots/poimandres-dark-05-session-switcher.png
  59. BIN
      packages/tui/test/theme/gallery/screenshots/poimandres-light-01-home.png
  60. BIN
      packages/tui/test/theme/gallery/screenshots/poimandres-light-02-markdown.png
  61. BIN
      packages/tui/test/theme/gallery/screenshots/poimandres-light-03-permission.png
  62. BIN
      packages/tui/test/theme/gallery/screenshots/poimandres-light-04-form.png
  63. BIN
      packages/tui/test/theme/gallery/screenshots/poimandres-light-05-session-switcher.png
  64. BIN
      packages/tui/test/theme/gallery/screenshots/solarized-dark-01-home.png
  65. BIN
      packages/tui/test/theme/gallery/screenshots/solarized-dark-02-markdown.png
  66. BIN
      packages/tui/test/theme/gallery/screenshots/solarized-dark-03-permission.png
  67. BIN
      packages/tui/test/theme/gallery/screenshots/solarized-dark-04-form.png
  68. BIN
      packages/tui/test/theme/gallery/screenshots/solarized-dark-05-session-switcher.png
  69. BIN
      packages/tui/test/theme/gallery/screenshots/solarized-light-01-home.png
  70. BIN
      packages/tui/test/theme/gallery/screenshots/solarized-light-02-markdown.png
  71. BIN
      packages/tui/test/theme/gallery/screenshots/solarized-light-03-permission.png
  72. BIN
      packages/tui/test/theme/gallery/screenshots/solarized-light-04-form.png
  73. BIN
      packages/tui/test/theme/gallery/screenshots/solarized-light-05-session-switcher.png
  74. BIN
      packages/tui/test/theme/gallery/screenshots/synthwave84-dark-01-home.png
  75. BIN
      packages/tui/test/theme/gallery/screenshots/synthwave84-dark-02-markdown.png
  76. BIN
      packages/tui/test/theme/gallery/screenshots/synthwave84-dark-03-permission.png
  77. BIN
      packages/tui/test/theme/gallery/screenshots/synthwave84-dark-04-form.png
  78. BIN
      packages/tui/test/theme/gallery/screenshots/synthwave84-dark-05-session-switcher.png
  79. BIN
      packages/tui/test/theme/gallery/screenshots/synthwave84-light-01-home.png
  80. BIN
      packages/tui/test/theme/gallery/screenshots/synthwave84-light-02-markdown.png
  81. BIN
      packages/tui/test/theme/gallery/screenshots/synthwave84-light-03-permission.png
  82. BIN
      packages/tui/test/theme/gallery/screenshots/synthwave84-light-04-form.png
  83. BIN
      packages/tui/test/theme/gallery/screenshots/synthwave84-light-05-session-switcher.png
  84. BIN
      packages/tui/test/theme/gallery/screenshots/vercel-dark-01-home.png
  85. BIN
      packages/tui/test/theme/gallery/screenshots/vercel-dark-02-markdown.png
  86. BIN
      packages/tui/test/theme/gallery/screenshots/vercel-dark-03-permission.png
  87. BIN
      packages/tui/test/theme/gallery/screenshots/vercel-dark-04-form.png
  88. BIN
      packages/tui/test/theme/gallery/screenshots/vercel-dark-05-session-switcher.png
  89. BIN
      packages/tui/test/theme/gallery/screenshots/vercel-light-01-home.png
  90. BIN
      packages/tui/test/theme/gallery/screenshots/vercel-light-02-markdown.png
  91. BIN
      packages/tui/test/theme/gallery/screenshots/vercel-light-03-permission.png
  92. BIN
      packages/tui/test/theme/gallery/screenshots/vercel-light-04-form.png
  93. BIN
      packages/tui/test/theme/gallery/screenshots/vercel-light-05-session-switcher.png
  94. 79 0
      packages/tui/test/theme/gallery/themes/candy-pop-dark.json
  95. 80 0
      packages/tui/test/theme/gallery/themes/candy-pop-light.json
  96. 75 0
      packages/tui/test/theme/gallery/themes/matchalk.json
  97. 221 0
      packages/tui/test/theme/gallery/themes/nightowl.json
  98. 245 0
      packages/tui/test/theme/gallery/themes/opencode.json
  99. 78 0
      packages/tui/test/theme/gallery/themes/poimandres.json
  100. 223 0
      packages/tui/test/theme/gallery/themes/solarized.json

+ 37 - 0
packages/tui/test/theme/gallery/README.md

@@ -0,0 +1,37 @@
+# TUI theme screenshot gallery
+
+This gallery runs one repeatable OpenCode Drive workflow for every V1 theme in a directory. Each theme runs in
+light and dark mode and produces a flat set of screenshots covering the home screen, markdown, permission prompt,
+form prompt, and session switcher.
+
+It expects `opencode-drive` to be installed globally and available on `PATH`.
+
+The checked-in fixtures include selected built-in OpenCode themes and community themes from
+[`vaprdev/opencode-themes`](https://github.com/vaprdev/opencode-themes). Theme-specific attribution and licenses
+remain documented in that source repository.
+
+## Run
+
+Place theme JSON files in `themes/`, then run from the repository root:
+
+```sh
+bun packages/tui/test/theme/gallery/run.ts
+```
+
+Custom input and output directories can be passed as positional arguments:
+
+```sh
+bun packages/tui/test/theme/gallery/run.ts ./my-themes ./theme-screenshots
+```
+
+Output files are named `<theme>-<mode>-<state>.png` in one flat directory. Existing files with the same names are
+overwritten. Runs are sequential so each isolated OpenCode Drive instance owns its own ports and artifacts.
+
+The current TUI discovers V1 theme files and migrates them to V2 at runtime. Native V2 JSON files are reported as
+unsupported and make the runner exit nonzero; they are not converted or silently rendered with a fallback theme.
+
+Before changing the scenario, typecheck it with:
+
+```sh
+opencode-drive check packages/tui/test/theme/gallery/scenario.ts
+```

+ 79 - 0
packages/tui/test/theme/gallery/run.ts

@@ -0,0 +1,79 @@
+import path from "node:path"
+import { mkdir } from "node:fs/promises"
+
+const root = path.resolve(import.meta.dir, "../../../../..")
+const themes = path.resolve(Bun.argv[2] ?? path.join(import.meta.dir, "themes"))
+const screenshots = path.resolve(Bun.argv[3] ?? path.join(import.meta.dir, "screenshots"))
+const scenario = path.join(import.meta.dir, "scenario.ts")
+const files = await Array.fromAsync(new Bun.Glob("**/*.json").scan({ cwd: themes, absolute: true }))
+
+if (!files.length) {
+  console.error(`No JSON themes found in ${themes}`)
+  process.exit(1)
+}
+
+await mkdir(screenshots, { recursive: true })
+
+const failures: string[] = []
+const slugs = new Set<string>()
+
+for (const file of files.sort()) {
+  const source = await Bun.file(file).json().catch(() => undefined)
+  const slug = path.basename(file, ".json").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "")
+  if (!slug) {
+    failures.push(`${file}: filename does not produce a usable theme prefix`)
+    continue
+  }
+  if (slugs.has(slug)) {
+    failures.push(`${file}: duplicate theme prefix "${slug}"`)
+    continue
+  }
+  slugs.add(slug)
+
+  if (!isRecord(source)) {
+    failures.push(`${file}: invalid JSON theme object`)
+    continue
+  }
+  if (source.version === 2) {
+    failures.push(`${file}: native V2 theme loading is not supported by the TUI yet`)
+    continue
+  }
+  if (!isRecord(source.theme)) {
+    failures.push(`${file}: expected a V1 theme with a "theme" object`)
+    continue
+  }
+
+  for (const mode of ["light", "dark"] as const) {
+    const name = `theme-gallery-${slug}-${mode}-${process.pid}`
+    console.log(`\n[${slug}/${mode}] capturing screenshots`)
+    const child = Bun.spawn(
+      ["opencode-drive", "start", "--name", name, "--script", scenario, "--dev", root],
+      {
+        cwd: root,
+        env: {
+          ...process.env,
+          OPENCODE_THEME_GALLERY_FILE: file,
+          OPENCODE_THEME_GALLERY_MODE: mode,
+          OPENCODE_THEME_GALLERY_OUTPUT: screenshots,
+          OPENCODE_THEME_GALLERY_SLUG: slug,
+        },
+        stdout: "inherit",
+        stderr: "inherit",
+      },
+    )
+    const exit = await child.exited
+    if (exit !== 0) failures.push(`${file} (${mode}): OpenCode Drive exited with ${exit}`)
+  }
+}
+
+if (failures.length) {
+  console.error("\nTheme gallery completed with errors:")
+  failures.forEach((failure) => console.error(`- ${failure}`))
+  process.exit(1)
+}
+
+console.log(`\nScreenshots written to ${screenshots}`)
+
+function isRecord(value: unknown): value is Record<string, unknown> {
+  return !!value && typeof value === "object" && !Array.isArray(value)
+}

+ 123 - 0
packages/tui/test/theme/gallery/scenario.ts

@@ -0,0 +1,123 @@
+import path from "node:path"
+import { mkdir } from "node:fs/promises"
+import { defineScript, wait } from "opencode-drive"
+
+const file = required("OPENCODE_THEME_GALLERY_FILE")
+const mode = required("OPENCODE_THEME_GALLERY_MODE")
+const output = required("OPENCODE_THEME_GALLERY_OUTPUT")
+const slug = required("OPENCODE_THEME_GALLERY_SLUG")
+const themeName = `gallery-${slug}`
+
+export default defineScript({
+  async setup({ fs, config }) {
+    await fs.writeFile("README.md", "# Theme gallery fixture\n\nA stable project for OpenCode TUI screenshots.\n")
+    await fs.writeFile("src/example.ts", "export const palette = ['neutral', 'accent', 'interactive']\n")
+    await fs.writeFile(`.opencode/themes/${themeName}.json`, await Bun.file(file).text())
+    await fs.writeFile(
+      ".opencode/cli.json",
+      `${JSON.stringify({
+        theme: { name: themeName, mode },
+      }, undefined, 2)}\n`,
+    )
+    config.permissions = [
+      { action: "*", resource: "*", effect: "allow" },
+      { action: "shell", resource: "*", effect: "ask" },
+    ]
+  },
+  async run({ llm, ui }) {
+    await mkdir(output, { recursive: true })
+    llm.title((_request, index) => (index === 0 ? "Theme gallery" : `Theme gallery ${index + 1}`))
+
+    await ui.waitFor((state) => state.focused.editor)
+    await ui.waitFor("local")
+    await wait(750)
+    await capture(ui, "01-home")
+
+    await ui.submit("Show me a compact markdown theme specimen")
+    await llm.send(
+      llm.reasoning("I will provide a stable markdown sample for the theme gallery."),
+      llm.text(
+        [
+          "# Theme Review",
+          "",
+          "A compact response with **strong text**, *emphasis*, and an `inline token`.",
+          "",
+          "> Good themes preserve hierarchy without losing contrast.",
+          "",
+          "- Neutral surfaces",
+          "- Interactive accents",
+          "- Success, warning, and error feedback",
+          "",
+          "```ts",
+          "const mode = 'gallery'",
+          "```",
+        ].join("\n"),
+      ),
+    )
+    await ui.waitFor("Theme Review")
+    await capture(ui, "02-markdown")
+
+    const permission = llm.send(
+      llm.toolCall({
+        id: "theme-gallery-permission",
+        index: 0,
+        name: "shell",
+        input: { command: "printf 'theme gallery permission'" },
+      }),
+    )
+    await ui.submit("Run a protected command so I can inspect the permission prompt")
+    await ui.waitFor("Permission required")
+    await capture(ui, "03-permission")
+    await ui.enter()
+    await permission
+    await llm.send(llm.text("The protected command completed successfully."))
+    await ui.waitFor("completed successfully")
+
+    const form = llm.send(
+      llm.toolCall({
+        id: "theme-gallery-question",
+        index: 0,
+        name: "question",
+        input: {
+          questions: [
+            {
+              header: "Theme direction",
+              question: "Which direction should this theme emphasize?",
+              options: [
+                { label: "Balanced", description: "Keep surfaces and accents evenly weighted" },
+                { label: "Expressive", description: "Give accent colors more visual presence" },
+                { label: "Quiet", description: "Favor neutral surfaces and restrained contrast" },
+              ],
+            },
+          ],
+        },
+      }),
+    )
+    await ui.submit("Ask me for a theme direction")
+    await ui.waitFor("Which direction should this theme emphasize?")
+    await capture(ui, "04-form")
+    await ui.enter()
+    await form
+    await llm.send(llm.text("The theme review form was submitted."))
+    await ui.waitFor("form was submitted")
+
+    await ui.submit("/new")
+    await ui.waitFor((state) => state.focused.editor)
+    await ui.submit("Create a second session for the session switcher gallery")
+    await llm.send(llm.text("This second session makes the switcher state visible."))
+    await ui.submit("/sessions")
+    await ui.waitFor("Sessions")
+    await capture(ui, "05-session-switcher")
+  },
+})
+
+async function capture(ui: { screenshot(name?: string): Promise<string> }, state: string) {
+  const source = await ui.screenshot(`${slug}-${mode}-${state}`)
+  await Bun.write(path.join(output, `${slug}-${mode}-${state}.png`), Bun.file(source))
+}
+
+function required(name: string) {
+  const value = process.env[name]
+  if (!value) throw new Error(`${name} is required`)
+  return value
+}

BIN
packages/tui/test/theme/gallery/screenshots/candy-pop-dark-dark-01-home.png


BIN
packages/tui/test/theme/gallery/screenshots/candy-pop-dark-dark-02-markdown.png


BIN
packages/tui/test/theme/gallery/screenshots/candy-pop-dark-dark-03-permission.png


BIN
packages/tui/test/theme/gallery/screenshots/candy-pop-dark-dark-04-form.png


BIN
packages/tui/test/theme/gallery/screenshots/candy-pop-dark-dark-05-session-switcher.png


BIN
packages/tui/test/theme/gallery/screenshots/candy-pop-dark-light-01-home.png


BIN
packages/tui/test/theme/gallery/screenshots/candy-pop-dark-light-02-markdown.png


BIN
packages/tui/test/theme/gallery/screenshots/candy-pop-dark-light-03-permission.png


BIN
packages/tui/test/theme/gallery/screenshots/candy-pop-dark-light-04-form.png


BIN
packages/tui/test/theme/gallery/screenshots/candy-pop-dark-light-05-session-switcher.png


BIN
packages/tui/test/theme/gallery/screenshots/candy-pop-light-dark-01-home.png


BIN
packages/tui/test/theme/gallery/screenshots/candy-pop-light-dark-02-markdown.png


BIN
packages/tui/test/theme/gallery/screenshots/candy-pop-light-dark-03-permission.png


BIN
packages/tui/test/theme/gallery/screenshots/candy-pop-light-dark-04-form.png


BIN
packages/tui/test/theme/gallery/screenshots/candy-pop-light-dark-05-session-switcher.png


BIN
packages/tui/test/theme/gallery/screenshots/candy-pop-light-light-01-home.png


BIN
packages/tui/test/theme/gallery/screenshots/candy-pop-light-light-02-markdown.png


BIN
packages/tui/test/theme/gallery/screenshots/candy-pop-light-light-03-permission.png


BIN
packages/tui/test/theme/gallery/screenshots/candy-pop-light-light-04-form.png


BIN
packages/tui/test/theme/gallery/screenshots/candy-pop-light-light-05-session-switcher.png


BIN
packages/tui/test/theme/gallery/screenshots/matchalk-dark-01-home.png


BIN
packages/tui/test/theme/gallery/screenshots/matchalk-dark-02-markdown.png


BIN
packages/tui/test/theme/gallery/screenshots/matchalk-dark-03-permission.png


BIN
packages/tui/test/theme/gallery/screenshots/matchalk-dark-04-form.png


BIN
packages/tui/test/theme/gallery/screenshots/matchalk-dark-05-session-switcher.png


BIN
packages/tui/test/theme/gallery/screenshots/matchalk-light-01-home.png


BIN
packages/tui/test/theme/gallery/screenshots/matchalk-light-02-markdown.png


BIN
packages/tui/test/theme/gallery/screenshots/matchalk-light-03-permission.png


BIN
packages/tui/test/theme/gallery/screenshots/matchalk-light-04-form.png


BIN
packages/tui/test/theme/gallery/screenshots/matchalk-light-05-session-switcher.png


BIN
packages/tui/test/theme/gallery/screenshots/nightowl-dark-01-home.png


BIN
packages/tui/test/theme/gallery/screenshots/nightowl-dark-02-markdown.png


BIN
packages/tui/test/theme/gallery/screenshots/nightowl-dark-03-permission.png


BIN
packages/tui/test/theme/gallery/screenshots/nightowl-dark-04-form.png


BIN
packages/tui/test/theme/gallery/screenshots/nightowl-dark-05-session-switcher.png


BIN
packages/tui/test/theme/gallery/screenshots/nightowl-light-01-home.png


BIN
packages/tui/test/theme/gallery/screenshots/nightowl-light-02-markdown.png


BIN
packages/tui/test/theme/gallery/screenshots/nightowl-light-03-permission.png


BIN
packages/tui/test/theme/gallery/screenshots/nightowl-light-04-form.png


BIN
packages/tui/test/theme/gallery/screenshots/nightowl-light-05-session-switcher.png


BIN
packages/tui/test/theme/gallery/screenshots/opencode-dark-01-home.png


BIN
packages/tui/test/theme/gallery/screenshots/opencode-dark-02-markdown.png


BIN
packages/tui/test/theme/gallery/screenshots/opencode-dark-03-permission.png


BIN
packages/tui/test/theme/gallery/screenshots/opencode-dark-04-form.png


BIN
packages/tui/test/theme/gallery/screenshots/opencode-dark-05-session-switcher.png


BIN
packages/tui/test/theme/gallery/screenshots/opencode-light-01-home.png


BIN
packages/tui/test/theme/gallery/screenshots/opencode-light-02-markdown.png


BIN
packages/tui/test/theme/gallery/screenshots/opencode-light-03-permission.png


BIN
packages/tui/test/theme/gallery/screenshots/opencode-light-04-form.png


BIN
packages/tui/test/theme/gallery/screenshots/opencode-light-05-session-switcher.png


BIN
packages/tui/test/theme/gallery/screenshots/poimandres-dark-01-home.png


BIN
packages/tui/test/theme/gallery/screenshots/poimandres-dark-02-markdown.png


BIN
packages/tui/test/theme/gallery/screenshots/poimandres-dark-03-permission.png


BIN
packages/tui/test/theme/gallery/screenshots/poimandres-dark-04-form.png


BIN
packages/tui/test/theme/gallery/screenshots/poimandres-dark-05-session-switcher.png


BIN
packages/tui/test/theme/gallery/screenshots/poimandres-light-01-home.png


BIN
packages/tui/test/theme/gallery/screenshots/poimandres-light-02-markdown.png


BIN
packages/tui/test/theme/gallery/screenshots/poimandres-light-03-permission.png


BIN
packages/tui/test/theme/gallery/screenshots/poimandres-light-04-form.png


BIN
packages/tui/test/theme/gallery/screenshots/poimandres-light-05-session-switcher.png


BIN
packages/tui/test/theme/gallery/screenshots/solarized-dark-01-home.png


BIN
packages/tui/test/theme/gallery/screenshots/solarized-dark-02-markdown.png


BIN
packages/tui/test/theme/gallery/screenshots/solarized-dark-03-permission.png


BIN
packages/tui/test/theme/gallery/screenshots/solarized-dark-04-form.png


BIN
packages/tui/test/theme/gallery/screenshots/solarized-dark-05-session-switcher.png


BIN
packages/tui/test/theme/gallery/screenshots/solarized-light-01-home.png


BIN
packages/tui/test/theme/gallery/screenshots/solarized-light-02-markdown.png


BIN
packages/tui/test/theme/gallery/screenshots/solarized-light-03-permission.png


BIN
packages/tui/test/theme/gallery/screenshots/solarized-light-04-form.png


BIN
packages/tui/test/theme/gallery/screenshots/solarized-light-05-session-switcher.png


BIN
packages/tui/test/theme/gallery/screenshots/synthwave84-dark-01-home.png


BIN
packages/tui/test/theme/gallery/screenshots/synthwave84-dark-02-markdown.png


BIN
packages/tui/test/theme/gallery/screenshots/synthwave84-dark-03-permission.png


BIN
packages/tui/test/theme/gallery/screenshots/synthwave84-dark-04-form.png


BIN
packages/tui/test/theme/gallery/screenshots/synthwave84-dark-05-session-switcher.png


BIN
packages/tui/test/theme/gallery/screenshots/synthwave84-light-01-home.png


BIN
packages/tui/test/theme/gallery/screenshots/synthwave84-light-02-markdown.png


BIN
packages/tui/test/theme/gallery/screenshots/synthwave84-light-03-permission.png


BIN
packages/tui/test/theme/gallery/screenshots/synthwave84-light-04-form.png


BIN
packages/tui/test/theme/gallery/screenshots/synthwave84-light-05-session-switcher.png


BIN
packages/tui/test/theme/gallery/screenshots/vercel-dark-01-home.png


BIN
packages/tui/test/theme/gallery/screenshots/vercel-dark-02-markdown.png


BIN
packages/tui/test/theme/gallery/screenshots/vercel-dark-03-permission.png


BIN
packages/tui/test/theme/gallery/screenshots/vercel-dark-04-form.png


BIN
packages/tui/test/theme/gallery/screenshots/vercel-dark-05-session-switcher.png


BIN
packages/tui/test/theme/gallery/screenshots/vercel-light-01-home.png


BIN
packages/tui/test/theme/gallery/screenshots/vercel-light-02-markdown.png


BIN
packages/tui/test/theme/gallery/screenshots/vercel-light-03-permission.png


BIN
packages/tui/test/theme/gallery/screenshots/vercel-light-04-form.png


BIN
packages/tui/test/theme/gallery/screenshots/vercel-light-05-session-switcher.png


+ 79 - 0
packages/tui/test/theme/gallery/themes/candy-pop-dark.json

@@ -0,0 +1,79 @@
+{
+  "$schema": "https://opencode.ai/theme.json",
+  "defs": {
+    "bg": "#2e1a47",
+    "panel": "#371f54",
+    "element": "#4a2b7a",
+    "borderSubtle": "#553183",
+    "border": "#683b9f",
+    "text": "#ffffff",
+    "textSoft": "#e0c3fc",
+    "textMuted": "#b39ddb",
+    "pink": "#ec4899",
+    "pinkBright": "#f472b6",
+    "purple": "#a78bfa",
+    "cyan": "#22d3ee",
+    "green": "#34d399",
+    "greenBright": "#6ee7b7",
+    "yellow": "#facc15",
+    "red": "#fb7185",
+    "addedBg": "#2f294e",
+    "removedBg": "#3f214c",
+    "contextBg": "#371f54",
+    "addedLineBg": "#304052",
+    "removedLineBg": "#54294f"
+  },
+  "theme": {
+    "primary": "pink",
+    "secondary": "cyan",
+    "accent": "pinkBright",
+    "error": "red",
+    "warning": "yellow",
+    "success": "green",
+    "info": "cyan",
+    "text": "text",
+    "textMuted": "textMuted",
+    "background": "bg",
+    "backgroundPanel": "panel",
+    "backgroundElement": "element",
+    "backgroundMenu": "element",
+    "border": "border",
+    "borderActive": "pink",
+    "borderSubtle": "borderSubtle",
+    "diffAdded": "green",
+    "diffRemoved": "red",
+    "diffContext": "textMuted",
+    "diffHunkHeader": "pink",
+    "diffHighlightAdded": "greenBright",
+    "diffHighlightRemoved": "pinkBright",
+    "diffAddedBg": "addedBg",
+    "diffRemovedBg": "removedBg",
+    "diffContextBg": "contextBg",
+    "diffLineNumber": "textMuted",
+    "diffAddedLineNumberBg": "addedLineBg",
+    "diffRemovedLineNumberBg": "removedLineBg",
+    "markdownText": "text",
+    "markdownHeading": "pink",
+    "markdownLink": "cyan",
+    "markdownLinkText": "pinkBright",
+    "markdownCode": "green",
+    "markdownBlockQuote": "purple",
+    "markdownEmph": "pinkBright",
+    "markdownStrong": "text",
+    "markdownHorizontalRule": "border",
+    "markdownListItem": "pink",
+    "markdownListEnumeration": "cyan",
+    "markdownImage": "cyan",
+    "markdownImageText": "pinkBright",
+    "markdownCodeBlock": "textSoft",
+    "syntaxComment": "textMuted",
+    "syntaxKeyword": "pink",
+    "syntaxFunction": "cyan",
+    "syntaxVariable": "text",
+    "syntaxString": "green",
+    "syntaxNumber": "yellow",
+    "syntaxType": "pinkBright",
+    "syntaxOperator": "textSoft",
+    "syntaxPunctuation": "textMuted"
+  }
+}

+ 80 - 0
packages/tui/test/theme/gallery/themes/candy-pop-light.json

@@ -0,0 +1,80 @@
+{
+  "$schema": "https://opencode.ai/theme.json",
+  "defs": {
+    "bg": "#fdf2f8",
+    "panel": "#fce7f3",
+    "element": "#fbcfe8",
+    "menu": "#ffffff",
+    "borderSubtle": "#fbcfe8",
+    "border": "#f9a8d4",
+    "text": "#831843",
+    "textSoft": "#9d174d",
+    "textMuted": "#be185d",
+    "pink": "#db2777",
+    "pinkBright": "#be185d",
+    "purple": "#7c3aed",
+    "cyan": "#0891b2",
+    "green": "#059669",
+    "greenBright": "#047857",
+    "yellow": "#d97706",
+    "red": "#e11d48",
+    "addedBg": "#e0f2e8",
+    "removedBg": "#fce1e8",
+    "contextBg": "#fce7f3",
+    "addedLineBg": "#c9ead9",
+    "removedLineBg": "#f8cbd7"
+  },
+  "theme": {
+    "primary": "pink",
+    "secondary": "cyan",
+    "accent": "pinkBright",
+    "error": "red",
+    "warning": "yellow",
+    "success": "green",
+    "info": "cyan",
+    "text": "text",
+    "textMuted": "textMuted",
+    "background": "bg",
+    "backgroundPanel": "panel",
+    "backgroundElement": "element",
+    "backgroundMenu": "menu",
+    "border": "border",
+    "borderActive": "pink",
+    "borderSubtle": "borderSubtle",
+    "diffAdded": "green",
+    "diffRemoved": "red",
+    "diffContext": "textMuted",
+    "diffHunkHeader": "pink",
+    "diffHighlightAdded": "greenBright",
+    "diffHighlightRemoved": "pinkBright",
+    "diffAddedBg": "addedBg",
+    "diffRemovedBg": "removedBg",
+    "diffContextBg": "contextBg",
+    "diffLineNumber": "textMuted",
+    "diffAddedLineNumberBg": "addedLineBg",
+    "diffRemovedLineNumberBg": "removedLineBg",
+    "markdownText": "text",
+    "markdownHeading": "pink",
+    "markdownLink": "cyan",
+    "markdownLinkText": "pinkBright",
+    "markdownCode": "green",
+    "markdownBlockQuote": "purple",
+    "markdownEmph": "pinkBright",
+    "markdownStrong": "text",
+    "markdownHorizontalRule": "border",
+    "markdownListItem": "pink",
+    "markdownListEnumeration": "cyan",
+    "markdownImage": "cyan",
+    "markdownImageText": "pinkBright",
+    "markdownCodeBlock": "textSoft",
+    "syntaxComment": "textMuted",
+    "syntaxKeyword": "pink",
+    "syntaxFunction": "cyan",
+    "syntaxVariable": "text",
+    "syntaxString": "green",
+    "syntaxNumber": "yellow",
+    "syntaxType": "pinkBright",
+    "syntaxOperator": "textSoft",
+    "syntaxPunctuation": "textMuted"
+  }
+}

+ 75 - 0
packages/tui/test/theme/gallery/themes/matchalk.json

@@ -0,0 +1,75 @@
+{
+  "$schema": "https://opencode.ai/theme.json",
+  "defs": {
+    "bg": "#1C2427",
+    "panel": "#273136",
+    "element": "#323E45",
+    "borderSubtle": "#304E37",
+    "text": "#D1DED3",
+    "textMuted": "#9AAEA7",
+    "commentMuted": "#60777D",
+    "green": "#7EB08A",
+    "tan": "#D2B48C",
+    "pink": "#FF819F",
+    "purple": "#BA8EAF",
+    "blue": "#7EA4B0",
+    "violet": "#8A7EB0",
+    "addedBg": "#2B3D33",
+    "removedBg": "#4D3740",
+    "contextBg": "#222A2E",
+    "addedLineBg": "#3A5244",
+    "removedLineBg": "#60414B"
+  },
+  "theme": {
+    "primary": "green",
+    "secondary": "tan",
+    "accent": "pink",
+    "error": "pink",
+    "warning": "purple",
+    "success": "green",
+    "info": "tan",
+    "text": "text",
+    "textMuted": "textMuted",
+    "background": "bg",
+    "backgroundPanel": "panel",
+    "backgroundElement": "element",
+    "border": "element",
+    "borderActive": "green",
+    "borderSubtle": "borderSubtle",
+    "diffAdded": "green",
+    "diffRemoved": "pink",
+    "diffContext": "textMuted",
+    "diffHunkHeader": "tan",
+    "diffHighlightAdded": "green",
+    "diffHighlightRemoved": "pink",
+    "diffAddedBg": "addedBg",
+    "diffRemovedBg": "removedBg",
+    "diffContextBg": "contextBg",
+    "diffLineNumber": "blue",
+    "diffAddedLineNumberBg": "addedLineBg",
+    "diffRemovedLineNumberBg": "removedLineBg",
+    "markdownText": "text",
+    "markdownHeading": "tan",
+    "markdownLink": "tan",
+    "markdownLinkText": "green",
+    "markdownCode": "tan",
+    "markdownBlockQuote": "blue",
+    "markdownEmph": "text",
+    "markdownStrong": "text",
+    "markdownHorizontalRule": "tan",
+    "markdownListItem": "tan",
+    "markdownListEnumeration": "tan",
+    "markdownImage": "tan",
+    "markdownImageText": "pink",
+    "markdownCodeBlock": "green",
+    "syntaxComment": "commentMuted",
+    "syntaxKeyword": "tan",
+    "syntaxFunction": "green",
+    "syntaxVariable": "text",
+    "syntaxString": "purple",
+    "syntaxNumber": "blue",
+    "syntaxType": "blue",
+    "syntaxOperator": "tan",
+    "syntaxPunctuation": "blue"
+  }
+}

+ 221 - 0
packages/tui/test/theme/gallery/themes/nightowl.json

@@ -0,0 +1,221 @@
+{
+  "$schema": "https://opencode.ai/theme.json",
+  "defs": {
+    "nightOwlBg": "#011627",
+    "nightOwlFg": "#d6deeb",
+    "nightOwlBlue": "#82AAFF",
+    "nightOwlCyan": "#7fdbca",
+    "nightOwlGreen": "#c5e478",
+    "nightOwlYellow": "#ecc48d",
+    "nightOwlOrange": "#F78C6C",
+    "nightOwlRed": "#EF5350",
+    "nightOwlPink": "#ff5874",
+    "nightOwlPurple": "#c792ea",
+    "nightOwlMuted": "#5f7e97",
+    "nightOwlGray": "#637777",
+    "nightOwlLightGray": "#89a4bb",
+    "nightOwlPanel": "#0b253a"
+  },
+  "theme": {
+    "primary": {
+      "dark": "nightOwlBlue",
+      "light": "nightOwlBlue"
+    },
+    "secondary": {
+      "dark": "nightOwlCyan",
+      "light": "nightOwlCyan"
+    },
+    "accent": {
+      "dark": "nightOwlPurple",
+      "light": "nightOwlPurple"
+    },
+    "error": {
+      "dark": "nightOwlRed",
+      "light": "nightOwlRed"
+    },
+    "warning": {
+      "dark": "nightOwlYellow",
+      "light": "nightOwlYellow"
+    },
+    "success": {
+      "dark": "nightOwlGreen",
+      "light": "nightOwlGreen"
+    },
+    "info": {
+      "dark": "nightOwlBlue",
+      "light": "nightOwlBlue"
+    },
+    "text": {
+      "dark": "nightOwlFg",
+      "light": "nightOwlFg"
+    },
+    "textMuted": {
+      "dark": "nightOwlMuted",
+      "light": "nightOwlMuted"
+    },
+    "background": {
+      "dark": "nightOwlBg",
+      "light": "nightOwlBg"
+    },
+    "backgroundPanel": {
+      "dark": "nightOwlPanel",
+      "light": "nightOwlPanel"
+    },
+    "backgroundElement": {
+      "dark": "nightOwlPanel",
+      "light": "nightOwlPanel"
+    },
+    "border": {
+      "dark": "nightOwlMuted",
+      "light": "nightOwlMuted"
+    },
+    "borderActive": {
+      "dark": "nightOwlBlue",
+      "light": "nightOwlBlue"
+    },
+    "borderSubtle": {
+      "dark": "nightOwlMuted",
+      "light": "nightOwlMuted"
+    },
+    "diffAdded": {
+      "dark": "nightOwlGreen",
+      "light": "nightOwlGreen"
+    },
+    "diffRemoved": {
+      "dark": "nightOwlRed",
+      "light": "nightOwlRed"
+    },
+    "diffContext": {
+      "dark": "nightOwlMuted",
+      "light": "nightOwlMuted"
+    },
+    "diffHunkHeader": {
+      "dark": "nightOwlMuted",
+      "light": "nightOwlMuted"
+    },
+    "diffHighlightAdded": {
+      "dark": "nightOwlGreen",
+      "light": "nightOwlGreen"
+    },
+    "diffHighlightRemoved": {
+      "dark": "nightOwlRed",
+      "light": "nightOwlRed"
+    },
+    "diffAddedBg": {
+      "dark": "#0a2e1a",
+      "light": "#0a2e1a"
+    },
+    "diffRemovedBg": {
+      "dark": "#2d1b1b",
+      "light": "#2d1b1b"
+    },
+    "diffContextBg": {
+      "dark": "nightOwlPanel",
+      "light": "nightOwlPanel"
+    },
+    "diffLineNumber": {
+      "dark": "#7791a6",
+      "light": "#7791a6"
+    },
+    "diffAddedLineNumberBg": {
+      "dark": "#0a2e1a",
+      "light": "#0a2e1a"
+    },
+    "diffRemovedLineNumberBg": {
+      "dark": "#2d1b1b",
+      "light": "#2d1b1b"
+    },
+    "markdownText": {
+      "dark": "nightOwlFg",
+      "light": "nightOwlFg"
+    },
+    "markdownHeading": {
+      "dark": "nightOwlBlue",
+      "light": "nightOwlBlue"
+    },
+    "markdownLink": {
+      "dark": "nightOwlCyan",
+      "light": "nightOwlCyan"
+    },
+    "markdownLinkText": {
+      "dark": "nightOwlBlue",
+      "light": "nightOwlBlue"
+    },
+    "markdownCode": {
+      "dark": "nightOwlGreen",
+      "light": "nightOwlGreen"
+    },
+    "markdownBlockQuote": {
+      "dark": "nightOwlMuted",
+      "light": "nightOwlMuted"
+    },
+    "markdownEmph": {
+      "dark": "nightOwlPurple",
+      "light": "nightOwlPurple"
+    },
+    "markdownStrong": {
+      "dark": "nightOwlYellow",
+      "light": "nightOwlYellow"
+    },
+    "markdownHorizontalRule": {
+      "dark": "nightOwlMuted",
+      "light": "nightOwlMuted"
+    },
+    "markdownListItem": {
+      "dark": "nightOwlBlue",
+      "light": "nightOwlBlue"
+    },
+    "markdownListEnumeration": {
+      "dark": "nightOwlCyan",
+      "light": "nightOwlCyan"
+    },
+    "markdownImage": {
+      "dark": "nightOwlCyan",
+      "light": "nightOwlCyan"
+    },
+    "markdownImageText": {
+      "dark": "nightOwlBlue",
+      "light": "nightOwlBlue"
+    },
+    "markdownCodeBlock": {
+      "dark": "nightOwlFg",
+      "light": "nightOwlFg"
+    },
+    "syntaxComment": {
+      "dark": "nightOwlGray",
+      "light": "nightOwlGray"
+    },
+    "syntaxKeyword": {
+      "dark": "nightOwlPurple",
+      "light": "nightOwlPurple"
+    },
+    "syntaxFunction": {
+      "dark": "nightOwlBlue",
+      "light": "nightOwlBlue"
+    },
+    "syntaxVariable": {
+      "dark": "nightOwlFg",
+      "light": "nightOwlFg"
+    },
+    "syntaxString": {
+      "dark": "nightOwlYellow",
+      "light": "nightOwlYellow"
+    },
+    "syntaxNumber": {
+      "dark": "nightOwlOrange",
+      "light": "nightOwlOrange"
+    },
+    "syntaxType": {
+      "dark": "nightOwlGreen",
+      "light": "nightOwlGreen"
+    },
+    "syntaxOperator": {
+      "dark": "nightOwlCyan",
+      "light": "nightOwlCyan"
+    },
+    "syntaxPunctuation": {
+      "dark": "nightOwlFg",
+      "light": "nightOwlFg"
+    }
+  }
+}

+ 245 - 0
packages/tui/test/theme/gallery/themes/opencode.json

@@ -0,0 +1,245 @@
+{
+  "$schema": "https://opencode.ai/theme.json",
+  "defs": {
+    "darkStep1": "#0a0a0a",
+    "darkStep2": "#141414",
+    "darkStep3": "#1e1e1e",
+    "darkStep4": "#282828",
+    "darkStep5": "#323232",
+    "darkStep6": "#3c3c3c",
+    "darkStep7": "#484848",
+    "darkStep8": "#606060",
+    "darkStep9": "#fab283",
+    "darkStep10": "#ffc09f",
+    "darkStep11": "#808080",
+    "darkStep12": "#eeeeee",
+    "darkSecondary": "#5c9cf5",
+    "darkAccent": "#9d7cd8",
+    "darkRed": "#e06c75",
+    "darkOrange": "#f5a742",
+    "darkGreen": "#7fd88f",
+    "darkCyan": "#56b6c2",
+    "darkYellow": "#e5c07b",
+    "lightStep1": "#ffffff",
+    "lightStep2": "#fafafa",
+    "lightStep3": "#f5f5f5",
+    "lightStep4": "#ebebeb",
+    "lightStep5": "#e1e1e1",
+    "lightStep6": "#d4d4d4",
+    "lightStep7": "#b8b8b8",
+    "lightStep8": "#a0a0a0",
+    "lightStep9": "#3b7dd8",
+    "lightStep10": "#2968c3",
+    "lightStep11": "#8a8a8a",
+    "lightStep12": "#1a1a1a",
+    "lightSecondary": "#7b5bb6",
+    "lightAccent": "#d68c27",
+    "lightRed": "#d1383d",
+    "lightOrange": "#d68c27",
+    "lightGreen": "#3d9a57",
+    "lightCyan": "#318795",
+    "lightYellow": "#b0851f"
+  },
+  "theme": {
+    "primary": {
+      "dark": "darkStep9",
+      "light": "lightStep9"
+    },
+    "secondary": {
+      "dark": "darkSecondary",
+      "light": "lightSecondary"
+    },
+    "accent": {
+      "dark": "darkAccent",
+      "light": "lightAccent"
+    },
+    "error": {
+      "dark": "darkRed",
+      "light": "lightRed"
+    },
+    "warning": {
+      "dark": "darkOrange",
+      "light": "lightOrange"
+    },
+    "success": {
+      "dark": "darkGreen",
+      "light": "lightGreen"
+    },
+    "info": {
+      "dark": "darkCyan",
+      "light": "lightCyan"
+    },
+    "text": {
+      "dark": "darkStep12",
+      "light": "lightStep12"
+    },
+    "textMuted": {
+      "dark": "darkStep11",
+      "light": "lightStep11"
+    },
+    "background": {
+      "dark": "darkStep1",
+      "light": "lightStep1"
+    },
+    "backgroundPanel": {
+      "dark": "darkStep2",
+      "light": "lightStep2"
+    },
+    "backgroundElement": {
+      "dark": "darkStep3",
+      "light": "lightStep3"
+    },
+    "border": {
+      "dark": "darkStep7",
+      "light": "lightStep7"
+    },
+    "borderActive": {
+      "dark": "darkStep8",
+      "light": "lightStep8"
+    },
+    "borderSubtle": {
+      "dark": "darkStep6",
+      "light": "lightStep6"
+    },
+    "diffAdded": {
+      "dark": "#4fd6be",
+      "light": "#1e725c"
+    },
+    "diffRemoved": {
+      "dark": "#c53b53",
+      "light": "#c53b53"
+    },
+    "diffContext": {
+      "dark": "#828bb8",
+      "light": "#7086b5"
+    },
+    "diffHunkHeader": {
+      "dark": "#828bb8",
+      "light": "#7086b5"
+    },
+    "diffHighlightAdded": {
+      "dark": "#b8db87",
+      "light": "#4db380"
+    },
+    "diffHighlightRemoved": {
+      "dark": "#e26a75",
+      "light": "#f52a65"
+    },
+    "diffAddedBg": {
+      "dark": "#20303b",
+      "light": "#d5e5d5"
+    },
+    "diffRemovedBg": {
+      "dark": "#37222c",
+      "light": "#f7d8db"
+    },
+    "diffContextBg": {
+      "dark": "darkStep2",
+      "light": "lightStep2"
+    },
+    "diffLineNumber": {
+      "dark": "#8f8f8f",
+      "light": "#595959"
+    },
+    "diffAddedLineNumberBg": {
+      "dark": "#1b2b34",
+      "light": "#c5d5c5"
+    },
+    "diffRemovedLineNumberBg": {
+      "dark": "#2d1f26",
+      "light": "#e7c8cb"
+    },
+    "markdownText": {
+      "dark": "darkStep12",
+      "light": "lightStep12"
+    },
+    "markdownHeading": {
+      "dark": "darkAccent",
+      "light": "lightAccent"
+    },
+    "markdownLink": {
+      "dark": "darkStep9",
+      "light": "lightStep9"
+    },
+    "markdownLinkText": {
+      "dark": "darkCyan",
+      "light": "lightCyan"
+    },
+    "markdownCode": {
+      "dark": "darkGreen",
+      "light": "lightGreen"
+    },
+    "markdownBlockQuote": {
+      "dark": "darkYellow",
+      "light": "lightYellow"
+    },
+    "markdownEmph": {
+      "dark": "darkYellow",
+      "light": "lightYellow"
+    },
+    "markdownStrong": {
+      "dark": "darkOrange",
+      "light": "lightOrange"
+    },
+    "markdownHorizontalRule": {
+      "dark": "darkStep11",
+      "light": "lightStep11"
+    },
+    "markdownListItem": {
+      "dark": "darkStep9",
+      "light": "lightStep9"
+    },
+    "markdownListEnumeration": {
+      "dark": "darkCyan",
+      "light": "lightCyan"
+    },
+    "markdownImage": {
+      "dark": "darkStep9",
+      "light": "lightStep9"
+    },
+    "markdownImageText": {
+      "dark": "darkCyan",
+      "light": "lightCyan"
+    },
+    "markdownCodeBlock": {
+      "dark": "darkStep12",
+      "light": "lightStep12"
+    },
+    "syntaxComment": {
+      "dark": "darkStep11",
+      "light": "lightStep11"
+    },
+    "syntaxKeyword": {
+      "dark": "darkAccent",
+      "light": "lightAccent"
+    },
+    "syntaxFunction": {
+      "dark": "darkStep9",
+      "light": "lightStep9"
+    },
+    "syntaxVariable": {
+      "dark": "darkRed",
+      "light": "lightRed"
+    },
+    "syntaxString": {
+      "dark": "darkGreen",
+      "light": "lightGreen"
+    },
+    "syntaxNumber": {
+      "dark": "darkOrange",
+      "light": "lightOrange"
+    },
+    "syntaxType": {
+      "dark": "darkYellow",
+      "light": "lightYellow"
+    },
+    "syntaxOperator": {
+      "dark": "darkCyan",
+      "light": "lightCyan"
+    },
+    "syntaxPunctuation": {
+      "dark": "darkStep12",
+      "light": "lightStep12"
+    }
+  }
+}

+ 78 - 0
packages/tui/test/theme/gallery/themes/poimandres.json

@@ -0,0 +1,78 @@
+{
+  "$schema": "https://opencode.ai/theme.json",
+  "defs": {
+    "bg": "#1b1e28",
+    "panel": "#202430",
+    "element": "#303340",
+    "borderSubtle": "#252834",
+    "text": "#a6accd",
+    "textMuted": "#767c9d",
+    "offWhite": "#e4f0fb",
+    "blue": "#ADD7FF",
+    "cyan": "#89ddff",
+    "mint": "#5DE4c7",
+    "green": "#5fb3a1",
+    "typeBlue": "#91B4D5",
+    "slate": "#7390AA",
+    "red": "#d0679d",
+    "pink": "#f087bd",
+    "yellow": "#fffac2",
+    "addedBg": "#233037",
+    "removedBg": "#332631",
+    "contextBg": "#1e212c",
+    "addedLineBg": "#2b3c40",
+    "removedLineBg": "#422938"
+  },
+  "theme": {
+    "primary": "blue",
+    "secondary": "mint",
+    "accent": "cyan",
+    "error": "red",
+    "warning": "yellow",
+    "success": "mint",
+    "info": "cyan",
+    "text": "text",
+    "textMuted": "textMuted",
+    "background": "bg",
+    "backgroundPanel": "panel",
+    "backgroundElement": "element",
+    "border": "element",
+    "borderActive": "blue",
+    "borderSubtle": "borderSubtle",
+    "diffAdded": "green",
+    "diffRemoved": "red",
+    "diffContext": "textMuted",
+    "diffHunkHeader": "cyan",
+    "diffHighlightAdded": "mint",
+    "diffHighlightRemoved": "pink",
+    "diffAddedBg": "addedBg",
+    "diffRemovedBg": "removedBg",
+    "diffContextBg": "contextBg",
+    "diffLineNumber": "slate",
+    "diffAddedLineNumberBg": "addedLineBg",
+    "diffRemovedLineNumberBg": "removedLineBg",
+    "markdownText": "offWhite",
+    "markdownHeading": "offWhite",
+    "markdownLink": "blue",
+    "markdownLinkText": "mint",
+    "markdownCode": "typeBlue",
+    "markdownBlockQuote": "mint",
+    "markdownEmph": "slate",
+    "markdownStrong": "offWhite",
+    "markdownHorizontalRule": "textMuted",
+    "markdownListItem": "blue",
+    "markdownListEnumeration": "blue",
+    "markdownImage": "blue",
+    "markdownImageText": "mint",
+    "markdownCodeBlock": "blue",
+    "syntaxComment": "textMuted",
+    "syntaxKeyword": "text",
+    "syntaxFunction": "blue",
+    "syntaxVariable": "offWhite",
+    "syntaxString": "mint",
+    "syntaxNumber": "mint",
+    "syntaxType": "typeBlue",
+    "syntaxOperator": "typeBlue",
+    "syntaxPunctuation": "text"
+  }
+}

+ 223 - 0
packages/tui/test/theme/gallery/themes/solarized.json

@@ -0,0 +1,223 @@
+{
+  "$schema": "https://opencode.ai/theme.json",
+  "defs": {
+    "base03": "#002b36",
+    "base02": "#073642",
+    "base01": "#586e75",
+    "base00": "#657b83",
+    "base0": "#839496",
+    "base1": "#93a1a1",
+    "base2": "#eee8d5",
+    "base3": "#fdf6e3",
+    "yellow": "#b58900",
+    "orange": "#cb4b16",
+    "red": "#dc322f",
+    "magenta": "#d33682",
+    "violet": "#6c71c4",
+    "blue": "#268bd2",
+    "cyan": "#2aa198",
+    "green": "#859900"
+  },
+  "theme": {
+    "primary": {
+      "dark": "blue",
+      "light": "blue"
+    },
+    "secondary": {
+      "dark": "violet",
+      "light": "violet"
+    },
+    "accent": {
+      "dark": "cyan",
+      "light": "cyan"
+    },
+    "error": {
+      "dark": "red",
+      "light": "red"
+    },
+    "warning": {
+      "dark": "yellow",
+      "light": "yellow"
+    },
+    "success": {
+      "dark": "green",
+      "light": "green"
+    },
+    "info": {
+      "dark": "orange",
+      "light": "orange"
+    },
+    "text": {
+      "dark": "base0",
+      "light": "base00"
+    },
+    "textMuted": {
+      "dark": "base01",
+      "light": "base1"
+    },
+    "background": {
+      "dark": "base03",
+      "light": "base3"
+    },
+    "backgroundPanel": {
+      "dark": "base02",
+      "light": "base2"
+    },
+    "backgroundElement": {
+      "dark": "#073642",
+      "light": "#eee8d5"
+    },
+    "border": {
+      "dark": "base02",
+      "light": "base2"
+    },
+    "borderActive": {
+      "dark": "base01",
+      "light": "base1"
+    },
+    "borderSubtle": {
+      "dark": "#073642",
+      "light": "#eee8d5"
+    },
+    "diffAdded": {
+      "dark": "green",
+      "light": "green"
+    },
+    "diffRemoved": {
+      "dark": "red",
+      "light": "red"
+    },
+    "diffContext": {
+      "dark": "base01",
+      "light": "base1"
+    },
+    "diffHunkHeader": {
+      "dark": "base01",
+      "light": "base1"
+    },
+    "diffHighlightAdded": {
+      "dark": "green",
+      "light": "green"
+    },
+    "diffHighlightRemoved": {
+      "dark": "red",
+      "light": "red"
+    },
+    "diffAddedBg": {
+      "dark": "#073642",
+      "light": "#eee8d5"
+    },
+    "diffRemovedBg": {
+      "dark": "#073642",
+      "light": "#eee8d5"
+    },
+    "diffContextBg": {
+      "dark": "base02",
+      "light": "base2"
+    },
+    "diffLineNumber": {
+      "dark": "#8b9b9f",
+      "light": "#5f6969"
+    },
+    "diffAddedLineNumberBg": {
+      "dark": "#073642",
+      "light": "#eee8d5"
+    },
+    "diffRemovedLineNumberBg": {
+      "dark": "#073642",
+      "light": "#eee8d5"
+    },
+    "markdownText": {
+      "dark": "base0",
+      "light": "base00"
+    },
+    "markdownHeading": {
+      "dark": "blue",
+      "light": "blue"
+    },
+    "markdownLink": {
+      "dark": "cyan",
+      "light": "cyan"
+    },
+    "markdownLinkText": {
+      "dark": "violet",
+      "light": "violet"
+    },
+    "markdownCode": {
+      "dark": "green",
+      "light": "green"
+    },
+    "markdownBlockQuote": {
+      "dark": "base01",
+      "light": "base1"
+    },
+    "markdownEmph": {
+      "dark": "yellow",
+      "light": "yellow"
+    },
+    "markdownStrong": {
+      "dark": "orange",
+      "light": "orange"
+    },
+    "markdownHorizontalRule": {
+      "dark": "base01",
+      "light": "base1"
+    },
+    "markdownListItem": {
+      "dark": "blue",
+      "light": "blue"
+    },
+    "markdownListEnumeration": {
+      "dark": "cyan",
+      "light": "cyan"
+    },
+    "markdownImage": {
+      "dark": "cyan",
+      "light": "cyan"
+    },
+    "markdownImageText": {
+      "dark": "violet",
+      "light": "violet"
+    },
+    "markdownCodeBlock": {
+      "dark": "base0",
+      "light": "base00"
+    },
+    "syntaxComment": {
+      "dark": "base01",
+      "light": "base1"
+    },
+    "syntaxKeyword": {
+      "dark": "green",
+      "light": "green"
+    },
+    "syntaxFunction": {
+      "dark": "blue",
+      "light": "blue"
+    },
+    "syntaxVariable": {
+      "dark": "cyan",
+      "light": "cyan"
+    },
+    "syntaxString": {
+      "dark": "cyan",
+      "light": "cyan"
+    },
+    "syntaxNumber": {
+      "dark": "magenta",
+      "light": "magenta"
+    },
+    "syntaxType": {
+      "dark": "yellow",
+      "light": "yellow"
+    },
+    "syntaxOperator": {
+      "dark": "green",
+      "light": "green"
+    },
+    "syntaxPunctuation": {
+      "dark": "base0",
+      "light": "base00"
+    }
+  }
+}

Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor