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
@@ -0,0 +1,80 @@
1
+ /**
2
+ * src/tui/themes/kanagawa.mjs — Kanagawa (Wave).
3
+ *
4
+ * Source: rebelot/kanagawa.nvim "wave" — sumiInk3 #1F1F28 (bg),
5
+ * fujiWhite #DCD7BA (fg), crystalBlue #7E9CD8 (signature accent),
6
+ * oniViolet #957FB8, springGreen #98BB6C, carpYellow #E6C384,
7
+ * springBlue #7FB4CA, surimiOrange #FFA066, peachRed #FF5D62,
8
+ * waveRed #E46876, waveAqua2 #7AA89F, fujiGray #727169.
9
+ */
10
+ import { basePalette } from './base.mjs';
11
+
12
+ /** Kanagawa Wave — muted ink dark with crystal-blue accent. */
13
+ export const kanagawaPalette = {
14
+ ...basePalette,
15
+ background: 'transparent', // sumiInk3 #1F1F28
16
+ claude: 'rgb(210,126,153)', // sakuraPink accent (opencode)
17
+ logo: 'rgb(232,156,182)', // welcome banner — brighter than accent
18
+ claudeShimmer: 'rgb(156,171,202)', // springViolet2 #9CABCA (lighter accent)
19
+ mixdogOrange: 'rgb(210,126,153)', // sakuraPink accent (opencode)
20
+ mixdogAmber: 'rgb(156,171,202)', // lighter accent
21
+ mixdogIvory: 'rgb(220,215,186)', // fujiWhite #DCD7BA
22
+ spinnerGlyph: 'rgb(228,104,118)', // most-emphasized: waveRed
23
+ spinnerText: 'rgb(228,104,118)',
24
+ spinnerShimmer: 'rgb(255,140,150)',
25
+ thinkingAccent: 'rgb(114,113,105)', // fujiGray #727169
26
+ thinkingText: 'rgb(220,215,186)', // fg
27
+ thinkingBase: 'rgb(114,113,105)', // fujiGray
28
+ thinkingGlow: 'rgb(235,231,205)', // brighter fg
29
+ statusText: 'rgb(220,215,186)', // fg
30
+ statusSubtle: 'rgb(114,113,105)', // fujiGray
31
+ timerText: 'rgb(114,113,105)', // fujiGray
32
+ text: 'rgb(220,215,186)', // fujiWhite #DCD7BA
33
+ inverseText: 'rgb(31,31,40)', // background
34
+ selectionText: 'rgb(238,232,204)',
35
+ selectionBackground: 'rgb(61,70,96)',
36
+ inactive: 'rgb(114,113,105)', // fujiGray
37
+ subtle: 'rgb(114,113,105)', // fujiGray
38
+ promptBorder: 'rgb(114,113,105)', // fujiGray (muted grey)
39
+ success: 'rgb(152,187,108)', // springGreen #98BB6C
40
+ error: 'rgb(232,36,36)', // dragonRed #E82424
41
+ warning: 'rgb(215,166,87)', // roninYellow #D7A657
42
+ suggestion: 'rgb(126,156,216)', // crystalBlue
43
+ panelTitle: 'rgb(210,126,153)', // sakuraPink
44
+ permission: 'rgb(228,104,118)', // waveRed #E46876
45
+ code: 'rgb(126,156,216)', // crystalBlue
46
+ codeBlock: 'rgb(220,215,186)', // fg
47
+ mdHeading: 'rgb(149,127,184)', // oniViolet
48
+ mdCode: 'rgb(152,187,108)', // lotusGreen #98BB6C
49
+ mdCodeBlock: 'rgb(220,215,186)', // fg
50
+ mdQuote: 'rgb(142,140,132)', // lifted fujiGray
51
+ mdQuoteBorder: 'rgb(142,140,132)', // lifted fujiGray
52
+ mdHr: 'rgb(114,113,105)', // fujiGray
53
+ mdListBullet: 'rgb(126,156,216)', // crystalBlue accent
54
+ mdCodeBlockBorder: 'rgb(54,54,70)', // sumiInk5 #363646
55
+ mdCodeBlockBg: 'rgb(42,42,55)', // sumiInk4 #2A2A37 (lifted)
56
+ mdCodeSpanBg: 'rgb(54,54,70)', // sumiInk5 #363646
57
+ mdLink: 'rgb(126,156,216)', // crystalBlue
58
+ mdLinkText: 'rgb(118,148,106)', // waveAqua #76946A
59
+ mdStrong: 'rgb(215,166,87)', // roninYellow #D7A657
60
+ mdEmph: 'rgb(195,141,157)', // carpYellow opencode #C38D9D
61
+ mdDiffAdded: 'rgb(152,187,108)', // springGreen
62
+ mdDiffRemoved: 'rgb(255,93,98)', // peachRed
63
+ mdDiffHunk: 'rgb(45,79,103)', // waveBlue #2D4F67
64
+ mdDiffHeader: 'rgb(149,127,184)', // oniViolet #957FB8
65
+ mdDiffContext: 'rgb(114,113,105)', // fujiGray
66
+ mdDiffAddedBg: 'rgb(37,46,37)', // #252E25
67
+ mdDiffRemovedBg: 'rgb(54,32,32)', // #362020
68
+ syntaxComment: 'rgb(142,140,132)', // lifted fujiGray
69
+ syntaxKeyword: 'rgb(149,127,184)', // oniViolet
70
+ syntaxFunction: 'rgb(126,156,216)', // crystalBlue
71
+ syntaxVariable: 'rgb(220,215,186)', // fujiWhite
72
+ syntaxString: 'rgb(152,187,108)', // springGreen
73
+ syntaxNumber: 'rgb(215,166,87)', // roninYellow #D7A657
74
+ syntaxType: 'rgb(195,141,157)', // carpYellow opencode #C38D9D
75
+ syntaxOperator: 'rgb(210,126,153)', // sakuraPink
76
+ syntaxPunctuation: 'rgb(220,215,186)', // fg
77
+ userMessageBackground: 'rgb(42,42,55)', // sumiInk4 #2A2A37
78
+ userMessageBackgroundHover: 'rgb(34,50,73)', // waveBlue1 #223249
79
+ fastMode: 'rgb(255,158,59)', // roninYellow #FF9E3B (vivid in-theme orange)
80
+ };
@@ -0,0 +1,81 @@
1
+ /**
2
+ * src/tui/themes/light.mjs — GitHub Light / VS Code 2026 Light (terminal TUI).
3
+ *
4
+ * High-contrast light palette for Windows Terminal and picker rows: white
5
+ * surface, near-black ink, solid blue selection (#0069CC), visible chrome
6
+ * borders, and GitHub/VS Code light syntax (no pastel wash). Spreads
7
+ * `basePalette` first so the full key set is always present.
8
+ */
9
+ import { basePalette } from './base.mjs';
10
+
11
+ /** GitHub Light high-contrast — terminal-first readability. */
12
+ export const lightPalette = {
13
+ ...basePalette,
14
+ background: 'rgb(255,255,255)', // lightBg #ffffff
15
+ text: 'rgb(32,32,32)', // VS Code 2026 Light fg #202020
16
+ inverseText: 'rgb(255,255,255)',
17
+ selectionText: 'rgb(255,255,255)', // quickInputList.focusForeground
18
+ selectionBackground: 'rgb(0,105,204)', // #0069CC focus / active list
19
+ selectionHighlightText: 'rgb(0,0,0)',
20
+ selectionHighlightBackground: 'rgb(180,213,255)', // classic light-mode text selection blue
21
+ inactive: 'rgb(87,96,106)', // lightFgMuted #57606a
22
+ subtle: 'rgb(110,119,129)', // #6e7781
23
+ promptBorder: 'rgb(175,184,193)', // darker than #d0d7de for visible chrome
24
+ statusText: 'rgb(32,32,32)',
25
+ statusSubtle: 'rgb(87,96,106)',
26
+ timerText: 'rgb(87,96,106)',
27
+ thinkingText: 'rgb(32,32,32)',
28
+ thinkingBase: 'rgb(110,119,129)',
29
+ thinkingAccent: 'rgb(87,96,106)',
30
+ thinkingGlow: 'rgb(20,24,28)',
31
+ claude: 'rgb(9,105,218)', // lightBlue #0969da (signature accent)
32
+ logo: 'rgb(9,105,218)', // welcome banner — high-contrast on white
33
+ claudeShimmer: 'rgb(84,153,237)',
34
+ mixdogOrange: 'rgb(9,105,218)',
35
+ mixdogAmber: 'rgb(84,153,237)',
36
+ mixdogIvory: 'rgb(32,32,32)',
37
+ spinnerGlyph: 'rgb(9,105,218)',
38
+ spinnerText: 'rgb(9,105,218)',
39
+ spinnerShimmer: 'rgb(84,153,237)',
40
+ panelTitle: 'rgb(9,105,218)',
41
+ success: 'rgb(26,127,55)', // lightGreen #1a7f37
42
+ error: 'rgb(207,34,46)', // lightRed #cf222e
43
+ warning: 'rgb(154,103,0)', // lightYellow #9a6700
44
+ permission: 'rgb(207,34,46)',
45
+ suggestion: 'rgb(9,105,218)',
46
+ code: 'rgb(9,105,218)',
47
+ codeBlock: 'rgb(32,32,32)',
48
+ userMessageBackground: 'rgb(240,243,246)', // lightBgPanel #f0f3f6
49
+ userMessageBackgroundHover: 'rgb(246,248,250)', // lightBgAlt #f6f8fa
50
+ fastMode: 'rgb(188,76,0)', // lightOrange #bc4c00
51
+ mdHeading: 'rgb(9,105,218)', // lightBlue
52
+ mdCode: 'rgb(191,57,137)', // lightPink #bf3989 (inline code)
53
+ mdCodeBlock: 'rgb(36,41,47)', // GitHub fg #24292f
54
+ mdQuote: 'rgb(87,96,106)',
55
+ mdQuoteBorder: 'rgb(175,184,193)',
56
+ mdHr: 'rgb(175,184,193)',
57
+ mdListBullet: 'rgb(9,105,218)',
58
+ mdCodeBlockBorder: 'rgb(216,216,216)', // VS Code panel border #D8D8D8
59
+ mdCodeBlockBg: 'rgb(246,248,250)', // #f6f8fa
60
+ mdCodeSpanBg: 'rgb(240,243,246)', // #f0f3f6
61
+ mdLink: 'rgb(9,105,218)',
62
+ mdLinkText: 'rgb(27,124,131)', // lightCyan #1b7c83
63
+ mdStrong: 'rgb(149,56,0)', // #953800
64
+ mdEmph: 'rgb(154,103,0)', // lightYellow #9a6700
65
+ mdDiffAdded: 'rgb(26,127,55)',
66
+ mdDiffRemoved: 'rgb(207,34,46)',
67
+ mdDiffHunk: 'rgb(9,105,218)',
68
+ mdDiffHeader: 'rgb(130,80,223)', // lightPurple #8250df
69
+ mdDiffContext: 'rgb(87,96,106)',
70
+ mdDiffAddedBg: 'rgb(218,251,225)', // #dafbe1
71
+ mdDiffRemovedBg: 'rgb(255,235,233)', // #ffebe9
72
+ syntaxComment: 'rgb(110,119,129)', // #6e7781
73
+ syntaxKeyword: 'rgb(207,34,46)', // lightRed
74
+ syntaxFunction: 'rgb(130,80,223)', // lightPurple
75
+ syntaxVariable: 'rgb(149,56,0)', // #953800
76
+ syntaxString: 'rgb(10,48,105)', // #0a3069 dark blue strings
77
+ syntaxNumber: 'rgb(27,124,131)', // lightCyan
78
+ syntaxType: 'rgb(149,56,0)', // #953800
79
+ syntaxOperator: 'rgb(207,34,46)', // lightRed
80
+ syntaxPunctuation: 'rgb(36,41,47)', // dark ink
81
+ };
@@ -0,0 +1,72 @@
1
+ import { basePalette } from './base.mjs';
2
+
3
+ /** Nord (nordtheme.com) — Polar Night, Snow Storm, Frost, Aurora */
4
+ export const nordPalette = {
5
+ ...basePalette,
6
+ background: 'transparent',
7
+ text: 'rgb(216,222,233)',
8
+ inverseText: 'rgb(46,52,64)',
9
+ selectionText: 'rgb(229,233,240)',
10
+ selectionBackground: 'rgb(67,92,122)',
11
+ inactive: 'rgb(76,86,106)',
12
+ subtle: 'rgb(76,86,106)',
13
+ promptBorder: 'rgb(76,86,106)',
14
+ statusText: 'rgb(216,222,233)',
15
+ statusSubtle: 'rgb(76,86,106)',
16
+ timerText: 'rgb(76,86,106)',
17
+ thinkingText: 'rgb(216,222,233)',
18
+ thinkingBase: 'rgb(76,86,106)',
19
+ thinkingAccent: 'rgb(76,86,106)',
20
+ thinkingGlow: 'rgb(229,233,240)',
21
+ claude: 'rgb(136,192,208)',
22
+ logo: 'rgb(170,218,232)', // welcome banner — brighter than accent
23
+ claudeShimmer: 'rgb(143,188,187)',
24
+ mixdogOrange: 'rgb(136,192,208)',
25
+ mixdogAmber: 'rgb(143,188,187)',
26
+ mixdogIvory: 'rgb(216,222,233)',
27
+ spinnerGlyph: 'rgb(208,135,112)', // most-emphasized: aurora orange
28
+ spinnerText: 'rgb(208,135,112)',
29
+ spinnerShimmer: 'rgb(224,160,140)',
30
+ panelTitle: 'rgb(136,192,208)',
31
+ success: 'rgb(163,190,140)',
32
+ error: 'rgb(191,97,106)',
33
+ warning: 'rgb(235,203,139)',
34
+ permission: 'rgb(191,97,106)',
35
+ suggestion: 'rgb(129,161,193)',
36
+ code: 'rgb(129,161,193)',
37
+ codeBlock: 'rgb(216,222,233)',
38
+ userMessageBackground: 'rgb(59,66,82)',
39
+ userMessageBackgroundHover: 'rgb(67,76,94)',
40
+ fastMode: 'rgb(208,135,112)',
41
+ mdHeading: 'rgb(180,142,173)',
42
+ mdCode: 'rgb(143,188,187)',
43
+ mdCodeBlock: 'rgb(216,222,233)',
44
+ mdQuote: 'rgb(130,142,168)',
45
+ mdQuoteBorder: 'rgb(130,142,168)',
46
+ mdHr: 'rgb(76,86,106)',
47
+ mdListBullet: 'rgb(136,192,208)',
48
+ mdCodeBlockBorder: 'rgb(67,76,94)',
49
+ mdCodeBlockBg: 'rgb(59,66,82)',
50
+ mdCodeSpanBg: 'rgb(67,76,94)',
51
+ mdLink: 'rgb(129,161,193)',
52
+ mdLinkText: 'rgb(143,188,187)',
53
+ mdStrong: 'rgb(208,135,112)',
54
+ mdEmph: 'rgb(235,203,139)',
55
+ mdDiffAdded: 'rgb(163,190,140)',
56
+ mdDiffRemoved: 'rgb(191,97,106)',
57
+ mdDiffHunk: 'rgb(94,129,172)',
58
+ mdDiffHeader: 'rgb(180,142,173)',
59
+ mdDiffContext: 'rgb(76,86,106)',
60
+ mdDiffAddedBg: 'rgb(52,68,58)',
61
+ mdDiffRemovedBg: 'rgb(68,52,56)',
62
+ syntaxComment: 'rgb(130,142,168)',
63
+ syntaxKeyword: 'rgb(129,161,193)',
64
+ syntaxFunction: 'rgb(136,192,208)',
65
+ syntaxVariable: 'rgb(191,97,106)',
66
+ syntaxString: 'rgb(163,190,140)',
67
+ syntaxNumber: 'rgb(180,142,173)',
68
+ syntaxType: 'rgb(143,188,187)',
69
+ syntaxOperator: 'rgb(129,161,193)',
70
+ syntaxPunctuation: 'rgb(216,222,233)',
71
+ };
72
+
@@ -0,0 +1,16 @@
1
+ /**
2
+ * src/tui/themes/onedark.mjs — One Dark (the default theme).
3
+ *
4
+ * One Dark IS the base palette, so this theme simply re-exports the full base
5
+ * key set under the `onedarkPalette` name expected by the registry.
6
+ */
7
+ import { basePalette } from './base.mjs';
8
+
9
+ /** One Dark — base palette with a hot coral-red spinner (most-emphasized live state). */
10
+ export const onedarkPalette = {
11
+ ...basePalette,
12
+ spinnerGlyph: 'rgb(224,108,117)', // most-emphasized: coral red
13
+ spinnerText: 'rgb(224,108,117)',
14
+ spinnerShimmer: 'rgb(240,140,148)',
15
+ syntaxComment: 'rgb(118,126,142)', // lifted grey for code-block readability
16
+ };
@@ -0,0 +1,70 @@
1
+ import { basePalette } from './base.mjs';
2
+ /** Rosé Pine main — https://rosepinetheme.com/palette/ingredients */
3
+ export const rosepinePalette = {
4
+ ...basePalette,
5
+ background: 'transparent',
6
+ text: 'rgb(224,222,244)',
7
+ inverseText: 'rgb(25,23,36)',
8
+ selectionText: 'rgb(238,232,255)',
9
+ selectionBackground: 'rgb(65,52,92)',
10
+ claude: 'rgb(196,167,231)',
11
+ logo: 'rgb(220,196,245)', // welcome banner — brighter than accent
12
+ claudeShimmer: 'rgb(235,188,186)',
13
+ mixdogOrange: 'rgb(196,167,231)',
14
+ mixdogAmber: 'rgb(246,193,119)',
15
+ mixdogIvory: 'rgb(224,222,244)',
16
+ spinnerGlyph: 'rgb(235,111,146)', // most-emphasized: love
17
+ spinnerText: 'rgb(235,111,146)',
18
+ spinnerShimmer: 'rgb(245,150,175)',
19
+ thinkingAccent: 'rgb(110,106,134)',
20
+ thinkingText: 'rgb(224,222,244)',
21
+ thinkingBase: 'rgb(110,106,134)',
22
+ thinkingGlow: 'rgb(236,234,252)',
23
+ statusText: 'rgb(224,222,244)',
24
+ statusSubtle: 'rgb(144,140,170)',
25
+ timerText: 'rgb(110,106,134)',
26
+ inactive: 'rgb(110,106,134)',
27
+ subtle: 'rgb(144,140,170)',
28
+ promptBorder: 'rgb(110,106,134)',
29
+ success: 'rgb(110,158,135)',
30
+ error: 'rgb(235,111,146)',
31
+ warning: 'rgb(246,193,119)',
32
+ suggestion: 'rgb(156,207,216)',
33
+ panelTitle: 'rgb(196,167,231)',
34
+ permission: 'rgb(235,111,146)',
35
+ code: 'rgb(156,207,216)',
36
+ codeBlock: 'rgb(224,222,244)',
37
+ mdHeading: 'rgb(196,167,231)',
38
+ mdCode: 'rgb(156,207,216)',
39
+ mdCodeBlock: 'rgb(224,222,244)',
40
+ mdQuote: 'rgb(138,134,166)',
41
+ mdQuoteBorder: 'rgb(138,134,166)',
42
+ mdHr: 'rgb(144,140,170)',
43
+ mdListBullet: 'rgb(196,167,231)',
44
+ mdCodeBlockBorder: 'rgb(64,61,82)',
45
+ mdCodeBlockBg: 'rgb(31,29,46)',
46
+ mdCodeSpanBg: 'rgb(38,35,58)',
47
+ mdLink: 'rgb(156,207,216)',
48
+ mdLinkText: 'rgb(235,188,186)',
49
+ mdStrong: 'rgb(246,193,119)',
50
+ mdEmph: 'rgb(235,188,186)',
51
+ mdDiffAdded: 'rgb(110,158,135)',
52
+ mdDiffRemoved: 'rgb(235,111,146)',
53
+ mdDiffHunk: 'rgb(144,140,170)',
54
+ mdDiffHeader: 'rgb(196,167,231)',
55
+ mdDiffContext: 'rgb(144,140,170)',
56
+ mdDiffAddedBg: 'rgb(26,42,34)',
57
+ mdDiffRemovedBg: 'rgb(48,30,42)',
58
+ syntaxComment: 'rgb(110,106,134)',
59
+ syntaxKeyword: 'rgb(196,167,231)',
60
+ syntaxFunction: 'rgb(156,207,216)',
61
+ syntaxVariable: 'rgb(224,222,244)',
62
+ syntaxString: 'rgb(246,193,119)',
63
+ syntaxNumber: 'rgb(246,193,119)',
64
+ syntaxType: 'rgb(156,207,216)',
65
+ syntaxOperator: 'rgb(49,116,143)',
66
+ syntaxPunctuation: 'rgb(224,222,244)',
67
+ userMessageBackground: 'rgb(38,35,58)',
68
+ userMessageBackgroundHover: 'rgb(64,61,82)',
69
+ fastMode: 'rgb(246,193,119)',
70
+ };
@@ -0,0 +1,81 @@
1
+ /**
2
+ * src/tui/themes/teal.mjs — Teal (pi style).
3
+ *
4
+ * Faithful port of pi's `dark.json` (refs/pi .../theme/dark.json). Values are
5
+ * taken verbatim: accent teal #8abeb7, body text #d4d4d4, page bg #18181e,
6
+ * green #b5bd68, red #cc6666, warning pure yellow #ffff00, blue #81a2be,
7
+ * mdHeading #f0c674, gray #808080. Syntax uses pi's VS Code Dark+ palette
8
+ * (keyword #569CD6, string #CE9178, function #DCDCAA, etc.). Spreads
9
+ * `basePalette` first so the full key set is always present.
10
+ */
11
+ import { basePalette } from './base.mjs';
12
+
13
+ /** Teal — pi-style teal accent with soft body text. */
14
+ export const tealPalette = {
15
+ ...basePalette,
16
+ background: 'transparent', // export.pageBg #18181e
17
+ claude: 'rgb(138,190,183)', // accent #8abeb7
18
+ logo: 'rgb(174,216,210)', // welcome banner — brighter than accent
19
+ claudeShimmer: 'rgb(170,214,208)', // lighter accent
20
+ mixdogOrange: 'rgb(138,190,183)',
21
+ mixdogAmber: 'rgb(170,214,208)',
22
+ mixdogIvory: 'rgb(212,212,212)', // text #d4d4d4
23
+ spinnerGlyph: 'rgb(235,140,110)', // most-emphasized: warm coral (complementary to teal)
24
+ spinnerText: 'rgb(235,140,110)',
25
+ spinnerShimmer: 'rgb(245,170,145)',
26
+ thinkingAccent: 'rgb(128,128,128)', // gray #808080
27
+ thinkingText: 'rgb(128,128,128)', // thinkingText = gray #808080
28
+ thinkingBase: 'rgb(128,128,128)',
29
+ thinkingGlow: 'rgb(200,200,200)',
30
+ statusText: 'rgb(212,212,212)', // text #d4d4d4
31
+ statusSubtle: 'rgb(128,128,128)', // gray
32
+ timerText: 'rgb(128,128,128)',
33
+ text: 'rgb(212,212,212)', // text #d4d4d4
34
+ inverseText: 'rgb(24,24,30)',
35
+ selectionText: 'rgb(220,245,242)',
36
+ selectionBackground: 'rgb(35,78,82)',
37
+ inactive: 'rgb(128,128,128)', // muted/gray #808080
38
+ subtle: 'rgb(102,102,102)', // dim/dimGray #666666
39
+ promptBorder: 'rgb(80,80,80)', // borderMuted/darkGray #505050
40
+ success: 'rgb(181,189,104)', // green #b5bd68
41
+ error: 'rgb(204,102,102)', // red #cc6666
42
+ warning: 'rgb(255,255,0)', // yellow #ffff00 (pi uses pure yellow)
43
+ suggestion: 'rgb(129,162,190)', // mdLink #81a2be
44
+ panelTitle: 'rgb(138,190,183)', // accent
45
+ permission: 'rgb(204,102,102)', // red
46
+ code: 'rgb(138,190,183)', // mdCode = accent
47
+ codeBlock: 'rgb(181,189,104)', // mdCodeBlock = green
48
+ mdHeading: 'rgb(240,198,116)', // mdHeading #f0c674
49
+ mdCode: 'rgb(138,190,183)', // accent
50
+ mdCodeBlock: 'rgb(181,189,104)', // green
51
+ mdQuote: 'rgb(128,128,128)', // gray
52
+ mdQuoteBorder: 'rgb(128,128,128)',
53
+ mdHr: 'rgb(128,128,128)',
54
+ mdListBullet: 'rgb(138,190,183)', // accent
55
+ mdCodeBlockBorder: 'rgb(54,56,62)', // just above mdCodeSpanBg
56
+ mdCodeBlockBg: 'rgb(30,30,36)', // export.cardBg #1e1e24
57
+ mdCodeSpanBg: 'rgb(40,40,46)', // one step above cardBg
58
+ mdLink: 'rgb(129,162,190)', // mdLink #81a2be
59
+ mdLinkText: 'rgb(138,190,183)', // teal accent (readable link label)
60
+ mdStrong: 'rgb(240,198,116)', // heading-warm
61
+ mdEmph: 'rgb(229,192,123)',
62
+ mdDiffAdded: 'rgb(181,189,104)', // toolDiffAdded = green
63
+ mdDiffRemoved: 'rgb(204,102,102)', // toolDiffRemoved = red
64
+ mdDiffHunk: 'rgb(129,162,190)',
65
+ mdDiffHeader: 'rgb(149,117,205)', // customMessageLabel #9575cd purple
66
+ mdDiffContext: 'rgb(128,128,128)', // toolDiffContext = gray
67
+ mdDiffAddedBg: 'rgb(40,50,40)', // toolSuccessBg #283228
68
+ mdDiffRemovedBg: 'rgb(60,40,40)', // toolErrorBg #3c2828
69
+ syntaxComment: 'rgb(106,153,85)', // #6A9955 (VS Code Dark+)
70
+ syntaxKeyword: 'rgb(86,156,214)', // #569CD6
71
+ syntaxFunction: 'rgb(220,220,170)', // #DCDCAA
72
+ syntaxVariable: 'rgb(156,220,254)', // #9CDCFE
73
+ syntaxString: 'rgb(206,145,120)', // #CE9178
74
+ syntaxNumber: 'rgb(181,206,168)', // #B5CEA8
75
+ syntaxType: 'rgb(78,201,176)', // #4EC9B0
76
+ syntaxOperator: 'rgb(212,212,212)', // #D4D4D4
77
+ syntaxPunctuation: 'rgb(212,212,212)', // #D4D4D4
78
+ userMessageBackground: 'rgb(52,53,65)', // userMsgBg #343541
79
+ userMessageBackgroundHover: 'rgb(64,65,79)',
80
+ fastMode: 'rgb(255,120,20)',
81
+ };
@@ -0,0 +1,79 @@
1
+ /**
2
+ * src/tui/themes/tokyonight.mjs — Tokyo Night (Storm).
3
+ *
4
+ * Source: folke/tokyonight.nvim "storm" — bg #24283b, bgDark #1f2335,
5
+ * fg #c0caf5, comment #565f89, blue #7aa2f7 (signature accent),
6
+ * magenta #bb9af7, cyan #7dcfff, green #9ece6a, orange #ff9e64,
7
+ * yellow #e0af68, red #f7768e, terminalBlack #414868.
8
+ */
9
+ import { basePalette } from './base.mjs';
10
+
11
+ /** Tokyo Night Storm — soft blue/purple dark with neon markdown. */
12
+ export const tokyonightPalette = {
13
+ ...basePalette,
14
+ background: 'transparent', // bg #24283b
15
+ claude: 'rgb(122,162,247)', // blue accent
16
+ logo: 'rgb(160,190,255)', // welcome banner — brighter than accent
17
+ claudeShimmer: 'rgb(160,190,255)', // lighter blue
18
+ mixdogOrange: 'rgb(122,162,247)', // signature accent (blue)
19
+ mixdogAmber: 'rgb(160,190,255)', // lighter accent
20
+ mixdogIvory: 'rgb(192,202,245)', // fg
21
+ spinnerGlyph: 'rgb(255,158,100)', // most-emphasized: orange
22
+ spinnerText: 'rgb(255,158,100)',
23
+ spinnerShimmer: 'rgb(255,180,130)',
24
+ thinkingAccent: 'rgb(86,95,137)', // comment #565f89
25
+ thinkingText: 'rgb(192,202,245)', // fg
26
+ thinkingBase: 'rgb(86,95,137)', // comment
27
+ thinkingGlow: 'rgb(215,222,255)', // brighter fg
28
+ statusText: 'rgb(192,202,245)', // fg
29
+ statusSubtle: 'rgb(86,95,137)', // comment
30
+ timerText: 'rgb(86,95,137)', // comment
31
+ text: 'rgb(192,202,245)', // fg #c0caf5
32
+ inverseText: 'rgb(36,40,59)', // background
33
+ selectionText: 'rgb(225,232,255)',
34
+ selectionBackground: 'rgb(52,72,130)',
35
+ inactive: 'rgb(86,95,137)', // comment
36
+ subtle: 'rgb(86,95,137)', // comment
37
+ promptBorder: 'rgb(86,95,137)', // comment (muted grey)
38
+ success: 'rgb(158,206,106)', // green #9ece6a
39
+ error: 'rgb(247,118,142)', // red #f7768e
40
+ warning: 'rgb(255,158,100)', // orange #ff9e64
41
+ suggestion: 'rgb(122,162,247)', // blue
42
+ panelTitle: 'rgb(122,162,247)', // blue
43
+ permission: 'rgb(247,118,142)', // red
44
+ code: 'rgb(122,162,247)', // blue
45
+ codeBlock: 'rgb(192,202,245)', // fg
46
+ mdHeading: 'rgb(187,154,247)', // magenta #bb9af7
47
+ mdCode: 'rgb(158,206,106)', // green
48
+ mdCodeBlock: 'rgb(192,202,245)', // fg
49
+ mdQuote: 'rgb(110,120,162)', // lifted comment
50
+ mdQuoteBorder: 'rgb(110,120,162)', // lifted comment
51
+ mdHr: 'rgb(86,95,137)', // comment
52
+ mdListBullet: 'rgb(122,162,247)', // blue accent
53
+ mdCodeBlockBorder: 'rgb(65,72,104)', // terminalBlack #414868
54
+ mdCodeBlockBg: 'rgb(42,46,66)', // surface (lifted from bg)
55
+ mdCodeSpanBg: 'rgb(50,55,77)', // one step above codeBlockBg
56
+ mdLink: 'rgb(122,162,247)', // blue
57
+ mdLinkText: 'rgb(125,207,255)', // cyan #7dcfff
58
+ mdStrong: 'rgb(255,158,100)', // orange
59
+ mdEmph: 'rgb(224,175,104)', // yellow #e0af68
60
+ mdDiffAdded: 'rgb(158,206,106)', // green
61
+ mdDiffRemoved: 'rgb(247,118,142)', // red
62
+ mdDiffHunk: 'rgb(86,95,137)', // comment
63
+ mdDiffHeader: 'rgb(187,154,247)', // magenta
64
+ mdDiffContext: 'rgb(86,95,137)', // comment
65
+ mdDiffAddedBg: 'rgb(32,48,40)', // dark green derived from bg
66
+ mdDiffRemovedBg: 'rgb(55,34,44)', // dark red derived from bg
67
+ syntaxComment: 'rgb(110,120,162)', // lifted comment
68
+ syntaxKeyword: 'rgb(187,154,247)', // magenta
69
+ syntaxFunction: 'rgb(122,162,247)', // blue
70
+ syntaxVariable: 'rgb(247,118,142)', // red
71
+ syntaxString: 'rgb(158,206,106)', // green
72
+ syntaxNumber: 'rgb(255,158,100)', // orange
73
+ syntaxType: 'rgb(224,175,104)', // yellow
74
+ syntaxOperator: 'rgb(125,207,255)', // cyan
75
+ syntaxPunctuation: 'rgb(192,202,245)', // fg
76
+ userMessageBackground: 'rgb(31,35,53)', // bgDark #1f2335
77
+ userMessageBackgroundHover: 'rgb(65,72,104)', // terminalBlack #414868
78
+ fastMode: 'rgb(255,150,70)', // vivid in-theme orange
79
+ };
@@ -0,0 +1,106 @@
1
+ /**
2
+ * src/tui/themes/utils.mjs — palette post-processing helpers.
3
+ *
4
+ * Reference pattern (Claude Code / opencode / pi):
5
+ * - keep body text neutral and highly readable;
6
+ * - keep strong live-state colors for spinners/status;
7
+ * - use accent colors sparingly for headings, links and syntax, preferably
8
+ * muted/desaturated enough for long coding sessions.
9
+ *
10
+ * Theme modules still define their full, expressive palettes. The registry runs
11
+ * them through `softenTypographyColors()` so text-bearing accent roles are a
12
+ * little less saturated without flattening each theme's signature color.
13
+ */
14
+
15
+ const RGB_RE = /^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/;
16
+
17
+ const SOFTEN_KEYS = [
18
+ 'mdHeading',
19
+ 'code',
20
+ 'mdLink',
21
+ 'mdLinkText',
22
+ 'mdStrong',
23
+ 'mdEmph',
24
+ 'mdDiffHunk',
25
+ 'mdDiffHeader',
26
+ 'syntaxKeyword',
27
+ 'syntaxFunction',
28
+ 'syntaxString',
29
+ 'syntaxNumber',
30
+ 'syntaxType',
31
+ 'syntaxOperator',
32
+ ];
33
+
34
+ // Inline codespan (`emphasis`). Kept only lightly muted with a FIXED small
35
+ // amount instead of the saturation-scaled soften, so accented inline code reads
36
+ // a touch brighter/livelier instead of graying out on long sessions.
37
+ const ACCENT_SOFTEN_KEYS = [
38
+ 'mdCode',
39
+ ];
40
+ const ACCENT_SOFTEN_AMOUNT = 0.14;
41
+
42
+ const SUBTLE_SOFTEN_KEYS = [
43
+ 'mdListBullet',
44
+ ];
45
+
46
+ const UI_SOFTEN_KEYS = [
47
+ 'panelTitle',
48
+ ];
49
+
50
+ function parseRgb(value) {
51
+ const m = RGB_RE.exec(String(value || ''));
52
+ return m ? [Number(m[1]), Number(m[2]), Number(m[3])] : null;
53
+ }
54
+
55
+ function rgbString(rgb) {
56
+ return `rgb(${rgb.map((v) => Math.max(0, Math.min(255, Math.round(v)))).join(',')})`;
57
+ }
58
+
59
+ function mix(a, b, amount) {
60
+ return a.map((v, i) => v + (b[i] - v) * amount);
61
+ }
62
+
63
+ function saturation([r, g, b]) {
64
+ r /= 255; g /= 255; b /= 255;
65
+ const max = Math.max(r, g, b);
66
+ const min = Math.min(r, g, b);
67
+ const l = (max + min) / 2;
68
+ if (max === min) return 0;
69
+ const d = max - min;
70
+ return l > 0.5 ? d / (2 - max - min) : d / (max + min);
71
+ }
72
+
73
+ function softenAmount(rgb, base = 0.05) {
74
+ const s = saturation(rgb);
75
+ if (s >= 0.85) return base + 0.20;
76
+ if (s >= 0.65) return base + 0.15;
77
+ if (s >= 0.45) return base + 0.10;
78
+ if (s >= 0.25) return base + 0.06;
79
+ return base + 0.02;
80
+ }
81
+
82
+ function softenKey(out, key, target, baseAmount = 0.08) {
83
+ const rgb = parseRgb(out[key]);
84
+ if (!rgb || !target) return;
85
+ out[key] = rgbString(mix(rgb, target, softenAmount(rgb, baseAmount)));
86
+ }
87
+
88
+ function softenKeyFixed(out, key, target, amount) {
89
+ const rgb = parseRgb(out[key]);
90
+ if (!rgb || !target) return;
91
+ out[key] = rgbString(mix(rgb, target, amount));
92
+ }
93
+
94
+ export function softenTypographyColors(palette) {
95
+ const out = { ...palette };
96
+ const text = parseRgb(out.text) || parseRgb(out.mdCodeBlock) || parseRgb(out.statusText);
97
+ const subtle = parseRgb(out.subtle) || parseRgb(out.inactive) || text;
98
+ if (!text) return out;
99
+ const neutralText = subtle ? mix(text, subtle, 0.26) : text;
100
+
101
+ for (const key of SOFTEN_KEYS) softenKey(out, key, neutralText, 0.06);
102
+ for (const key of ACCENT_SOFTEN_KEYS) softenKeyFixed(out, key, neutralText, ACCENT_SOFTEN_AMOUNT);
103
+ for (const key of SUBTLE_SOFTEN_KEYS) softenKey(out, key, subtle || neutralText, 0.22);
104
+ for (const key of UI_SOFTEN_KEYS) softenKey(out, key, neutralText, 0.05);
105
+ return out;
106
+ }
@@ -0,0 +1,79 @@
1
+ /**
2
+ * src/tui/themes/warm.mjs — Warm (soft sunset / coral on charcoal).
3
+ *
4
+ * Distinct from Basic (amber-gold) and earth-tone themes: neutral charcoal
5
+ * surfaces, readable cool-neutral body text, and coral–peach accents for
6
+ * titles, links, and live state. Spreads `basePalette` first so the full key
7
+ * set is always present.
8
+ */
9
+ import { basePalette } from './base.mjs';
10
+
11
+ /** Warm — soft sunset dark (coral accent, neutral ink). */
12
+ export const warmPalette = {
13
+ ...basePalette,
14
+ background: 'transparent',
15
+ claude: 'rgb(255,120,96)',
16
+ logo: 'rgb(255,145,110)',
17
+ claudeShimmer: 'rgb(255,190,160)',
18
+ mixdogOrange: 'rgb(255,120,96)',
19
+ mixdogAmber: 'rgb(255,190,160)',
20
+ mixdogIvory: 'rgb(228,230,235)',
21
+ spinnerGlyph: 'rgb(255,100,72)',
22
+ spinnerText: 'rgb(255,100,72)',
23
+ spinnerShimmer: 'rgb(255,150,115)',
24
+ thinkingAccent: 'rgb(255,140,110)',
25
+ thinkingText: 'rgb(200,204,212)',
26
+ thinkingBase: 'rgb(120,124,134)',
27
+ thinkingGlow: 'rgb(240,228,220)',
28
+ statusText: 'rgb(228,230,235)',
29
+ statusSubtle: 'rgb(150,154,162)',
30
+ timerText: 'rgb(150,154,162)',
31
+ text: 'rgb(228,230,235)',
32
+ inverseText: 'rgb(28,30,34)',
33
+ selectionText: 'rgb(238,240,245)',
34
+ selectionBackground: 'rgb(72,78,96)',
35
+ inactive: 'rgb(150,154,162)',
36
+ subtle: 'rgb(130,134,142)',
37
+ promptBorder: 'rgb(90,94,102)',
38
+ success: 'rgb(140,190,118)',
39
+ error: 'rgb(230,86,78)',
40
+ warning: 'rgb(238,142,78)',
41
+ suggestion: 'rgb(255,190,160)',
42
+ panelTitle: 'rgb(255,120,96)',
43
+ permission: 'rgb(230,86,78)',
44
+ code: 'rgb(255,175,140)',
45
+ codeBlock: 'rgb(220,222,228)',
46
+ mdHeading: 'rgb(255,120,96)',
47
+ mdCode: 'rgb(255,175,140)',
48
+ mdCodeBlock: 'rgb(220,222,228)',
49
+ mdQuote: 'rgb(150,154,168)',
50
+ mdQuoteBorder: 'rgb(120,124,136)',
51
+ mdHr: 'rgb(120,124,136)',
52
+ mdListBullet: 'rgb(255,120,96)',
53
+ mdCodeBlockBorder: 'rgb(52,56,64)',
54
+ mdCodeBlockBg: 'rgb(32,34,40)',
55
+ mdCodeSpanBg: 'rgb(42,44,52)',
56
+ mdLink: 'rgb(255,190,160)',
57
+ mdLinkText: 'rgb(255,130,110)',
58
+ mdStrong: 'rgb(255,190,160)',
59
+ mdEmph: 'rgb(255,150,130)',
60
+ mdDiffAdded: 'rgb(140,190,118)',
61
+ mdDiffRemoved: 'rgb(230,86,78)',
62
+ mdDiffHunk: 'rgb(255,130,110)',
63
+ mdDiffHeader: 'rgb(255,190,160)',
64
+ mdDiffContext: 'rgb(150,154,168)',
65
+ mdDiffAddedBg: 'rgb(34,44,36)',
66
+ mdDiffRemovedBg: 'rgb(52,30,30)',
67
+ syntaxComment: 'rgb(150,154,168)',
68
+ syntaxKeyword: 'rgb(255,120,96)',
69
+ syntaxFunction: 'rgb(255,190,160)',
70
+ syntaxVariable: 'rgb(230,100,92)',
71
+ syntaxString: 'rgb(140,190,130)',
72
+ syntaxNumber: 'rgb(255,150,130)',
73
+ syntaxType: 'rgb(255,175,140)',
74
+ syntaxOperator: 'rgb(200,204,212)',
75
+ syntaxPunctuation: 'rgb(228,230,235)',
76
+ userMessageBackground: 'rgb(38,40,46)',
77
+ userMessageBackgroundHover: 'rgb(52,56,64)',
78
+ fastMode: 'rgb(255,100,72)',
79
+ };