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