@earendil-works/pi-coding-agent 0.87.1 → 0.99.0

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 (721) hide show
  1. package/CHANGELOG.md +79 -0
  2. package/dist/bun/cli.d.ts.map +1 -1
  3. package/dist/bun/restore-sandbox-env.d.ts.map +1 -1
  4. package/dist/bun/restore-sandbox-env.js.map +1 -1
  5. package/dist/bun/runtime-setup.d.ts.map +1 -1
  6. package/dist/bun/runtime-setup.js +4 -1
  7. package/dist/bun/runtime-setup.js.map +1 -1
  8. package/dist/bun/sandbox-env-setup.d.ts.map +1 -1
  9. package/dist/bundle/chunks/anthropic-messages-A6EXUBG6.js +6 -0
  10. package/dist/bundle/chunks/anthropic.js +2 -2
  11. package/dist/bundle/chunks/azure-openai-responses-EN5WOBET.js +2 -0
  12. package/dist/bundle/chunks/bedrock-converse-stream.js +2 -2
  13. package/dist/bundle/chunks/chunk-4CSSZFEW.js +1435 -0
  14. package/dist/bundle/chunks/chunk-7JGR3GZN.js +11 -0
  15. package/dist/bundle/chunks/chunk-AXPY26X7.js +146 -0
  16. package/dist/bundle/chunks/chunk-EPDRUIU6.js +2 -0
  17. package/dist/bundle/chunks/chunk-GOPCREV2.js +4 -0
  18. package/dist/bundle/chunks/chunk-H3QXYIF7.js +31 -0
  19. package/dist/bundle/chunks/{chunk-S7SZN6Z3.js → chunk-HSPCVFST.js} +1 -1
  20. package/dist/bundle/chunks/chunk-IMTXZUO7.js +82 -0
  21. package/dist/bundle/chunks/chunk-J4CWPC4N.js +2 -0
  22. package/dist/bundle/chunks/chunk-LLMKQWZS.js +21 -0
  23. package/dist/bundle/chunks/{chunk-WIUZI2CJ.js → chunk-LRS5S6EK.js} +3 -3
  24. package/dist/bundle/chunks/chunk-PEHWOV5U.js +187 -0
  25. package/dist/bundle/chunks/{chunk-XDUWOHPL.js → chunk-S3GGRYIO.js} +2 -2
  26. package/dist/bundle/chunks/chunk-UTB4DTYQ.js +2 -0
  27. package/dist/bundle/chunks/{chunk-FUXEF6JQ.js → chunk-W2DOMZSC.js} +1 -1
  28. package/dist/bundle/chunks/cli-AZXNGIZH.js +49 -0
  29. package/dist/bundle/chunks/cloudflare-workers-ai-system-one-XJQQYGGU.js +2 -0
  30. package/dist/bundle/chunks/codemode-worker.js +295 -0
  31. package/dist/bundle/chunks/execute-7XXPZAWW.js +308 -0
  32. package/dist/bundle/chunks/github-copilot.js +1 -1
  33. package/dist/bundle/chunks/google-generative-ai-CQAKKJTA.js +2 -0
  34. package/dist/bundle/chunks/google-vertex-AE36YXJU.js +2 -0
  35. package/dist/bundle/chunks/{lib-HGQMNYVT.js → lib-TEDK3E5I.js} +2 -2
  36. package/dist/bundle/chunks/llama-cpp-classify-PJJYKPLD.js +22 -0
  37. package/dist/bundle/chunks/mistral-conversations-KEYTXJM7.js +5 -0
  38. package/dist/bundle/chunks/{openai-codex-responses-QDSOTBBO.js → openai-codex-responses-JQTCOVEG.js} +2 -2
  39. package/dist/bundle/chunks/openai-codex.js +2 -2
  40. package/dist/bundle/chunks/{openai-completions-OBX42CLD.js → openai-completions-XW2Q5HVC.js} +2 -2
  41. package/dist/bundle/chunks/openai-responses-6AXWFL75.js +3 -0
  42. package/dist/bundle/chunks/{openrouter-images-N4XVVFSD.js → openrouter-images-TPQ4V6OR.js} +1 -1
  43. package/dist/bundle/chunks/openrouter.js +2 -2
  44. package/dist/bundle/chunks/{pi-messages-GFKBWJHZ.js → pi-messages-TM5SOOIW.js} +2 -2
  45. package/dist/bundle/chunks/radius.js +2 -2
  46. package/dist/bundle/chunks/runtime-G5WJPRBM.js +2 -0
  47. package/dist/bundle/chunks/typesafe-system-one-E7A4HNJI.js +2 -0
  48. package/dist/bundle/chunks/virtual-modules-AQ3FLU6H.js +2 -0
  49. package/dist/bundle/cli-runtime.js +1 -1
  50. package/dist/bundle/index.js +1 -1
  51. package/dist/bundle/rpc-entry.js +1 -1
  52. package/dist/cli/args.d.ts.map +1 -1
  53. package/dist/cli/args.js +4 -3
  54. package/dist/cli/args.js.map +1 -1
  55. package/dist/cli/auth-check.d.ts.map +1 -1
  56. package/dist/cli/auth-check.js.map +1 -1
  57. package/dist/cli/auth-command.d.ts.map +1 -1
  58. package/dist/cli/auth-command.js.map +1 -1
  59. package/dist/cli/config-selector.d.ts.map +1 -1
  60. package/dist/cli/config-selector.js.map +1 -1
  61. package/dist/cli/credential-print.d.ts.map +1 -1
  62. package/dist/cli/credential-print.js.map +1 -1
  63. package/dist/cli/file-processor.d.ts.map +1 -1
  64. package/dist/cli/file-processor.js.map +1 -1
  65. package/dist/cli/initial-message.d.ts +1 -1
  66. package/dist/cli/initial-message.d.ts.map +1 -1
  67. package/dist/cli/initial-message.js.map +1 -1
  68. package/dist/cli/list-models.d.ts.map +1 -1
  69. package/dist/cli/list-models.js.map +1 -1
  70. package/dist/cli/project-trust.d.ts.map +1 -1
  71. package/dist/cli/project-trust.js.map +1 -1
  72. package/dist/cli/session-picker.d.ts.map +1 -1
  73. package/dist/cli/session-picker.js.map +1 -1
  74. package/dist/cli/setup.d.ts.map +1 -1
  75. package/dist/cli/setup.js.map +1 -1
  76. package/dist/cli/startup-ui.d.ts.map +1 -1
  77. package/dist/cli/startup-ui.js +38 -30
  78. package/dist/cli/startup-ui.js.map +1 -1
  79. package/dist/cli.d.ts.map +1 -1
  80. package/dist/config.d.ts +18 -4
  81. package/dist/config.d.ts.map +1 -1
  82. package/dist/config.js +30 -4
  83. package/dist/config.js.map +1 -1
  84. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  85. package/dist/core/agent-session-runtime.js +1 -1
  86. package/dist/core/agent-session-runtime.js.map +1 -1
  87. package/dist/core/agent-session-services.d.ts.map +1 -1
  88. package/dist/core/agent-session-services.js +13 -0
  89. package/dist/core/agent-session-services.js.map +1 -1
  90. package/dist/core/agent-session.d.ts +135 -11
  91. package/dist/core/agent-session.d.ts.map +1 -1
  92. package/dist/core/agent-session.js +509 -253
  93. package/dist/core/agent-session.js.map +1 -1
  94. package/dist/core/auth-guidance.d.ts.map +1 -1
  95. package/dist/core/auth-guidance.js.map +1 -1
  96. package/dist/core/auth-storage.d.ts.map +1 -1
  97. package/dist/core/auth-storage.js.map +1 -1
  98. package/dist/core/bash-executor.d.ts.map +1 -1
  99. package/dist/core/bash-executor.js.map +1 -1
  100. package/dist/core/bug-report-upload.d.ts.map +1 -1
  101. package/dist/core/bug-report-upload.js.map +1 -1
  102. package/dist/core/bug-report.d.ts +1 -1
  103. package/dist/core/bug-report.d.ts.map +1 -1
  104. package/dist/core/bug-report.js +1 -1
  105. package/dist/core/bug-report.js.map +1 -1
  106. package/dist/core/cache-stats.d.ts.map +1 -1
  107. package/dist/core/cache-stats.js.map +1 -1
  108. package/dist/core/cache-warmer.d.ts.map +1 -1
  109. package/dist/core/cache-warmer.js.map +1 -1
  110. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  111. package/dist/core/compaction/branch-summarization.js.map +1 -1
  112. package/dist/core/compaction/compaction.d.ts.map +1 -1
  113. package/dist/core/compaction/compaction.js +1 -22
  114. package/dist/core/compaction/compaction.js.map +1 -1
  115. package/dist/core/compaction/index.d.ts.map +1 -1
  116. package/dist/core/compaction/utils.d.ts +2 -1
  117. package/dist/core/compaction/utils.d.ts.map +1 -1
  118. package/dist/core/compaction/utils.js +25 -18
  119. package/dist/core/compaction/utils.js.map +1 -1
  120. package/dist/core/crash-log.d.ts.map +1 -1
  121. package/dist/core/crash-log.js +2 -1
  122. package/dist/core/crash-log.js.map +1 -1
  123. package/dist/core/defaults.d.ts.map +1 -1
  124. package/dist/core/diagnostics.d.ts.map +1 -1
  125. package/dist/core/event-bus.d.ts.map +1 -1
  126. package/dist/core/event-bus.js.map +1 -1
  127. package/dist/core/exec.d.ts.map +1 -1
  128. package/dist/core/exec.js.map +1 -1
  129. package/dist/core/experimental.d.ts.map +1 -1
  130. package/dist/core/experimental.js.map +1 -1
  131. package/dist/core/export-html/ansi-to-html.d.ts.map +1 -1
  132. package/dist/core/export-html/ansi-to-html.js.map +1 -1
  133. package/dist/core/export-html/index.d.ts.map +1 -1
  134. package/dist/core/export-html/index.js.map +1 -1
  135. package/dist/core/export-html/template.css +10 -0
  136. package/dist/core/export-html/template.js +66 -17
  137. package/dist/core/export-html/tool-renderer.d.ts.map +1 -1
  138. package/dist/core/export-html/tool-renderer.js.map +1 -1
  139. package/dist/core/extensions/index.d.ts +1 -1
  140. package/dist/core/extensions/index.d.ts.map +1 -1
  141. package/dist/core/extensions/index.js.map +1 -1
  142. package/dist/core/extensions/jiti-loader.d.ts.map +1 -1
  143. package/dist/core/extensions/jiti-static-loader.d.ts.map +1 -1
  144. package/dist/core/extensions/loader.d.ts.map +1 -1
  145. package/dist/core/extensions/loader.js +55 -5
  146. package/dist/core/extensions/loader.js.map +1 -1
  147. package/dist/core/extensions/runner.d.ts +18 -1
  148. package/dist/core/extensions/runner.d.ts.map +1 -1
  149. package/dist/core/extensions/runner.js +99 -0
  150. package/dist/core/extensions/runner.js.map +1 -1
  151. package/dist/core/extensions/types.d.ts +296 -22
  152. package/dist/core/extensions/types.d.ts.map +1 -1
  153. package/dist/core/extensions/types.js.map +1 -1
  154. package/dist/core/extensions/virtual-modules.d.ts.map +1 -1
  155. package/dist/core/extensions/wrapper.d.ts +2 -2
  156. package/dist/core/extensions/wrapper.d.ts.map +1 -1
  157. package/dist/core/extensions/wrapper.js +3 -3
  158. package/dist/core/extensions/wrapper.js.map +1 -1
  159. package/dist/core/footer-data-provider.d.ts.map +1 -1
  160. package/dist/core/footer-data-provider.js.map +1 -1
  161. package/dist/core/http-dispatcher.d.ts.map +1 -1
  162. package/dist/core/http-dispatcher.js.map +1 -1
  163. package/dist/core/index.d.ts.map +1 -1
  164. package/dist/core/keybindings.d.ts +1 -1
  165. package/dist/core/keybindings.d.ts.map +1 -1
  166. package/dist/core/keybindings.js +1 -1
  167. package/dist/core/keybindings.js.map +1 -1
  168. package/dist/core/mcp-servers.d.ts +98 -0
  169. package/dist/core/mcp-servers.d.ts.map +1 -0
  170. package/dist/core/mcp-servers.js +157 -0
  171. package/dist/core/mcp-servers.js.map +1 -0
  172. package/dist/core/messages.d.ts.map +1 -1
  173. package/dist/core/messages.js.map +1 -1
  174. package/dist/core/model-config.d.ts.map +1 -1
  175. package/dist/core/model-config.js.map +1 -1
  176. package/dist/core/model-registry.d.ts +13 -1
  177. package/dist/core/model-registry.d.ts.map +1 -1
  178. package/dist/core/model-registry.js +25 -0
  179. package/dist/core/model-registry.js.map +1 -1
  180. package/dist/core/model-resolver.d.ts +2 -2
  181. package/dist/core/model-resolver.d.ts.map +1 -1
  182. package/dist/core/model-resolver.js +4 -4
  183. package/dist/core/model-resolver.js.map +1 -1
  184. package/dist/core/model-runtime.d.ts +41 -3
  185. package/dist/core/model-runtime.d.ts.map +1 -1
  186. package/dist/core/model-runtime.js +167 -17
  187. package/dist/core/model-runtime.js.map +1 -1
  188. package/dist/core/models-store.d.ts.map +1 -1
  189. package/dist/core/models-store.js.map +1 -1
  190. package/dist/core/nested-tool-calls.d.ts +102 -0
  191. package/dist/core/nested-tool-calls.d.ts.map +1 -0
  192. package/dist/core/nested-tool-calls.js +178 -0
  193. package/dist/core/nested-tool-calls.js.map +1 -0
  194. package/dist/core/output-guard.d.ts.map +1 -1
  195. package/dist/core/output-guard.js.map +1 -1
  196. package/dist/core/package-manager.d.ts +4 -0
  197. package/dist/core/package-manager.d.ts.map +1 -1
  198. package/dist/core/package-manager.js +59 -12
  199. package/dist/core/package-manager.js.map +1 -1
  200. package/dist/core/pi-manifest.d.ts.map +1 -1
  201. package/dist/core/pi-manifest.js.map +1 -1
  202. package/dist/core/project-trust.d.ts.map +1 -1
  203. package/dist/core/project-trust.js.map +1 -1
  204. package/dist/core/prompt-templates.d.ts.map +1 -1
  205. package/dist/core/prompt-templates.js.map +1 -1
  206. package/dist/core/provider-attribution.d.ts.map +1 -1
  207. package/dist/core/provider-attribution.js.map +1 -1
  208. package/dist/core/provider-composer.d.ts +40 -21
  209. package/dist/core/provider-composer.d.ts.map +1 -1
  210. package/dist/core/provider-composer.js +92 -40
  211. package/dist/core/provider-composer.js.map +1 -1
  212. package/dist/core/radius.d.ts.map +1 -1
  213. package/dist/core/radius.js.map +1 -1
  214. package/dist/core/remote-catalog-provider.d.ts +8 -1
  215. package/dist/core/remote-catalog-provider.d.ts.map +1 -1
  216. package/dist/core/remote-catalog-provider.js +18 -3
  217. package/dist/core/remote-catalog-provider.js.map +1 -1
  218. package/dist/core/resolve-config-value.d.ts.map +1 -1
  219. package/dist/core/resolve-config-value.js.map +1 -1
  220. package/dist/core/resource-loader.d.ts +7 -1
  221. package/dist/core/resource-loader.d.ts.map +1 -1
  222. package/dist/core/resource-loader.js +161 -35
  223. package/dist/core/resource-loader.js.map +1 -1
  224. package/dist/core/runtime-credentials.d.ts.map +1 -1
  225. package/dist/core/runtime-credentials.js.map +1 -1
  226. package/dist/core/sdk.d.ts +1 -1
  227. package/dist/core/sdk.d.ts.map +1 -1
  228. package/dist/core/sdk.js +24 -6
  229. package/dist/core/sdk.js.map +1 -1
  230. package/dist/core/session-cwd.d.ts.map +1 -1
  231. package/dist/core/session-cwd.js.map +1 -1
  232. package/dist/core/session-export.d.ts.map +1 -1
  233. package/dist/core/session-export.js.map +1 -1
  234. package/dist/core/session-manager.d.ts +9 -0
  235. package/dist/core/session-manager.d.ts.map +1 -1
  236. package/dist/core/session-manager.js +22 -22
  237. package/dist/core/session-manager.js.map +1 -1
  238. package/dist/core/settings-diagnostics.d.ts.map +1 -1
  239. package/dist/core/settings-diagnostics.js.map +1 -1
  240. package/dist/core/settings-manager.d.ts +31 -1
  241. package/dist/core/settings-manager.d.ts.map +1 -1
  242. package/dist/core/settings-manager.js +72 -2
  243. package/dist/core/settings-manager.js.map +1 -1
  244. package/dist/core/skills.d.ts.map +1 -1
  245. package/dist/core/skills.js.map +1 -1
  246. package/dist/core/slash-commands.d.ts.map +1 -1
  247. package/dist/core/source-info.d.ts +8 -0
  248. package/dist/core/source-info.d.ts.map +1 -1
  249. package/dist/core/source-info.js +16 -0
  250. package/dist/core/source-info.js.map +1 -1
  251. package/dist/core/system-prompt.d.ts.map +1 -1
  252. package/dist/core/system-prompt.js +1 -1
  253. package/dist/core/system-prompt.js.map +1 -1
  254. package/dist/core/telemetry.d.ts.map +1 -1
  255. package/dist/core/telemetry.js.map +1 -1
  256. package/dist/core/timings.d.ts.map +1 -1
  257. package/dist/core/timings.js.map +1 -1
  258. package/dist/core/tools/bash.d.ts +12 -0
  259. package/dist/core/tools/bash.d.ts.map +1 -1
  260. package/dist/core/tools/bash.js +35 -2
  261. package/dist/core/tools/bash.js.map +1 -1
  262. package/dist/core/tools/edit-diff.d.ts.map +1 -1
  263. package/dist/core/tools/edit-diff.js.map +1 -1
  264. package/dist/core/tools/edit.d.ts.map +1 -1
  265. package/dist/core/tools/edit.js.map +1 -1
  266. package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
  267. package/dist/core/tools/file-mutation-queue.js.map +1 -1
  268. package/dist/core/tools/find.d.ts.map +1 -1
  269. package/dist/core/tools/find.js.map +1 -1
  270. package/dist/core/tools/grep.d.ts.map +1 -1
  271. package/dist/core/tools/grep.js.map +1 -1
  272. package/dist/core/tools/index.d.ts.map +1 -1
  273. package/dist/core/tools/index.js.map +1 -1
  274. package/dist/core/tools/ls.d.ts.map +1 -1
  275. package/dist/core/tools/ls.js.map +1 -1
  276. package/dist/core/tools/output-accumulator.d.ts +11 -0
  277. package/dist/core/tools/output-accumulator.d.ts.map +1 -1
  278. package/dist/core/tools/output-accumulator.js +36 -0
  279. package/dist/core/tools/output-accumulator.js.map +1 -1
  280. package/dist/core/tools/path-utils.d.ts.map +1 -1
  281. package/dist/core/tools/path-utils.js.map +1 -1
  282. package/dist/core/tools/powershell.d.ts.map +1 -1
  283. package/dist/core/tools/powershell.js.map +1 -1
  284. package/dist/core/tools/read.d.ts.map +1 -1
  285. package/dist/core/tools/read.js.map +1 -1
  286. package/dist/core/tools/render-utils.d.ts +6 -0
  287. package/dist/core/tools/render-utils.d.ts.map +1 -1
  288. package/dist/core/tools/render-utils.js +26 -0
  289. package/dist/core/tools/render-utils.js.map +1 -1
  290. package/dist/core/tools/renderers/bash.d.ts.map +1 -1
  291. package/dist/core/tools/renderers/bash.js +9 -10
  292. package/dist/core/tools/renderers/bash.js.map +1 -1
  293. package/dist/core/tools/renderers/edit.d.ts.map +1 -1
  294. package/dist/core/tools/renderers/edit.js.map +1 -1
  295. package/dist/core/tools/renderers/find.d.ts.map +1 -1
  296. package/dist/core/tools/renderers/find.js.map +1 -1
  297. package/dist/core/tools/renderers/grep.d.ts.map +1 -1
  298. package/dist/core/tools/renderers/grep.js.map +1 -1
  299. package/dist/core/tools/renderers/index.d.ts.map +1 -1
  300. package/dist/core/tools/renderers/index.js.map +1 -1
  301. package/dist/core/tools/renderers/ls.d.ts.map +1 -1
  302. package/dist/core/tools/renderers/ls.js.map +1 -1
  303. package/dist/core/tools/renderers/read.d.ts.map +1 -1
  304. package/dist/core/tools/renderers/read.js +3 -2
  305. package/dist/core/tools/renderers/read.js.map +1 -1
  306. package/dist/core/tools/renderers/write.d.ts.map +1 -1
  307. package/dist/core/tools/renderers/write.js.map +1 -1
  308. package/dist/core/tools/tool-definition-wrapper.d.ts +5 -3
  309. package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
  310. package/dist/core/tools/tool-definition-wrapper.js +3 -1
  311. package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
  312. package/dist/core/tools/truncate.d.ts +14 -0
  313. package/dist/core/tools/truncate.d.ts.map +1 -1
  314. package/dist/core/tools/truncate.js +29 -0
  315. package/dist/core/tools/truncate.js.map +1 -1
  316. package/dist/core/tools/write.d.ts.map +1 -1
  317. package/dist/core/tools/write.js.map +1 -1
  318. package/dist/core/trust-manager.d.ts.map +1 -1
  319. package/dist/core/trust-manager.js +1 -0
  320. package/dist/core/trust-manager.js.map +1 -1
  321. package/dist/core/usage-totals.d.ts +2 -0
  322. package/dist/core/usage-totals.d.ts.map +1 -1
  323. package/dist/core/usage-totals.js +23 -0
  324. package/dist/core/usage-totals.js.map +1 -1
  325. package/dist/core/virtual-models.d.ts +115 -0
  326. package/dist/core/virtual-models.d.ts.map +1 -0
  327. package/dist/core/virtual-models.js +117 -0
  328. package/dist/core/virtual-models.js.map +1 -0
  329. package/dist/extensions/codemode/execute.d.ts +16 -0
  330. package/dist/extensions/codemode/execute.d.ts.map +1 -0
  331. package/dist/extensions/codemode/execute.js +390 -0
  332. package/dist/extensions/codemode/execute.js.map +1 -0
  333. package/dist/extensions/codemode/execute.lazy.d.ts +3 -0
  334. package/dist/extensions/codemode/execute.lazy.d.ts.map +1 -0
  335. package/dist/extensions/codemode/execute.lazy.js +3 -0
  336. package/dist/extensions/codemode/execute.lazy.js.map +1 -0
  337. package/dist/extensions/codemode/index.d.ts +21 -0
  338. package/dist/extensions/codemode/index.d.ts.map +1 -0
  339. package/dist/extensions/codemode/index.js +31 -0
  340. package/dist/extensions/codemode/index.js.map +1 -0
  341. package/dist/extensions/codemode/renderer.d.ts +12 -0
  342. package/dist/extensions/codemode/renderer.d.ts.map +1 -0
  343. package/dist/extensions/codemode/renderer.js +119 -0
  344. package/dist/extensions/codemode/renderer.js.map +1 -0
  345. package/dist/extensions/codemode/tool.d.ts +122 -0
  346. package/dist/extensions/codemode/tool.d.ts.map +1 -0
  347. package/dist/extensions/codemode/tool.js +324 -0
  348. package/dist/extensions/codemode/tool.js.map +1 -0
  349. package/dist/extensions/codemode/worker.d.ts +7 -0
  350. package/dist/extensions/codemode/worker.d.ts.map +1 -0
  351. package/dist/extensions/codemode/worker.js +7 -0
  352. package/dist/extensions/codemode/worker.js.map +1 -0
  353. package/dist/extensions/index.d.ts.map +1 -1
  354. package/dist/extensions/index.js +11 -1
  355. package/dist/extensions/index.js.map +1 -1
  356. package/dist/extensions/llama/client.d.ts.map +1 -1
  357. package/dist/extensions/llama/client.js.map +1 -1
  358. package/dist/extensions/llama/huggingface.d.ts.map +1 -1
  359. package/dist/extensions/llama/huggingface.js.map +1 -1
  360. package/dist/extensions/llama/index.d.ts.map +1 -1
  361. package/dist/extensions/llama/index.js.map +1 -1
  362. package/dist/extensions/llama/provider.d.ts +1 -1
  363. package/dist/extensions/llama/provider.d.ts.map +1 -1
  364. package/dist/extensions/llama/provider.js +65 -13
  365. package/dist/extensions/llama/provider.js.map +1 -1
  366. package/dist/extensions/llama/ui.d.ts.map +1 -1
  367. package/dist/extensions/llama/ui.js.map +1 -1
  368. package/dist/extensions/mcp/cli.d.ts +21 -0
  369. package/dist/extensions/mcp/cli.d.ts.map +1 -0
  370. package/dist/extensions/mcp/cli.js +485 -0
  371. package/dist/extensions/mcp/cli.js.map +1 -0
  372. package/dist/extensions/mcp/cli.lazy.d.ts +3 -0
  373. package/dist/extensions/mcp/cli.lazy.d.ts.map +1 -0
  374. package/dist/extensions/mcp/cli.lazy.js +3 -0
  375. package/dist/extensions/mcp/cli.lazy.js.map +1 -0
  376. package/dist/extensions/mcp/config.d.ts +70 -0
  377. package/dist/extensions/mcp/config.d.ts.map +1 -0
  378. package/dist/extensions/mcp/config.js +146 -0
  379. package/dist/extensions/mcp/config.js.map +1 -0
  380. package/dist/extensions/mcp/index.d.ts +52 -0
  381. package/dist/extensions/mcp/index.d.ts.map +1 -0
  382. package/dist/extensions/mcp/index.js +902 -0
  383. package/dist/extensions/mcp/index.js.map +1 -0
  384. package/dist/extensions/mcp/log.d.ts +16 -0
  385. package/dist/extensions/mcp/log.d.ts.map +1 -0
  386. package/dist/extensions/mcp/log.js +66 -0
  387. package/dist/extensions/mcp/log.js.map +1 -0
  388. package/dist/extensions/mcp/oauth.d.ts +94 -0
  389. package/dist/extensions/mcp/oauth.d.ts.map +1 -0
  390. package/dist/extensions/mcp/oauth.js +333 -0
  391. package/dist/extensions/mcp/oauth.js.map +1 -0
  392. package/dist/extensions/mcp/resources.d.ts +43 -0
  393. package/dist/extensions/mcp/resources.d.ts.map +1 -0
  394. package/dist/extensions/mcp/resources.js +262 -0
  395. package/dist/extensions/mcp/resources.js.map +1 -0
  396. package/dist/extensions/mcp/runtime.d.ts +96 -0
  397. package/dist/extensions/mcp/runtime.d.ts.map +1 -0
  398. package/dist/extensions/mcp/runtime.js +388 -0
  399. package/dist/extensions/mcp/runtime.js.map +1 -0
  400. package/dist/extensions/mcp/runtime.lazy.d.ts +3 -0
  401. package/dist/extensions/mcp/runtime.lazy.d.ts.map +1 -0
  402. package/dist/extensions/mcp/runtime.lazy.js +3 -0
  403. package/dist/extensions/mcp/runtime.lazy.js.map +1 -0
  404. package/dist/extensions/mcp/tools.d.ts +83 -0
  405. package/dist/extensions/mcp/tools.d.ts.map +1 -0
  406. package/dist/extensions/mcp/tools.js +233 -0
  407. package/dist/extensions/mcp/tools.js.map +1 -0
  408. package/dist/extensions/mcp/ui.d.ts +60 -0
  409. package/dist/extensions/mcp/ui.d.ts.map +1 -0
  410. package/dist/extensions/mcp/ui.js +172 -0
  411. package/dist/extensions/mcp/ui.js.map +1 -0
  412. package/dist/extensions/tool-search/index.d.ts +12 -0
  413. package/dist/extensions/tool-search/index.d.ts.map +1 -0
  414. package/dist/extensions/tool-search/index.js +15 -0
  415. package/dist/extensions/tool-search/index.js.map +1 -0
  416. package/dist/extensions/tool-search/tool.d.ts +72 -0
  417. package/dist/extensions/tool-search/tool.d.ts.map +1 -0
  418. package/dist/extensions/tool-search/tool.js +210 -0
  419. package/dist/extensions/tool-search/tool.js.map +1 -0
  420. package/dist/index.d.ts +9 -2
  421. package/dist/index.d.ts.map +1 -1
  422. package/dist/index.js +5 -0
  423. package/dist/index.js.map +1 -1
  424. package/dist/main.d.ts.map +1 -1
  425. package/dist/main.js +10 -0
  426. package/dist/main.js.map +1 -1
  427. package/dist/migrations.d.ts.map +1 -1
  428. package/dist/migrations.js.map +1 -1
  429. package/dist/modes/index.d.ts.map +1 -1
  430. package/dist/modes/interactive/bug-report.d.ts.map +1 -1
  431. package/dist/modes/interactive/bug-report.js.map +1 -1
  432. package/dist/modes/interactive/chat-viewport.d.ts.map +1 -1
  433. package/dist/modes/interactive/chat-viewport.js.map +1 -1
  434. package/dist/modes/interactive/components/armin.d.ts.map +1 -1
  435. package/dist/modes/interactive/components/armin.js.map +1 -1
  436. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  437. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  438. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  439. package/dist/modes/interactive/components/bash-execution.js.map +1 -1
  440. package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -1
  441. package/dist/modes/interactive/components/bordered-loader.js.map +1 -1
  442. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
  443. package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
  444. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
  445. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
  446. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  447. package/dist/modes/interactive/components/config-selector.js +13 -3
  448. package/dist/modes/interactive/components/config-selector.js.map +1 -1
  449. package/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -1
  450. package/dist/modes/interactive/components/countdown-timer.js.map +1 -1
  451. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
  452. package/dist/modes/interactive/components/custom-editor.js.map +1 -1
  453. package/dist/modes/interactive/components/custom-entry.d.ts.map +1 -1
  454. package/dist/modes/interactive/components/custom-entry.js.map +1 -1
  455. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
  456. package/dist/modes/interactive/components/custom-message.js.map +1 -1
  457. package/dist/modes/interactive/components/daxnuts.d.ts.map +1 -1
  458. package/dist/modes/interactive/components/daxnuts.js.map +1 -1
  459. package/dist/modes/interactive/components/diff.d.ts.map +1 -1
  460. package/dist/modes/interactive/components/diff.js.map +1 -1
  461. package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
  462. package/dist/modes/interactive/components/dynamic-border.js.map +1 -1
  463. package/dist/modes/interactive/components/earendil-announcement.d.ts.map +1 -1
  464. package/dist/modes/interactive/components/earendil-announcement.js.map +1 -1
  465. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
  466. package/dist/modes/interactive/components/extension-editor.js.map +1 -1
  467. package/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
  468. package/dist/modes/interactive/components/extension-input.js.map +1 -1
  469. package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
  470. package/dist/modes/interactive/components/extension-selector.js.map +1 -1
  471. package/dist/modes/interactive/components/first-time-setup.d.ts +4 -4
  472. package/dist/modes/interactive/components/first-time-setup.d.ts.map +1 -1
  473. package/dist/modes/interactive/components/first-time-setup.js +8 -2
  474. package/dist/modes/interactive/components/first-time-setup.js.map +1 -1
  475. package/dist/modes/interactive/components/footer.d.ts +7 -0
  476. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  477. package/dist/modes/interactive/components/footer.js +43 -3
  478. package/dist/modes/interactive/components/footer.js.map +1 -1
  479. package/dist/modes/interactive/components/index.d.ts.map +1 -1
  480. package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
  481. package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
  482. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  483. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  484. package/dist/modes/interactive/components/markdown-transform.d.ts.map +1 -1
  485. package/dist/modes/interactive/components/markdown-transform.js.map +1 -1
  486. package/dist/modes/interactive/components/mermaid.d.ts.map +1 -1
  487. package/dist/modes/interactive/components/mermaid.js.map +1 -1
  488. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  489. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  490. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  491. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  492. package/dist/modes/interactive/components/pi-logo.d.ts +12 -0
  493. package/dist/modes/interactive/components/pi-logo.d.ts.map +1 -0
  494. package/dist/modes/interactive/components/pi-logo.js +25 -0
  495. package/dist/modes/interactive/components/pi-logo.js.map +1 -0
  496. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
  497. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
  498. package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
  499. package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
  500. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  501. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  502. package/dist/modes/interactive/components/settings-selector.d.ts +3 -1
  503. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  504. package/dist/modes/interactive/components/settings-selector.js +28 -6
  505. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  506. package/dist/modes/interactive/components/settings-submenu.d.ts.map +1 -1
  507. package/dist/modes/interactive/components/settings-submenu.js.map +1 -1
  508. package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -1
  509. package/dist/modes/interactive/components/show-images-selector.js.map +1 -1
  510. package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
  511. package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
  512. package/dist/modes/interactive/components/status-indicator.d.ts.map +1 -1
  513. package/dist/modes/interactive/components/status-indicator.js.map +1 -1
  514. package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -1
  515. package/dist/modes/interactive/components/theme-selector.js.map +1 -1
  516. package/dist/modes/interactive/components/themed-text.d.ts +17 -0
  517. package/dist/modes/interactive/components/themed-text.d.ts.map +1 -0
  518. package/dist/modes/interactive/components/themed-text.js +29 -0
  519. package/dist/modes/interactive/components/themed-text.js.map +1 -0
  520. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
  521. package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
  522. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  523. package/dist/modes/interactive/components/tool-execution.js +2 -2
  524. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  525. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
  526. package/dist/modes/interactive/components/tree-selector.js.map +1 -1
  527. package/dist/modes/interactive/components/trust-selector.d.ts.map +1 -1
  528. package/dist/modes/interactive/components/trust-selector.js.map +1 -1
  529. package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
  530. package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
  531. package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  532. package/dist/modes/interactive/components/user-message.js.map +1 -1
  533. package/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -1
  534. package/dist/modes/interactive/components/visual-truncate.js.map +1 -1
  535. package/dist/modes/interactive/external-editor.d.ts.map +1 -1
  536. package/dist/modes/interactive/external-editor.js.map +1 -1
  537. package/dist/modes/interactive/interactive-mode.d.ts +11 -0
  538. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  539. package/dist/modes/interactive/interactive-mode.js +199 -161
  540. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  541. package/dist/modes/interactive/model-catalog-refresh.d.ts.map +1 -1
  542. package/dist/modes/interactive/model-catalog-refresh.js.map +1 -1
  543. package/dist/modes/interactive/model-search.d.ts.map +1 -1
  544. package/dist/modes/interactive/model-search.js.map +1 -1
  545. package/dist/modes/interactive/session-share.d.ts.map +1 -1
  546. package/dist/modes/interactive/session-share.js.map +1 -1
  547. package/dist/modes/interactive/theme/dark.json +59 -72
  548. package/dist/modes/interactive/theme/light.json +57 -69
  549. package/dist/modes/interactive/theme/system-theme.d.ts +54 -0
  550. package/dist/modes/interactive/theme/system-theme.d.ts.map +1 -0
  551. package/dist/modes/interactive/theme/system-theme.js +535 -0
  552. package/dist/modes/interactive/theme/system-theme.js.map +1 -0
  553. package/dist/modes/interactive/theme/theme-controller.d.ts +46 -6
  554. package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -1
  555. package/dist/modes/interactive/theme/theme-controller.js +127 -47
  556. package/dist/modes/interactive/theme/theme-controller.js.map +1 -1
  557. package/dist/modes/interactive/theme/theme-json.d.ts +1 -0
  558. package/dist/modes/interactive/theme/theme-json.d.ts.map +1 -1
  559. package/dist/modes/interactive/theme/theme-json.js +3 -1
  560. package/dist/modes/interactive/theme/theme-json.js.map +1 -1
  561. package/dist/modes/interactive/theme/theme-schema.json +7 -2
  562. package/dist/modes/interactive/theme/theme.d.ts +66 -39
  563. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  564. package/dist/modes/interactive/theme/theme.js +238 -317
  565. package/dist/modes/interactive/theme/theme.js.map +1 -1
  566. package/dist/modes/interactive/tui-renderer.d.ts +2 -1
  567. package/dist/modes/interactive/tui-renderer.d.ts.map +1 -1
  568. package/dist/modes/interactive/tui-renderer.js +1 -0
  569. package/dist/modes/interactive/tui-renderer.js.map +1 -1
  570. package/dist/modes/json-event.d.ts.map +1 -1
  571. package/dist/modes/json-event.js.map +1 -1
  572. package/dist/modes/print-mode.d.ts.map +1 -1
  573. package/dist/modes/print-mode.js.map +1 -1
  574. package/dist/modes/rpc/jsonl.d.ts.map +1 -1
  575. package/dist/modes/rpc/jsonl.js.map +1 -1
  576. package/dist/modes/rpc/rpc-client.d.ts +6 -6
  577. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  578. package/dist/modes/rpc/rpc-client.js +12 -8
  579. package/dist/modes/rpc/rpc-client.js.map +1 -1
  580. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  581. package/dist/modes/rpc/rpc-mode.js +7 -9
  582. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  583. package/dist/modes/rpc/rpc-types.d.ts +10 -1
  584. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  585. package/dist/modes/rpc/rpc-types.js.map +1 -1
  586. package/dist/package-manager-cli.d.ts.map +1 -1
  587. package/dist/package-manager-cli.js +6 -2
  588. package/dist/package-manager-cli.js.map +1 -1
  589. package/dist/rpc-entry.d.ts.map +1 -1
  590. package/dist/rpc-entry.js.map +1 -1
  591. package/dist/utils/abort.d.ts.map +1 -1
  592. package/dist/utils/abort.js.map +1 -1
  593. package/dist/utils/ansi.d.ts.map +1 -1
  594. package/dist/utils/ansi.js.map +1 -1
  595. package/dist/utils/changelog.d.ts.map +1 -1
  596. package/dist/utils/changelog.js.map +1 -1
  597. package/dist/utils/child-process.d.ts.map +1 -1
  598. package/dist/utils/child-process.js.map +1 -1
  599. package/dist/utils/clipboard-command.d.ts.map +1 -1
  600. package/dist/utils/clipboard-command.js.map +1 -1
  601. package/dist/utils/clipboard-image.d.ts.map +1 -1
  602. package/dist/utils/clipboard-image.js +14 -17
  603. package/dist/utils/clipboard-image.js.map +1 -1
  604. package/dist/utils/clipboard.d.ts +2 -0
  605. package/dist/utils/clipboard.d.ts.map +1 -1
  606. package/dist/utils/clipboard.js +5 -0
  607. package/dist/utils/clipboard.js.map +1 -1
  608. package/dist/utils/deprecation.d.ts.map +1 -1
  609. package/dist/utils/deprecation.js.map +1 -1
  610. package/dist/utils/exif-orientation.d.ts.map +1 -1
  611. package/dist/utils/exif-orientation.js.map +1 -1
  612. package/dist/utils/frontmatter.d.ts.map +1 -1
  613. package/dist/utils/frontmatter.js.map +1 -1
  614. package/dist/utils/fs-watch.d.ts.map +1 -1
  615. package/dist/utils/fs-watch.js.map +1 -1
  616. package/dist/utils/git.d.ts.map +1 -1
  617. package/dist/utils/git.js.map +1 -1
  618. package/dist/utils/html.d.ts.map +1 -1
  619. package/dist/utils/html.js.map +1 -1
  620. package/dist/utils/image-convert.d.ts.map +1 -1
  621. package/dist/utils/image-convert.js.map +1 -1
  622. package/dist/utils/image-process.d.ts.map +1 -1
  623. package/dist/utils/image-process.js.map +1 -1
  624. package/dist/utils/image-resize-core.d.ts.map +1 -1
  625. package/dist/utils/image-resize-core.js.map +1 -1
  626. package/dist/utils/image-resize-worker.d.ts.map +1 -1
  627. package/dist/utils/image-resize-worker.js.map +1 -1
  628. package/dist/utils/image-resize.d.ts.map +1 -1
  629. package/dist/utils/image-resize.js.map +1 -1
  630. package/dist/utils/json.d.ts.map +1 -1
  631. package/dist/utils/json.js.map +1 -1
  632. package/dist/utils/management-http.d.ts.map +1 -1
  633. package/dist/utils/management-http.js.map +1 -1
  634. package/dist/utils/mime.d.ts.map +1 -1
  635. package/dist/utils/mime.js.map +1 -1
  636. package/dist/utils/open-browser.d.ts.map +1 -1
  637. package/dist/utils/open-browser.js.map +1 -1
  638. package/dist/utils/paths.d.ts +3 -3
  639. package/dist/utils/paths.d.ts.map +1 -1
  640. package/dist/utils/paths.js +5 -4
  641. package/dist/utils/paths.js.map +1 -1
  642. package/dist/utils/photon.d.ts.map +1 -1
  643. package/dist/utils/photon.js.map +1 -1
  644. package/dist/utils/pi-user-agent.d.ts.map +1 -1
  645. package/dist/utils/pi-user-agent.js.map +1 -1
  646. package/dist/utils/shell.d.ts +1 -3
  647. package/dist/utils/shell.d.ts.map +1 -1
  648. package/dist/utils/shell.js +3 -30
  649. package/dist/utils/shell.js.map +1 -1
  650. package/dist/utils/sleep.d.ts.map +1 -1
  651. package/dist/utils/sleep.js.map +1 -1
  652. package/dist/utils/syntax-highlight.d.ts.map +1 -1
  653. package/dist/utils/syntax-highlight.js +2 -0
  654. package/dist/utils/syntax-highlight.js.map +1 -1
  655. package/dist/utils/text.d.ts.map +1 -1
  656. package/dist/utils/text.js.map +1 -1
  657. package/dist/utils/tool-result-images.d.ts.map +1 -1
  658. package/dist/utils/tool-result-images.js.map +1 -1
  659. package/dist/utils/tools-manager.d.ts.map +1 -1
  660. package/dist/utils/tools-manager.js.map +1 -1
  661. package/dist/utils/version-check.d.ts.map +1 -1
  662. package/dist/utils/version-check.js.map +1 -1
  663. package/dist/utils/windows-self-update.d.ts.map +1 -1
  664. package/dist/utils/windows-self-update.js.map +1 -1
  665. package/dist/utils/wsl.d.ts.map +1 -1
  666. package/dist/utils/wsl.js.map +1 -1
  667. package/dist/utils/zip.d.ts.map +1 -1
  668. package/dist/utils/zip.js.map +1 -1
  669. package/docs/cli.md +64 -3
  670. package/docs/configuration.md +2 -0
  671. package/docs/custom-provider.md +43 -4
  672. package/docs/docs.json +8 -0
  673. package/docs/extensions.md +55 -0
  674. package/docs/keybindings.md +1 -1
  675. package/docs/llama-cpp.md +13 -0
  676. package/docs/mcp.md +188 -0
  677. package/docs/models.md +35 -0
  678. package/docs/packages.md +4 -2
  679. package/docs/providers.md +1 -0
  680. package/docs/rpc-commands.md +9 -3
  681. package/docs/rpc.md +3 -1
  682. package/docs/sdk.md +7 -2
  683. package/docs/security.md +2 -0
  684. package/docs/session-format.md +5 -1
  685. package/docs/settings.md +20 -3
  686. package/docs/themes.md +33 -7
  687. package/docs/tui.md +18 -0
  688. package/docs/virtual-models.md +114 -0
  689. package/docs/windows.md +2 -0
  690. package/examples/README.md +1 -1
  691. package/examples/extensions/README.md +2 -0
  692. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  693. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  694. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  695. package/examples/extensions/custom-provider-gitlab-duo/test.ts +5 -5
  696. package/examples/extensions/debug-provider.ts +90 -0
  697. package/examples/extensions/gondolin/package-lock.json +2 -2
  698. package/examples/extensions/gondolin/package.json +1 -1
  699. package/examples/extensions/jev-router.ts +113 -0
  700. package/examples/extensions/sandbox/package-lock.json +2 -2
  701. package/examples/extensions/sandbox/package.json +1 -1
  702. package/examples/extensions/with-deps/package-lock.json +2 -2
  703. package/examples/extensions/with-deps/package.json +1 -1
  704. package/examples/rpc-client.ts +1 -1
  705. package/examples/rpc-extension-ui.ts +1 -1
  706. package/examples/sdk/14-codemode-mcp.ts +61 -0
  707. package/examples/sdk/README.md +2 -1
  708. package/npm-shrinkwrap.json +89 -39
  709. package/package.json +14 -12
  710. package/dist/bundle/chunks/anthropic-messages-J5WXPPPC.js +0 -6
  711. package/dist/bundle/chunks/azure-openai-responses-HUSQ3GP2.js +0 -2
  712. package/dist/bundle/chunks/chunk-65HAU2C5.js +0 -2
  713. package/dist/bundle/chunks/chunk-6R7UI4IY.js +0 -2
  714. package/dist/bundle/chunks/chunk-NUHFSC37.js +0 -25
  715. package/dist/bundle/chunks/chunk-OJP47DM6.js +0 -1568
  716. package/dist/bundle/chunks/chunk-RCZIEVGO.js +0 -11
  717. package/dist/bundle/chunks/google-generative-ai-IMS5EK2Y.js +0 -2
  718. package/dist/bundle/chunks/google-vertex-O4YJEQUW.js +0 -2
  719. package/dist/bundle/chunks/mistral-conversations-NOSQHBEY.js +0 -5
  720. package/dist/bundle/chunks/openai-responses-HWEUZ6WZ.js +0 -2
  721. package/dist/bundle/chunks/virtual-modules-VHMJYYWQ.js +0 -2
@@ -1,20 +1,31 @@
1
- import type { TUI } from "@earendil-works/pi-tui";
1
+ import type { TerminalColors, TUI } from "@earendil-works/pi-tui";
2
2
  import type { SettingsManager } from "../../../core/settings-manager.ts";
3
3
  import { type TerminalTheme, type Theme } from "./theme.ts";
4
4
  type ThemeResult = {
5
5
  success: boolean;
6
6
  error?: string;
7
7
  };
8
+ /**
9
+ * Query the terminal's colors and pass them to `apply` when the query completes or times out, and again
10
+ * if the terminal answers after the timeout. A failed query applies no colors. Settles after the first apply.
11
+ */
12
+ export declare function requestTerminalColors(ui: TUI, apply: (colors: TerminalColors) => void): Promise<void>;
13
+ /**
14
+ * Applies the theme setting and keeps it in sync with the terminal. The theme applies immediately, and the
15
+ * terminal's colors update it when they arrive; the system theme renders in grayscale until then. Callers
16
+ * that bake theme colors into content can wait for the colors with `waitForTerminalColors()`.
17
+ */
8
18
  export declare class InteractiveThemeController {
9
19
  private readonly ui;
10
20
  private readonly getSettingsManager;
11
21
  private readonly showError;
12
22
  private readonly onChanged;
13
23
  private currentThemeSetting;
14
- private terminalTheme;
24
+ private terminalColors;
15
25
  private activeThemeName;
16
26
  private autoSyncEnabled;
17
27
  private terminalColorSchemeUnsubscribe;
28
+ private terminalColorQuery;
18
29
  constructor(ui: TUI, options: {
19
30
  getSettingsManager: () => SettingsManager;
20
31
  showError: (message: string) => void;
@@ -22,20 +33,49 @@ export declare class InteractiveThemeController {
22
33
  initialThemeSetting?: string;
23
34
  });
24
35
  rebindTui(): void;
25
- applyFromSettings(): Promise<void>;
36
+ /**
37
+ * Apply the theme setting now and query the terminal's colors, which update the theme when they arrive.
38
+ * Theme pairs and the system theme follow terminal appearance changes.
39
+ */
40
+ applyFromSettings(): void;
41
+ /**
42
+ * Wait until the latest color query completed or timed out. Content that bakes theme colors into
43
+ * strings, such as the startup header, should be built after this. Terminals answer the DA1 request
44
+ * right after the color replies, so this only takes the full timeout when a terminal answers nothing.
45
+ */
46
+ waitForTerminalColors(): Promise<void>;
26
47
  getThemeSelection(): string | undefined;
27
48
  setThemeName(themeName: string, showError?: boolean): ThemeResult;
28
- setThemeSetting(themeSetting: string): Promise<void>;
49
+ setThemeSetting(themeSetting: string): void;
29
50
  setThemeInstance(themeInstance: Theme): ThemeResult;
30
51
  preview(themeSettingOrName: string): void;
31
52
  disableAutoSync(): void;
32
53
  dispose(): void;
33
54
  getTerminalTheme(): TerminalTheme;
55
+ private getThemeSetting;
56
+ /** The theme for the current setting and terminal appearance. Without a setting, pi uses the system theme. */
57
+ private resolveThemeName;
34
58
  private applyThemeName;
35
- private notifyChanged;
59
+ /** Query the terminal's colors without waiting for them; `waitForTerminalColors()` waits for this query. */
60
+ private queryTerminalColors;
61
+ /**
62
+ * Record reported colors: themes use the default colors for tokens set to "", the system theme is
63
+ * generated from all of them, and light/dark detection uses them. Re-renders only when they changed.
64
+ */
65
+ private applyTerminalColors;
66
+ /**
67
+ * Re-apply the setting after the terminal's colors or appearance changed: regenerate the system theme,
68
+ * or switch the theme of a pair. Themes set through extensions or previews are left alone.
69
+ */
70
+ private reapplyForTerminal;
36
71
  private setAutoSync;
37
72
  private bindTerminalColorSchemeListener;
38
- private applyTerminalTheme;
73
+ /**
74
+ * The terminal reported a light/dark switch. Its colors changed too, so query them again: they decide
75
+ * the appearance. The reported scheme only matters for terminals that do not report their background.
76
+ */
77
+ private applyTerminalColorSchemeChange;
78
+ private notifyChanged;
39
79
  }
40
80
  export {};
41
81
  //# sourceMappingURL=theme-controller.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"theme-controller.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/theme/theme-controller.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AACzE,OAAO,EASN,KAAK,aAAa,EAClB,KAAK,KAAK,EACV,MAAM,YAAY,CAAC;AAEpB,KAAK,WAAW,GAAG;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAExD,qBAAa,0BAA0B;IACtC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAM;IACzB,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAwB;IAC3D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA4B;IACtD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAa;IACvC,OAAO,CAAC,mBAAmB,CAAqB;IAChD,OAAO,CAAC,aAAa,CAA0D;IAC/E,OAAO,CAAC,eAAe,CAAqB;IAC5C,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,8BAA8B,CAA2B;IAEjE,YACC,EAAE,EAAE,GAAG,EACP,OAAO,EAAE;QACR,kBAAkB,EAAE,MAAM,eAAe,CAAC;QAC1C,SAAS,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;QACrC,SAAS,EAAE,MAAM,IAAI,CAAC;QACtB,mBAAmB,CAAC,EAAE,MAAM,CAAC;KAC7B,EAaD;IAED,SAAS,IAAI,IAAI,CAIhB;IAEK,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAwBvC;IAED,iBAAiB,IAAI,MAAM,GAAG,SAAS,CAEtC;IAED,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,UAAQ,GAAG,WAAW,CAO9D;IAEK,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGzD;IAED,gBAAgB,CAAC,aAAa,EAAE,KAAK,GAAG,WAAW,CAMlD;IAED,OAAO,CAAC,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAOxC;IAED,eAAe,IAAI,IAAI,CAEtB;IAED,OAAO,IAAI,IAAI,CAId;IAED,gBAAgB,IAAI,aAAa,CAEhC;IAED,OAAO,CAAC,cAAc;IAUtB,OAAO,CAAC,aAAa;IAKrB,OAAO,CAAC,WAAW;IAMnB,OAAO,CAAC,+BAA+B;IAMvC,OAAO,CAAC,kBAAkB;CAa1B","sourcesContent":["import type { TUI } from \"@earendil-works/pi-tui\";\nimport type { SettingsManager } from \"../../../core/settings-manager.ts\";\nimport {\n\tdetectTerminalBackgroundFromEnv,\n\tdetectTerminalBackgroundTheme,\n\tdetectTerminalThemeForAuto,\n\tinitTheme,\n\tparseAutoThemeSetting,\n\tresolveThemeSetting,\n\tsetTheme,\n\tsetThemeInstance,\n\ttype TerminalTheme,\n\ttype Theme,\n} from \"./theme.ts\";\n\ntype ThemeResult = { success: boolean; error?: string };\n\nexport class InteractiveThemeController {\n\tprivate readonly ui: TUI;\n\tprivate readonly getSettingsManager: () => SettingsManager;\n\tprivate readonly showError: (message: string) => void;\n\tprivate readonly onChanged: () => void;\n\tprivate currentThemeSetting: string | undefined;\n\tprivate terminalTheme: TerminalTheme = detectTerminalBackgroundFromEnv().theme;\n\tprivate activeThemeName: string | undefined;\n\tprivate autoSyncEnabled = false;\n\tprivate terminalColorSchemeUnsubscribe: (() => void) | undefined;\n\n\tconstructor(\n\t\tui: TUI,\n\t\toptions: {\n\t\t\tgetSettingsManager: () => SettingsManager;\n\t\t\tshowError: (message: string) => void;\n\t\t\tonChanged: () => void;\n\t\t\tinitialThemeSetting?: string;\n\t\t},\n\t) {\n\t\tthis.ui = ui;\n\t\tthis.getSettingsManager = options.getSettingsManager;\n\t\tthis.showError = options.showError;\n\t\tthis.onChanged = options.onChanged;\n\t\tthis.currentThemeSetting = options.initialThemeSetting;\n\t\tthis.activeThemeName = resolveThemeSetting(\n\t\t\tthis.currentThemeSetting ?? this.getSettingsManager().getThemeSetting(),\n\t\t\tthis.terminalTheme,\n\t\t);\n\t\tinitTheme(this.activeThemeName, true);\n\t\tthis.bindTerminalColorSchemeListener();\n\t}\n\n\trebindTui(): void {\n\t\tthis.terminalColorSchemeUnsubscribe?.();\n\t\tthis.bindTerminalColorSchemeListener();\n\t\tthis.ui.setTerminalColorSchemeNotifications(this.autoSyncEnabled);\n\t}\n\n\tasync applyFromSettings(): Promise<void> {\n\t\tconst settingsManager = this.getSettingsManager();\n\t\tconst themeSetting = this.currentThemeSetting ?? settingsManager.getThemeSetting();\n\t\tconst autoTheme = parseAutoThemeSetting(themeSetting);\n\t\tif (autoTheme) {\n\t\t\tthis.terminalTheme = await detectTerminalThemeForAuto({ ui: this.ui, timeoutMs: 100 });\n\t\t\tthis.setAutoSync(true);\n\t\t\tthis.applyThemeName(this.terminalTheme === \"light\" ? autoTheme.lightTheme : autoTheme.darkTheme, true);\n\t\t\treturn;\n\t\t}\n\n\t\tthis.setAutoSync(false);\n\t\tif (themeSetting !== undefined) {\n\t\t\tthis.applyThemeName(themeSetting, true);\n\t\t\treturn;\n\t\t}\n\n\t\tconst detection = await detectTerminalBackgroundTheme({ ui: this.ui, timeoutMs: 100 });\n\t\tthis.terminalTheme = detection.theme;\n\t\tif (!this.applyThemeName(detection.theme).success) return;\n\t\tif (detection.confidence === \"high\") {\n\t\t\tsettingsManager.setTheme(detection.theme);\n\t\t\tawait settingsManager.flush();\n\t\t}\n\t}\n\n\tgetThemeSelection(): string | undefined {\n\t\treturn this.currentThemeSetting ?? this.getSettingsManager().getThemeSetting() ?? this.activeThemeName;\n\t}\n\n\tsetThemeName(themeName: string, showError = false): ThemeResult {\n\t\tthis.setAutoSync(false);\n\t\tconst result = this.applyThemeName(themeName, showError);\n\t\tif (result.success) {\n\t\t\tthis.currentThemeSetting = themeName;\n\t\t}\n\t\treturn result;\n\t}\n\n\tasync setThemeSetting(themeSetting: string): Promise<void> {\n\t\tthis.currentThemeSetting = themeSetting;\n\t\tawait this.applyFromSettings();\n\t}\n\n\tsetThemeInstance(themeInstance: Theme): ThemeResult {\n\t\tthis.setAutoSync(false);\n\t\tsetThemeInstance(themeInstance);\n\t\tthis.activeThemeName = \"<in-memory>\";\n\t\tthis.notifyChanged();\n\t\treturn { success: true };\n\t}\n\n\tpreview(themeSettingOrName: string): void {\n\t\tconst themeName = resolveThemeSetting(themeSettingOrName, this.terminalTheme) ?? this.activeThemeName;\n\t\tif (!themeName) return;\n\t\tif (setTheme(themeName, true).success) {\n\t\t\tthis.ui.invalidate();\n\t\t\tthis.ui.requestRender();\n\t\t}\n\t}\n\n\tdisableAutoSync(): void {\n\t\tthis.setAutoSync(false);\n\t}\n\n\tdispose(): void {\n\t\tthis.setAutoSync(false);\n\t\tthis.terminalColorSchemeUnsubscribe?.();\n\t\tthis.terminalColorSchemeUnsubscribe = undefined;\n\t}\n\n\tgetTerminalTheme(): TerminalTheme {\n\t\treturn this.terminalTheme;\n\t}\n\n\tprivate applyThemeName(themeName: string, showError = false): ThemeResult {\n\t\tconst result = setTheme(themeName, true);\n\t\tthis.activeThemeName = result.success ? themeName : \"dark\";\n\t\tthis.notifyChanged();\n\t\tif (!result.success && showError) {\n\t\t\tthis.showError(`Failed to load theme \"${themeName}\": ${result.error}\\nFell back to dark theme.`);\n\t\t}\n\t\treturn result;\n\t}\n\n\tprivate notifyChanged(): void {\n\t\tthis.ui.invalidate();\n\t\tthis.onChanged();\n\t}\n\n\tprivate setAutoSync(enabled: boolean): void {\n\t\tif (this.autoSyncEnabled === enabled) return;\n\t\tthis.autoSyncEnabled = enabled;\n\t\tthis.ui.setTerminalColorSchemeNotifications(enabled);\n\t}\n\n\tprivate bindTerminalColorSchemeListener(): void {\n\t\tthis.terminalColorSchemeUnsubscribe = this.ui.onTerminalColorSchemeChange((terminalTheme) =>\n\t\t\tthis.applyTerminalTheme(terminalTheme),\n\t\t);\n\t}\n\n\tprivate applyTerminalTheme(terminalTheme: TerminalTheme): void {\n\t\tif (!this.autoSyncEnabled) return;\n\t\tthis.terminalTheme = terminalTheme;\n\t\tconst autoTheme = parseAutoThemeSetting(this.currentThemeSetting ?? this.getSettingsManager().getThemeSetting());\n\t\tif (!autoTheme) {\n\t\t\tthis.setAutoSync(false);\n\t\t\treturn;\n\t\t}\n\t\tconst themeName = terminalTheme === \"light\" ? autoTheme.lightTheme : autoTheme.darkTheme;\n\t\tif (themeName !== this.activeThemeName) {\n\t\t\tthis.applyThemeName(themeName);\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"theme-controller.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/theme/theme-controller.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAY,cAAc,EAAE,GAAG,EAAE,MAAM,wBAAwB,CAAC;AAC5E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AACzE,OAAO,EAWN,KAAK,aAAa,EAClB,KAAK,KAAK,EACV,MAAM,YAAY,CAAC;AAEpB,KAAK,WAAW,GAAG;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AASxD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CASrG;AAaD;;;;GAIG;AACH,qBAAa,0BAA0B;IACtC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAM;IACzB,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAwB;IAC3D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA4B;IACtD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAa;IACvC,OAAO,CAAC,mBAAmB,CAAqB;IAEhD,OAAO,CAAC,cAAc,CAA6B;IACnD,OAAO,CAAC,eAAe,CAAqB;IAC5C,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,8BAA8B,CAA2B;IAEjE,OAAO,CAAC,kBAAkB,CAAoC;IAE9D,YACC,EAAE,EAAE,GAAG,EACP,OAAO,EAAE;QACR,kBAAkB,EAAE,MAAM,eAAe,CAAC;QAC1C,SAAS,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;QACrC,SAAS,EAAE,MAAM,IAAI,CAAC;QACtB,mBAAmB,CAAC,EAAE,MAAM,CAAC;KAC7B,EAYD;IAED,SAAS,IAAI,IAAI,CAIhB;IAED;;;OAGG;IACH,iBAAiB,IAAI,IAAI,CAMxB;IAED;;;;OAIG;IACH,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC,CAErC;IAED,iBAAiB,IAAI,MAAM,GAAG,SAAS,CAEtC;IAED,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,UAAQ,GAAG,WAAW,CAO9D;IAED,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAG1C;IAED,gBAAgB,CAAC,aAAa,EAAE,KAAK,GAAG,WAAW,CAMlD;IAED,OAAO,CAAC,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAOxC;IAED,eAAe,IAAI,IAAI,CAEtB;IAED,OAAO,IAAI,IAAI,CAId;IAED,gBAAgB,IAAI,aAAa,CAEhC;IAED,OAAO,CAAC,eAAe;IAIvB,8GAA8G;IAC9G,OAAO,CAAC,gBAAgB;IAIxB,OAAO,CAAC,cAAc;IAUtB,4GAA4G;IAC5G,OAAO,CAAC,mBAAmB;IAI3B;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAgB3B;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAQ1B,OAAO,CAAC,WAAW;IAMnB,OAAO,CAAC,+BAA+B;IAMvC;;;OAGG;IACH,OAAO,CAAC,8BAA8B;IAQtC,OAAO,CAAC,aAAa;CAIrB"}
@@ -1,21 +1,64 @@
1
- import { detectTerminalBackgroundFromEnv, detectTerminalBackgroundTheme, detectTerminalThemeForAuto, initTheme, parseAutoThemeSetting, resolveThemeSetting, setTheme, setThemeInstance, } from "./theme.js";
1
+ import { getTerminalTheme, initTheme, markTerminalColorsPending, parseAutoThemeSetting, resolveThemeSetting, SYSTEM_THEME_NAME, setTerminalColorScheme, setTerminalColors, setTheme, setThemeInstance, } from "./theme.js";
2
+ /**
3
+ * How long the system theme stays grayscale before falling back to palette indices. Terminals answer
4
+ * the trailing DA1 request right after the color replies, so this only matters for terminals that
5
+ * answer neither. Replies arriving later still apply.
6
+ */
7
+ const TERMINAL_QUERY_TIMEOUT_MS = 100;
8
+ /**
9
+ * Query the terminal's colors and pass them to `apply` when the query completes or times out, and again
10
+ * if the terminal answers after the timeout. A failed query applies no colors. Settles after the first apply.
11
+ */
12
+ export function requestTerminalColors(ui, apply) {
13
+ let query;
14
+ try {
15
+ query = ui.queryTerminalColors({ timeoutMs: TERMINAL_QUERY_TIMEOUT_MS, onLateReply: apply });
16
+ }
17
+ catch {
18
+ // Treat a failed query like a terminal that does not report colors.
19
+ query = Promise.resolve({});
20
+ }
21
+ return query.then(apply, () => apply({}));
22
+ }
23
+ function sameRgb(a, b) {
24
+ return a === b || (a !== undefined && b !== undefined && a.r === b.r && a.g === b.g && a.b === b.b);
25
+ }
26
+ function sameTerminalColors(a, b) {
27
+ if (!sameRgb(a.foreground, b.foreground) || !sameRgb(a.background, b.background))
28
+ return false;
29
+ if (a.palette === b.palette)
30
+ return true;
31
+ if (!a.palette || !b.palette || a.palette.length !== b.palette.length)
32
+ return false;
33
+ return a.palette.every((color, index) => sameRgb(color, b.palette?.[index]));
34
+ }
35
+ /**
36
+ * Applies the theme setting and keeps it in sync with the terminal. The theme applies immediately, and the
37
+ * terminal's colors update it when they arrive; the system theme renders in grayscale until then. Callers
38
+ * that bake theme colors into content can wait for the colors with `waitForTerminalColors()`.
39
+ */
2
40
  export class InteractiveThemeController {
3
41
  ui;
4
42
  getSettingsManager;
5
43
  showError;
6
44
  onChanged;
7
45
  currentThemeSetting;
8
- terminalTheme = detectTerminalBackgroundFromEnv().theme;
46
+ // Last reported colors; a query that times out keeps them instead of erasing them.
47
+ terminalColors;
9
48
  activeThemeName;
10
49
  autoSyncEnabled = false;
11
50
  terminalColorSchemeUnsubscribe;
51
+ // Settles when the latest color query completed or timed out, and its colors applied.
52
+ terminalColorQuery = Promise.resolve();
12
53
  constructor(ui, options) {
13
54
  this.ui = ui;
14
55
  this.getSettingsManager = options.getSettingsManager;
15
56
  this.showError = options.showError;
16
57
  this.onChanged = options.onChanged;
17
58
  this.currentThemeSetting = options.initialThemeSetting;
18
- this.activeThemeName = resolveThemeSetting(this.currentThemeSetting ?? this.getSettingsManager().getThemeSetting(), this.terminalTheme);
59
+ this.activeThemeName = this.resolveThemeName();
60
+ // The system theme starts in grayscale; color follows once the terminal reports its colors.
61
+ markTerminalColorsPending();
19
62
  initTheme(this.activeThemeName, true);
20
63
  this.bindTerminalColorSchemeListener();
21
64
  }
@@ -24,44 +67,39 @@ export class InteractiveThemeController {
24
67
  this.bindTerminalColorSchemeListener();
25
68
  this.ui.setTerminalColorSchemeNotifications(this.autoSyncEnabled);
26
69
  }
27
- async applyFromSettings() {
28
- const settingsManager = this.getSettingsManager();
29
- const themeSetting = this.currentThemeSetting ?? settingsManager.getThemeSetting();
30
- const autoTheme = parseAutoThemeSetting(themeSetting);
31
- if (autoTheme) {
32
- this.terminalTheme = await detectTerminalThemeForAuto({ ui: this.ui, timeoutMs: 100 });
33
- this.setAutoSync(true);
34
- this.applyThemeName(this.terminalTheme === "light" ? autoTheme.lightTheme : autoTheme.darkTheme, true);
35
- return;
36
- }
37
- this.setAutoSync(false);
38
- if (themeSetting !== undefined) {
39
- this.applyThemeName(themeSetting, true);
40
- return;
41
- }
42
- const detection = await detectTerminalBackgroundTheme({ ui: this.ui, timeoutMs: 100 });
43
- this.terminalTheme = detection.theme;
44
- if (!this.applyThemeName(detection.theme).success)
45
- return;
46
- if (detection.confidence === "high") {
47
- settingsManager.setTheme(detection.theme);
48
- await settingsManager.flush();
49
- }
70
+ /**
71
+ * Apply the theme setting now and query the terminal's colors, which update the theme when they arrive.
72
+ * Theme pairs and the system theme follow terminal appearance changes.
73
+ */
74
+ applyFromSettings() {
75
+ const themeSetting = this.getThemeSetting();
76
+ const themeName = this.resolveThemeName();
77
+ this.setAutoSync(parseAutoThemeSetting(themeSetting) !== undefined || themeName === SYSTEM_THEME_NAME);
78
+ this.applyThemeName(themeName, themeSetting !== undefined);
79
+ this.queryTerminalColors();
80
+ }
81
+ /**
82
+ * Wait until the latest color query completed or timed out. Content that bakes theme colors into
83
+ * strings, such as the startup header, should be built after this. Terminals answer the DA1 request
84
+ * right after the color replies, so this only takes the full timeout when a terminal answers nothing.
85
+ */
86
+ waitForTerminalColors() {
87
+ return this.terminalColorQuery;
50
88
  }
51
89
  getThemeSelection() {
52
90
  return this.currentThemeSetting ?? this.getSettingsManager().getThemeSetting() ?? this.activeThemeName;
53
91
  }
54
92
  setThemeName(themeName, showError = false) {
55
- this.setAutoSync(false);
93
+ this.setAutoSync(themeName === SYSTEM_THEME_NAME);
56
94
  const result = this.applyThemeName(themeName, showError);
57
95
  if (result.success) {
58
96
  this.currentThemeSetting = themeName;
59
97
  }
60
98
  return result;
61
99
  }
62
- async setThemeSetting(themeSetting) {
100
+ setThemeSetting(themeSetting) {
63
101
  this.currentThemeSetting = themeSetting;
64
- await this.applyFromSettings();
102
+ this.applyFromSettings();
65
103
  }
66
104
  setThemeInstance(themeInstance) {
67
105
  this.setAutoSync(false);
@@ -71,7 +109,7 @@ export class InteractiveThemeController {
71
109
  return { success: true };
72
110
  }
73
111
  preview(themeSettingOrName) {
74
- const themeName = resolveThemeSetting(themeSettingOrName, this.terminalTheme) ?? this.activeThemeName;
112
+ const themeName = resolveThemeSetting(themeSettingOrName, getTerminalTheme()) ?? this.activeThemeName;
75
113
  if (!themeName)
76
114
  return;
77
115
  if (setTheme(themeName, true).success) {
@@ -88,20 +126,59 @@ export class InteractiveThemeController {
88
126
  this.terminalColorSchemeUnsubscribe = undefined;
89
127
  }
90
128
  getTerminalTheme() {
91
- return this.terminalTheme;
129
+ return getTerminalTheme();
130
+ }
131
+ getThemeSetting() {
132
+ return this.currentThemeSetting ?? this.getSettingsManager().getThemeSetting();
133
+ }
134
+ /** The theme for the current setting and terminal appearance. Without a setting, pi uses the system theme. */
135
+ resolveThemeName() {
136
+ return resolveThemeSetting(this.getThemeSetting(), getTerminalTheme()) ?? SYSTEM_THEME_NAME;
92
137
  }
93
138
  applyThemeName(themeName, showError = false) {
94
139
  const result = setTheme(themeName, true);
95
- this.activeThemeName = result.success ? themeName : "dark";
140
+ this.activeThemeName = result.success ? themeName : SYSTEM_THEME_NAME;
96
141
  this.notifyChanged();
97
142
  if (!result.success && showError) {
98
- this.showError(`Failed to load theme "${themeName}": ${result.error}\nFell back to dark theme.`);
143
+ this.showError(`Failed to load theme "${themeName}": ${result.error}\nFell back to the system theme.`);
99
144
  }
100
145
  return result;
101
146
  }
102
- notifyChanged() {
147
+ /** Query the terminal's colors without waiting for them; `waitForTerminalColors()` waits for this query. */
148
+ queryTerminalColors() {
149
+ this.terminalColorQuery = requestTerminalColors(this.ui, (colors) => this.applyTerminalColors(colors));
150
+ }
151
+ /**
152
+ * Record reported colors: themes use the default colors for tokens set to "", the system theme is
153
+ * generated from all of them, and light/dark detection uses them. Re-renders only when they changed.
154
+ */
155
+ applyTerminalColors(reported) {
156
+ const previous = this.terminalColors;
157
+ const next = {
158
+ foreground: reported.foreground ?? previous?.foreground,
159
+ background: reported.background ?? previous?.background,
160
+ palette: reported.palette ?? previous?.palette,
161
+ };
162
+ // Re-rendering rebuilds every component, so skip it when nothing changed (including timeouts).
163
+ if (previous && sameTerminalColors(previous, next))
164
+ return;
165
+ this.terminalColors = next;
166
+ setTerminalColors(next);
167
+ this.reapplyForTerminal();
103
168
  this.ui.invalidate();
104
- this.onChanged();
169
+ this.ui.requestRender();
170
+ }
171
+ /**
172
+ * Re-apply the setting after the terminal's colors or appearance changed: regenerate the system theme,
173
+ * or switch the theme of a pair. Themes set through extensions or previews are left alone.
174
+ */
175
+ reapplyForTerminal() {
176
+ if (this.activeThemeName === "<in-memory>")
177
+ return;
178
+ const themeName = this.resolveThemeName();
179
+ if (themeName === SYSTEM_THEME_NAME || themeName !== this.activeThemeName) {
180
+ this.applyThemeName(themeName);
181
+ }
105
182
  }
106
183
  setAutoSync(enabled) {
107
184
  if (this.autoSyncEnabled === enabled)
@@ -110,21 +187,24 @@ export class InteractiveThemeController {
110
187
  this.ui.setTerminalColorSchemeNotifications(enabled);
111
188
  }
112
189
  bindTerminalColorSchemeListener() {
113
- this.terminalColorSchemeUnsubscribe = this.ui.onTerminalColorSchemeChange((terminalTheme) => this.applyTerminalTheme(terminalTheme));
190
+ this.terminalColorSchemeUnsubscribe = this.ui.onTerminalColorSchemeChange((terminalTheme) => this.applyTerminalColorSchemeChange(terminalTheme));
114
191
  }
115
- applyTerminalTheme(terminalTheme) {
192
+ /**
193
+ * The terminal reported a light/dark switch. Its colors changed too, so query them again: they decide
194
+ * the appearance. The reported scheme only matters for terminals that do not report their background.
195
+ */
196
+ applyTerminalColorSchemeChange(terminalTheme) {
116
197
  if (!this.autoSyncEnabled)
117
198
  return;
118
- this.terminalTheme = terminalTheme;
119
- const autoTheme = parseAutoThemeSetting(this.currentThemeSetting ?? this.getSettingsManager().getThemeSetting());
120
- if (!autoTheme) {
121
- this.setAutoSync(false);
122
- return;
123
- }
124
- const themeName = terminalTheme === "light" ? autoTheme.lightTheme : autoTheme.darkTheme;
125
- if (themeName !== this.activeThemeName) {
126
- this.applyThemeName(themeName);
127
- }
199
+ const previous = getTerminalTheme();
200
+ setTerminalColorScheme(terminalTheme);
201
+ if (getTerminalTheme() !== previous)
202
+ this.reapplyForTerminal();
203
+ this.queryTerminalColors();
204
+ }
205
+ notifyChanged() {
206
+ this.ui.invalidate();
207
+ this.onChanged();
128
208
  }
129
209
  }
130
210
  //# sourceMappingURL=theme-controller.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"theme-controller.js","sourceRoot":"","sources":["../../../../src/modes/interactive/theme/theme-controller.ts"],"names":[],"mappings":"AAEA,OAAO,EACN,+BAA+B,EAC/B,6BAA6B,EAC7B,0BAA0B,EAC1B,SAAS,EACT,qBAAqB,EACrB,mBAAmB,EACnB,QAAQ,EACR,gBAAgB,GAGhB,MAAM,YAAY,CAAC;AAIpB,MAAM,OAAO,0BAA0B;IACrB,EAAE,CAAM;IACR,kBAAkB,CAAwB;IAC1C,SAAS,CAA4B;IACrC,SAAS,CAAa;IAC/B,mBAAmB,CAAqB;IACxC,aAAa,GAAkB,+BAA+B,EAAE,CAAC,KAAK,CAAC;IACvE,eAAe,CAAqB;IACpC,eAAe,GAAG,KAAK,CAAC;IACxB,8BAA8B,CAA2B;IAEjE,YACC,EAAO,EACP,OAKC,EACA;QACD,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC;QACrD,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;QACnC,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;QACnC,IAAI,CAAC,mBAAmB,GAAG,OAAO,CAAC,mBAAmB,CAAC;QACvD,IAAI,CAAC,eAAe,GAAG,mBAAmB,CACzC,IAAI,CAAC,mBAAmB,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC,eAAe,EAAE,EACvE,IAAI,CAAC,aAAa,CAClB,CAAC;QACF,SAAS,CAAC,IAAI,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC;QACtC,IAAI,CAAC,+BAA+B,EAAE,CAAC;IAAA,CACvC;IAED,SAAS,GAAS;QACjB,IAAI,CAAC,8BAA8B,EAAE,EAAE,CAAC;QACxC,IAAI,CAAC,+BAA+B,EAAE,CAAC;QACvC,IAAI,CAAC,EAAE,CAAC,mCAAmC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAAA,CAClE;IAED,KAAK,CAAC,iBAAiB,GAAkB;QACxC,MAAM,eAAe,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAClD,MAAM,YAAY,GAAG,IAAI,CAAC,mBAAmB,IAAI,eAAe,CAAC,eAAe,EAAE,CAAC;QACnF,MAAM,SAAS,GAAG,qBAAqB,CAAC,YAAY,CAAC,CAAC;QACtD,IAAI,SAAS,EAAE,CAAC;YACf,IAAI,CAAC,aAAa,GAAG,MAAM,0BAA0B,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC;YACvF,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;YACvB,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,aAAa,KAAK,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;YACvG,OAAO;QACR,CAAC;QAED,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QACxB,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;YAChC,IAAI,CAAC,cAAc,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;YACxC,OAAO;QACR,CAAC;QAED,MAAM,SAAS,GAAG,MAAM,6BAA6B,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC;QACvF,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC,KAAK,CAAC;QACrC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,OAAO;YAAE,OAAO;QAC1D,IAAI,SAAS,CAAC,UAAU,KAAK,MAAM,EAAE,CAAC;YACrC,eAAe,CAAC,QAAQ,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YAC1C,MAAM,eAAe,CAAC,KAAK,EAAE,CAAC;QAC/B,CAAC;IAAA,CACD;IAED,iBAAiB,GAAuB;QACvC,OAAO,IAAI,CAAC,mBAAmB,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC,eAAe,EAAE,IAAI,IAAI,CAAC,eAAe,CAAC;IAAA,CACvG;IAED,YAAY,CAAC,SAAiB,EAAE,SAAS,GAAG,KAAK,EAAe;QAC/D,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QACxB,MAAM,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QACzD,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,IAAI,CAAC,mBAAmB,GAAG,SAAS,CAAC;QACtC,CAAC;QACD,OAAO,MAAM,CAAC;IAAA,CACd;IAED,KAAK,CAAC,eAAe,CAAC,YAAoB,EAAiB;QAC1D,IAAI,CAAC,mBAAmB,GAAG,YAAY,CAAC;QACxC,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;IAAA,CAC/B;IAED,gBAAgB,CAAC,aAAoB,EAAe;QACnD,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QACxB,gBAAgB,CAAC,aAAa,CAAC,CAAC;QAChC,IAAI,CAAC,eAAe,GAAG,aAAa,CAAC;QACrC,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAAA,CACzB;IAED,OAAO,CAAC,kBAA0B,EAAQ;QACzC,MAAM,SAAS,GAAG,mBAAmB,CAAC,kBAAkB,EAAE,IAAI,CAAC,aAAa,CAAC,IAAI,IAAI,CAAC,eAAe,CAAC;QACtG,IAAI,CAAC,SAAS;YAAE,OAAO;QACvB,IAAI,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;YACvC,IAAI,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC;YACrB,IAAI,CAAC,EAAE,CAAC,aAAa,EAAE,CAAC;QACzB,CAAC;IAAA,CACD;IAED,eAAe,GAAS;QACvB,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IAAA,CACxB;IAED,OAAO,GAAS;QACf,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QACxB,IAAI,CAAC,8BAA8B,EAAE,EAAE,CAAC;QACxC,IAAI,CAAC,8BAA8B,GAAG,SAAS,CAAC;IAAA,CAChD;IAED,gBAAgB,GAAkB;QACjC,OAAO,IAAI,CAAC,aAAa,CAAC;IAAA,CAC1B;IAEO,cAAc,CAAC,SAAiB,EAAE,SAAS,GAAG,KAAK,EAAe;QACzE,MAAM,MAAM,GAAG,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QACzC,IAAI,CAAC,eAAe,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC;QAC3D,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,SAAS,EAAE,CAAC;YAClC,IAAI,CAAC,SAAS,CAAC,yBAAyB,SAAS,MAAM,MAAM,CAAC,KAAK,4BAA4B,CAAC,CAAC;QAClG,CAAC;QACD,OAAO,MAAM,CAAC;IAAA,CACd;IAEO,aAAa,GAAS;QAC7B,IAAI,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC;QACrB,IAAI,CAAC,SAAS,EAAE,CAAC;IAAA,CACjB;IAEO,WAAW,CAAC,OAAgB,EAAQ;QAC3C,IAAI,IAAI,CAAC,eAAe,KAAK,OAAO;YAAE,OAAO;QAC7C,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC;QAC/B,IAAI,CAAC,EAAE,CAAC,mCAAmC,CAAC,OAAO,CAAC,CAAC;IAAA,CACrD;IAEO,+BAA+B,GAAS;QAC/C,IAAI,CAAC,8BAA8B,GAAG,IAAI,CAAC,EAAE,CAAC,2BAA2B,CAAC,CAAC,aAAa,EAAE,EAAE,CAC3F,IAAI,CAAC,kBAAkB,CAAC,aAAa,CAAC,CACtC,CAAC;IAAA,CACF;IAEO,kBAAkB,CAAC,aAA4B,EAAQ;QAC9D,IAAI,CAAC,IAAI,CAAC,eAAe;YAAE,OAAO;QAClC,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACnC,MAAM,SAAS,GAAG,qBAAqB,CAAC,IAAI,CAAC,mBAAmB,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC,eAAe,EAAE,CAAC,CAAC;QACjH,IAAI,CAAC,SAAS,EAAE,CAAC;YAChB,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;YACxB,OAAO;QACR,CAAC;QACD,MAAM,SAAS,GAAG,aAAa,KAAK,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC;QACzF,IAAI,SAAS,KAAK,IAAI,CAAC,eAAe,EAAE,CAAC;YACxC,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;QAChC,CAAC;IAAA,CACD;CACD","sourcesContent":["import type { TUI } from \"@earendil-works/pi-tui\";\nimport type { SettingsManager } from \"../../../core/settings-manager.ts\";\nimport {\n\tdetectTerminalBackgroundFromEnv,\n\tdetectTerminalBackgroundTheme,\n\tdetectTerminalThemeForAuto,\n\tinitTheme,\n\tparseAutoThemeSetting,\n\tresolveThemeSetting,\n\tsetTheme,\n\tsetThemeInstance,\n\ttype TerminalTheme,\n\ttype Theme,\n} from \"./theme.ts\";\n\ntype ThemeResult = { success: boolean; error?: string };\n\nexport class InteractiveThemeController {\n\tprivate readonly ui: TUI;\n\tprivate readonly getSettingsManager: () => SettingsManager;\n\tprivate readonly showError: (message: string) => void;\n\tprivate readonly onChanged: () => void;\n\tprivate currentThemeSetting: string | undefined;\n\tprivate terminalTheme: TerminalTheme = detectTerminalBackgroundFromEnv().theme;\n\tprivate activeThemeName: string | undefined;\n\tprivate autoSyncEnabled = false;\n\tprivate terminalColorSchemeUnsubscribe: (() => void) | undefined;\n\n\tconstructor(\n\t\tui: TUI,\n\t\toptions: {\n\t\t\tgetSettingsManager: () => SettingsManager;\n\t\t\tshowError: (message: string) => void;\n\t\t\tonChanged: () => void;\n\t\t\tinitialThemeSetting?: string;\n\t\t},\n\t) {\n\t\tthis.ui = ui;\n\t\tthis.getSettingsManager = options.getSettingsManager;\n\t\tthis.showError = options.showError;\n\t\tthis.onChanged = options.onChanged;\n\t\tthis.currentThemeSetting = options.initialThemeSetting;\n\t\tthis.activeThemeName = resolveThemeSetting(\n\t\t\tthis.currentThemeSetting ?? this.getSettingsManager().getThemeSetting(),\n\t\t\tthis.terminalTheme,\n\t\t);\n\t\tinitTheme(this.activeThemeName, true);\n\t\tthis.bindTerminalColorSchemeListener();\n\t}\n\n\trebindTui(): void {\n\t\tthis.terminalColorSchemeUnsubscribe?.();\n\t\tthis.bindTerminalColorSchemeListener();\n\t\tthis.ui.setTerminalColorSchemeNotifications(this.autoSyncEnabled);\n\t}\n\n\tasync applyFromSettings(): Promise<void> {\n\t\tconst settingsManager = this.getSettingsManager();\n\t\tconst themeSetting = this.currentThemeSetting ?? settingsManager.getThemeSetting();\n\t\tconst autoTheme = parseAutoThemeSetting(themeSetting);\n\t\tif (autoTheme) {\n\t\t\tthis.terminalTheme = await detectTerminalThemeForAuto({ ui: this.ui, timeoutMs: 100 });\n\t\t\tthis.setAutoSync(true);\n\t\t\tthis.applyThemeName(this.terminalTheme === \"light\" ? autoTheme.lightTheme : autoTheme.darkTheme, true);\n\t\t\treturn;\n\t\t}\n\n\t\tthis.setAutoSync(false);\n\t\tif (themeSetting !== undefined) {\n\t\t\tthis.applyThemeName(themeSetting, true);\n\t\t\treturn;\n\t\t}\n\n\t\tconst detection = await detectTerminalBackgroundTheme({ ui: this.ui, timeoutMs: 100 });\n\t\tthis.terminalTheme = detection.theme;\n\t\tif (!this.applyThemeName(detection.theme).success) return;\n\t\tif (detection.confidence === \"high\") {\n\t\t\tsettingsManager.setTheme(detection.theme);\n\t\t\tawait settingsManager.flush();\n\t\t}\n\t}\n\n\tgetThemeSelection(): string | undefined {\n\t\treturn this.currentThemeSetting ?? this.getSettingsManager().getThemeSetting() ?? this.activeThemeName;\n\t}\n\n\tsetThemeName(themeName: string, showError = false): ThemeResult {\n\t\tthis.setAutoSync(false);\n\t\tconst result = this.applyThemeName(themeName, showError);\n\t\tif (result.success) {\n\t\t\tthis.currentThemeSetting = themeName;\n\t\t}\n\t\treturn result;\n\t}\n\n\tasync setThemeSetting(themeSetting: string): Promise<void> {\n\t\tthis.currentThemeSetting = themeSetting;\n\t\tawait this.applyFromSettings();\n\t}\n\n\tsetThemeInstance(themeInstance: Theme): ThemeResult {\n\t\tthis.setAutoSync(false);\n\t\tsetThemeInstance(themeInstance);\n\t\tthis.activeThemeName = \"<in-memory>\";\n\t\tthis.notifyChanged();\n\t\treturn { success: true };\n\t}\n\n\tpreview(themeSettingOrName: string): void {\n\t\tconst themeName = resolveThemeSetting(themeSettingOrName, this.terminalTheme) ?? this.activeThemeName;\n\t\tif (!themeName) return;\n\t\tif (setTheme(themeName, true).success) {\n\t\t\tthis.ui.invalidate();\n\t\t\tthis.ui.requestRender();\n\t\t}\n\t}\n\n\tdisableAutoSync(): void {\n\t\tthis.setAutoSync(false);\n\t}\n\n\tdispose(): void {\n\t\tthis.setAutoSync(false);\n\t\tthis.terminalColorSchemeUnsubscribe?.();\n\t\tthis.terminalColorSchemeUnsubscribe = undefined;\n\t}\n\n\tgetTerminalTheme(): TerminalTheme {\n\t\treturn this.terminalTheme;\n\t}\n\n\tprivate applyThemeName(themeName: string, showError = false): ThemeResult {\n\t\tconst result = setTheme(themeName, true);\n\t\tthis.activeThemeName = result.success ? themeName : \"dark\";\n\t\tthis.notifyChanged();\n\t\tif (!result.success && showError) {\n\t\t\tthis.showError(`Failed to load theme \"${themeName}\": ${result.error}\\nFell back to dark theme.`);\n\t\t}\n\t\treturn result;\n\t}\n\n\tprivate notifyChanged(): void {\n\t\tthis.ui.invalidate();\n\t\tthis.onChanged();\n\t}\n\n\tprivate setAutoSync(enabled: boolean): void {\n\t\tif (this.autoSyncEnabled === enabled) return;\n\t\tthis.autoSyncEnabled = enabled;\n\t\tthis.ui.setTerminalColorSchemeNotifications(enabled);\n\t}\n\n\tprivate bindTerminalColorSchemeListener(): void {\n\t\tthis.terminalColorSchemeUnsubscribe = this.ui.onTerminalColorSchemeChange((terminalTheme) =>\n\t\t\tthis.applyTerminalTheme(terminalTheme),\n\t\t);\n\t}\n\n\tprivate applyTerminalTheme(terminalTheme: TerminalTheme): void {\n\t\tif (!this.autoSyncEnabled) return;\n\t\tthis.terminalTheme = terminalTheme;\n\t\tconst autoTheme = parseAutoThemeSetting(this.currentThemeSetting ?? this.getSettingsManager().getThemeSetting());\n\t\tif (!autoTheme) {\n\t\t\tthis.setAutoSync(false);\n\t\t\treturn;\n\t\t}\n\t\tconst themeName = terminalTheme === \"light\" ? autoTheme.lightTheme : autoTheme.darkTheme;\n\t\tif (themeName !== this.activeThemeName) {\n\t\t\tthis.applyThemeName(themeName);\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"theme-controller.js","sourceRoot":"","sources":["../../../../src/modes/interactive/theme/theme-controller.ts"],"names":[],"mappings":"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","sourcesContent":["import type { RgbColor, TerminalColors, TUI } from \"@earendil-works/pi-tui\";\nimport type { SettingsManager } from \"../../../core/settings-manager.ts\";\nimport {\n\tgetTerminalTheme,\n\tinitTheme,\n\tmarkTerminalColorsPending,\n\tparseAutoThemeSetting,\n\tresolveThemeSetting,\n\tSYSTEM_THEME_NAME,\n\tsetTerminalColorScheme,\n\tsetTerminalColors,\n\tsetTheme,\n\tsetThemeInstance,\n\ttype TerminalTheme,\n\ttype Theme,\n} from \"./theme.ts\";\n\ntype ThemeResult = { success: boolean; error?: string };\n\n/**\n * How long the system theme stays grayscale before falling back to palette indices. Terminals answer\n * the trailing DA1 request right after the color replies, so this only matters for terminals that\n * answer neither. Replies arriving later still apply.\n */\nconst TERMINAL_QUERY_TIMEOUT_MS = 100;\n\n/**\n * Query the terminal's colors and pass them to `apply` when the query completes or times out, and again\n * if the terminal answers after the timeout. A failed query applies no colors. Settles after the first apply.\n */\nexport function requestTerminalColors(ui: TUI, apply: (colors: TerminalColors) => void): Promise<void> {\n\tlet query: Promise<TerminalColors>;\n\ttry {\n\t\tquery = ui.queryTerminalColors({ timeoutMs: TERMINAL_QUERY_TIMEOUT_MS, onLateReply: apply });\n\t} catch {\n\t\t// Treat a failed query like a terminal that does not report colors.\n\t\tquery = Promise.resolve({});\n\t}\n\treturn query.then(apply, () => apply({}));\n}\n\nfunction sameRgb(a: RgbColor | undefined, b: RgbColor | undefined): boolean {\n\treturn a === b || (a !== undefined && b !== undefined && a.r === b.r && a.g === b.g && a.b === b.b);\n}\n\nfunction sameTerminalColors(a: TerminalColors, b: TerminalColors): boolean {\n\tif (!sameRgb(a.foreground, b.foreground) || !sameRgb(a.background, b.background)) return false;\n\tif (a.palette === b.palette) return true;\n\tif (!a.palette || !b.palette || a.palette.length !== b.palette.length) return false;\n\treturn a.palette.every((color, index) => sameRgb(color, b.palette?.[index]));\n}\n\n/**\n * Applies the theme setting and keeps it in sync with the terminal. The theme applies immediately, and the\n * terminal's colors update it when they arrive; the system theme renders in grayscale until then. Callers\n * that bake theme colors into content can wait for the colors with `waitForTerminalColors()`.\n */\nexport class InteractiveThemeController {\n\tprivate readonly ui: TUI;\n\tprivate readonly getSettingsManager: () => SettingsManager;\n\tprivate readonly showError: (message: string) => void;\n\tprivate readonly onChanged: () => void;\n\tprivate currentThemeSetting: string | undefined;\n\t// Last reported colors; a query that times out keeps them instead of erasing them.\n\tprivate terminalColors: TerminalColors | undefined;\n\tprivate activeThemeName: string | undefined;\n\tprivate autoSyncEnabled = false;\n\tprivate terminalColorSchemeUnsubscribe: (() => void) | undefined;\n\t// Settles when the latest color query completed or timed out, and its colors applied.\n\tprivate terminalColorQuery: Promise<void> = Promise.resolve();\n\n\tconstructor(\n\t\tui: TUI,\n\t\toptions: {\n\t\t\tgetSettingsManager: () => SettingsManager;\n\t\t\tshowError: (message: string) => void;\n\t\t\tonChanged: () => void;\n\t\t\tinitialThemeSetting?: string;\n\t\t},\n\t) {\n\t\tthis.ui = ui;\n\t\tthis.getSettingsManager = options.getSettingsManager;\n\t\tthis.showError = options.showError;\n\t\tthis.onChanged = options.onChanged;\n\t\tthis.currentThemeSetting = options.initialThemeSetting;\n\t\tthis.activeThemeName = this.resolveThemeName();\n\t\t// The system theme starts in grayscale; color follows once the terminal reports its colors.\n\t\tmarkTerminalColorsPending();\n\t\tinitTheme(this.activeThemeName, true);\n\t\tthis.bindTerminalColorSchemeListener();\n\t}\n\n\trebindTui(): void {\n\t\tthis.terminalColorSchemeUnsubscribe?.();\n\t\tthis.bindTerminalColorSchemeListener();\n\t\tthis.ui.setTerminalColorSchemeNotifications(this.autoSyncEnabled);\n\t}\n\n\t/**\n\t * Apply the theme setting now and query the terminal's colors, which update the theme when they arrive.\n\t * Theme pairs and the system theme follow terminal appearance changes.\n\t */\n\tapplyFromSettings(): void {\n\t\tconst themeSetting = this.getThemeSetting();\n\t\tconst themeName = this.resolveThemeName();\n\t\tthis.setAutoSync(parseAutoThemeSetting(themeSetting) !== undefined || themeName === SYSTEM_THEME_NAME);\n\t\tthis.applyThemeName(themeName, themeSetting !== undefined);\n\t\tthis.queryTerminalColors();\n\t}\n\n\t/**\n\t * Wait until the latest color query completed or timed out. Content that bakes theme colors into\n\t * strings, such as the startup header, should be built after this. Terminals answer the DA1 request\n\t * right after the color replies, so this only takes the full timeout when a terminal answers nothing.\n\t */\n\twaitForTerminalColors(): Promise<void> {\n\t\treturn this.terminalColorQuery;\n\t}\n\n\tgetThemeSelection(): string | undefined {\n\t\treturn this.currentThemeSetting ?? this.getSettingsManager().getThemeSetting() ?? this.activeThemeName;\n\t}\n\n\tsetThemeName(themeName: string, showError = false): ThemeResult {\n\t\tthis.setAutoSync(themeName === SYSTEM_THEME_NAME);\n\t\tconst result = this.applyThemeName(themeName, showError);\n\t\tif (result.success) {\n\t\t\tthis.currentThemeSetting = themeName;\n\t\t}\n\t\treturn result;\n\t}\n\n\tsetThemeSetting(themeSetting: string): void {\n\t\tthis.currentThemeSetting = themeSetting;\n\t\tthis.applyFromSettings();\n\t}\n\n\tsetThemeInstance(themeInstance: Theme): ThemeResult {\n\t\tthis.setAutoSync(false);\n\t\tsetThemeInstance(themeInstance);\n\t\tthis.activeThemeName = \"<in-memory>\";\n\t\tthis.notifyChanged();\n\t\treturn { success: true };\n\t}\n\n\tpreview(themeSettingOrName: string): void {\n\t\tconst themeName = resolveThemeSetting(themeSettingOrName, getTerminalTheme()) ?? this.activeThemeName;\n\t\tif (!themeName) return;\n\t\tif (setTheme(themeName, true).success) {\n\t\t\tthis.ui.invalidate();\n\t\t\tthis.ui.requestRender();\n\t\t}\n\t}\n\n\tdisableAutoSync(): void {\n\t\tthis.setAutoSync(false);\n\t}\n\n\tdispose(): void {\n\t\tthis.setAutoSync(false);\n\t\tthis.terminalColorSchemeUnsubscribe?.();\n\t\tthis.terminalColorSchemeUnsubscribe = undefined;\n\t}\n\n\tgetTerminalTheme(): TerminalTheme {\n\t\treturn getTerminalTheme();\n\t}\n\n\tprivate getThemeSetting(): string | undefined {\n\t\treturn this.currentThemeSetting ?? this.getSettingsManager().getThemeSetting();\n\t}\n\n\t/** The theme for the current setting and terminal appearance. Without a setting, pi uses the system theme. */\n\tprivate resolveThemeName(): string {\n\t\treturn resolveThemeSetting(this.getThemeSetting(), getTerminalTheme()) ?? SYSTEM_THEME_NAME;\n\t}\n\n\tprivate applyThemeName(themeName: string, showError = false): ThemeResult {\n\t\tconst result = setTheme(themeName, true);\n\t\tthis.activeThemeName = result.success ? themeName : SYSTEM_THEME_NAME;\n\t\tthis.notifyChanged();\n\t\tif (!result.success && showError) {\n\t\t\tthis.showError(`Failed to load theme \"${themeName}\": ${result.error}\\nFell back to the system theme.`);\n\t\t}\n\t\treturn result;\n\t}\n\n\t/** Query the terminal's colors without waiting for them; `waitForTerminalColors()` waits for this query. */\n\tprivate queryTerminalColors(): void {\n\t\tthis.terminalColorQuery = requestTerminalColors(this.ui, (colors) => this.applyTerminalColors(colors));\n\t}\n\n\t/**\n\t * Record reported colors: themes use the default colors for tokens set to \"\", the system theme is\n\t * generated from all of them, and light/dark detection uses them. Re-renders only when they changed.\n\t */\n\tprivate applyTerminalColors(reported: TerminalColors): void {\n\t\tconst previous = this.terminalColors;\n\t\tconst next: TerminalColors = {\n\t\t\tforeground: reported.foreground ?? previous?.foreground,\n\t\t\tbackground: reported.background ?? previous?.background,\n\t\t\tpalette: reported.palette ?? previous?.palette,\n\t\t};\n\t\t// Re-rendering rebuilds every component, so skip it when nothing changed (including timeouts).\n\t\tif (previous && sameTerminalColors(previous, next)) return;\n\t\tthis.terminalColors = next;\n\t\tsetTerminalColors(next);\n\t\tthis.reapplyForTerminal();\n\t\tthis.ui.invalidate();\n\t\tthis.ui.requestRender();\n\t}\n\n\t/**\n\t * Re-apply the setting after the terminal's colors or appearance changed: regenerate the system theme,\n\t * or switch the theme of a pair. Themes set through extensions or previews are left alone.\n\t */\n\tprivate reapplyForTerminal(): void {\n\t\tif (this.activeThemeName === \"<in-memory>\") return;\n\t\tconst themeName = this.resolveThemeName();\n\t\tif (themeName === SYSTEM_THEME_NAME || themeName !== this.activeThemeName) {\n\t\t\tthis.applyThemeName(themeName);\n\t\t}\n\t}\n\n\tprivate setAutoSync(enabled: boolean): void {\n\t\tif (this.autoSyncEnabled === enabled) return;\n\t\tthis.autoSyncEnabled = enabled;\n\t\tthis.ui.setTerminalColorSchemeNotifications(enabled);\n\t}\n\n\tprivate bindTerminalColorSchemeListener(): void {\n\t\tthis.terminalColorSchemeUnsubscribe = this.ui.onTerminalColorSchemeChange((terminalTheme) =>\n\t\t\tthis.applyTerminalColorSchemeChange(terminalTheme),\n\t\t);\n\t}\n\n\t/**\n\t * The terminal reported a light/dark switch. Its colors changed too, so query them again: they decide\n\t * the appearance. The reported scheme only matters for terminals that do not report their background.\n\t */\n\tprivate applyTerminalColorSchemeChange(terminalTheme: TerminalTheme): void {\n\t\tif (!this.autoSyncEnabled) return;\n\t\tconst previous = getTerminalTheme();\n\t\tsetTerminalColorScheme(terminalTheme);\n\t\tif (getTerminalTheme() !== previous) this.reapplyForTerminal();\n\t\tthis.queryTerminalColors();\n\t}\n\n\tprivate notifyChanged(): void {\n\t\tthis.ui.invalidate();\n\t\tthis.onChanged();\n\t}\n}\n"]}
@@ -11,6 +11,7 @@ declare const ColorValueSchema: Type.TUnion<[Type.TString, Type.TInteger]>;
11
11
  declare const ThemeJsonSchema: Type.TObject<{
12
12
  $schema: Type.TOptional<Type.TString>;
13
13
  name: Type.TString;
14
+ appearance: Type.TOptional<Type.TUnion<[Type.TLiteral<"dark">, Type.TLiteral<"light">]>>;
14
15
  vars: Type.TOptional<Type.TRecord<"^.*$", Type.TUnion<[Type.TString, Type.TInteger]>>>;
15
16
  colors: Type.TObject<{
16
17
  accent: Type.TUnion<[Type.TString, Type.TInteger]>;
@@ -1 +1 @@
1
- {"version":3,"file":"theme-json.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/theme/theme-json.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAG5C,QAAA,MAAM,gBAAgB,4CAGpB,CAAC;AAEH,QAAA,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6EnB,CAAC;AAIH,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC9D,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,OAAO,eAAe,CAAC,CAAC;AAEhE,uFAAuF;AACvF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,kBAAkB,CA2ClF","sourcesContent":["/**\n * Theme JSON validation, kept out of `theme.ts` on purpose.\n *\n * Validating user-authored theme files needs typebox, which costs ~17 MB of module graph to import.\n * Palette lookup does not, so a presentation that only uses built-in themes should never pay for it.\n * `interactive-mode.ts` installs this validator; anything that does not simply skips validation, as\n * built-in themes already do.\n */\n\nimport { type Static, Type } from \"typebox\";\nimport { Compile } from \"typebox/compile\";\n\nconst ColorValueSchema = Type.Union([\n\tType.String(), // hex \"#ff0000\", var ref \"primary\", or empty \"\"\n\tType.Integer({ minimum: 0, maximum: 255 }), // 256-color index\n]);\n\nconst ThemeJsonSchema = Type.Object({\n\t$schema: Type.Optional(Type.String()),\n\tname: Type.String(),\n\tvars: Type.Optional(Type.Record(Type.String(), ColorValueSchema)),\n\tcolors: Type.Object({\n\t\t// Core UI (11 colors)\n\t\taccent: ColorValueSchema,\n\t\tborder: ColorValueSchema,\n\t\tborderAccent: ColorValueSchema,\n\t\tborderMuted: ColorValueSchema,\n\t\tsuccess: ColorValueSchema,\n\t\terror: ColorValueSchema,\n\t\twarning: ColorValueSchema,\n\t\tmuted: ColorValueSchema,\n\t\tdim: ColorValueSchema,\n\t\ttext: ColorValueSchema,\n\t\tthinkingText: ColorValueSchema,\n\t\t// Scrollbar (2 optional colors)\n\t\tscrollbarTrack: Type.Optional(ColorValueSchema),\n\t\tscrollbarThumb: Type.Optional(ColorValueSchema),\n\t\t// Backgrounds & Content Text (11 required, 2 optional)\n\t\tselectedBg: ColorValueSchema,\n\t\tsearchMatchBg: Type.Optional(ColorValueSchema),\n\t\tsearchMatchText: Type.Optional(ColorValueSchema),\n\t\tuserMessageBg: ColorValueSchema,\n\t\tuserMessageText: ColorValueSchema,\n\t\tcustomMessageBg: ColorValueSchema,\n\t\tcustomMessageText: ColorValueSchema,\n\t\tcustomMessageLabel: ColorValueSchema,\n\t\ttoolPendingBg: ColorValueSchema,\n\t\ttoolSuccessBg: ColorValueSchema,\n\t\ttoolErrorBg: ColorValueSchema,\n\t\ttoolTitle: ColorValueSchema,\n\t\ttoolOutput: ColorValueSchema,\n\t\t// Markdown (10 colors)\n\t\tmdHeading: ColorValueSchema,\n\t\tmdLink: ColorValueSchema,\n\t\tmdLinkUrl: ColorValueSchema,\n\t\tmdCode: ColorValueSchema,\n\t\tmdCodeBlock: ColorValueSchema,\n\t\tmdCodeBlockBorder: ColorValueSchema,\n\t\tmdQuote: ColorValueSchema,\n\t\tmdQuoteBorder: ColorValueSchema,\n\t\tmdHr: ColorValueSchema,\n\t\tmdListBullet: ColorValueSchema,\n\t\t// Tool Diffs (3 colors)\n\t\ttoolDiffAdded: ColorValueSchema,\n\t\ttoolDiffRemoved: ColorValueSchema,\n\t\ttoolDiffContext: ColorValueSchema,\n\t\t// Syntax Highlighting (9 colors)\n\t\tsyntaxComment: ColorValueSchema,\n\t\tsyntaxKeyword: ColorValueSchema,\n\t\tsyntaxFunction: ColorValueSchema,\n\t\tsyntaxVariable: ColorValueSchema,\n\t\tsyntaxString: ColorValueSchema,\n\t\tsyntaxNumber: ColorValueSchema,\n\t\tsyntaxType: ColorValueSchema,\n\t\tsyntaxOperator: ColorValueSchema,\n\t\tsyntaxPunctuation: ColorValueSchema,\n\t\t// Thinking Level Borders (6 colors)\n\t\tthinkingOff: ColorValueSchema,\n\t\tthinkingMinimal: ColorValueSchema,\n\t\tthinkingLow: ColorValueSchema,\n\t\tthinkingMedium: ColorValueSchema,\n\t\tthinkingHigh: ColorValueSchema,\n\t\tthinkingXhigh: ColorValueSchema,\n\t\tthinkingMax: Type.Optional(ColorValueSchema),\n\t\t// Bash Mode (1 color)\n\t\tbashMode: ColorValueSchema,\n\t}),\n\texport: Type.Optional(\n\t\tType.Object({\n\t\t\tpageBg: Type.Optional(ColorValueSchema),\n\t\t\tcardBg: Type.Optional(ColorValueSchema),\n\t\t\tinfoBg: Type.Optional(ColorValueSchema),\n\t\t}),\n\t),\n});\n\nconst compiledThemeSchema = Compile(ThemeJsonSchema);\n\nexport type ThemeColorValue = Static<typeof ColorValueSchema>;\nexport type ValidatedThemeJson = Static<typeof ThemeJsonSchema>;\n\n/** Validate one theme document, throwing a message that names the offending tokens. */\nexport function validateThemeJson(label: string, json: unknown): ValidatedThemeJson {\n\tif (!compiledThemeSchema.Check(json)) {\n\t\tconst errors = Array.from(compiledThemeSchema.Errors(json));\n\t\tconst missingColors = new Set<string>();\n\t\tconst otherErrors: string[] = [];\n\n\t\tfor (const error of errors) {\n\t\t\tif (error.keyword === \"required\" && error.instancePath === \"/colors\") {\n\t\t\t\tconst requiredProperties = (error.params as { requiredProperties?: string[] }).requiredProperties;\n\t\t\t\tfor (const requiredProperty of requiredProperties ?? []) {\n\t\t\t\t\tmissingColors.add(requiredProperty);\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst path = error.instancePath || \"/\";\n\t\t\totherErrors.push(` - ${path}: ${error.message}`);\n\t\t}\n\n\t\tlet errorMessage = `Invalid theme \"${label}\":\\n`;\n\t\tif (missingColors.size > 0) {\n\t\t\terrorMessage += \"\\nMissing required color tokens:\\n\";\n\t\t\terrorMessage += Array.from(missingColors)\n\t\t\t\t.sort()\n\t\t\t\t.map((color) => ` - ${color}`)\n\t\t\t\t.join(\"\\n\");\n\t\t\terrorMessage += '\\n\\nPlease add these colors to your theme\\'s \"colors\" object.';\n\t\t\terrorMessage += \"\\nSee the built-in themes (dark.json, light.json) for reference values.\";\n\t\t}\n\t\tif (otherErrors.length > 0) {\n\t\t\terrorMessage += `\\n\\nOther errors:\\n${otherErrors.join(\"\\n\")}`;\n\t\t}\n\n\t\tthrow new Error(errorMessage);\n\t}\n\n\tconst themeJson = json as ValidatedThemeJson;\n\tif (themeJson.name.includes(\"/\")) {\n\t\tthrow new Error(\n\t\t\t`Invalid theme name \"${themeJson.name}\": theme names cannot contain \"/\" because it is reserved for automatic light/dark theme settings.`,\n\t\t);\n\t}\n\treturn themeJson;\n}\n"]}
1
+ {"version":3,"file":"theme-json.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/theme/theme-json.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAG5C,QAAA,MAAM,gBAAgB,4CAGpB,CAAC;AAEH,QAAA,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+EnB,CAAC;AAIH,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC9D,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,OAAO,eAAe,CAAC,CAAC;AAEhE,uFAAuF;AACvF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,kBAAkB,CA2ClF"}
@@ -9,12 +9,14 @@
9
9
  import { Type } from "typebox";
10
10
  import { Compile } from "typebox/compile";
11
11
  const ColorValueSchema = Type.Union([
12
- Type.String(), // hex "#ff0000", var ref "primary", or empty ""
12
+ Type.String(), // hex, OKLCH, OKHSL, var ref "primary", or empty ""
13
13
  Type.Integer({ minimum: 0, maximum: 255 }), // 256-color index
14
14
  ]);
15
15
  const ThemeJsonSchema = Type.Object({
16
16
  $schema: Type.Optional(Type.String()),
17
17
  name: Type.String(),
18
+ // Background the theme is designed for. Detected from the theme colors when omitted.
19
+ appearance: Type.Optional(Type.Union([Type.Literal("dark"), Type.Literal("light")])),
18
20
  vars: Type.Optional(Type.Record(Type.String(), ColorValueSchema)),
19
21
  colors: Type.Object({
20
22
  // Core UI (11 colors)
@@ -1 +1 @@
1
- {"version":3,"file":"theme-json.js","sourceRoot":"","sources":["../../../../src/modes/interactive/theme/theme-json.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Theme JSON validation, kept out of `theme.ts` on purpose.\n *\n * Validating user-authored theme files needs typebox, which costs ~17 MB of module graph to import.\n * Palette lookup does not, so a presentation that only uses built-in themes should never pay for it.\n * `interactive-mode.ts` installs this validator; anything that does not simply skips validation, as\n * built-in themes already do.\n */\n\nimport { type Static, Type } from \"typebox\";\nimport { Compile } from \"typebox/compile\";\n\nconst ColorValueSchema = Type.Union([\n\tType.String(), // hex \"#ff0000\", var ref \"primary\", or empty \"\"\n\tType.Integer({ minimum: 0, maximum: 255 }), // 256-color index\n]);\n\nconst ThemeJsonSchema = Type.Object({\n\t$schema: Type.Optional(Type.String()),\n\tname: Type.String(),\n\tvars: Type.Optional(Type.Record(Type.String(), ColorValueSchema)),\n\tcolors: Type.Object({\n\t\t// Core UI (11 colors)\n\t\taccent: ColorValueSchema,\n\t\tborder: ColorValueSchema,\n\t\tborderAccent: ColorValueSchema,\n\t\tborderMuted: ColorValueSchema,\n\t\tsuccess: ColorValueSchema,\n\t\terror: ColorValueSchema,\n\t\twarning: ColorValueSchema,\n\t\tmuted: ColorValueSchema,\n\t\tdim: ColorValueSchema,\n\t\ttext: ColorValueSchema,\n\t\tthinkingText: ColorValueSchema,\n\t\t// Scrollbar (2 optional colors)\n\t\tscrollbarTrack: Type.Optional(ColorValueSchema),\n\t\tscrollbarThumb: Type.Optional(ColorValueSchema),\n\t\t// Backgrounds & Content Text (11 required, 2 optional)\n\t\tselectedBg: ColorValueSchema,\n\t\tsearchMatchBg: Type.Optional(ColorValueSchema),\n\t\tsearchMatchText: Type.Optional(ColorValueSchema),\n\t\tuserMessageBg: ColorValueSchema,\n\t\tuserMessageText: ColorValueSchema,\n\t\tcustomMessageBg: ColorValueSchema,\n\t\tcustomMessageText: ColorValueSchema,\n\t\tcustomMessageLabel: ColorValueSchema,\n\t\ttoolPendingBg: ColorValueSchema,\n\t\ttoolSuccessBg: ColorValueSchema,\n\t\ttoolErrorBg: ColorValueSchema,\n\t\ttoolTitle: ColorValueSchema,\n\t\ttoolOutput: ColorValueSchema,\n\t\t// Markdown (10 colors)\n\t\tmdHeading: ColorValueSchema,\n\t\tmdLink: ColorValueSchema,\n\t\tmdLinkUrl: ColorValueSchema,\n\t\tmdCode: ColorValueSchema,\n\t\tmdCodeBlock: ColorValueSchema,\n\t\tmdCodeBlockBorder: ColorValueSchema,\n\t\tmdQuote: ColorValueSchema,\n\t\tmdQuoteBorder: ColorValueSchema,\n\t\tmdHr: ColorValueSchema,\n\t\tmdListBullet: ColorValueSchema,\n\t\t// Tool Diffs (3 colors)\n\t\ttoolDiffAdded: ColorValueSchema,\n\t\ttoolDiffRemoved: ColorValueSchema,\n\t\ttoolDiffContext: ColorValueSchema,\n\t\t// Syntax Highlighting (9 colors)\n\t\tsyntaxComment: ColorValueSchema,\n\t\tsyntaxKeyword: ColorValueSchema,\n\t\tsyntaxFunction: ColorValueSchema,\n\t\tsyntaxVariable: ColorValueSchema,\n\t\tsyntaxString: ColorValueSchema,\n\t\tsyntaxNumber: ColorValueSchema,\n\t\tsyntaxType: ColorValueSchema,\n\t\tsyntaxOperator: ColorValueSchema,\n\t\tsyntaxPunctuation: ColorValueSchema,\n\t\t// Thinking Level Borders (6 colors)\n\t\tthinkingOff: ColorValueSchema,\n\t\tthinkingMinimal: ColorValueSchema,\n\t\tthinkingLow: ColorValueSchema,\n\t\tthinkingMedium: ColorValueSchema,\n\t\tthinkingHigh: ColorValueSchema,\n\t\tthinkingXhigh: ColorValueSchema,\n\t\tthinkingMax: Type.Optional(ColorValueSchema),\n\t\t// Bash Mode (1 color)\n\t\tbashMode: ColorValueSchema,\n\t}),\n\texport: Type.Optional(\n\t\tType.Object({\n\t\t\tpageBg: Type.Optional(ColorValueSchema),\n\t\t\tcardBg: Type.Optional(ColorValueSchema),\n\t\t\tinfoBg: Type.Optional(ColorValueSchema),\n\t\t}),\n\t),\n});\n\nconst compiledThemeSchema = Compile(ThemeJsonSchema);\n\nexport type ThemeColorValue = Static<typeof ColorValueSchema>;\nexport type ValidatedThemeJson = Static<typeof ThemeJsonSchema>;\n\n/** Validate one theme document, throwing a message that names the offending tokens. */\nexport function validateThemeJson(label: string, json: unknown): ValidatedThemeJson {\n\tif (!compiledThemeSchema.Check(json)) {\n\t\tconst errors = Array.from(compiledThemeSchema.Errors(json));\n\t\tconst missingColors = new Set<string>();\n\t\tconst otherErrors: string[] = [];\n\n\t\tfor (const error of errors) {\n\t\t\tif (error.keyword === \"required\" && error.instancePath === \"/colors\") {\n\t\t\t\tconst requiredProperties = (error.params as { requiredProperties?: string[] }).requiredProperties;\n\t\t\t\tfor (const requiredProperty of requiredProperties ?? []) {\n\t\t\t\t\tmissingColors.add(requiredProperty);\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst path = error.instancePath || \"/\";\n\t\t\totherErrors.push(` - ${path}: ${error.message}`);\n\t\t}\n\n\t\tlet errorMessage = `Invalid theme \"${label}\":\\n`;\n\t\tif (missingColors.size > 0) {\n\t\t\terrorMessage += \"\\nMissing required color tokens:\\n\";\n\t\t\terrorMessage += Array.from(missingColors)\n\t\t\t\t.sort()\n\t\t\t\t.map((color) => ` - ${color}`)\n\t\t\t\t.join(\"\\n\");\n\t\t\terrorMessage += '\\n\\nPlease add these colors to your theme\\'s \"colors\" object.';\n\t\t\terrorMessage += \"\\nSee the built-in themes (dark.json, light.json) for reference values.\";\n\t\t}\n\t\tif (otherErrors.length > 0) {\n\t\t\terrorMessage += `\\n\\nOther errors:\\n${otherErrors.join(\"\\n\")}`;\n\t\t}\n\n\t\tthrow new Error(errorMessage);\n\t}\n\n\tconst themeJson = json as ValidatedThemeJson;\n\tif (themeJson.name.includes(\"/\")) {\n\t\tthrow new Error(\n\t\t\t`Invalid theme name \"${themeJson.name}\": theme names cannot contain \"/\" because it is reserved for automatic light/dark theme settings.`,\n\t\t);\n\t}\n\treturn themeJson;\n}\n"]}
1
+ {"version":3,"file":"theme-json.js","sourceRoot":"","sources":["../../../../src/modes/interactive/theme/theme-json.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Theme JSON validation, kept out of `theme.ts` on purpose.\n *\n * Validating user-authored theme files needs typebox, which costs ~17 MB of module graph to import.\n * Palette lookup does not, so a presentation that only uses built-in themes should never pay for it.\n * `interactive-mode.ts` installs this validator; anything that does not simply skips validation, as\n * built-in themes already do.\n */\n\nimport { type Static, Type } from \"typebox\";\nimport { Compile } from \"typebox/compile\";\n\nconst ColorValueSchema = Type.Union([\n\tType.String(), // hex, OKLCH, OKHSL, var ref \"primary\", or empty \"\"\n\tType.Integer({ minimum: 0, maximum: 255 }), // 256-color index\n]);\n\nconst ThemeJsonSchema = Type.Object({\n\t$schema: Type.Optional(Type.String()),\n\tname: Type.String(),\n\t// Background the theme is designed for. Detected from the theme colors when omitted.\n\tappearance: Type.Optional(Type.Union([Type.Literal(\"dark\"), Type.Literal(\"light\")])),\n\tvars: Type.Optional(Type.Record(Type.String(), ColorValueSchema)),\n\tcolors: Type.Object({\n\t\t// Core UI (11 colors)\n\t\taccent: ColorValueSchema,\n\t\tborder: ColorValueSchema,\n\t\tborderAccent: ColorValueSchema,\n\t\tborderMuted: ColorValueSchema,\n\t\tsuccess: ColorValueSchema,\n\t\terror: ColorValueSchema,\n\t\twarning: ColorValueSchema,\n\t\tmuted: ColorValueSchema,\n\t\tdim: ColorValueSchema,\n\t\ttext: ColorValueSchema,\n\t\tthinkingText: ColorValueSchema,\n\t\t// Scrollbar (2 optional colors)\n\t\tscrollbarTrack: Type.Optional(ColorValueSchema),\n\t\tscrollbarThumb: Type.Optional(ColorValueSchema),\n\t\t// Backgrounds & Content Text (11 required, 2 optional)\n\t\tselectedBg: ColorValueSchema,\n\t\tsearchMatchBg: Type.Optional(ColorValueSchema),\n\t\tsearchMatchText: Type.Optional(ColorValueSchema),\n\t\tuserMessageBg: ColorValueSchema,\n\t\tuserMessageText: ColorValueSchema,\n\t\tcustomMessageBg: ColorValueSchema,\n\t\tcustomMessageText: ColorValueSchema,\n\t\tcustomMessageLabel: ColorValueSchema,\n\t\ttoolPendingBg: ColorValueSchema,\n\t\ttoolSuccessBg: ColorValueSchema,\n\t\ttoolErrorBg: ColorValueSchema,\n\t\ttoolTitle: ColorValueSchema,\n\t\ttoolOutput: ColorValueSchema,\n\t\t// Markdown (10 colors)\n\t\tmdHeading: ColorValueSchema,\n\t\tmdLink: ColorValueSchema,\n\t\tmdLinkUrl: ColorValueSchema,\n\t\tmdCode: ColorValueSchema,\n\t\tmdCodeBlock: ColorValueSchema,\n\t\tmdCodeBlockBorder: ColorValueSchema,\n\t\tmdQuote: ColorValueSchema,\n\t\tmdQuoteBorder: ColorValueSchema,\n\t\tmdHr: ColorValueSchema,\n\t\tmdListBullet: ColorValueSchema,\n\t\t// Tool Diffs (3 colors)\n\t\ttoolDiffAdded: ColorValueSchema,\n\t\ttoolDiffRemoved: ColorValueSchema,\n\t\ttoolDiffContext: ColorValueSchema,\n\t\t// Syntax Highlighting (9 colors)\n\t\tsyntaxComment: ColorValueSchema,\n\t\tsyntaxKeyword: ColorValueSchema,\n\t\tsyntaxFunction: ColorValueSchema,\n\t\tsyntaxVariable: ColorValueSchema,\n\t\tsyntaxString: ColorValueSchema,\n\t\tsyntaxNumber: ColorValueSchema,\n\t\tsyntaxType: ColorValueSchema,\n\t\tsyntaxOperator: ColorValueSchema,\n\t\tsyntaxPunctuation: ColorValueSchema,\n\t\t// Thinking Level Borders (6 colors)\n\t\tthinkingOff: ColorValueSchema,\n\t\tthinkingMinimal: ColorValueSchema,\n\t\tthinkingLow: ColorValueSchema,\n\t\tthinkingMedium: ColorValueSchema,\n\t\tthinkingHigh: ColorValueSchema,\n\t\tthinkingXhigh: ColorValueSchema,\n\t\tthinkingMax: Type.Optional(ColorValueSchema),\n\t\t// Bash Mode (1 color)\n\t\tbashMode: ColorValueSchema,\n\t}),\n\texport: Type.Optional(\n\t\tType.Object({\n\t\t\tpageBg: Type.Optional(ColorValueSchema),\n\t\t\tcardBg: Type.Optional(ColorValueSchema),\n\t\t\tinfoBg: Type.Optional(ColorValueSchema),\n\t\t}),\n\t),\n});\n\nconst compiledThemeSchema = Compile(ThemeJsonSchema);\n\nexport type ThemeColorValue = Static<typeof ColorValueSchema>;\nexport type ValidatedThemeJson = Static<typeof ThemeJsonSchema>;\n\n/** Validate one theme document, throwing a message that names the offending tokens. */\nexport function validateThemeJson(label: string, json: unknown): ValidatedThemeJson {\n\tif (!compiledThemeSchema.Check(json)) {\n\t\tconst errors = Array.from(compiledThemeSchema.Errors(json));\n\t\tconst missingColors = new Set<string>();\n\t\tconst otherErrors: string[] = [];\n\n\t\tfor (const error of errors) {\n\t\t\tif (error.keyword === \"required\" && error.instancePath === \"/colors\") {\n\t\t\t\tconst requiredProperties = (error.params as { requiredProperties?: string[] }).requiredProperties;\n\t\t\t\tfor (const requiredProperty of requiredProperties ?? []) {\n\t\t\t\t\tmissingColors.add(requiredProperty);\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst path = error.instancePath || \"/\";\n\t\t\totherErrors.push(` - ${path}: ${error.message}`);\n\t\t}\n\n\t\tlet errorMessage = `Invalid theme \"${label}\":\\n`;\n\t\tif (missingColors.size > 0) {\n\t\t\terrorMessage += \"\\nMissing required color tokens:\\n\";\n\t\t\terrorMessage += Array.from(missingColors)\n\t\t\t\t.sort()\n\t\t\t\t.map((color) => ` - ${color}`)\n\t\t\t\t.join(\"\\n\");\n\t\t\terrorMessage += '\\n\\nPlease add these colors to your theme\\'s \"colors\" object.';\n\t\t\terrorMessage += \"\\nSee the built-in themes (dark.json, light.json) for reference values.\";\n\t\t}\n\t\tif (otherErrors.length > 0) {\n\t\t\terrorMessage += `\\n\\nOther errors:\\n${otherErrors.join(\"\\n\")}`;\n\t\t}\n\n\t\tthrow new Error(errorMessage);\n\t}\n\n\tconst themeJson = json as ValidatedThemeJson;\n\tif (themeJson.name.includes(\"/\")) {\n\t\tthrow new Error(\n\t\t\t`Invalid theme name \"${themeJson.name}\": theme names cannot contain \"/\" because it is reserved for automatic light/dark theme settings.`,\n\t\t);\n\t}\n\treturn themeJson;\n}\n"]}
@@ -14,6 +14,11 @@
14
14
  "pattern": "^[^/]+$",
15
15
  "description": "Theme name. Must not contain '/' because it is reserved for automatic light/dark theme settings."
16
16
  },
17
+ "appearance": {
18
+ "type": "string",
19
+ "enum": ["dark", "light"],
20
+ "description": "Background the theme is designed for. Detected from the theme colors when omitted."
21
+ },
17
22
  "vars": {
18
23
  "type": "object",
19
24
  "description": "Reusable color variables",
@@ -21,7 +26,7 @@
21
26
  "oneOf": [
22
27
  {
23
28
  "type": "string",
24
- "description": "Hex color (#RRGGBB), variable reference, or empty string for terminal default"
29
+ "description": "Hex color (#RGB or #RRGGBB), OKLCH or OKHSL color, variable reference, or empty string for terminal default"
25
30
  },
26
31
  {
27
32
  "type": "integer",
@@ -342,7 +347,7 @@
342
347
  "oneOf": [
343
348
  {
344
349
  "type": "string",
345
- "description": "Hex color (#RRGGBB), variable reference, or empty string for terminal default"
350
+ "description": "Hex color (#RGB or #RRGGBB), OKLCH or OKHSL color, variable reference, or empty string for terminal default"
346
351
  },
347
352
  {
348
353
  "type": "integer",