mixdog 0.9.0 → 0.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (240) hide show
  1. package/package.json +10 -3
  2. package/scripts/_bench-cwc.json +20 -0
  3. package/scripts/agent-loop-policy-test.mjs +37 -0
  4. package/scripts/agent-parallel-smoke.mjs +54 -10
  5. package/scripts/background-task-meta-smoke.mjs +1 -1
  6. package/scripts/bench-run.mjs +262 -0
  7. package/scripts/compact-smoke.mjs +12 -0
  8. package/scripts/compact-trigger-migration-smoke.mjs +67 -1
  9. package/scripts/ingest-pure-conversation-smoke.mjs +148 -0
  10. package/scripts/internal-comms-bench.mjs +727 -0
  11. package/scripts/internal-comms-smoke.mjs +75 -0
  12. package/scripts/lead-workflow-smoke.mjs +4 -4
  13. package/scripts/live-worker-smoke.mjs +9 -9
  14. package/scripts/output-style-bench.mjs +285 -0
  15. package/scripts/output-style-smoke.mjs +13 -10
  16. package/scripts/patch-replay.mjs +90 -0
  17. package/scripts/provider-stream-stall-test.mjs +276 -0
  18. package/scripts/provider-toolcall-test.mjs +599 -1
  19. package/scripts/routing-corpus.mjs +281 -0
  20. package/scripts/session-bench.mjs +1526 -0
  21. package/scripts/session-diag.mjs +595 -0
  22. package/scripts/session-ingest-smoke.mjs +2 -2
  23. package/scripts/task-bench.mjs +207 -0
  24. package/scripts/tool-failures.mjs +6 -6
  25. package/scripts/tool-smoke.mjs +306 -66
  26. package/scripts/toolcall-args-test.mjs +81 -0
  27. package/src/agents/debugger/AGENT.md +4 -4
  28. package/src/agents/heavy-worker/AGENT.md +4 -2
  29. package/src/agents/reviewer/AGENT.md +4 -4
  30. package/src/agents/worker/AGENT.md +4 -2
  31. package/src/app.mjs +10 -6
  32. package/src/defaults/{hidden-roles.json → agents.json} +7 -7
  33. package/src/examples/schedules/SCHEDULE.example.md +32 -0
  34. package/src/examples/webhooks/WEBHOOK.example.md +40 -0
  35. package/src/headless-role.mjs +14 -14
  36. package/src/help.mjs +1 -0
  37. package/src/lib/mixdog-debug.cjs +0 -22
  38. package/src/lib/plugin-paths.cjs +1 -7
  39. package/src/lib/rules-builder.cjs +34 -56
  40. package/src/mixdog-session-runtime.mjs +710 -319
  41. package/src/output-styles/default.md +12 -7
  42. package/src/output-styles/minimal.md +25 -0
  43. package/src/output-styles/oneline.md +21 -0
  44. package/src/output-styles/simple.md +10 -9
  45. package/src/repl.mjs +12 -4
  46. package/src/rules/agent/00-common.md +7 -5
  47. package/src/rules/agent/30-explorer.md +7 -8
  48. package/src/rules/lead/01-general.md +3 -1
  49. package/src/rules/lead/lead-tool.md +7 -0
  50. package/src/rules/shared/01-tool.md +17 -12
  51. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs +90 -32
  52. package/src/runtime/agent/orchestrator/agent-runtime/agent-loop-policy.mjs +32 -0
  53. package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +18 -6
  54. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +23 -20
  55. package/src/runtime/agent/orchestrator/agent-runtime/session-builder.mjs +48 -14
  56. package/src/runtime/agent/orchestrator/agent-trace.mjs +87 -12
  57. package/src/runtime/agent/orchestrator/config.mjs +3 -0
  58. package/src/runtime/agent/orchestrator/context/collect.mjs +131 -67
  59. package/src/runtime/agent/orchestrator/{internal-roles.mjs → internal-agents.mjs} +72 -72
  60. package/src/runtime/agent/orchestrator/internal-tools.mjs +13 -26
  61. package/src/runtime/agent/orchestrator/mcp/client.mjs +94 -16
  62. package/src/runtime/agent/orchestrator/providers/anthropic-betas.mjs +7 -0
  63. package/src/runtime/agent/orchestrator/providers/anthropic-effort.mjs +188 -0
  64. package/src/runtime/agent/orchestrator/providers/anthropic-leaked-toolcall.mjs +444 -0
  65. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +359 -106
  66. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +63 -51
  67. package/src/runtime/agent/orchestrator/providers/api-usage.mjs +27 -20
  68. package/src/runtime/agent/orchestrator/providers/gemini.mjs +184 -17
  69. package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +8 -1
  70. package/src/runtime/agent/orchestrator/providers/model-catalog.mjs +18 -8
  71. package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +210 -21
  72. package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +86 -30
  73. package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +254 -280
  74. package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +191 -50
  75. package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +18 -0
  76. package/src/runtime/agent/orchestrator/providers/opencode-go-usage.mjs +11 -5
  77. package/src/runtime/agent/orchestrator/providers/registry.mjs +2 -1
  78. package/src/runtime/agent/orchestrator/providers/retry-classifier.mjs +265 -1
  79. package/src/runtime/agent/orchestrator/session/compact.mjs +560 -51
  80. package/src/runtime/agent/orchestrator/session/context-utils.mjs +250 -3
  81. package/src/runtime/agent/orchestrator/session/loop.mjs +394 -132
  82. package/src/runtime/agent/orchestrator/session/manager.mjs +217 -170
  83. package/src/runtime/agent/orchestrator/session/store.mjs +4 -4
  84. package/src/runtime/agent/orchestrator/session/tool-envelope.mjs +61 -0
  85. package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +5 -0
  86. package/src/runtime/agent/orchestrator/stall-policy.mjs +63 -15
  87. package/src/runtime/agent/orchestrator/tools/bash-session.mjs +1 -1
  88. package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +194 -32
  89. package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.test.mjs +143 -0
  90. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +1 -44
  91. package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +34 -18
  92. package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.mjs +0 -0
  93. package/src/runtime/agent/orchestrator/tools/builtin/list-formatting.mjs +10 -0
  94. package/src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs +5 -4
  95. package/src/runtime/agent/orchestrator/tools/builtin/path-utils.mjs +15 -0
  96. package/src/runtime/agent/orchestrator/tools/builtin/read-args.mjs +9 -44
  97. package/src/runtime/agent/orchestrator/tools/builtin/read-constants.mjs +2 -1
  98. package/src/runtime/agent/orchestrator/tools/builtin/read-formatting.mjs +13 -4
  99. package/src/runtime/agent/orchestrator/tools/builtin/read-tool.mjs +10 -17
  100. package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +18 -2
  101. package/src/runtime/agent/orchestrator/tools/builtin/shell-output.mjs +3 -2
  102. package/src/runtime/agent/orchestrator/tools/builtin/tool-output-limit.mjs +10 -0
  103. package/src/runtime/agent/orchestrator/tools/builtin.mjs +59 -1
  104. package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +5 -5
  105. package/src/runtime/agent/orchestrator/tools/code-graph.mjs +4076 -3985
  106. package/src/runtime/agent/orchestrator/tools/patch.mjs +116 -2
  107. package/src/runtime/channels/backends/discord.mjs +99 -9
  108. package/src/runtime/channels/backends/telegram.mjs +501 -0
  109. package/src/runtime/channels/index.mjs +441 -1254
  110. package/src/runtime/channels/lib/cli-worker-host.mjs +1 -8
  111. package/src/runtime/channels/lib/config.mjs +54 -3
  112. package/src/runtime/channels/lib/drop-trace.mjs +1 -1
  113. package/src/runtime/channels/lib/executor.mjs +0 -3
  114. package/src/runtime/channels/lib/format.mjs +4 -2
  115. package/src/runtime/channels/lib/memory-client.mjs +0 -38
  116. package/src/runtime/channels/lib/output-forwarder.mjs +77 -71
  117. package/src/runtime/channels/lib/runtime-paths.mjs +29 -6
  118. package/src/runtime/channels/lib/scheduler.mjs +1 -1
  119. package/src/runtime/channels/lib/session-discovery.mjs +0 -4
  120. package/src/runtime/channels/lib/telegram-format.mjs +283 -0
  121. package/src/runtime/channels/lib/tool-format.mjs +1 -2
  122. package/src/runtime/channels/lib/transcript-discovery.mjs +20 -11
  123. package/src/runtime/channels/lib/webhook.mjs +59 -31
  124. package/src/runtime/channels/tool-defs.mjs +1 -1
  125. package/src/runtime/lib/keychain-cjs.cjs +0 -1
  126. package/src/runtime/memory/data/runtime-manifest.json +6 -7
  127. package/src/runtime/memory/index.mjs +187 -43
  128. package/src/runtime/memory/lib/agent-ipc.mjs +2 -2
  129. package/src/runtime/memory/lib/core-memory-store.mjs +1 -1
  130. package/src/runtime/memory/lib/llm-worker-host.mjs +0 -4
  131. package/src/runtime/memory/lib/memory-cycle1.mjs +1 -1
  132. package/src/runtime/memory/lib/memory-cycle2.mjs +9 -6
  133. package/src/runtime/memory/lib/memory-cycle3.mjs +1 -1
  134. package/src/runtime/memory/lib/memory-ops-policy.mjs +0 -1
  135. package/src/runtime/memory/lib/memory.mjs +101 -4
  136. package/src/runtime/memory/lib/pg/adapter.mjs +139 -15
  137. package/src/runtime/memory/lib/runtime-fetcher.mjs +43 -18
  138. package/src/runtime/memory/lib/session-ingest.mjs +116 -7
  139. package/src/runtime/memory/lib/trace-store.mjs +69 -22
  140. package/src/runtime/memory/tool-defs.mjs +6 -3
  141. package/src/runtime/search/index.mjs +2 -7
  142. package/src/runtime/search/lib/config.mjs +0 -4
  143. package/src/runtime/search/lib/state.mjs +1 -15
  144. package/src/runtime/search/lib/web-tools.mjs +0 -1
  145. package/src/runtime/shared/channel-notification-routing.mjs +12 -0
  146. package/src/runtime/shared/channel-notification-routing.test.mjs +45 -0
  147. package/src/runtime/shared/child-spawn-gate.mjs +0 -6
  148. package/src/runtime/shared/config.mjs +9 -0
  149. package/src/runtime/shared/llm/http-agent.mjs +12 -5
  150. package/src/runtime/shared/schedules-store.mjs +21 -19
  151. package/src/runtime/shared/tool-surface.mjs +98 -13
  152. package/src/runtime/shared/transcript-writer.mjs +129 -0
  153. package/src/runtime/shared/update-checker.mjs +214 -0
  154. package/src/standalone/agent-tool.mjs +255 -109
  155. package/src/standalone/channel-admin.mjs +133 -40
  156. package/src/standalone/channel-worker.mjs +8 -291
  157. package/src/standalone/explore-tool.mjs +2 -2
  158. package/src/standalone/memory-runtime-proxy.mjs +3 -1
  159. package/src/standalone/provider-admin.mjs +11 -0
  160. package/src/standalone/seeds.mjs +1 -11
  161. package/src/standalone/usage-dashboard.mjs +1 -1
  162. package/src/tui/App.jsx +2137 -750
  163. package/src/tui/components/ConfirmBar.jsx +47 -0
  164. package/src/tui/components/ContextPanel.jsx +5 -3
  165. package/src/tui/components/ItemRightHintOverprint.jsx +54 -0
  166. package/src/tui/components/Markdown.jsx +22 -98
  167. package/src/tui/components/Message.jsx +14 -35
  168. package/src/tui/components/Picker.jsx +87 -12
  169. package/src/tui/components/PromptInput.jsx +146 -9
  170. package/src/tui/components/QueuedCommands.jsx +1 -1
  171. package/src/tui/components/SlashCommandPalette.jsx +8 -5
  172. package/src/tui/components/Spinner.jsx +7 -7
  173. package/src/tui/components/StatusLine.jsx +40 -21
  174. package/src/tui/components/TextEntryPanel.jsx +51 -7
  175. package/src/tui/components/ToolExecution.jsx +177 -100
  176. package/src/tui/components/TurnDone.jsx +4 -4
  177. package/src/tui/components/UsagePanel.jsx +1 -1
  178. package/src/tui/components/tool-output-format.mjs +312 -40
  179. package/src/tui/components/tool-output-format.test.mjs +180 -1
  180. package/src/tui/display-width.mjs +69 -0
  181. package/src/tui/display-width.test.mjs +35 -0
  182. package/src/tui/dist/index.mjs +7324 -2393
  183. package/src/tui/engine.mjs +287 -126
  184. package/src/tui/index.jsx +117 -7
  185. package/src/tui/keyboard-protocol.mjs +42 -0
  186. package/src/tui/lib/voice-recorder.mjs +453 -0
  187. package/src/tui/markdown/format-token.mjs +354 -142
  188. package/src/tui/markdown/format-token.test.mjs +155 -17
  189. package/src/tui/markdown/measure-rendered-rows.mjs +85 -0
  190. package/src/tui/markdown/render-ansi.test.mjs +1 -1
  191. package/src/tui/markdown/streaming-markdown.mjs +167 -0
  192. package/src/tui/markdown/streaming-markdown.test.mjs +70 -0
  193. package/src/tui/markdown/table-layout.mjs +9 -9
  194. package/src/tui/paste-attachments.mjs +0 -11
  195. package/src/tui/prompt-history-store.mjs +129 -0
  196. package/src/tui/prompt-history-store.test.mjs +52 -0
  197. package/src/tui/statusline-ansi-bridge.test.mjs +3 -3
  198. package/src/tui/theme.mjs +41 -647
  199. package/src/tui/themes/base.mjs +86 -0
  200. package/src/tui/themes/basic.mjs +85 -0
  201. package/src/tui/themes/catppuccin.mjs +72 -0
  202. package/src/tui/themes/dracula.mjs +70 -0
  203. package/src/tui/themes/everforest.mjs +71 -0
  204. package/src/tui/themes/gruvbox.mjs +71 -0
  205. package/src/tui/themes/index.mjs +71 -0
  206. package/src/tui/themes/indigo.mjs +78 -0
  207. package/src/tui/themes/kanagawa.mjs +80 -0
  208. package/src/tui/themes/light.mjs +81 -0
  209. package/src/tui/themes/nord.mjs +72 -0
  210. package/src/tui/themes/onedark.mjs +16 -0
  211. package/src/tui/themes/rosepine.mjs +70 -0
  212. package/src/tui/themes/teal.mjs +81 -0
  213. package/src/tui/themes/tokyonight.mjs +79 -0
  214. package/src/tui/themes/utils.mjs +106 -0
  215. package/src/tui/themes/warm.mjs +79 -0
  216. package/src/tui/transcript-tool-failures.mjs +13 -2
  217. package/src/ui/markdown.mjs +1 -1
  218. package/src/ui/model-display.mjs +2 -2
  219. package/src/ui/statusline.mjs +26 -27
  220. package/src/vendor/statusline/bin/statusline-lib.mjs +0 -623
  221. package/src/vendor/statusline/bin/statusline-route.mjs +5 -12
  222. package/src/vendor/statusline/src/gateway/claude-current.mjs +3 -3
  223. package/src/vendor/statusline/src/gateway/route-meta.mjs +30 -16
  224. package/src/workflows/default/WORKFLOW.md +39 -12
  225. package/src/workflows/sequential/WORKFLOW.md +46 -0
  226. package/src/workflows/solo/WORKFLOW.md +7 -0
  227. package/vendor/ink/build/display-width.js +62 -0
  228. package/vendor/ink/build/ink.js +154 -20
  229. package/vendor/ink/build/measure-text.js +4 -1
  230. package/vendor/ink/build/output.js +115 -9
  231. package/vendor/ink/build/render-node-to-output.js +4 -1
  232. package/vendor/ink/build/render.js +4 -0
  233. package/src/hooks/lib/permission-rules.cjs +0 -170
  234. package/src/hooks/lib/settings-loader.cjs +0 -112
  235. package/src/lib/hook-pipe-path.cjs +0 -10
  236. package/src/output-styles/extreme-simple.md +0 -20
  237. package/src/rules/lead/04-workflow.md +0 -51
  238. package/src/runtime/channels/lib/hook-pipe-server.mjs +0 -671
  239. package/src/workflows/default/workflow.json +0 -13
  240. package/src/workflows/solo/workflow.json +0 -7
package/src/tui/theme.mjs CHANGED
@@ -1,9 +1,15 @@
1
1
  /**
2
- * src/tui/theme.mjs — active-theme registry for the React/ink TUI.
2
+ * src/tui/theme.mjs — active-theme runtime for the React/ink TUI.
3
3
  *
4
4
  * ink accepts `rgb(r,g,b)` strings directly on the `color`/`backgroundColor`
5
- * props, so these are plain strings (no escape wrapping needed — ink emits the
6
- * SGR and honors NO_COLOR/non-TTY itself).
5
+ * props, so palette values are plain strings (no escape wrapping needed — ink
6
+ * emits the SGR and honors NO_COLOR/non-TTY itself).
7
+ *
8
+ * Palettes now live in `./themes/*.mjs`: `themes/base.mjs` holds the full
9
+ * One Dark key set, each theme module spreads that base plus its overrides, and
10
+ * `themes/index.mjs` wires them into THEME_REGISTRY / THEME_ORDER /
11
+ * DEFAULT_THEME_ID. This module keeps only the runtime: the live singleton and
12
+ * the switch/persistence/glyph logic.
7
13
  *
8
14
  * The exported `theme` is a SINGLETON object: every TUI module does
9
15
  * `import { theme } from '../theme.mjs'` and reads live keys off it. A theme
@@ -18,652 +24,20 @@
18
24
  * static keychain/config dependency.
19
25
  */
20
26
 
21
- // ── Palettes ──────────────────────────────────────────────────────────────
22
- // Each palette is a COMPLETE set of theme keys. Non-default palettes spread the
23
- // Mixdog base first so a missing key can never leak the previous theme's color
24
- // through Object.assign.
25
-
26
- /** Default Mixdog dark palette (preserves the original colors verbatim). */
27
- const mixdogPalette = {
28
- background: 'rgb(13,13,13)', // opaque TUI surface; masks clipped scrollback behind fixed rows
29
- claude: 'rgb(215,119,87)', // orange title/header accent
30
- claudeShimmer: 'rgb(235,159,127)',
31
- mixdogOrange: 'rgb(215,119,87)',
32
- mixdogAmber: 'rgb(235,159,127)',
33
- mixdogIvory: 'rgb(232,226,215)',
34
- spinnerGlyph: 'rgb(215,119,87)',
35
- spinnerText: 'rgb(215,119,87)',
36
- spinnerShimmer: 'rgb(255,214,186)',
37
- thinkingAccent: 'rgb(168,168,168)',
38
- thinkingText: 'rgb(198,198,198)', // live reasoning body text
39
- thinkingBase: 'rgb(168,168,168)', // quiet base; thinking rows should not compete with answers
40
- thinkingGlow: 'rgb(220,220,220)', // subtle highlight for the thinking shimmer
41
- statusText: 'rgb(198,198,198)',
42
- statusSubtle: 'rgb(168,168,168)',
43
- timerText: 'rgb(168,168,168)', // live elapsed timer — metadata weight, no bright accent
44
- text: 'rgb(198,198,198)', // primary text
45
- inverseText: 'rgb(0,0,0)', // text on an inverted (light) background
46
- selectionText: 'rgb(0,0,0)', // text inside an active drag/copy selection
47
- selectionBackground: 'rgb(245,245,245)', // selection highlight band
48
- inactive: 'rgb(136,136,136)', // secondary text
49
- subtle: 'rgb(140,140,140)', // helper text / quiet rules
50
- promptBorder: 'rgb(158,158,158)', // input border / prompt
51
- success: 'rgb(28,150,78)', // muted green accent
52
- error: 'rgb(210,60,76)', // muted red accent
53
- warning: 'rgb(204,157,44)', // muted amber
54
- suggestion: 'rgb(47,127,255)', // path/link blue
55
- panelTitle: 'rgb(215,119,87)', // panel/picker titles stay orange
56
- permission: 'rgb(239,68,88)', // permission red
57
- code: 'rgb(47,127,255)', // inline code/link accent
58
- codeBlock: 'rgb(136,190,142)', // code block body
59
- // Markdown (pi dark.json md* tokens — headings/code/quotes only in format-token)
60
- mdHeading: 'rgb(240,198,116)', // #f0c674 warm yellow-beige
61
- mdCode: 'rgb(138,190,183)', // #8abeb7 muted teal (inline codespan)
62
- mdCodeBlock: 'rgb(181,189,104)', // #b5bd68 muted green (fenced blocks)
63
- mdQuote: 'rgb(128,128,128)', // #808080 quote body
64
- mdQuoteBorder: 'rgb(128,128,128)', // blockquote bar
65
- mdHr: 'rgb(128,128,128)', // horizontal rule
66
- mdListBullet: 'rgb(138,190,183)', // list markers (pi accent)
67
- // Markdown extras (fenced fences / inline links / emphasis) — warm dark base.
68
- mdCodeBlockBorder: 'rgb(110,110,110)', // ``` fence + lang label rule
69
- mdCodeBlockBg: 'rgb(34,35,40)', // code-block background band (distinct from bg)
70
- mdLink: 'rgb(47,127,255)', // link URL (suggestion blue)
71
- mdLinkText: 'rgb(138,190,183)', // link label (teal accent)
72
- mdStrong: 'rgb(235,159,127)', // **bold** warm amber
73
- mdEmph: 'rgb(229,192,123)', // *italic* soft yellow
74
- // Diff / patch rendering (OpenCode + Codex conventions, ANSI-safe).
75
- mdDiffAdded: 'rgb(120,200,130)', // + lines (green)
76
- mdDiffRemoved: 'rgb(224,108,117)', // - lines (red)
77
- mdDiffHunk: 'rgb(130,139,184)', // @@ hunk markers
78
- mdDiffHeader: 'rgb(170,150,210)', // ---/+++ / diff --git headers
79
- mdDiffContext: 'rgb(140,140,140)', // unchanged context lines
80
- mdDiffAddedBg: 'rgb(33,58,43)', // #213A2B muted add tint (codex dark)
81
- mdDiffRemovedBg: 'rgb(74,34,29)', // #4A221D muted del tint (codex dark)
82
- // Lightweight syntax highlight palette (regex token classes).
83
- syntaxComment: 'rgb(128,128,128)',
84
- syntaxKeyword: 'rgb(215,119,87)', // brand orange
85
- syntaxFunction: 'rgb(138,190,183)', // teal
86
- syntaxVariable: 'rgb(224,108,117)', // red-pink
87
- syntaxString: 'rgb(181,189,104)', // #b5bd68 green
88
- syntaxNumber: 'rgb(235,159,127)', // amber
89
- syntaxType: 'rgb(229,192,123)', // yellow
90
- syntaxOperator: 'rgb(138,190,183)', // teal/cyan
91
- syntaxPunctuation: 'rgb(198,198,198)', // body text
92
- userMessageBackground: 'rgb(108,108,108)', // user prompt band
93
- userMessageBackgroundHover: 'rgb(120,120,120)', // hover variant
94
- fastMode: 'rgb(255,120,20)',
95
- };
96
-
97
- /** Teal dark — teal accent, soft body. */
98
- const piDarkPalette = {
99
- ...mixdogPalette,
100
- claude: 'rgb(138,190,183)', // pi accent teal as the title/header accent
101
- claudeShimmer: 'rgb(170,214,208)',
102
- spinnerGlyph: 'rgb(138,190,183)',
103
- spinnerText: 'rgb(138,190,183)',
104
- spinnerShimmer: 'rgb(170,214,208)',
105
- panelTitle: 'rgb(138,190,183)',
106
- thinkingText: 'rgb(190,190,190)',
107
- statusText: 'rgb(212,212,212)',
108
- text: 'rgb(212,212,212)', // #d4d4d4
109
- promptBorder: 'rgb(120,128,140)',
110
- success: 'rgb(181,189,104)', // #b5bd68
111
- error: 'rgb(204,102,102)', // #cc6666
112
- warning: 'rgb(255,255,0)', // #ffff00
113
- suggestion: 'rgb(95,135,255)', // #5f87ff
114
- permission: 'rgb(204,102,102)',
115
- selectionText: 'rgb(26,27,33)',
116
- selectionBackground: 'rgb(212,212,212)',
117
- code: 'rgb(95,135,255)',
118
- codeBlock: 'rgb(181,189,104)',
119
- mdCodeBlockBorder: 'rgb(96,104,116)',
120
- mdCodeBlockBg: 'rgb(32,36,44)',
121
- mdLink: 'rgb(95,135,255)',
122
- mdLinkText: 'rgb(138,190,183)',
123
- mdStrong: 'rgb(181,189,104)',
124
- mdEmph: 'rgb(229,192,123)',
125
- mdDiffAdded: 'rgb(181,189,104)', // #b5bd68
126
- mdDiffRemoved: 'rgb(204,102,102)', // #cc6666
127
- mdDiffHunk: 'rgb(129,162,190)',
128
- mdDiffHeader: 'rgb(178,148,187)',
129
- mdDiffContext: 'rgb(150,150,150)',
130
- mdDiffAddedBg: 'rgb(30,46,34)',
131
- mdDiffRemovedBg: 'rgb(58,32,32)',
132
- syntaxKeyword: 'rgb(178,148,187)', // pi mauve keyword
133
- syntaxFunction: 'rgb(129,162,190)', // soft blue
134
- syntaxString: 'rgb(181,189,104)',
135
- syntaxNumber: 'rgb(222,147,95)',
136
- syntaxOperator: 'rgb(138,190,183)',
137
- userMessageBackground: 'rgb(52,53,65)', // #343541
138
- userMessageBackgroundHover: 'rgb(64,65,79)',
139
- };
140
-
141
- /** Warm dark — orange accent, bright body text. */
142
- const claudeDarkPalette = {
143
- ...mixdogPalette,
144
- background: 'rgb(13,13,13)', // keep the opaque dark surface (Claude's bg is decorative)
145
- claude: 'rgb(215,119,87)',
146
- claudeShimmer: 'rgb(235,159,127)',
147
- spinnerGlyph: 'rgb(215,119,87)',
148
- spinnerText: 'rgb(215,119,87)',
149
- spinnerShimmer: 'rgb(255,214,186)',
150
- panelTitle: 'rgb(215,119,87)',
151
- text: 'rgb(235,235,235)',
152
- thinkingText: 'rgb(200,200,200)',
153
- thinkingBase: 'rgb(153,153,153)',
154
- thinkingGlow: 'rgb(225,225,225)',
155
- statusText: 'rgb(220,220,220)',
156
- statusSubtle: 'rgb(150,150,150)',
157
- timerText: 'rgb(150,150,150)',
158
- inactive: 'rgb(153,153,153)',
159
- subtle: 'rgb(120,120,120)',
160
- promptBorder: 'rgb(136,136,136)',
161
- success: 'rgb(78,186,101)',
162
- error: 'rgb(255,107,128)',
163
- warning: 'rgb(255,193,7)',
164
- suggestion: 'rgb(177,185,249)', // blue-purple
165
- permission: 'rgb(177,185,249)',
166
- selectionText: 'rgb(13,13,13)',
167
- selectionBackground: 'rgb(235,235,235)',
168
- code: 'rgb(177,185,249)',
169
- codeBlock: 'rgb(200,200,200)', // plain code body (no brand coloring)
170
- mdHeading: 'rgb(235,159,127)', // warm heading accent
171
- mdCode: 'rgb(177,185,249)', // inline codespan = permission/suggestion blue-purple
172
- mdCodeBlock: 'rgb(200,200,200)', // fenced blocks stay plain
173
- mdQuote: 'rgb(140,140,140)',
174
- mdQuoteBorder: 'rgb(140,140,140)',
175
- mdHr: 'rgb(140,140,140)',
176
- mdListBullet: 'rgb(177,185,249)',
177
- mdCodeBlockBorder: 'rgb(120,120,120)',
178
- mdCodeBlockBg: 'rgb(34,35,40)',
179
- mdLink: 'rgb(177,185,249)',
180
- mdLinkText: 'rgb(150,200,210)',
181
- mdStrong: 'rgb(235,159,127)',
182
- mdEmph: 'rgb(229,192,123)',
183
- mdDiffAdded: 'rgb(78,186,101)',
184
- mdDiffRemoved: 'rgb(255,107,128)',
185
- mdDiffHunk: 'rgb(150,160,200)',
186
- mdDiffHeader: 'rgb(177,185,249)',
187
- mdDiffContext: 'rgb(150,150,150)',
188
- mdDiffAddedBg: 'rgb(28,46,34)',
189
- mdDiffRemovedBg: 'rgb(58,30,36)',
190
- syntaxComment: 'rgb(140,140,140)',
191
- syntaxKeyword: 'rgb(235,159,127)',
192
- syntaxFunction: 'rgb(177,185,249)',
193
- syntaxVariable: 'rgb(255,107,128)',
194
- syntaxString: 'rgb(140,200,150)',
195
- syntaxNumber: 'rgb(235,159,127)',
196
- syntaxType: 'rgb(229,192,123)',
197
- syntaxOperator: 'rgb(150,200,210)',
198
- syntaxPunctuation: 'rgb(220,220,220)',
199
- userMessageBackground: 'rgb(55,55,55)',
200
- userMessageBackgroundHover: 'rgb(70,70,70)',
201
- fastMode: 'rgb(255,120,20)',
202
- };
203
-
204
- /** Violet dark — classic purple/pink/cyan contrast. */
205
- const draculaPalette = {
206
- ...mixdogPalette,
207
- background: 'rgb(40,42,54)',
208
- claude: 'rgb(189,147,249)', // purple
209
- claudeShimmer: 'rgb(212,182,251)',
210
- spinnerGlyph: 'rgb(189,147,249)',
211
- spinnerText: 'rgb(189,147,249)',
212
- spinnerShimmer: 'rgb(212,182,251)',
213
- panelTitle: 'rgb(189,147,249)',
214
- text: 'rgb(248,248,242)',
215
- thinkingText: 'rgb(180,180,200)',
216
- thinkingBase: 'rgb(98,114,164)',
217
- thinkingGlow: 'rgb(220,220,235)',
218
- statusText: 'rgb(230,230,235)',
219
- statusSubtle: 'rgb(98,114,164)',
220
- timerText: 'rgb(98,114,164)',
221
- inactive: 'rgb(98,114,164)',
222
- subtle: 'rgb(98,114,164)',
223
- promptBorder: 'rgb(98,114,164)',
224
- success: 'rgb(80,250,123)', // green
225
- error: 'rgb(255,85,85)', // red
226
- warning: 'rgb(241,250,140)', // yellow
227
- suggestion: 'rgb(139,233,253)', // cyan
228
- permission: 'rgb(255,85,85)',
229
- selectionText: 'rgb(40,42,54)',
230
- selectionBackground: 'rgb(248,248,242)',
231
- code: 'rgb(139,233,253)',
232
- codeBlock: 'rgb(248,248,242)',
233
- mdHeading: 'rgb(189,147,249)',
234
- mdCode: 'rgb(80,250,123)',
235
- mdCodeBlock: 'rgb(248,248,242)',
236
- mdQuote: 'rgb(98,114,164)',
237
- mdQuoteBorder: 'rgb(98,114,164)',
238
- mdHr: 'rgb(98,114,164)',
239
- mdListBullet: 'rgb(189,147,249)',
240
- mdCodeBlockBorder: 'rgb(68,71,90)',
241
- mdCodeBlockBg: 'rgb(60,63,79)',
242
- mdLink: 'rgb(139,233,253)',
243
- mdLinkText: 'rgb(255,121,198)', // pink
244
- mdStrong: 'rgb(255,184,108)', // orange
245
- mdEmph: 'rgb(241,250,140)',
246
- mdDiffAdded: 'rgb(80,250,123)',
247
- mdDiffRemoved: 'rgb(255,85,85)',
248
- mdDiffHunk: 'rgb(98,114,164)',
249
- mdDiffHeader: 'rgb(255,121,198)',
250
- mdDiffContext: 'rgb(98,114,164)',
251
- mdDiffAddedBg: 'rgb(26,58,26)',
252
- mdDiffRemovedBg: 'rgb(58,26,26)',
253
- syntaxComment: 'rgb(98,114,164)',
254
- syntaxKeyword: 'rgb(255,121,198)',
255
- syntaxFunction: 'rgb(80,250,123)',
256
- syntaxVariable: 'rgb(248,248,242)',
257
- syntaxString: 'rgb(241,250,140)',
258
- syntaxNumber: 'rgb(189,147,249)',
259
- syntaxType: 'rgb(139,233,253)',
260
- syntaxOperator: 'rgb(255,121,198)',
261
- syntaxPunctuation: 'rgb(248,248,242)',
262
- userMessageBackground: 'rgb(68,71,90)',
263
- userMessageBackgroundHover: 'rgb(82,85,104)',
264
- };
265
-
266
- /** Midnight dark — soft blue/purple contrast. */
267
- const tokyonightPalette = {
268
- ...mixdogPalette,
269
- background: 'rgb(26,27,38)',
270
- claude: 'rgb(130,170,255)', // blue
271
- claudeShimmer: 'rgb(170,198,255)',
272
- spinnerGlyph: 'rgb(130,170,255)',
273
- spinnerText: 'rgb(130,170,255)',
274
- spinnerShimmer: 'rgb(170,198,255)',
275
- panelTitle: 'rgb(130,170,255)',
276
- text: 'rgb(200,211,245)',
277
- thinkingText: 'rgb(170,180,210)',
278
- thinkingBase: 'rgb(130,139,184)',
279
- thinkingGlow: 'rgb(210,218,250)',
280
- statusText: 'rgb(200,211,245)',
281
- statusSubtle: 'rgb(130,139,184)',
282
- timerText: 'rgb(130,139,184)',
283
- inactive: 'rgb(130,139,184)',
284
- subtle: 'rgb(115,122,162)',
285
- promptBorder: 'rgb(115,122,162)',
286
- success: 'rgb(195,232,141)',
287
- error: 'rgb(255,117,127)',
288
- warning: 'rgb(255,150,108)',
289
- suggestion: 'rgb(130,170,255)',
290
- permission: 'rgb(255,117,127)',
291
- selectionText: 'rgb(26,27,38)',
292
- selectionBackground: 'rgb(200,211,245)',
293
- code: 'rgb(130,170,255)',
294
- codeBlock: 'rgb(200,211,245)',
295
- mdHeading: 'rgb(192,153,255)', // purple
296
- mdCode: 'rgb(195,232,141)', // green
297
- mdCodeBlock: 'rgb(200,211,245)',
298
- mdQuote: 'rgb(255,199,119)',
299
- mdQuoteBorder: 'rgb(130,139,184)',
300
- mdHr: 'rgb(130,139,184)',
301
- mdListBullet: 'rgb(130,170,255)',
302
- mdCodeBlockBorder: 'rgb(84,92,126)',
303
- mdCodeBlockBg: 'rgb(45,47,64)',
304
- mdLink: 'rgb(130,170,255)',
305
- mdLinkText: 'rgb(134,225,252)', // cyan
306
- mdStrong: 'rgb(255,150,108)', // orange
307
- mdEmph: 'rgb(255,199,119)', // yellow
308
- mdDiffAdded: 'rgb(79,214,190)',
309
- mdDiffRemoved: 'rgb(197,59,83)',
310
- mdDiffHunk: 'rgb(130,139,184)',
311
- mdDiffHeader: 'rgb(192,153,255)',
312
- mdDiffContext: 'rgb(130,139,184)',
313
- mdDiffAddedBg: 'rgb(32,48,59)',
314
- mdDiffRemovedBg: 'rgb(55,34,44)',
315
- syntaxComment: 'rgb(130,139,184)',
316
- syntaxKeyword: 'rgb(192,153,255)',
317
- syntaxFunction: 'rgb(130,170,255)',
318
- syntaxVariable: 'rgb(255,117,127)',
319
- syntaxString: 'rgb(195,232,141)',
320
- syntaxNumber: 'rgb(255,150,108)',
321
- syntaxType: 'rgb(255,199,119)',
322
- syntaxOperator: 'rgb(134,225,252)',
323
- syntaxPunctuation: 'rgb(200,211,245)',
324
- userMessageBackground: 'rgb(34,36,54)',
325
- userMessageBackgroundHover: 'rgb(46,49,71)',
326
- };
327
-
328
- /** Frost dark — cool arctic blue/teal contrast. */
329
- const nordPalette = {
330
- ...mixdogPalette,
331
- background: 'rgb(46,52,64)',
332
- claude: 'rgb(136,192,208)', // nord8 frost
333
- claudeShimmer: 'rgb(168,212,224)',
334
- spinnerGlyph: 'rgb(136,192,208)',
335
- spinnerText: 'rgb(136,192,208)',
336
- spinnerShimmer: 'rgb(168,212,224)',
337
- panelTitle: 'rgb(136,192,208)',
338
- text: 'rgb(236,239,244)',
339
- thinkingText: 'rgb(200,206,218)',
340
- thinkingBase: 'rgb(139,149,167)',
341
- thinkingGlow: 'rgb(226,230,238)',
342
- statusText: 'rgb(216,222,233)',
343
- statusSubtle: 'rgb(139,149,167)',
344
- timerText: 'rgb(139,149,167)',
345
- inactive: 'rgb(139,149,167)',
346
- subtle: 'rgb(118,128,146)',
347
- promptBorder: 'rgb(76,86,106)',
348
- success: 'rgb(163,190,140)',
349
- error: 'rgb(191,97,106)',
350
- warning: 'rgb(208,135,112)',
351
- suggestion: 'rgb(129,161,193)',
352
- permission: 'rgb(191,97,106)',
353
- selectionText: 'rgb(46,52,64)',
354
- selectionBackground: 'rgb(236,239,244)',
355
- code: 'rgb(129,161,193)',
356
- codeBlock: 'rgb(216,222,233)',
357
- mdHeading: 'rgb(136,192,208)',
358
- mdCode: 'rgb(163,190,140)',
359
- mdCodeBlock: 'rgb(216,222,233)',
360
- mdQuote: 'rgb(139,149,167)',
361
- mdQuoteBorder: 'rgb(139,149,167)',
362
- mdHr: 'rgb(139,149,167)',
363
- mdListBullet: 'rgb(136,192,208)',
364
- mdCodeBlockBorder: 'rgb(67,76,94)',
365
- mdCodeBlockBg: 'rgb(64,71,87)',
366
- mdLink: 'rgb(129,161,193)',
367
- mdLinkText: 'rgb(143,188,187)',
368
- mdStrong: 'rgb(235,203,139)',
369
- mdEmph: 'rgb(208,135,112)',
370
- mdDiffAdded: 'rgb(163,190,140)',
371
- mdDiffRemoved: 'rgb(191,97,106)',
372
- mdDiffHunk: 'rgb(139,149,167)',
373
- mdDiffHeader: 'rgb(180,142,173)',
374
- mdDiffContext: 'rgb(139,149,167)',
375
- mdDiffAddedBg: 'rgb(50,62,52)',
376
- mdDiffRemovedBg: 'rgb(70,52,56)',
377
- syntaxComment: 'rgb(139,149,167)',
378
- syntaxKeyword: 'rgb(129,161,193)',
379
- syntaxFunction: 'rgb(136,192,208)',
380
- syntaxVariable: 'rgb(143,188,187)',
381
- syntaxString: 'rgb(163,190,140)',
382
- syntaxNumber: 'rgb(180,142,173)',
383
- syntaxType: 'rgb(143,188,187)',
384
- syntaxOperator: 'rgb(129,161,193)',
385
- syntaxPunctuation: 'rgb(216,222,233)',
386
- userMessageBackground: 'rgb(67,76,94)',
387
- userMessageBackgroundHover: 'rgb(76,86,106)',
388
- };
389
-
390
- /** Earth dark — retro warm earthy contrast. */
391
- const gruvboxPalette = {
392
- ...mixdogPalette,
393
- background: 'rgb(40,40,40)',
394
- claude: 'rgb(131,165,152)', // blue-bright
395
- claudeShimmer: 'rgb(166,194,184)',
396
- spinnerGlyph: 'rgb(131,165,152)',
397
- spinnerText: 'rgb(131,165,152)',
398
- spinnerShimmer: 'rgb(166,194,184)',
399
- panelTitle: 'rgb(131,165,152)',
400
- text: 'rgb(235,219,178)',
401
- thinkingText: 'rgb(213,198,161)',
402
- thinkingBase: 'rgb(146,131,116)',
403
- thinkingGlow: 'rgb(240,228,196)',
404
- statusText: 'rgb(235,219,178)',
405
- statusSubtle: 'rgb(146,131,116)',
406
- timerText: 'rgb(146,131,116)',
407
- inactive: 'rgb(146,131,116)',
408
- subtle: 'rgb(146,131,116)',
409
- promptBorder: 'rgb(102,92,84)',
410
- success: 'rgb(184,187,38)',
411
- error: 'rgb(251,73,52)',
412
- warning: 'rgb(254,128,25)',
413
- suggestion: 'rgb(131,165,152)',
414
- permission: 'rgb(251,73,52)',
415
- selectionText: 'rgb(40,40,40)',
416
- selectionBackground: 'rgb(235,219,178)',
417
- code: 'rgb(142,192,124)',
418
- codeBlock: 'rgb(235,219,178)',
419
- mdHeading: 'rgb(131,165,152)',
420
- mdCode: 'rgb(250,189,47)',
421
- mdCodeBlock: 'rgb(235,219,178)',
422
- mdQuote: 'rgb(146,131,116)',
423
- mdQuoteBorder: 'rgb(146,131,116)',
424
- mdHr: 'rgb(146,131,116)',
425
- mdListBullet: 'rgb(131,165,152)',
426
- mdCodeBlockBorder: 'rgb(80,73,69)',
427
- mdCodeBlockBg: 'rgb(60,58,52)',
428
- mdLink: 'rgb(142,192,124)',
429
- mdLinkText: 'rgb(184,187,38)',
430
- mdStrong: 'rgb(254,128,25)',
431
- mdEmph: 'rgb(211,134,155)',
432
- mdDiffAdded: 'rgb(152,151,26)',
433
- mdDiffRemoved: 'rgb(204,36,29)',
434
- mdDiffHunk: 'rgb(104,157,106)',
435
- mdDiffHeader: 'rgb(211,134,155)',
436
- mdDiffContext: 'rgb(146,131,116)',
437
- mdDiffAddedBg: 'rgb(50,48,47)',
438
- mdDiffRemovedBg: 'rgb(50,41,41)',
439
- syntaxComment: 'rgb(146,131,116)',
440
- syntaxKeyword: 'rgb(251,73,52)',
441
- syntaxFunction: 'rgb(184,187,38)',
442
- syntaxVariable: 'rgb(131,165,152)',
443
- syntaxString: 'rgb(250,189,47)',
444
- syntaxNumber: 'rgb(211,134,155)',
445
- syntaxType: 'rgb(142,192,124)',
446
- syntaxOperator: 'rgb(254,128,25)',
447
- syntaxPunctuation: 'rgb(235,219,178)',
448
- userMessageBackground: 'rgb(80,73,69)',
449
- userMessageBackgroundHover: 'rgb(102,92,84)',
450
- };
451
-
452
- /** Pastel dark — gentle violet/blue contrast. */
453
- const catppuccinPalette = {
454
- ...mixdogPalette,
455
- background: 'rgb(30,30,46)',
456
- claude: 'rgb(137,180,250)', // blue
457
- claudeShimmer: 'rgb(180,190,254)',
458
- spinnerGlyph: 'rgb(137,180,250)',
459
- spinnerText: 'rgb(137,180,250)',
460
- spinnerShimmer: 'rgb(180,190,254)',
461
- panelTitle: 'rgb(137,180,250)',
462
- text: 'rgb(205,214,244)',
463
- thinkingText: 'rgb(186,194,222)',
464
- thinkingBase: 'rgb(147,153,178)',
465
- thinkingGlow: 'rgb(215,222,250)',
466
- statusText: 'rgb(205,214,244)',
467
- statusSubtle: 'rgb(147,153,178)',
468
- timerText: 'rgb(147,153,178)',
469
- inactive: 'rgb(147,153,178)',
470
- subtle: 'rgb(127,132,156)',
471
- promptBorder: 'rgb(88,91,112)',
472
- success: 'rgb(166,227,161)',
473
- error: 'rgb(243,139,168)',
474
- warning: 'rgb(249,226,175)',
475
- suggestion: 'rgb(137,180,250)',
476
- permission: 'rgb(243,139,168)',
477
- selectionText: 'rgb(30,30,46)',
478
- selectionBackground: 'rgb(205,214,244)',
479
- code: 'rgb(166,227,161)',
480
- codeBlock: 'rgb(205,214,244)',
481
- mdHeading: 'rgb(203,166,247)', // mauve
482
- mdCode: 'rgb(166,227,161)',
483
- mdCodeBlock: 'rgb(205,214,244)',
484
- mdQuote: 'rgb(249,226,175)',
485
- mdQuoteBorder: 'rgb(147,153,178)',
486
- mdHr: 'rgb(166,173,200)',
487
- mdListBullet: 'rgb(137,180,250)',
488
- mdCodeBlockBorder: 'rgb(49,50,68)',
489
- mdCodeBlockBg: 'rgb(49,50,68)',
490
- mdLink: 'rgb(137,180,250)',
491
- mdLinkText: 'rgb(137,220,235)', // sky
492
- mdStrong: 'rgb(250,179,135)', // peach
493
- mdEmph: 'rgb(249,226,175)',
494
- mdDiffAdded: 'rgb(166,227,161)',
495
- mdDiffRemoved: 'rgb(243,139,168)',
496
- mdDiffHunk: 'rgb(250,179,135)',
497
- mdDiffHeader: 'rgb(203,166,247)',
498
- mdDiffContext: 'rgb(147,153,178)',
499
- mdDiffAddedBg: 'rgb(36,49,43)',
500
- mdDiffRemovedBg: 'rgb(60,42,50)',
501
- syntaxComment: 'rgb(147,153,178)',
502
- syntaxKeyword: 'rgb(203,166,247)',
503
- syntaxFunction: 'rgb(137,180,250)',
504
- syntaxVariable: 'rgb(243,139,168)',
505
- syntaxString: 'rgb(166,227,161)',
506
- syntaxNumber: 'rgb(250,179,135)',
507
- syntaxType: 'rgb(249,226,175)',
508
- syntaxOperator: 'rgb(137,220,235)',
509
- syntaxPunctuation: 'rgb(205,214,244)',
510
- userMessageBackground: 'rgb(49,50,68)',
511
- userMessageBackgroundHover: 'rgb(69,71,90)',
512
- };
513
-
514
- /** Forest dark — soft natural green contrast. */
515
- const everforestPalette = {
516
- ...mixdogPalette,
517
- background: 'rgb(45,53,59)',
518
- claude: 'rgb(167,192,128)', // green
519
- claudeShimmer: 'rgb(193,212,162)',
520
- spinnerGlyph: 'rgb(167,192,128)',
521
- spinnerText: 'rgb(167,192,128)',
522
- spinnerShimmer: 'rgb(193,212,162)',
523
- panelTitle: 'rgb(167,192,128)',
524
- text: 'rgb(211,198,170)',
525
- thinkingText: 'rgb(189,178,153)',
526
- thinkingBase: 'rgb(122,132,120)',
527
- thinkingGlow: 'rgb(220,210,185)',
528
- statusText: 'rgb(211,198,170)',
529
- statusSubtle: 'rgb(122,132,120)',
530
- timerText: 'rgb(122,132,120)',
531
- inactive: 'rgb(122,132,120)',
532
- subtle: 'rgb(122,132,120)',
533
- promptBorder: 'rgb(133,146,137)',
534
- success: 'rgb(167,192,128)',
535
- error: 'rgb(230,126,128)',
536
- warning: 'rgb(230,152,117)',
537
- suggestion: 'rgb(127,187,179)',
538
- permission: 'rgb(230,126,128)',
539
- selectionText: 'rgb(45,53,59)',
540
- selectionBackground: 'rgb(211,198,170)',
541
- code: 'rgb(131,192,146)',
542
- codeBlock: 'rgb(211,198,170)',
543
- mdHeading: 'rgb(214,153,182)', // purple
544
- mdCode: 'rgb(167,192,128)',
545
- mdCodeBlock: 'rgb(211,198,170)',
546
- mdQuote: 'rgb(219,188,127)',
547
- mdQuoteBorder: 'rgb(122,132,120)',
548
- mdHr: 'rgb(122,132,120)',
549
- mdListBullet: 'rgb(167,192,128)',
550
- mdCodeBlockBorder: 'rgb(52,63,68)',
551
- mdCodeBlockBg: 'rgb(62,71,78)',
552
- mdLink: 'rgb(167,192,128)',
553
- mdLinkText: 'rgb(131,192,146)', // cyan
554
- mdStrong: 'rgb(230,152,117)', // orange
555
- mdEmph: 'rgb(219,188,127)', // yellow
556
- mdDiffAdded: 'rgb(167,192,128)',
557
- mdDiffRemoved: 'rgb(230,126,128)',
558
- mdDiffHunk: 'rgb(131,192,146)',
559
- mdDiffHeader: 'rgb(214,153,182)',
560
- mdDiffContext: 'rgb(122,132,120)',
561
- mdDiffAddedBg: 'rgb(40,54,46)',
562
- mdDiffRemovedBg: 'rgb(58,42,44)',
563
- syntaxComment: 'rgb(122,132,120)',
564
- syntaxKeyword: 'rgb(214,153,182)',
565
- syntaxFunction: 'rgb(167,192,128)',
566
- syntaxVariable: 'rgb(230,126,128)',
567
- syntaxString: 'rgb(167,192,128)',
568
- syntaxNumber: 'rgb(230,152,117)',
569
- syntaxType: 'rgb(219,188,127)',
570
- syntaxOperator: 'rgb(131,192,146)',
571
- syntaxPunctuation: 'rgb(211,198,170)',
572
- userMessageBackground: 'rgb(52,63,68)',
573
- userMessageBackgroundHover: 'rgb(61,72,77)',
574
- };
575
-
576
- /** Light — near-white surface with high-contrast dark text. */
577
- const whitePalette = {
578
- ...mixdogPalette,
579
- background: 'rgb(250,250,250)',
580
- text: 'rgb(28,28,30)',
581
- statusText: 'rgb(40,40,42)',
582
- statusSubtle: 'rgb(120,120,124)',
583
- thinkingText: 'rgb(60,60,64)',
584
- thinkingAccent: 'rgb(110,110,116)',
585
- thinkingBase: 'rgb(120,120,126)',
586
- thinkingGlow: 'rgb(80,80,86)',
587
- timerText: 'rgb(120,120,126)',
588
- inactive: 'rgb(120,120,126)',
589
- subtle: 'rgb(140,140,146)',
590
- promptBorder: 'rgb(180,180,186)',
591
- inverseText: 'rgb(250,250,250)',
592
- selectionText: 'rgb(20,20,22)',
593
- selectionBackground: 'rgb(180,213,255)',
594
- claude: 'rgb(199,108,78)',
595
- claudeShimmer: 'rgb(219,128,98)',
596
- mixdogOrange: 'rgb(199,108,78)',
597
- mixdogAmber: 'rgb(180,120,40)',
598
- mixdogIvory: 'rgb(72,68,64)',
599
- spinnerGlyph: 'rgb(199,108,78)',
600
- spinnerText: 'rgb(199,108,78)',
601
- spinnerShimmer: 'rgb(229,148,118)',
602
- panelTitle: 'rgb(199,108,78)',
603
- success: 'rgb(34,134,58)',
604
- error: 'rgb(207,34,46)',
605
- warning: 'rgb(154,103,0)',
606
- suggestion: 'rgb(9,105,218)',
607
- permission: 'rgb(207,34,46)',
608
- code: 'rgb(9,105,218)',
609
- codeBlock: 'rgb(36,41,47)',
610
- mdHeading: 'rgb(130,80,8)',
611
- mdCode: 'rgb(0,92,197)',
612
- mdCodeBlock: 'rgb(36,41,47)',
613
- mdQuote: 'rgb(106,115,125)',
614
- mdQuoteBorder: 'rgb(175,184,193)',
615
- mdHr: 'rgb(175,184,193)',
616
- mdListBullet: 'rgb(9,105,218)',
617
- mdCodeBlockBorder: 'rgb(200,206,212)',
618
- mdCodeBlockBg: 'rgb(232,232,236)',
619
- mdLink: 'rgb(9,105,218)',
620
- mdLinkText: 'rgb(0,92,197)',
621
- mdStrong: 'rgb(130,80,8)',
622
- mdEmph: 'rgb(154,103,0)',
623
- mdDiffAdded: 'rgb(34,134,58)',
624
- mdDiffRemoved: 'rgb(207,34,46)',
625
- mdDiffHunk: 'rgb(9,105,218)',
626
- mdDiffHeader: 'rgb(110,80,170)',
627
- mdDiffContext: 'rgb(106,115,125)',
628
- mdDiffAddedBg: 'rgb(218,243,224)',
629
- mdDiffRemovedBg: 'rgb(255,224,228)',
630
- syntaxComment: 'rgb(106,115,125)',
631
- syntaxKeyword: 'rgb(207,34,46)',
632
- syntaxFunction: 'rgb(9,105,218)',
633
- syntaxVariable: 'rgb(149,33,110)',
634
- syntaxString: 'rgb(10,120,60)',
635
- syntaxNumber: 'rgb(0,92,197)',
636
- syntaxType: 'rgb(130,80,8)',
637
- syntaxOperator: 'rgb(36,41,47)',
638
- syntaxPunctuation: 'rgb(36,41,47)',
639
- userMessageBackground: 'rgb(232,232,234)',
640
- userMessageBackgroundHover: 'rgb(222,222,226)',
641
- fastMode: 'rgb(255,106,0)',
642
- };
643
-
644
- // ── Registry / metadata ─────────────────────────────────────────────────────
645
- const THEME_REGISTRY = {
646
- mixdog: { id: 'mixdog', label: 'Basic', description: 'Warm dark base with teal markdown accents.', palette: mixdogPalette },
647
- 'pi-dark': { id: 'pi-dark', label: 'Teal', description: 'Teal accent with soft body text.', palette: piDarkPalette },
648
- 'claude-dark': { id: 'claude-dark', label: 'Warm', description: 'Orange accent with bright body text.', palette: claudeDarkPalette },
649
- dracula: { id: 'dracula', label: 'Violet', description: 'Purple/pink accents with cyan links.', palette: draculaPalette },
650
- tokyonight: { id: 'tokyonight', label: 'Midnight', description: 'Soft blue/purple dark with neon markdown.', palette: tokyonightPalette },
651
- nord: { id: 'nord', label: 'Frost', description: 'Cool arctic blue/teal dark.', palette: nordPalette },
652
- gruvbox: { id: 'gruvbox', label: 'Earth', description: 'Retro warm earthy dark with green/orange accents.', palette: gruvboxPalette },
653
- catppuccin: { id: 'catppuccin', label: 'Pastel', description: 'Gentle pastel violet/blue dark.', palette: catppuccinPalette },
654
- everforest: { id: 'everforest', label: 'Forest', description: 'Soft natural green dark, easy on the eyes.', palette: everforestPalette },
655
- white: { id: 'white', label: 'Light', description: 'Bright white background with high-contrast dark text.', palette: whitePalette },
656
- };
657
-
658
- const DEFAULT_THEME_ID = 'mixdog';
659
- const THEME_ORDER = ['mixdog', 'pi-dark', 'claude-dark', 'dracula', 'tokyonight', 'nord', 'gruvbox', 'catppuccin', 'everforest', 'white'];
27
+ import {
28
+ THEME_REGISTRY,
29
+ THEME_ORDER,
30
+ THEME_ALIASES,
31
+ DEFAULT_THEME_ID,
32
+ basicPalette,
33
+ } from './themes/index.mjs';
660
34
 
661
35
  /**
662
36
  * Live singleton consumed across the TUI. Seeded with the default palette and
663
37
  * mutated in-place by `applyPalette()` so `import { theme }` references stay
664
38
  * valid after a theme switch.
665
39
  */
666
- export const theme = { ...mixdogPalette };
40
+ export const theme = { ...basicPalette };
667
41
 
668
42
  let _activeThemeId = DEFAULT_THEME_ID;
669
43
  let _themeVersion = 0;
@@ -673,7 +47,7 @@ export function getThemeVersion() {
673
47
  return _themeVersion;
674
48
  }
675
49
 
676
- /** Active theme id (e.g. 'mixdog'). */
50
+ /** Active theme id (e.g. 'onedark'). */
677
51
  export function getThemeSetting() {
678
52
  return _activeThemeId;
679
53
  }
@@ -681,6 +55,7 @@ export function getThemeSetting() {
681
55
  /** Coerce any value to a known theme id, falling back to the default. */
682
56
  export function resolveThemeId(id) {
683
57
  const key = String(id || '').trim();
58
+ if (THEME_ALIASES[key] && THEME_REGISTRY[THEME_ALIASES[key]]) return THEME_ALIASES[key];
684
59
  return THEME_REGISTRY[key] ? key : DEFAULT_THEME_ID;
685
60
  }
686
61
 
@@ -697,10 +72,28 @@ export function listThemes() {
697
72
  });
698
73
  }
699
74
 
75
+ /**
76
+ * Paintable Box background.
77
+ *
78
+ * Keep this disabled by default: applying a full-screen Box background makes
79
+ * every descendant Text inherit that background through Ink's BackgroundContext,
80
+ * which is fragile with nested/ANSI-heavy output and can destabilize theme
81
+ * switching on some terminals. Themes may still set `background` for terminal
82
+ * OSC 11 (`emitTerminalBackground`) and for future opt-in surfaces, but the TUI
83
+ * itself stays transparent unless explicitly allowed.
84
+ */
85
+ export function surfaceBackground() {
86
+ if (theme.paintSurfaceBackground !== true) return undefined;
87
+ return /^rgb\(\d+,\s*\d+,\s*\d+\)$/.test(String(theme.background || '')) ? theme.background : undefined;
88
+ }
89
+
700
90
  export function emitTerminalBackground(rgbString) {
701
91
  try {
702
92
  const m = /^rgb\((\d+),(\d+),(\d+)\)$/.exec(String(rgbString || '').replace(/\s+/g, ''));
703
- if (!m) return;
93
+ if (!m) {
94
+ if (process.stdout && process.stdout.isTTY) process.stdout.write('\x1b]111\x07');
95
+ return;
96
+ }
704
97
  const hex = (n) => Math.max(0, Math.min(255, Number(n))).toString(16).padStart(2, '0');
705
98
  // OSC 11 ; rgb:RR/GG/BB (BEL-terminated). Many terminals also accept #RRGGBB.
706
99
  const seq = `\x1b]11;rgb:${hex(m[1])}${hex(m[1])}/${hex(m[2])}${hex(m[2])}/${hex(m[3])}${hex(m[3])}\x07`;
@@ -760,8 +153,9 @@ export async function loadThemeSettingFromConfig() {
760
153
  const { readConfig } = await loadConfigModule();
761
154
  const cfg = readConfig() || {};
762
155
  const stored = cfg && cfg.ui && typeof cfg.ui === 'object' ? cfg.ui.theme : null;
763
- if (stored && THEME_REGISTRY[resolveThemeId(stored)] && resolveThemeId(stored) === String(stored)) {
764
- applyPalette(stored);
156
+ const storedKey = String(stored || '').trim();
157
+ if (storedKey && (THEME_REGISTRY[storedKey] || THEME_ALIASES[storedKey])) {
158
+ applyPalette(resolveThemeId(storedKey));
765
159
  }
766
160
  } catch {
767
161
  // Fall back to the already-applied default theme.