@astralyn/pi 0.87.6 → 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 (698) hide show
  1. package/CHANGELOG.md +30 -6
  2. package/README.md +3 -3
  3. package/dist/bun/runtime-setup.js +4 -1
  4. package/dist/bun/runtime-setup.js.map +1 -1
  5. package/dist/bundle/chunks/anthropic-messages-KIXY7EDT.js +6 -0
  6. package/dist/bundle/chunks/anthropic.js +2 -2
  7. package/dist/bundle/chunks/azure-openai-responses-RPBERDXD.js +2 -0
  8. package/dist/bundle/chunks/bedrock-converse-stream.js +8 -8
  9. package/dist/bundle/chunks/{chunk-LPQCB2VJ.js → chunk-A576H74Y.js} +2 -2
  10. package/dist/bundle/chunks/{chunk-NW5FIDD7.js → chunk-ABVRAYXT.js} +3 -3
  11. package/dist/bundle/chunks/{chunk-I5IVW2WS.js → chunk-CLLDCO64.js} +1 -1
  12. package/dist/bundle/chunks/chunk-DEWXBB6W.js +2 -0
  13. package/dist/bundle/chunks/chunk-G4RY3GN7.js +11 -0
  14. package/dist/bundle/chunks/chunk-GCKVOFWP.js +2 -0
  15. package/dist/bundle/chunks/chunk-MPDALHNJ.js +2 -0
  16. package/dist/bundle/chunks/chunk-OO6DJ3CL.js +31 -0
  17. package/dist/bundle/chunks/{chunk-4W4Q2H6W.js → chunk-VW2P3X6P.js} +905 -278
  18. package/dist/bundle/chunks/chunk-VWCWZD6E.js +2 -0
  19. package/dist/bundle/chunks/cloudflare-workers-ai-system-one-ZYSAFXXL.js +2 -0
  20. package/dist/bundle/chunks/codemode-worker.js +295 -0
  21. package/dist/bundle/chunks/github-copilot.js +1 -1
  22. package/dist/bundle/chunks/google-generative-ai-SDNQVVXA.js +2 -0
  23. package/dist/bundle/chunks/google-vertex-LZXOLBIO.js +2 -0
  24. package/dist/bundle/chunks/llama-cpp-classify-7IYGGPND.js +22 -0
  25. package/dist/bundle/chunks/meta.js +2 -0
  26. package/dist/bundle/chunks/mistral-conversations-VYKPSSAM.js +5 -0
  27. package/dist/bundle/chunks/openai-chatgpt.js +75 -0
  28. package/dist/bundle/chunks/openai-codex-responses-HZ4VUDXD.js +10 -0
  29. package/dist/bundle/chunks/openai-codex.js +2 -2
  30. package/dist/bundle/chunks/openai-completions-SKDGF6OE.js +7 -0
  31. package/dist/bundle/chunks/openai-responses-FPML4SSG.js +3 -0
  32. package/dist/bundle/chunks/{openrouter-images-6XDE2CEW.js → openrouter-images-5524IQHX.js} +1 -1
  33. package/dist/bundle/chunks/openrouter.js +2 -2
  34. package/dist/bundle/chunks/{pi-messages-MQMPIPNC.js → pi-messages-HZZ7GEEW.js} +2 -2
  35. package/dist/bundle/chunks/radius.js +2 -2
  36. package/dist/bundle/chunks/typesafe-system-one-Z2CDLKEY.js +2 -0
  37. package/dist/bundle/chunks/virtual-modules-TQRORWJQ.js +2 -0
  38. package/dist/bundle/cli.js +1 -1
  39. package/dist/bundle/index.js +1 -1
  40. package/dist/bundle/rpc-entry.js +1 -1
  41. package/dist/cli/args.d.ts.map +1 -1
  42. package/dist/cli/args.js +4 -3
  43. package/dist/cli/args.js.map +1 -1
  44. package/dist/cli/startup-ui.d.ts.map +1 -1
  45. package/dist/cli/startup-ui.js +38 -30
  46. package/dist/cli/startup-ui.js.map +1 -1
  47. package/dist/config.d.ts +18 -4
  48. package/dist/config.d.ts.map +1 -1
  49. package/dist/config.js +30 -4
  50. package/dist/config.js.map +1 -1
  51. package/dist/core/agent-session-runtime.d.ts +1 -1
  52. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  53. package/dist/core/agent-session-runtime.js +13 -13
  54. package/dist/core/agent-session-runtime.js.map +1 -1
  55. package/dist/core/agent-session-services.d.ts +2 -2
  56. package/dist/core/agent-session-services.d.ts.map +1 -1
  57. package/dist/core/agent-session-services.js +14 -1
  58. package/dist/core/agent-session-services.js.map +1 -1
  59. package/dist/core/agent-session.d.ts +100 -35
  60. package/dist/core/agent-session.d.ts.map +1 -1
  61. package/dist/core/agent-session.js +456 -194
  62. package/dist/core/agent-session.js.map +1 -1
  63. package/dist/core/bug-report.js +1 -1
  64. package/dist/core/bug-report.js.map +1 -1
  65. package/dist/core/compaction/compaction.d.ts.map +1 -1
  66. package/dist/core/compaction/compaction.js +1 -22
  67. package/dist/core/compaction/compaction.js.map +1 -1
  68. package/dist/core/compaction/utils.d.ts +2 -1
  69. package/dist/core/compaction/utils.d.ts.map +1 -1
  70. package/dist/core/compaction/utils.js +25 -18
  71. package/dist/core/compaction/utils.js.map +1 -1
  72. package/dist/core/crash-log.d.ts.map +1 -1
  73. package/dist/core/crash-log.js +2 -1
  74. package/dist/core/crash-log.js.map +1 -1
  75. package/dist/core/export-html/template.css +10 -0
  76. package/dist/core/export-html/template.js +66 -17
  77. package/dist/core/extensions/distribution-api.d.ts +1 -1
  78. package/dist/core/extensions/distribution-api.d.ts.map +1 -1
  79. package/dist/core/extensions/distribution-api.js.map +1 -1
  80. package/dist/core/extensions/index.d.ts +2 -2
  81. package/dist/core/extensions/index.d.ts.map +1 -1
  82. package/dist/core/extensions/index.js.map +1 -1
  83. package/dist/core/extensions/loader.d.ts.map +1 -1
  84. package/dist/core/extensions/loader.js +55 -5
  85. package/dist/core/extensions/loader.js.map +1 -1
  86. package/dist/core/extensions/runner.d.ts +22 -3
  87. package/dist/core/extensions/runner.d.ts.map +1 -1
  88. package/dist/core/extensions/runner.js +124 -8
  89. package/dist/core/extensions/runner.js.map +1 -1
  90. package/dist/core/extensions/types.d.ts +305 -25
  91. package/dist/core/extensions/types.d.ts.map +1 -1
  92. package/dist/core/extensions/types.js.map +1 -1
  93. package/dist/core/extensions/wrapper.d.ts +2 -2
  94. package/dist/core/extensions/wrapper.d.ts.map +1 -1
  95. package/dist/core/extensions/wrapper.js +3 -3
  96. package/dist/core/extensions/wrapper.js.map +1 -1
  97. package/dist/core/keybindings.d.ts +30 -5
  98. package/dist/core/keybindings.d.ts.map +1 -1
  99. package/dist/core/keybindings.js +7 -1
  100. package/dist/core/keybindings.js.map +1 -1
  101. package/dist/core/mcp-servers.d.ts +98 -0
  102. package/dist/core/mcp-servers.d.ts.map +1 -0
  103. package/dist/core/mcp-servers.js +158 -0
  104. package/dist/core/mcp-servers.js.map +1 -0
  105. package/dist/core/model-registry.d.ts +13 -1
  106. package/dist/core/model-registry.d.ts.map +1 -1
  107. package/dist/core/model-registry.js +25 -0
  108. package/dist/core/model-registry.js.map +1 -1
  109. package/dist/core/model-resolver.d.ts +2 -2
  110. package/dist/core/model-resolver.d.ts.map +1 -1
  111. package/dist/core/model-resolver.js +5 -5
  112. package/dist/core/model-resolver.js.map +1 -1
  113. package/dist/core/model-runtime.d.ts +41 -3
  114. package/dist/core/model-runtime.d.ts.map +1 -1
  115. package/dist/core/model-runtime.js +167 -17
  116. package/dist/core/model-runtime.js.map +1 -1
  117. package/dist/core/nested-tool-calls.d.ts +102 -0
  118. package/dist/core/nested-tool-calls.d.ts.map +1 -0
  119. package/dist/core/nested-tool-calls.js +177 -0
  120. package/dist/core/nested-tool-calls.js.map +1 -0
  121. package/dist/core/package-manager.d.ts +4 -0
  122. package/dist/core/package-manager.d.ts.map +1 -1
  123. package/dist/core/package-manager.js +58 -12
  124. package/dist/core/package-manager.js.map +1 -1
  125. package/dist/core/provider-composer.d.ts +40 -21
  126. package/dist/core/provider-composer.d.ts.map +1 -1
  127. package/dist/core/provider-composer.js +92 -40
  128. package/dist/core/provider-composer.js.map +1 -1
  129. package/dist/core/remote-catalog-provider.d.ts +8 -1
  130. package/dist/core/remote-catalog-provider.d.ts.map +1 -1
  131. package/dist/core/remote-catalog-provider.js +18 -3
  132. package/dist/core/remote-catalog-provider.js.map +1 -1
  133. package/dist/core/resource-loader.d.ts +7 -1
  134. package/dist/core/resource-loader.d.ts.map +1 -1
  135. package/dist/core/resource-loader.js +160 -35
  136. package/dist/core/resource-loader.js.map +1 -1
  137. package/dist/core/sdk.d.ts +3 -3
  138. package/dist/core/sdk.d.ts.map +1 -1
  139. package/dist/core/sdk.js +25 -7
  140. package/dist/core/sdk.js.map +1 -1
  141. package/dist/core/session-manager.d.ts +9 -0
  142. package/dist/core/session-manager.d.ts.map +1 -1
  143. package/dist/core/session-manager.js +22 -22
  144. package/dist/core/session-manager.js.map +1 -1
  145. package/dist/core/settings-manager.d.ts +36 -1
  146. package/dist/core/settings-manager.d.ts.map +1 -1
  147. package/dist/core/settings-manager.js +108 -2
  148. package/dist/core/settings-manager.js.map +1 -1
  149. package/dist/core/slash-commands.d.ts.map +1 -1
  150. package/dist/core/slash-commands.js +1 -0
  151. package/dist/core/slash-commands.js.map +1 -1
  152. package/dist/core/source-info.d.ts +8 -0
  153. package/dist/core/source-info.d.ts.map +1 -1
  154. package/dist/core/source-info.js +16 -0
  155. package/dist/core/source-info.js.map +1 -1
  156. package/dist/core/system-prompt.js +1 -1
  157. package/dist/core/system-prompt.js.map +1 -1
  158. package/dist/core/tasks/delivery.d.ts +40 -0
  159. package/dist/core/tasks/delivery.d.ts.map +1 -0
  160. package/dist/core/tasks/delivery.js +157 -0
  161. package/dist/core/tasks/delivery.js.map +1 -0
  162. package/dist/core/tasks/history.d.ts +4 -0
  163. package/dist/core/tasks/history.d.ts.map +1 -0
  164. package/dist/core/{background → tasks}/history.js +24 -48
  165. package/dist/core/tasks/history.js.map +1 -0
  166. package/dist/core/{background → tasks}/output.d.ts +4 -4
  167. package/dist/core/tasks/output.d.ts.map +1 -0
  168. package/dist/core/{background → tasks}/output.js +11 -11
  169. package/dist/core/tasks/output.js.map +1 -0
  170. package/dist/core/tasks/presentation.d.ts +9 -0
  171. package/dist/core/tasks/presentation.d.ts.map +1 -0
  172. package/dist/core/{background → tasks}/presentation.js +53 -51
  173. package/dist/core/tasks/presentation.js.map +1 -0
  174. package/dist/core/{background/service.d.ts → tasks/runtime.d.ts} +22 -23
  175. package/dist/core/tasks/runtime.d.ts.map +1 -0
  176. package/dist/core/{background/service.js → tasks/runtime.js} +154 -198
  177. package/dist/core/tasks/runtime.js.map +1 -0
  178. package/dist/core/tasks/session.d.ts +49 -0
  179. package/dist/core/tasks/session.d.ts.map +1 -0
  180. package/dist/core/tasks/session.js +129 -0
  181. package/dist/core/tasks/session.js.map +1 -0
  182. package/dist/core/tasks/store.d.ts +32 -0
  183. package/dist/core/tasks/store.d.ts.map +1 -0
  184. package/dist/core/tasks/store.js +135 -0
  185. package/dist/core/tasks/store.js.map +1 -0
  186. package/dist/core/{background → tasks}/types.d.ts +80 -62
  187. package/dist/core/tasks/types.d.ts.map +1 -0
  188. package/dist/core/{background → tasks}/types.js +9 -9
  189. package/dist/core/tasks/types.js.map +1 -0
  190. package/dist/core/tasks/view-data.d.ts +8 -0
  191. package/dist/core/tasks/view-data.d.ts.map +1 -0
  192. package/dist/core/tasks/view-data.js +61 -0
  193. package/dist/core/tasks/view-data.js.map +1 -0
  194. package/dist/core/tasks/view.d.ts +30 -0
  195. package/dist/core/tasks/view.d.ts.map +1 -0
  196. package/dist/core/tasks/view.js +50 -0
  197. package/dist/core/tasks/view.js.map +1 -0
  198. package/dist/core/tools/bash.d.ts +8 -93
  199. package/dist/core/tools/bash.d.ts.map +1 -1
  200. package/dist/core/tools/bash.js +8 -240
  201. package/dist/core/tools/bash.js.map +1 -1
  202. package/dist/core/tools/grep.d.ts +2 -0
  203. package/dist/core/tools/grep.d.ts.map +1 -1
  204. package/dist/core/tools/grep.js +2 -0
  205. package/dist/core/tools/grep.js.map +1 -1
  206. package/dist/core/tools/index.d.ts +2 -1
  207. package/dist/core/tools/index.d.ts.map +1 -1
  208. package/dist/core/tools/index.js +9 -0
  209. package/dist/core/tools/index.js.map +1 -1
  210. package/dist/core/tools/output-accumulator.d.ts +11 -0
  211. package/dist/core/tools/output-accumulator.d.ts.map +1 -1
  212. package/dist/core/tools/output-accumulator.js +36 -0
  213. package/dist/core/tools/output-accumulator.js.map +1 -1
  214. package/dist/core/tools/powershell.d.ts +6 -2
  215. package/dist/core/tools/powershell.d.ts.map +1 -1
  216. package/dist/core/tools/powershell.js +1 -1
  217. package/dist/core/tools/powershell.js.map +1 -1
  218. package/dist/core/tools/render-utils.d.ts +6 -0
  219. package/dist/core/tools/render-utils.d.ts.map +1 -1
  220. package/dist/core/tools/render-utils.js +26 -0
  221. package/dist/core/tools/render-utils.js.map +1 -1
  222. package/dist/core/tools/renderers/bash.d.ts +1 -1
  223. package/dist/core/tools/renderers/bash.d.ts.map +1 -1
  224. package/dist/core/tools/renderers/bash.js +9 -10
  225. package/dist/core/tools/renderers/bash.js.map +1 -1
  226. package/dist/core/tools/renderers/index.d.ts.map +1 -1
  227. package/dist/core/tools/renderers/index.js +5 -7
  228. package/dist/core/tools/renderers/index.js.map +1 -1
  229. package/dist/core/tools/renderers/read.d.ts.map +1 -1
  230. package/dist/core/tools/renderers/read.js +3 -2
  231. package/dist/core/tools/renderers/read.js.map +1 -1
  232. package/dist/core/tools/renderers/shell-task.d.ts +4 -0
  233. package/dist/core/tools/renderers/shell-task.d.ts.map +1 -0
  234. package/dist/core/tools/renderers/shell-task.js +35 -0
  235. package/dist/core/tools/renderers/shell-task.js.map +1 -0
  236. package/dist/core/tools/shell-execution.d.ts +4 -5
  237. package/dist/core/tools/shell-execution.d.ts.map +1 -1
  238. package/dist/core/tools/shell-execution.js +19 -3
  239. package/dist/core/tools/shell-execution.js.map +1 -1
  240. package/dist/core/tools/shell-tool.d.ts +93 -0
  241. package/dist/core/tools/shell-tool.d.ts.map +1 -0
  242. package/dist/core/tools/shell-tool.js +251 -0
  243. package/dist/core/tools/shell-tool.js.map +1 -0
  244. package/dist/core/tools/tasks/actions.d.ts +12 -0
  245. package/dist/core/tools/tasks/actions.d.ts.map +1 -0
  246. package/dist/{extensions/background → core/tools/tasks}/actions.js +20 -19
  247. package/dist/core/tools/tasks/actions.js.map +1 -0
  248. package/dist/{extensions/background → core/tools/tasks}/constants.d.ts +10 -10
  249. package/dist/core/tools/tasks/constants.d.ts.map +1 -0
  250. package/dist/{extensions/background → core/tools/tasks}/constants.js +10 -10
  251. package/dist/core/tools/tasks/constants.js.map +1 -0
  252. package/dist/{extensions/background → core/tools/tasks}/schema.d.ts +6 -6
  253. package/dist/core/tools/tasks/schema.d.ts.map +1 -0
  254. package/dist/{extensions/background → core/tools/tasks}/schema.js +17 -17
  255. package/dist/core/tools/tasks/schema.js.map +1 -0
  256. package/dist/{extensions/background → core/tools/tasks}/types.d.ts +15 -17
  257. package/dist/core/tools/tasks/types.d.ts.map +1 -0
  258. package/dist/core/tools/tasks/types.js.map +1 -0
  259. package/dist/core/tools/tasks.d.ts +14 -0
  260. package/dist/core/tools/tasks.d.ts.map +1 -0
  261. package/dist/core/tools/tasks.js +40 -0
  262. package/dist/core/tools/tasks.js.map +1 -0
  263. package/dist/core/tools/tool-definition-wrapper.d.ts +4 -3
  264. package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
  265. package/dist/core/tools/tool-definition-wrapper.js +4 -2
  266. package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
  267. package/dist/core/tools/truncate.d.ts +14 -0
  268. package/dist/core/tools/truncate.d.ts.map +1 -1
  269. package/dist/core/tools/truncate.js +29 -0
  270. package/dist/core/tools/truncate.js.map +1 -1
  271. package/dist/core/trust-manager.d.ts.map +1 -1
  272. package/dist/core/trust-manager.js +1 -0
  273. package/dist/core/trust-manager.js.map +1 -1
  274. package/dist/core/usage-totals.d.ts +5 -3
  275. package/dist/core/usage-totals.d.ts.map +1 -1
  276. package/dist/core/usage-totals.js +27 -4
  277. package/dist/core/usage-totals.js.map +1 -1
  278. package/dist/core/virtual-models.d.ts +115 -0
  279. package/dist/core/virtual-models.d.ts.map +1 -0
  280. package/dist/core/virtual-models.js +117 -0
  281. package/dist/core/virtual-models.js.map +1 -0
  282. package/dist/extensions/codemode/execute.d.ts +16 -0
  283. package/dist/extensions/codemode/execute.d.ts.map +1 -0
  284. package/dist/extensions/codemode/execute.js +390 -0
  285. package/dist/extensions/codemode/execute.js.map +1 -0
  286. package/dist/extensions/codemode/execute.lazy.d.ts +3 -0
  287. package/dist/extensions/codemode/execute.lazy.d.ts.map +1 -0
  288. package/dist/extensions/codemode/execute.lazy.js +3 -0
  289. package/dist/extensions/codemode/execute.lazy.js.map +1 -0
  290. package/dist/extensions/codemode/index.d.ts +21 -0
  291. package/dist/extensions/codemode/index.d.ts.map +1 -0
  292. package/dist/extensions/codemode/index.js +36 -0
  293. package/dist/extensions/codemode/index.js.map +1 -0
  294. package/dist/extensions/codemode/renderer.d.ts +12 -0
  295. package/dist/extensions/codemode/renderer.d.ts.map +1 -0
  296. package/dist/extensions/codemode/renderer.js +119 -0
  297. package/dist/extensions/codemode/renderer.js.map +1 -0
  298. package/dist/extensions/codemode/search.d.ts +33 -0
  299. package/dist/extensions/codemode/search.d.ts.map +1 -0
  300. package/dist/extensions/codemode/search.js +117 -0
  301. package/dist/extensions/codemode/search.js.map +1 -0
  302. package/dist/extensions/codemode/tool.d.ts +122 -0
  303. package/dist/extensions/codemode/tool.d.ts.map +1 -0
  304. package/dist/extensions/codemode/tool.js +324 -0
  305. package/dist/extensions/codemode/tool.js.map +1 -0
  306. package/dist/extensions/codemode/worker.d.ts +7 -0
  307. package/dist/extensions/codemode/worker.d.ts.map +1 -0
  308. package/dist/extensions/codemode/worker.js +7 -0
  309. package/dist/extensions/codemode/worker.js.map +1 -0
  310. package/dist/extensions/deepwiki/schema.d.ts +1 -1
  311. package/dist/extensions/index.d.ts.map +1 -1
  312. package/dist/extensions/index.js +14 -12
  313. package/dist/extensions/index.js.map +1 -1
  314. package/dist/extensions/llama/provider.d.ts +1 -1
  315. package/dist/extensions/llama/provider.d.ts.map +1 -1
  316. package/dist/extensions/llama/provider.js +65 -13
  317. package/dist/extensions/llama/provider.js.map +1 -1
  318. package/dist/extensions/mcp/cli.d.ts +21 -0
  319. package/dist/extensions/mcp/cli.d.ts.map +1 -0
  320. package/dist/extensions/mcp/cli.js +485 -0
  321. package/dist/extensions/mcp/cli.js.map +1 -0
  322. package/dist/extensions/mcp/cli.lazy.d.ts +3 -0
  323. package/dist/extensions/mcp/cli.lazy.d.ts.map +1 -0
  324. package/dist/extensions/mcp/cli.lazy.js +3 -0
  325. package/dist/extensions/mcp/cli.lazy.js.map +1 -0
  326. package/dist/extensions/mcp/config.d.ts +70 -0
  327. package/dist/extensions/mcp/config.d.ts.map +1 -0
  328. package/dist/extensions/mcp/config.js +146 -0
  329. package/dist/extensions/mcp/config.js.map +1 -0
  330. package/dist/extensions/mcp/index.d.ts +52 -0
  331. package/dist/extensions/mcp/index.d.ts.map +1 -0
  332. package/dist/extensions/mcp/index.js +904 -0
  333. package/dist/extensions/mcp/index.js.map +1 -0
  334. package/dist/extensions/mcp/log.d.ts +16 -0
  335. package/dist/extensions/mcp/log.d.ts.map +1 -0
  336. package/dist/extensions/mcp/log.js +64 -0
  337. package/dist/extensions/mcp/log.js.map +1 -0
  338. package/dist/extensions/mcp/oauth.d.ts +94 -0
  339. package/dist/extensions/mcp/oauth.d.ts.map +1 -0
  340. package/dist/extensions/mcp/oauth.js +330 -0
  341. package/dist/extensions/mcp/oauth.js.map +1 -0
  342. package/dist/extensions/mcp/resources.d.ts +43 -0
  343. package/dist/extensions/mcp/resources.d.ts.map +1 -0
  344. package/dist/extensions/mcp/resources.js +262 -0
  345. package/dist/extensions/mcp/resources.js.map +1 -0
  346. package/dist/extensions/mcp/runtime.d.ts +96 -0
  347. package/dist/extensions/mcp/runtime.d.ts.map +1 -0
  348. package/dist/extensions/mcp/runtime.js +372 -0
  349. package/dist/extensions/mcp/runtime.js.map +1 -0
  350. package/dist/extensions/mcp/runtime.lazy.d.ts +3 -0
  351. package/dist/extensions/mcp/runtime.lazy.d.ts.map +1 -0
  352. package/dist/extensions/mcp/runtime.lazy.js +3 -0
  353. package/dist/extensions/mcp/runtime.lazy.js.map +1 -0
  354. package/dist/extensions/mcp/tools.d.ts +83 -0
  355. package/dist/extensions/mcp/tools.d.ts.map +1 -0
  356. package/dist/extensions/mcp/tools.js +233 -0
  357. package/dist/extensions/mcp/tools.js.map +1 -0
  358. package/dist/extensions/mcp/ui.d.ts +60 -0
  359. package/dist/extensions/mcp/ui.d.ts.map +1 -0
  360. package/dist/extensions/mcp/ui.js +166 -0
  361. package/dist/extensions/mcp/ui.js.map +1 -0
  362. package/dist/extensions/statusline/index.js +2 -2
  363. package/dist/extensions/statusline/index.js.map +1 -1
  364. package/dist/extensions/tool-search/index.d.ts +12 -0
  365. package/dist/extensions/tool-search/index.d.ts.map +1 -0
  366. package/dist/extensions/tool-search/index.js +20 -0
  367. package/dist/extensions/tool-search/index.js.map +1 -0
  368. package/dist/extensions/tool-search/tool.d.ts +72 -0
  369. package/dist/extensions/tool-search/tool.d.ts.map +1 -0
  370. package/dist/extensions/tool-search/tool.js +208 -0
  371. package/dist/extensions/tool-search/tool.js.map +1 -0
  372. package/dist/index.d.ts +13 -4
  373. package/dist/index.d.ts.map +1 -1
  374. package/dist/index.js +7 -1
  375. package/dist/index.js.map +1 -1
  376. package/dist/main.d.ts.map +1 -1
  377. package/dist/main.js +10 -0
  378. package/dist/main.js.map +1 -1
  379. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  380. package/dist/modes/interactive/components/config-selector.js +13 -3
  381. package/dist/modes/interactive/components/config-selector.js.map +1 -1
  382. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
  383. package/dist/modes/interactive/components/custom-message.js +3 -1
  384. package/dist/modes/interactive/components/custom-message.js.map +1 -1
  385. package/dist/modes/interactive/components/first-time-setup.d.ts +4 -4
  386. package/dist/modes/interactive/components/first-time-setup.d.ts.map +1 -1
  387. package/dist/modes/interactive/components/first-time-setup.js +8 -2
  388. package/dist/modes/interactive/components/first-time-setup.js.map +1 -1
  389. package/dist/modes/interactive/components/footer.d.ts +7 -0
  390. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  391. package/dist/modes/interactive/components/footer.js +42 -3
  392. package/dist/modes/interactive/components/footer.js.map +1 -1
  393. package/dist/modes/interactive/components/pi-logo.d.ts +12 -0
  394. package/dist/modes/interactive/components/pi-logo.d.ts.map +1 -0
  395. package/dist/modes/interactive/components/pi-logo.js +25 -0
  396. package/dist/modes/interactive/components/pi-logo.js.map +1 -0
  397. package/dist/modes/interactive/components/settings-selector.d.ts +3 -1
  398. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  399. package/dist/modes/interactive/components/settings-selector.js +28 -6
  400. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  401. package/dist/modes/interactive/components/status-marker.d.ts +2 -2
  402. package/dist/modes/interactive/components/status-marker.js +2 -2
  403. package/dist/modes/interactive/components/status-marker.js.map +1 -1
  404. package/dist/modes/interactive/components/themed-text.d.ts +17 -0
  405. package/dist/modes/interactive/components/themed-text.d.ts.map +1 -0
  406. package/dist/modes/interactive/components/themed-text.js +28 -0
  407. package/dist/modes/interactive/components/themed-text.js.map +1 -0
  408. package/dist/modes/interactive/interactive-mode.d.ts +2 -4
  409. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  410. package/dist/modes/interactive/interactive-mode.js +214 -163
  411. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  412. package/dist/modes/interactive/tasks/completion-render.d.ts +8 -0
  413. package/dist/modes/interactive/tasks/completion-render.d.ts.map +1 -0
  414. package/dist/{extensions/background → modes/interactive/tasks}/completion-render.js +31 -27
  415. package/dist/modes/interactive/tasks/completion-render.js.map +1 -0
  416. package/dist/modes/interactive/tasks/fallback-view.d.ts +4 -0
  417. package/dist/modes/interactive/tasks/fallback-view.d.ts.map +1 -0
  418. package/dist/modes/interactive/tasks/fallback-view.js +27 -0
  419. package/dist/modes/interactive/tasks/fallback-view.js.map +1 -0
  420. package/dist/modes/interactive/tasks/index.d.ts +12 -0
  421. package/dist/modes/interactive/tasks/index.d.ts.map +1 -0
  422. package/dist/modes/interactive/tasks/index.js +97 -0
  423. package/dist/modes/interactive/tasks/index.js.map +1 -0
  424. package/dist/modes/interactive/tasks/manager.d.ts +67 -0
  425. package/dist/modes/interactive/tasks/manager.d.ts.map +1 -0
  426. package/dist/modes/interactive/tasks/manager.js +380 -0
  427. package/dist/modes/interactive/tasks/manager.js.map +1 -0
  428. package/dist/{extensions/background → modes/interactive/tasks}/render.d.ts +13 -13
  429. package/dist/modes/interactive/tasks/render.d.ts.map +1 -0
  430. package/dist/{extensions/background → modes/interactive/tasks}/render.js +18 -18
  431. package/dist/modes/interactive/tasks/render.js.map +1 -0
  432. package/dist/{extensions/background → modes/interactive/tasks}/task-view.d.ts +7 -7
  433. package/dist/modes/interactive/tasks/task-view.d.ts.map +1 -0
  434. package/dist/{extensions/background → modes/interactive/tasks}/task-view.js +4 -4
  435. package/dist/modes/interactive/tasks/task-view.js.map +1 -0
  436. package/dist/{extensions/background → modes/interactive/tasks}/text.d.ts +1 -1
  437. package/dist/modes/interactive/tasks/text.d.ts.map +1 -0
  438. package/dist/{extensions/background → modes/interactive/tasks}/text.js +1 -1
  439. package/dist/modes/interactive/tasks/text.js.map +1 -0
  440. package/dist/modes/interactive/tasks/viewport.d.ts +15 -0
  441. package/dist/modes/interactive/tasks/viewport.d.ts.map +1 -0
  442. package/dist/modes/interactive/tasks/viewport.js +49 -0
  443. package/dist/modes/interactive/tasks/viewport.js.map +1 -0
  444. package/dist/modes/interactive/theme/dark.json +59 -72
  445. package/dist/modes/interactive/theme/light.json +57 -69
  446. package/dist/modes/interactive/theme/system-theme.d.ts +54 -0
  447. package/dist/modes/interactive/theme/system-theme.d.ts.map +1 -0
  448. package/dist/modes/interactive/theme/system-theme.js +535 -0
  449. package/dist/modes/interactive/theme/system-theme.js.map +1 -0
  450. package/dist/modes/interactive/theme/theme-controller.d.ts +46 -6
  451. package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -1
  452. package/dist/modes/interactive/theme/theme-controller.js +125 -47
  453. package/dist/modes/interactive/theme/theme-controller.js.map +1 -1
  454. package/dist/modes/interactive/theme/theme-json.d.ts +1 -0
  455. package/dist/modes/interactive/theme/theme-json.d.ts.map +1 -1
  456. package/dist/modes/interactive/theme/theme-json.js +3 -1
  457. package/dist/modes/interactive/theme/theme-json.js.map +1 -1
  458. package/dist/modes/interactive/theme/theme-schema.json +7 -2
  459. package/dist/modes/interactive/theme/theme.d.ts +70 -39
  460. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  461. package/dist/modes/interactive/theme/theme.js +247 -313
  462. package/dist/modes/interactive/theme/theme.js.map +1 -1
  463. package/dist/modes/interactive/tool-view/fallback.d.ts +1 -1
  464. package/dist/modes/interactive/tool-view/fallback.d.ts.map +1 -1
  465. package/dist/modes/interactive/tool-view/fallback.js +4 -1
  466. package/dist/modes/interactive/tool-view/fallback.js.map +1 -1
  467. package/dist/modes/interactive/tool-view/tool-execution.js +2 -2
  468. package/dist/modes/interactive/tool-view/tool-execution.js.map +1 -1
  469. package/dist/modes/interactive/tui-renderer.d.ts +2 -1
  470. package/dist/modes/interactive/tui-renderer.d.ts.map +1 -1
  471. package/dist/modes/interactive/tui-renderer.js +1 -0
  472. package/dist/modes/interactive/tui-renderer.js.map +1 -1
  473. package/dist/modes/rpc/rpc-client.d.ts +6 -6
  474. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  475. package/dist/modes/rpc/rpc-client.js +12 -8
  476. package/dist/modes/rpc/rpc-client.js.map +1 -1
  477. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  478. package/dist/modes/rpc/rpc-mode.js +7 -9
  479. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  480. package/dist/modes/rpc/rpc-types.d.ts +10 -1
  481. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  482. package/dist/modes/rpc/rpc-types.js.map +1 -1
  483. package/dist/package-manager-cli.d.ts.map +1 -1
  484. package/dist/package-manager-cli.js +6 -2
  485. package/dist/package-manager-cli.js.map +1 -1
  486. package/dist/utils/clipboard-image.d.ts.map +1 -1
  487. package/dist/utils/clipboard-image.js +14 -17
  488. package/dist/utils/clipboard-image.js.map +1 -1
  489. package/dist/utils/clipboard.d.ts +2 -0
  490. package/dist/utils/clipboard.d.ts.map +1 -1
  491. package/dist/utils/clipboard.js +5 -0
  492. package/dist/utils/clipboard.js.map +1 -1
  493. package/dist/utils/paths.d.ts +3 -3
  494. package/dist/utils/paths.d.ts.map +1 -1
  495. package/dist/utils/paths.js +5 -4
  496. package/dist/utils/paths.js.map +1 -1
  497. package/dist/utils/shell.d.ts +1 -3
  498. package/dist/utils/shell.d.ts.map +1 -1
  499. package/dist/utils/shell.js +3 -30
  500. package/dist/utils/shell.js.map +1 -1
  501. package/docs/bundled/README.md +22 -8
  502. package/docs/bundled/extensions/statusline.md +2 -2
  503. package/docs/bundled/tasks.md +141 -0
  504. package/docs/bundled/tool-presentation.md +1 -1
  505. package/docs/custom-provider.md +44 -0
  506. package/docs/docs.json +10 -6
  507. package/docs/extensions.md +89 -86
  508. package/docs/index.md +2 -1
  509. package/docs/keybindings.md +8 -7
  510. package/docs/llama-cpp.md +12 -1
  511. package/docs/mcp.md +188 -0
  512. package/docs/models.md +35 -0
  513. package/docs/packages.md +4 -0
  514. package/docs/providers.md +6 -0
  515. package/docs/rpc.md +5 -3
  516. package/docs/sdk.md +26 -16
  517. package/docs/security.md +4 -0
  518. package/docs/session-format.md +18 -11
  519. package/docs/settings.md +26 -2
  520. package/docs/themes.md +27 -5
  521. package/docs/tui.md +20 -0
  522. package/docs/usage.md +61 -3
  523. package/docs/virtual-models.md +114 -0
  524. package/docs/windows.md +2 -0
  525. package/examples/README.md +1 -1
  526. package/examples/extensions/README.md +2 -0
  527. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  528. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  529. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  530. package/examples/extensions/custom-provider-gitlab-duo/test.ts +4 -4
  531. package/examples/extensions/debug-provider.ts +90 -0
  532. package/examples/extensions/gondolin/package-lock.json +2 -2
  533. package/examples/extensions/gondolin/package.json +1 -1
  534. package/examples/extensions/jev-router.ts +113 -0
  535. package/examples/extensions/sandbox/package-lock.json +2 -2
  536. package/examples/extensions/sandbox/package.json +1 -1
  537. package/examples/extensions/with-deps/package-lock.json +2 -2
  538. package/examples/extensions/with-deps/package.json +1 -1
  539. package/examples/rpc-client.ts +1 -1
  540. package/examples/rpc-extension-ui.ts +1 -1
  541. package/examples/sdk/14-codemode-mcp.ts +61 -0
  542. package/examples/sdk/README.md +1 -0
  543. package/npm-shrinkwrap.json +409 -423
  544. package/package.json +13 -10
  545. package/dist/bundle/chunks/anthropic-messages-XWFTZP2N.js +0 -6
  546. package/dist/bundle/chunks/azure-openai-responses-HS35BQV6.js +0 -2
  547. package/dist/bundle/chunks/chunk-2IO5GDBS.js +0 -11
  548. package/dist/bundle/chunks/chunk-EDBLK2JQ.js +0 -2
  549. package/dist/bundle/chunks/chunk-IORR2FW4.js +0 -2
  550. package/dist/bundle/chunks/chunk-NUHFSC37.js +0 -25
  551. package/dist/bundle/chunks/google-generative-ai-NOVAJBFC.js +0 -2
  552. package/dist/bundle/chunks/google-vertex-4VHCZJV5.js +0 -2
  553. package/dist/bundle/chunks/mistral-conversations-WC6A2WCJ.js +0 -5
  554. package/dist/bundle/chunks/openai-codex-responses-XCDG75W2.js +0 -10
  555. package/dist/bundle/chunks/openai-completions-SHS3CAEL.js +0 -7
  556. package/dist/bundle/chunks/openai-responses-UT6XFKC7.js +0 -2
  557. package/dist/bundle/chunks/virtual-modules-KUEIEAZN.js +0 -2
  558. package/dist/core/background/history.d.ts +0 -4
  559. package/dist/core/background/history.d.ts.map +0 -1
  560. package/dist/core/background/history.js.map +0 -1
  561. package/dist/core/background/output.d.ts.map +0 -1
  562. package/dist/core/background/output.js.map +0 -1
  563. package/dist/core/background/presentation.d.ts +0 -9
  564. package/dist/core/background/presentation.d.ts.map +0 -1
  565. package/dist/core/background/presentation.js.map +0 -1
  566. package/dist/core/background/service.d.ts.map +0 -1
  567. package/dist/core/background/service.js.map +0 -1
  568. package/dist/core/background/session.d.ts +0 -67
  569. package/dist/core/background/session.d.ts.map +0 -1
  570. package/dist/core/background/session.js +0 -248
  571. package/dist/core/background/session.js.map +0 -1
  572. package/dist/core/background/types.d.ts.map +0 -1
  573. package/dist/core/background/types.js.map +0 -1
  574. package/dist/extensions/background/actions.d.ts +0 -11
  575. package/dist/extensions/background/actions.d.ts.map +0 -1
  576. package/dist/extensions/background/actions.js.map +0 -1
  577. package/dist/extensions/background/completion-render.d.ts +0 -8
  578. package/dist/extensions/background/completion-render.d.ts.map +0 -1
  579. package/dist/extensions/background/completion-render.js.map +0 -1
  580. package/dist/extensions/background/constants.d.ts.map +0 -1
  581. package/dist/extensions/background/constants.js.map +0 -1
  582. package/dist/extensions/background/index.d.ts +0 -7
  583. package/dist/extensions/background/index.d.ts.map +0 -1
  584. package/dist/extensions/background/index.js +0 -135
  585. package/dist/extensions/background/index.js.map +0 -1
  586. package/dist/extensions/background/keybindings.d.ts +0 -10
  587. package/dist/extensions/background/keybindings.d.ts.map +0 -1
  588. package/dist/extensions/background/keybindings.js +0 -14
  589. package/dist/extensions/background/keybindings.js.map +0 -1
  590. package/dist/extensions/background/manager.d.ts +0 -80
  591. package/dist/extensions/background/manager.d.ts.map +0 -1
  592. package/dist/extensions/background/manager.js +0 -673
  593. package/dist/extensions/background/manager.js.map +0 -1
  594. package/dist/extensions/background/render.d.ts.map +0 -1
  595. package/dist/extensions/background/render.js.map +0 -1
  596. package/dist/extensions/background/schema.d.ts.map +0 -1
  597. package/dist/extensions/background/schema.js.map +0 -1
  598. package/dist/extensions/background/task-view.d.ts.map +0 -1
  599. package/dist/extensions/background/task-view.js.map +0 -1
  600. package/dist/extensions/background/text.d.ts.map +0 -1
  601. package/dist/extensions/background/text.js.map +0 -1
  602. package/dist/extensions/background/types.d.ts.map +0 -1
  603. package/dist/extensions/background/types.js.map +0 -1
  604. package/dist/extensions/subagent/activity.d.ts +0 -34
  605. package/dist/extensions/subagent/activity.d.ts.map +0 -1
  606. package/dist/extensions/subagent/activity.js +0 -192
  607. package/dist/extensions/subagent/activity.js.map +0 -1
  608. package/dist/extensions/subagent/agents-command.d.ts +0 -4
  609. package/dist/extensions/subagent/agents-command.d.ts.map +0 -1
  610. package/dist/extensions/subagent/agents-command.js +0 -230
  611. package/dist/extensions/subagent/agents-command.js.map +0 -1
  612. package/dist/extensions/subagent/agents.d.ts +0 -6
  613. package/dist/extensions/subagent/agents.d.ts.map +0 -1
  614. package/dist/extensions/subagent/agents.js +0 -53
  615. package/dist/extensions/subagent/agents.js.map +0 -1
  616. package/dist/extensions/subagent/budget.d.ts +0 -15
  617. package/dist/extensions/subagent/budget.d.ts.map +0 -1
  618. package/dist/extensions/subagent/budget.js +0 -123
  619. package/dist/extensions/subagent/budget.js.map +0 -1
  620. package/dist/extensions/subagent/cancellation.d.ts +0 -29
  621. package/dist/extensions/subagent/cancellation.d.ts.map +0 -1
  622. package/dist/extensions/subagent/cancellation.js +0 -91
  623. package/dist/extensions/subagent/cancellation.js.map +0 -1
  624. package/dist/extensions/subagent/constants.d.ts +0 -25
  625. package/dist/extensions/subagent/constants.d.ts.map +0 -1
  626. package/dist/extensions/subagent/constants.js +0 -50
  627. package/dist/extensions/subagent/constants.js.map +0 -1
  628. package/dist/extensions/subagent/index.d.ts +0 -3
  629. package/dist/extensions/subagent/index.d.ts.map +0 -1
  630. package/dist/extensions/subagent/index.js +0 -151
  631. package/dist/extensions/subagent/index.js.map +0 -1
  632. package/dist/extensions/subagent/model-selection.d.ts +0 -16
  633. package/dist/extensions/subagent/model-selection.d.ts.map +0 -1
  634. package/dist/extensions/subagent/model-selection.js +0 -51
  635. package/dist/extensions/subagent/model-selection.js.map +0 -1
  636. package/dist/extensions/subagent/render.d.ts +0 -24
  637. package/dist/extensions/subagent/render.d.ts.map +0 -1
  638. package/dist/extensions/subagent/render.js +0 -336
  639. package/dist/extensions/subagent/render.js.map +0 -1
  640. package/dist/extensions/subagent/resolve.d.ts +0 -31
  641. package/dist/extensions/subagent/resolve.d.ts.map +0 -1
  642. package/dist/extensions/subagent/resolve.js +0 -111
  643. package/dist/extensions/subagent/resolve.js.map +0 -1
  644. package/dist/extensions/subagent/runner.d.ts +0 -35
  645. package/dist/extensions/subagent/runner.d.ts.map +0 -1
  646. package/dist/extensions/subagent/runner.js +0 -255
  647. package/dist/extensions/subagent/runner.js.map +0 -1
  648. package/dist/extensions/subagent/schema.d.ts +0 -28
  649. package/dist/extensions/subagent/schema.d.ts.map +0 -1
  650. package/dist/extensions/subagent/schema.js +0 -58
  651. package/dist/extensions/subagent/schema.js.map +0 -1
  652. package/dist/extensions/subagent/sdk-runner.d.ts +0 -33
  653. package/dist/extensions/subagent/sdk-runner.d.ts.map +0 -1
  654. package/dist/extensions/subagent/sdk-runner.js +0 -331
  655. package/dist/extensions/subagent/sdk-runner.js.map +0 -1
  656. package/dist/extensions/subagent/settings.d.ts +0 -8
  657. package/dist/extensions/subagent/settings.d.ts.map +0 -1
  658. package/dist/extensions/subagent/settings.js +0 -206
  659. package/dist/extensions/subagent/settings.js.map +0 -1
  660. package/dist/extensions/subagent/state.d.ts +0 -102
  661. package/dist/extensions/subagent/state.d.ts.map +0 -1
  662. package/dist/extensions/subagent/state.js +0 -383
  663. package/dist/extensions/subagent/state.js.map +0 -1
  664. package/dist/extensions/subagent/text.d.ts +0 -6
  665. package/dist/extensions/subagent/text.d.ts.map +0 -1
  666. package/dist/extensions/subagent/text.js +0 -66
  667. package/dist/extensions/subagent/text.js.map +0 -1
  668. package/dist/extensions/subagent/types.d.ts +0 -91
  669. package/dist/extensions/subagent/types.d.ts.map +0 -1
  670. package/dist/extensions/subagent/types.js +0 -2
  671. package/dist/extensions/subagent/types.js.map +0 -1
  672. package/dist/extensions/subagent/ui/agents-dialog.d.ts +0 -4
  673. package/dist/extensions/subagent/ui/agents-dialog.d.ts.map +0 -1
  674. package/dist/extensions/subagent/ui/agents-dialog.js +0 -84
  675. package/dist/extensions/subagent/ui/agents-dialog.js.map +0 -1
  676. package/dist/extensions/subagent/ui/choice-menu.d.ts +0 -39
  677. package/dist/extensions/subagent/ui/choice-menu.d.ts.map +0 -1
  678. package/dist/extensions/subagent/ui/choice-menu.js +0 -93
  679. package/dist/extensions/subagent/ui/choice-menu.js.map +0 -1
  680. package/dist/extensions/subagent/ui/choices.d.ts +0 -36
  681. package/dist/extensions/subagent/ui/choices.d.ts.map +0 -1
  682. package/dist/extensions/subagent/ui/choices.js +0 -54
  683. package/dist/extensions/subagent/ui/choices.js.map +0 -1
  684. package/dist/extensions/subagent/ui/model-list.d.ts +0 -66
  685. package/dist/extensions/subagent/ui/model-list.d.ts.map +0 -1
  686. package/dist/extensions/subagent/ui/model-list.js +0 -235
  687. package/dist/extensions/subagent/ui/model-list.js.map +0 -1
  688. package/dist/extensions/subagent/ui/model-picker.d.ts +0 -47
  689. package/dist/extensions/subagent/ui/model-picker.d.ts.map +0 -1
  690. package/dist/extensions/subagent/ui/model-picker.js +0 -143
  691. package/dist/extensions/subagent/ui/model-picker.js.map +0 -1
  692. package/dist/extensions/subagent/ui/profile-settings-menu.d.ts +0 -41
  693. package/dist/extensions/subagent/ui/profile-settings-menu.d.ts.map +0 -1
  694. package/dist/extensions/subagent/ui/profile-settings-menu.js +0 -98
  695. package/dist/extensions/subagent/ui/profile-settings-menu.js.map +0 -1
  696. package/docs/bundled/extensions/background.md +0 -132
  697. package/docs/bundled/extensions/subagent.md +0 -148
  698. /package/dist/{extensions/background → core/tools/tasks}/types.js +0 -0
@@ -1,11 +1,13 @@
1
1
  import * as fs from "node:fs";
2
2
  import * as path from "node:path";
3
- import { getCapabilities, } from "@earendil-works/pi-tui";
3
+ import { backgroundAnsi, colorToHex, colorToOklch, foregroundAnsi, getTerminalColorMode, indexedColor, mixColors, parseColor, rgbColor, styleTextWithAnsi, } from "@earendil-works/pi-tui";
4
4
  import chalk from "chalk";
5
5
  import { getCustomThemesDir, getThemesDir } from "../../../config.js";
6
6
  import { closeWatcher, watchWithErrorHandler } from "../../../utils/fs-watch.js";
7
7
  import { highlight, supportsLanguage } from "../../../utils/syntax-highlight.js";
8
8
  import { stripBom } from "../../../utils/text.js";
9
+ import { generateSystemThemeColors, SYSTEM_THEME_NAME, terminalAppearance } from "./system-theme.js";
10
+ export { SYSTEM_THEME_NAME } from "./system-theme.js";
9
11
  let themeJsonValidator;
10
12
  /**
11
13
  * Install full theme validation. Without it, documents are accepted as-is, which is what built-in
@@ -15,134 +17,11 @@ let themeJsonValidator;
15
17
  export function setThemeJsonValidator(validator) {
16
18
  themeJsonValidator = validator;
17
19
  }
18
- const THEME_BACKGROUND_KEYS = new Set([
19
- "selectedBg",
20
- "searchMatchBg",
21
- "userMessageBg",
22
- "customMessageBg",
23
- "toolPendingBg",
24
- "toolSuccessBg",
25
- "toolErrorBg",
26
- ]);
27
20
  // ============================================================================
28
21
  // Color Utilities
29
22
  // ============================================================================
30
- function hexToRgb(hex) {
31
- const cleaned = hex.replace("#", "");
32
- if (cleaned.length !== 6) {
33
- throw new Error(`Invalid hex color: ${hex}`);
34
- }
35
- const r = parseInt(cleaned.substring(0, 2), 16);
36
- const g = parseInt(cleaned.substring(2, 4), 16);
37
- const b = parseInt(cleaned.substring(4, 6), 16);
38
- if (Number.isNaN(r) || Number.isNaN(g) || Number.isNaN(b)) {
39
- throw new Error(`Invalid hex color: ${hex}`);
40
- }
41
- return { r, g, b };
42
- }
43
- // The 6x6x6 color cube channel values (indices 0-5)
44
- const CUBE_VALUES = [0, 95, 135, 175, 215, 255];
45
- // Grayscale ramp values (indices 232-255, 24 grays from 8 to 238)
46
- const GRAY_VALUES = Array.from({ length: 24 }, (_, i) => 8 + i * 10);
47
- function findClosestCubeIndex(value) {
48
- let minDist = Infinity;
49
- let minIdx = 0;
50
- for (let i = 0; i < CUBE_VALUES.length; i++) {
51
- const dist = Math.abs(value - CUBE_VALUES[i]);
52
- if (dist < minDist) {
53
- minDist = dist;
54
- minIdx = i;
55
- }
56
- }
57
- return minIdx;
58
- }
59
- function findClosestGrayIndex(gray) {
60
- let minDist = Infinity;
61
- let minIdx = 0;
62
- for (let i = 0; i < GRAY_VALUES.length; i++) {
63
- const dist = Math.abs(gray - GRAY_VALUES[i]);
64
- if (dist < minDist) {
65
- minDist = dist;
66
- minIdx = i;
67
- }
68
- }
69
- return minIdx;
70
- }
71
- function colorDistance(r1, g1, b1, r2, g2, b2) {
72
- // Weighted Euclidean distance (human eye is more sensitive to green)
73
- const dr = r1 - r2;
74
- const dg = g1 - g2;
75
- const db = b1 - b2;
76
- return dr * dr * 0.299 + dg * dg * 0.587 + db * db * 0.114;
77
- }
78
- function rgbTo256(r, g, b) {
79
- // Find closest color in the 6x6x6 cube
80
- const rIdx = findClosestCubeIndex(r);
81
- const gIdx = findClosestCubeIndex(g);
82
- const bIdx = findClosestCubeIndex(b);
83
- const cubeR = CUBE_VALUES[rIdx];
84
- const cubeG = CUBE_VALUES[gIdx];
85
- const cubeB = CUBE_VALUES[bIdx];
86
- const cubeIndex = 16 + 36 * rIdx + 6 * gIdx + bIdx;
87
- const cubeDist = colorDistance(r, g, b, cubeR, cubeG, cubeB);
88
- // Find closest grayscale
89
- const gray = Math.round(0.299 * r + 0.587 * g + 0.114 * b);
90
- const grayIdx = findClosestGrayIndex(gray);
91
- const grayValue = GRAY_VALUES[grayIdx];
92
- const grayIndex = 232 + grayIdx;
93
- const grayDist = colorDistance(r, g, b, grayValue, grayValue, grayValue);
94
- // Check if color has noticeable saturation (hue matters)
95
- // If max-min spread is significant, prefer cube to preserve tint
96
- const maxC = Math.max(r, g, b);
97
- const minC = Math.min(r, g, b);
98
- const spread = maxC - minC;
99
- // Only consider grayscale if color is nearly neutral (spread < 10)
100
- // AND grayscale is actually closer
101
- if (spread < 10 && grayDist < cubeDist) {
102
- return grayIndex;
103
- }
104
- return cubeIndex;
105
- }
106
- function hexTo256(hex) {
107
- const { r, g, b } = hexToRgb(hex);
108
- return rgbTo256(r, g, b);
109
- }
110
- function fgAnsi(color, mode) {
111
- if (color === "")
112
- return "\x1b[39m";
113
- if (typeof color === "number")
114
- return `\x1b[38;5;${color}m`;
115
- if (color.startsWith("#")) {
116
- if (mode === "truecolor") {
117
- const { r, g, b } = hexToRgb(color);
118
- return `\x1b[38;2;${r};${g};${b}m`;
119
- }
120
- else {
121
- const index = hexTo256(color);
122
- return `\x1b[38;5;${index}m`;
123
- }
124
- }
125
- throw new Error(`Invalid color value: ${color}`);
126
- }
127
- function bgAnsi(color, mode) {
128
- if (color === "")
129
- return "\x1b[49m";
130
- if (typeof color === "number")
131
- return `\x1b[48;5;${color}m`;
132
- if (color.startsWith("#")) {
133
- if (mode === "truecolor") {
134
- const { r, g, b } = hexToRgb(color);
135
- return `\x1b[48;2;${r};${g};${b}m`;
136
- }
137
- else {
138
- const index = hexTo256(color);
139
- return `\x1b[48;5;${index}m`;
140
- }
141
- }
142
- throw new Error(`Invalid color value: ${color}`);
143
- }
144
23
  function resolveVarRefs(value, vars, visited = new Set()) {
145
- if (typeof value === "number" || value === "" || value.startsWith("#")) {
24
+ if (typeof value === "number" || value === "" || value.startsWith("#") || /^ok(lch|hsl)\(/i.test(value)) {
146
25
  return value;
147
26
  }
148
27
  if (visited.has(value)) {
@@ -171,46 +50,161 @@ function withThemeColorFallbacks(colors) {
171
50
  searchMatchText: colors.searchMatchText ?? colors.text,
172
51
  };
173
52
  }
53
+ // The terminal's reported colors. Replaced (never mutated) on update, so themes can cache resolved colors
54
+ // by identity.
55
+ let terminalColors = {};
56
+ // While the terminal color query is in flight, the system theme renders in grayscale.
57
+ let terminalColorsPending = false;
58
+ // The terminal's last light/dark report (mode 2031). Only used while it has not reported a background.
59
+ let terminalColorScheme;
60
+ /**
61
+ * Record the terminal's reported colors. Themes use the default colors for tokens set to "" (terminal
62
+ * default); the system theme is generated from all of them. Ends the pending state.
63
+ */
64
+ export function setTerminalColors(colors) {
65
+ terminalColors = { ...colors };
66
+ terminalColorsPending = false;
67
+ }
68
+ /** Record the terminal's light/dark report, the fallback for terminals that do not report their background. */
69
+ export function setTerminalColorScheme(scheme) {
70
+ terminalColorScheme = scheme;
71
+ }
72
+ /** Render the system theme in grayscale until `setTerminalColors()` reports the terminal's colors. */
73
+ export function markTerminalColorsPending() {
74
+ terminalColorsPending = true;
75
+ }
76
+ /** Assumed terminal default colors when the terminal does not report them. */
77
+ const GUESSED_DEFAULT_COLORS = {
78
+ dark: { foreground: parseColor("#e5e5e7"), background: parseColor("#000000") },
79
+ light: { foreground: parseColor("#000000"), background: parseColor("#ffffff") },
80
+ };
81
+ function averageLightness(colors) {
82
+ // Palette colors 0-15 follow the user's terminal palette, so they say nothing about the theme.
83
+ const fixed = colors.filter((color) => color.kind !== "indexed" || color.index >= 16);
84
+ if (fixed.length === 0)
85
+ return undefined;
86
+ return fixed.reduce((sum, color) => sum + colorToOklch(color).l, 0) / fixed.length;
87
+ }
88
+ /** Detect the background a theme is designed for from the lightness of its own colors. */
89
+ function detectAppearance(foregrounds, backgrounds) {
90
+ const fg = averageLightness(foregrounds);
91
+ const bg = averageLightness(backgrounds);
92
+ if (fg !== undefined && bg !== undefined)
93
+ return bg < fg ? "dark" : "light";
94
+ if (bg !== undefined)
95
+ return bg < 0.5 ? "dark" : "light";
96
+ if (fg !== undefined)
97
+ return fg > 0.5 ? "dark" : "light";
98
+ return undefined;
99
+ }
174
100
  // ============================================================================
175
101
  // Theme Class
176
102
  // ============================================================================
177
103
  export class Theme {
178
104
  constructor(fgColors, bgColors, mode, options = {}) {
105
+ // Precomputed escape sequences keep fg()/bg() on the render hot path to a lookup and concat.
106
+ this.fgAnsi = new Map();
107
+ this.bgAnsi = new Map();
108
+ // Tokens set to "" have no color of their own; `colors` fills them from the terminal defaults.
109
+ this.concreteColors = {};
110
+ this.defaultForegroundTokens = [];
111
+ this.defaultBackgroundTokens = [];
179
112
  this.name = options.name;
180
113
  this.sourcePath = options.sourcePath;
181
114
  this.sourceInfo = options.sourceInfo;
182
115
  this.mode = mode;
183
- this.fgColors = new Map();
184
- const colors = {
116
+ this.dimTokens = new Set(options.dim);
117
+ const foregrounds = {
185
118
  ...fgColors,
186
119
  scrollbarTrack: fgColors.scrollbarTrack ?? fgColors.muted,
187
120
  scrollbarThumb: fgColors.scrollbarThumb ?? fgColors.text,
188
121
  thinkingMax: fgColors.thinkingMax ?? fgColors.thinkingXhigh,
189
122
  searchMatchText: fgColors.searchMatchText ?? fgColors.text,
190
123
  };
191
- for (const [key, value] of Object.entries(colors)) {
192
- this.fgColors.set(key, fgAnsi(value, mode));
193
- }
194
- this.bgColors = new Map();
195
- const backgrounds = {
196
- ...bgColors,
197
- searchMatchBg: bgColors.searchMatchBg ?? bgColors.selectedBg,
124
+ const backgrounds = { ...bgColors, searchMatchBg: bgColors.searchMatchBg ?? bgColors.selectedBg };
125
+ const concreteForegrounds = [];
126
+ const concreteBackgrounds = [];
127
+ // Returns the escape sequence for the token's own slot.
128
+ const addToken = (token, value, isBackground) => {
129
+ if (value === "") {
130
+ (isBackground ? this.defaultBackgroundTokens : this.defaultForegroundTokens).push(token);
131
+ return isBackground ? "\x1b[49m" : "\x1b[39m";
132
+ }
133
+ const color = parseColor(value);
134
+ this.concreteColors[token] = color;
135
+ (isBackground ? concreteBackgrounds : concreteForegrounds).push(color);
136
+ return isBackground ? backgroundAnsi(color, mode) : foregroundAnsi(color, mode);
198
137
  };
199
- for (const [key, value] of Object.entries(backgrounds)) {
200
- this.bgColors.set(key, bgAnsi(value, mode));
138
+ for (const [token, value] of Object.entries(foregrounds)) {
139
+ this.fgAnsi.set(token, addToken(token, value, false));
140
+ }
141
+ for (const [token, value] of Object.entries(backgrounds)) {
142
+ this.bgAnsi.set(token, addToken(token, value, true));
143
+ }
144
+ this.ownAppearance = options.appearance ?? detectAppearance(concreteForegrounds, concreteBackgrounds);
145
+ }
146
+ /**
147
+ * The background the theme is designed for: declared in the theme JSON, detected from its colors,
148
+ * or, for themes without usable colors, the terminal's appearance.
149
+ */
150
+ get appearance() {
151
+ return this.ownAppearance ?? getTerminalTheme();
152
+ }
153
+ /**
154
+ * Concrete colors for all tokens. Tokens set to "" (terminal default) use the terminal's reported
155
+ * default colors, or a guess based on `appearance` when the terminal did not report them. Faint
156
+ * tokens are approximated by mixing their color toward the background.
157
+ */
158
+ get colors() {
159
+ const terminal = terminalColors;
160
+ if (this.resolvedColors?.terminal !== terminal) {
161
+ const guess = GUESSED_DEFAULT_COLORS[this.appearance];
162
+ const toColor = (rgb, fallback) => rgb ? rgbColor(rgb.r, rgb.g, rgb.b) : fallback;
163
+ const foreground = toColor(terminal.foreground, guess.foreground);
164
+ const background = toColor(terminal.background, guess.background);
165
+ const colors = { ...this.concreteColors };
166
+ for (const token of this.defaultForegroundTokens)
167
+ colors[token] = foreground;
168
+ for (const token of this.defaultBackgroundTokens)
169
+ colors[token] = background;
170
+ for (const token of this.dimTokens) {
171
+ const color = colors[token];
172
+ if (color)
173
+ colors[token] = mixColors(color, background, 0.4);
174
+ }
175
+ this.resolvedColors = { terminal, colors: Object.freeze(colors) };
201
176
  }
177
+ return this.resolvedColors.colors;
178
+ }
179
+ style(text, options) {
180
+ const { fg, bg } = options;
181
+ if (typeof fg === "string" && this.dimTokens.has(fg))
182
+ options = { ...options, dim: true };
183
+ return styleTextWithAnsi(text, fg === undefined
184
+ ? undefined
185
+ : typeof fg === "string"
186
+ ? this.tokenAnsi(this.fgAnsi, fg)
187
+ : foregroundAnsi(fg, this.mode), bg === undefined
188
+ ? undefined
189
+ : typeof bg === "string"
190
+ ? this.tokenAnsi(this.bgAnsi, bg)
191
+ : backgroundAnsi(bg, this.mode), options);
202
192
  }
203
193
  fg(color, text) {
204
- const ansi = this.fgColors.get(color);
205
- if (!ansi)
206
- throw new Error(`Unknown theme color: ${color}`);
207
- return `${ansi}${text}\x1b[39m`; // Reset only foreground color
194
+ const ansi = this.tokenAnsi(this.fgAnsi, color);
195
+ if (this.dimTokens.has(color))
196
+ return `${ansi}\x1b[2m${text}\x1b[22;39m`;
197
+ return `${ansi}${text}\x1b[39m`;
208
198
  }
209
199
  bg(color, text) {
210
- const ansi = this.bgColors.get(color);
211
- if (!ansi)
212
- throw new Error(`Unknown theme background color: ${color}`);
213
- return `${ansi}${text}\x1b[49m`; // Reset only background color
200
+ const ansi = this.tokenAnsi(this.bgAnsi, color);
201
+ return `${ansi}${text}\x1b[49m`;
202
+ }
203
+ tokenAnsi(ansi, token) {
204
+ const value = ansi.get(token);
205
+ if (value === undefined)
206
+ throw new Error(`Unknown theme color: ${token}`);
207
+ return value;
214
208
  }
215
209
  bold(text) {
216
210
  return chalk.bold(text);
@@ -227,17 +221,13 @@ export class Theme {
227
221
  strikethrough(text) {
228
222
  return chalk.strikethrough(text);
229
223
  }
224
+ /** Opening escape sequence for a foreground token. Faint tokens include SGR 2, which `\x1b[22m` closes. */
230
225
  getFgAnsi(color) {
231
- const ansi = this.fgColors.get(color);
232
- if (!ansi)
233
- throw new Error(`Unknown theme color: ${color}`);
234
- return ansi;
226
+ const ansi = this.tokenAnsi(this.fgAnsi, color);
227
+ return this.dimTokens.has(color) ? `${ansi}\x1b[2m` : ansi;
235
228
  }
236
229
  getBgAnsi(color) {
237
- const ansi = this.bgColors.get(color);
238
- if (!ansi)
239
- throw new Error(`Unknown theme background color: ${color}`);
240
- return ansi;
230
+ return this.tokenAnsi(this.bgAnsi, color);
241
231
  }
242
232
  getColorMode() {
243
233
  return this.mode;
@@ -297,7 +287,8 @@ export function getAvailableThemesWithPaths() {
297
287
  seen.add(themeInfo.name);
298
288
  result.push(themeInfo);
299
289
  };
300
- // Built-in themes
290
+ // Built-in themes. The system theme is generated, so it has no file.
291
+ addTheme({ name: SYSTEM_THEME_NAME, path: undefined });
301
292
  for (const name of Object.keys(getBuiltinThemes())) {
302
293
  addTheme({ name, path: path.join(themesDir, `${name}.json`) });
303
294
  }
@@ -308,7 +299,8 @@ export function getAvailableThemesWithPaths() {
308
299
  for (const [name, theme] of registeredThemes.entries()) {
309
300
  addTheme({ name, path: theme.sourcePath });
310
301
  }
311
- return result.sort((a, b) => a.name.localeCompare(b.name));
302
+ // The system theme comes first: it is the default and adapts to every terminal.
303
+ return result.sort((a, b) => a.name === SYSTEM_THEME_NAME ? -1 : b.name === SYSTEM_THEME_NAME ? 1 : a.name.localeCompare(b.name));
312
304
  }
313
305
  function getCustomThemeInfos() {
314
306
  const customThemesDir = getCustomThemesDir();
@@ -378,22 +370,50 @@ function loadThemeJson(name) {
378
370
  const content = fs.readFileSync(themePath, "utf-8");
379
371
  return parseThemeJsonContent(name, content);
380
372
  }
381
- function createTheme(themeJson, mode, sourcePath) {
382
- const colorMode = mode ?? (getCapabilities().trueColor ? "truecolor" : "256color");
383
- const resolvedColors = resolveThemeColors(withThemeColorFallbacks(themeJson.colors), themeJson.vars);
373
+ const BACKGROUND_TOKENS = new Set([
374
+ "selectedBg",
375
+ "searchMatchBg",
376
+ "userMessageBg",
377
+ "customMessageBg",
378
+ "toolPendingBg",
379
+ "toolSuccessBg",
380
+ "toolErrorBg",
381
+ ]);
382
+ function splitThemeColors(colors) {
384
383
  const fgColors = {};
385
384
  const bgColors = {};
386
- for (const [key, value] of Object.entries(resolvedColors)) {
387
- if (THEME_BACKGROUND_KEYS.has(key)) {
385
+ for (const [key, value] of Object.entries(colors)) {
386
+ if (BACKGROUND_TOKENS.has(key)) {
388
387
  bgColors[key] = value;
389
388
  }
390
389
  else {
391
390
  fgColors[key] = value;
392
391
  }
393
392
  }
393
+ return { fgColors, bgColors };
394
+ }
395
+ function createTheme(themeJson, mode, sourcePath) {
396
+ const colorMode = mode ?? getTerminalColorMode();
397
+ const resolvedColors = resolveThemeColors(withThemeColorFallbacks(themeJson.colors), themeJson.vars);
398
+ const { fgColors, bgColors } = splitThemeColors(resolvedColors);
394
399
  return new Theme(fgColors, bgColors, colorMode, {
395
400
  name: themeJson.name,
396
401
  sourcePath,
402
+ appearance: themeJson.appearance,
403
+ });
404
+ }
405
+ /** Generate the system theme from the terminal's reported colors (grayscale while they are pending). */
406
+ function createSystemTheme(mode) {
407
+ const generated = generateSystemThemeColors({
408
+ ...terminalColors,
409
+ saturation: terminalColorsPending ? 0 : 1,
410
+ appearanceHint: getTerminalTheme(),
411
+ });
412
+ const { fgColors, bgColors } = splitThemeColors(generated.colors);
413
+ return new Theme(fgColors, bgColors, mode ?? getTerminalColorMode(), {
414
+ name: SYSTEM_THEME_NAME,
415
+ appearance: generated.appearance,
416
+ dim: generated.dim,
397
417
  });
398
418
  }
399
419
  export function loadThemeFromPath(themePath, mode) {
@@ -402,6 +422,9 @@ export function loadThemeFromPath(themePath, mode) {
402
422
  return createTheme(themeJson, mode, themePath);
403
423
  }
404
424
  function loadTheme(name, mode) {
425
+ // The system theme name is reserved: it takes precedence over custom themes of the same name.
426
+ if (name === SYSTEM_THEME_NAME)
427
+ return createSystemTheme(mode);
405
428
  const registeredTheme = registeredThemes.get(name);
406
429
  if (registeredTheme) {
407
430
  return registeredTheme;
@@ -442,95 +465,45 @@ export function resolveThemeSetting(themeSetting, terminalTheme) {
442
465
  return themeSetting;
443
466
  return undefined;
444
467
  }
445
- function getColorFgBgBackgroundIndex(colorfgbg) {
446
- const parts = colorfgbg.split(";");
447
- for (let i = parts.length - 1; i >= 0; i--) {
448
- const bg = parseInt(parts[i].trim(), 10);
449
- if (Number.isInteger(bg) && bg >= 0 && bg <= 255) {
450
- return bg;
451
- }
452
- }
453
- return undefined;
454
- }
455
- function getRgbColorLuminance({ r, g, b }) {
456
- const toLinear = (channel) => {
457
- const value = channel / 255;
458
- return value <= 0.03928 ? value / 12.92 : ((value + 0.055) / 1.055) ** 2.4;
459
- };
460
- return 0.2126 * toLinear(r) + 0.7152 * toLinear(g) + 0.0722 * toLinear(b);
461
- }
462
- function getAnsiColorLuminance(index) {
463
- return getRgbColorLuminance(hexToRgb(ansi256ToHex(index)));
464
- }
465
- export function getThemeForRgbColor(rgb) {
466
- return getRgbColorLuminance(rgb) >= 0.5 ? "light" : "dark";
467
- }
468
- export function detectTerminalBackgroundFromEnv(options = {}) {
469
- const env = options.env ?? process.env;
470
- const colorfgbg = env.COLORFGBG || "";
471
- const bg = getColorFgBgBackgroundIndex(colorfgbg);
472
- if (bg !== undefined) {
473
- return {
474
- theme: getAnsiColorLuminance(bg) >= 0.5 ? "light" : "dark",
475
- source: "COLORFGBG",
476
- detail: `background color index ${bg}`,
477
- confidence: "high",
478
- };
479
- }
480
- return {
481
- theme: "dark",
482
- source: "fallback",
483
- detail: "no terminal background hint found",
484
- confidence: "low",
485
- };
486
- }
487
- export async function detectTerminalBackgroundTheme({ ui, timeoutMs, env, }) {
488
- try {
489
- const rgb = await ui.queryTerminalBackgroundColor({ timeoutMs });
490
- if (rgb) {
491
- return {
492
- theme: getThemeForRgbColor(rgb),
493
- source: "terminal background",
494
- detail: `OSC 11 background rgb(${rgb.r}, ${rgb.g}, ${rgb.b})`,
495
- confidence: "high",
496
- };
497
- }
498
- }
499
- catch {
500
- // Fall back to environment-based detection when the terminal query fails.
501
- }
502
- return detectTerminalBackgroundFromEnv({ env });
468
+ /**
469
+ * Dark or light from the `COLORFGBG` environment variable some terminals set, or undefined without a
470
+ * usable background index. The value is `fg;bg` or `fg;xpm;bg` (rxvt), where a field is an ANSI color
471
+ * index or `default` when the color is not in the palette. The index refers to the terminal's own palette,
472
+ * whose colors are unknown here, so it is classified by index like Vim does: 0-6 and 8 (bright black, e.g.
473
+ * Solarized Dark's background) are dark, 7 and 9-15 are light.
474
+ */
475
+ export function detectColorFgBgTheme(env = process.env) {
476
+ const bg = env.COLORFGBG?.split(";").at(-1)?.trim();
477
+ if (!bg || !/^\d{1,2}$/.test(bg))
478
+ return undefined;
479
+ const index = Number(bg);
480
+ if (index > 15)
481
+ return undefined;
482
+ return index <= 6 || index === 8 ? "dark" : "light";
503
483
  }
504
- export async function detectTerminalThemeForAuto({ ui, timeoutMs, env, }) {
505
- let colorSchemePromise;
506
- try {
507
- colorSchemePromise = ui.queryTerminalColorScheme?.({ timeoutMs });
508
- }
509
- catch {
510
- // Fall back to OSC 11 / COLORFGBG detection when starting the color-scheme query fails.
511
- }
512
- const backgroundThemePromise = detectTerminalBackgroundTheme({ ui, timeoutMs, env });
513
- try {
514
- const colorScheme = await colorSchemePromise;
515
- if (colorScheme)
516
- return colorScheme;
517
- }
518
- catch {
519
- // Fall back to the concurrently queried OSC 11 / COLORFGBG detection.
520
- }
521
- return (await backgroundThemePromise).theme;
484
+ /**
485
+ * Whether the terminal is dark or light. The background it renders decides, classified the same way the
486
+ * system theme does. Without a reported background: the terminal's light/dark report, then COLORFGBG,
487
+ * then dark.
488
+ */
489
+ export function detectTerminalTheme(colors = {}, reportedScheme, env = process.env) {
490
+ const { background, foreground } = colors;
491
+ if (background)
492
+ return terminalAppearance(background, foreground);
493
+ return reportedScheme ?? detectColorFgBgTheme(env) ?? "dark";
522
494
  }
523
- export function getDefaultTheme() {
524
- return detectTerminalBackgroundFromEnv().theme;
495
+ /** Whether the terminal is dark or light, from everything it reported so far. See `detectTerminalTheme()`. */
496
+ export function getTerminalTheme() {
497
+ return detectTerminalTheme(terminalColors, terminalColorScheme);
525
498
  }
526
499
  // ============================================================================
527
500
  // Global Theme Instance
528
501
  // ============================================================================
529
- // Use globalThis to share theme across module loaders (tsx + jiti in dev mode)
502
+ // Use globalThis to share theme across module loaders (node + jiti in dev mode)
530
503
  const THEME_KEY = Symbol.for("@earendil-works/pi-coding-agent:theme");
531
504
  const THEME_KEY_OLD = Symbol.for("@mariozechner/pi-coding-agent:theme");
532
505
  // Export theme as a getter that reads from globalThis
533
- // This ensures all module instances (tsx, jiti) see the same theme
506
+ // This ensures all module instances (node, jiti) see the same theme
534
507
  export const theme = new Proxy({}, {
535
508
  get(_target, prop) {
536
509
  const t = globalThis[THEME_KEY];
@@ -558,7 +531,7 @@ export function setRegisteredThemes(themes) {
558
531
  }
559
532
  }
560
533
  export function initTheme(themeName, enableWatcher = false) {
561
- const name = themeName ?? getDefaultTheme();
534
+ const name = themeName ?? SYSTEM_THEME_NAME;
562
535
  currentThemeName = name;
563
536
  try {
564
537
  setGlobalTheme(loadTheme(name));
@@ -567,9 +540,9 @@ export function initTheme(themeName, enableWatcher = false) {
567
540
  }
568
541
  }
569
542
  catch (_error) {
570
- // Theme is invalid - fall back to dark theme silently
571
- currentThemeName = "dark";
572
- setGlobalTheme(loadTheme("dark"));
543
+ // Theme is invalid - fall back to the system theme silently
544
+ currentThemeName = SYSTEM_THEME_NAME;
545
+ setGlobalTheme(loadTheme(SYSTEM_THEME_NAME));
573
546
  // Don't start watcher for fallback theme
574
547
  }
575
548
  }
@@ -586,9 +559,9 @@ export function setTheme(name, enableWatcher = false) {
586
559
  return { success: true };
587
560
  }
588
561
  catch (error) {
589
- // Theme is invalid - fall back to dark theme
590
- currentThemeName = "dark";
591
- setGlobalTheme(loadTheme("dark"));
562
+ // Theme is invalid - fall back to the system theme
563
+ currentThemeName = SYSTEM_THEME_NAME;
564
+ setGlobalTheme(loadTheme(SYSTEM_THEME_NAME));
592
565
  // Don't start watcher for fallback theme
593
566
  return {
594
567
  success: false,
@@ -610,7 +583,7 @@ export function onThemeChange(callback) {
610
583
  function startThemeWatcher() {
611
584
  stopThemeWatcher();
612
585
  // Only watch if it's a custom theme (not built-in)
613
- if (!currentThemeName || currentThemeName in getBuiltinThemes()) {
586
+ if (!currentThemeName || currentThemeName in getBuiltinThemes() || currentThemeName === SYSTEM_THEME_NAME) {
614
587
  return;
615
588
  }
616
589
  const customThemesDir = getCustomThemesDir();
@@ -679,95 +652,56 @@ export function stopThemeWatcher() {
679
652
  // ============================================================================
680
653
  // HTML Export Helpers
681
654
  // ============================================================================
682
- /**
683
- * Convert a 256-color index to hex string.
684
- * Indices 0-15: basic colors (approximate)
685
- * Indices 16-231: 6x6x6 color cube
686
- * Indices 232-255: grayscale ramp
687
- */
688
- function ansi256ToHex(index) {
689
- // Basic colors (0-15) - approximate common terminal values
690
- const basicColors = [
691
- "#000000",
692
- "#800000",
693
- "#008000",
694
- "#808000",
695
- "#000080",
696
- "#800080",
697
- "#008080",
698
- "#c0c0c0",
699
- "#808080",
700
- "#ff0000",
701
- "#00ff00",
702
- "#ffff00",
703
- "#0000ff",
704
- "#ff00ff",
705
- "#00ffff",
706
- "#ffffff",
707
- ];
708
- if (index < 16) {
709
- return basicColors[index];
710
- }
711
- // Color cube (16-231): 6x6x6 = 216 colors
712
- if (index < 232) {
713
- const cubeIndex = index - 16;
714
- const r = Math.floor(cubeIndex / 36);
715
- const g = Math.floor((cubeIndex % 36) / 6);
716
- const b = cubeIndex % 6;
717
- const toHex = (n) => (n === 0 ? 0 : 55 + n * 40).toString(16).padStart(2, "0");
718
- return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
719
- }
720
- // Grayscale (232-255): 24 shades
721
- const gray = 8 + (index - 232) * 10;
722
- const grayHex = gray.toString(16).padStart(2, "0");
723
- return `#${grayHex}${grayHex}${grayHex}`;
724
- }
725
655
  /**
726
656
  * Get resolved theme colors as CSS-compatible hex strings.
727
657
  * Used by HTML export to generate CSS custom properties.
728
658
  */
729
659
  export function getResolvedThemeColors(themeName) {
730
- const name = themeName ?? currentThemeName ?? getDefaultTheme();
731
- const themeJson = loadThemeJson(name);
732
- const resolved = resolveThemeColors(withThemeColorFallbacks(themeJson.colors), themeJson.vars);
733
- const resolvedText = resolved.text;
734
- const defaultText = typeof resolvedText === "number"
735
- ? ansi256ToHex(resolvedText)
736
- : resolvedText || (name === "light" || name === "ice-cream-light" ? "#000000" : "#e5e5e7");
737
- const cssColors = {};
738
- for (const [key, value] of Object.entries(resolved)) {
739
- if (typeof value === "number") {
740
- cssColors[key] = ansi256ToHex(value);
741
- }
742
- else if (value === "") {
743
- cssColors[key] = THEME_BACKGROUND_KEYS.has(key) ? "transparent" : defaultText;
744
- }
745
- else {
746
- cssColors[key] = value;
747
- }
748
- }
749
- return cssColors;
660
+ const name = themeName ?? currentThemeName ?? SYSTEM_THEME_NAME;
661
+ const colors = loadTheme(name).colors;
662
+ const css = Object.fromEntries(Object.entries(colors).map(([token, color]) => [token, colorToHex(color)]));
663
+ const registered = registeredThemes.get(name);
664
+ if (name === SYSTEM_THEME_NAME || (registered && !registered.sourcePath))
665
+ return css;
666
+ const json = loadThemeJson(name);
667
+ const resolved = resolveThemeColors(withThemeColorFallbacks(json.colors), json.vars);
668
+ for (const [token, value] of Object.entries(resolved)) {
669
+ if (value === "")
670
+ css[token] = BACKGROUND_TOKENS.has(token) ? "transparent" : css.text;
671
+ }
672
+ return css;
673
+ }
674
+ /**
675
+ * Check if a theme is a "light" theme (for CSS that needs light/dark variants).
676
+ */
677
+ export function isLightTheme(themeName) {
678
+ return loadTheme(themeName ?? currentThemeName ?? SYSTEM_THEME_NAME).appearance === "light";
750
679
  }
751
680
  /**
752
681
  * Get explicit export colors from theme JSON, if specified.
753
682
  * Returns undefined for each color that isn't explicitly set.
754
683
  */
755
684
  export function getThemeExportColors(themeName) {
756
- const name = themeName ?? currentThemeName ?? getDefaultTheme();
685
+ const name = themeName ?? currentThemeName ?? SYSTEM_THEME_NAME;
686
+ if (name === SYSTEM_THEME_NAME)
687
+ return {};
757
688
  try {
758
689
  const themeJson = loadThemeJson(name);
759
690
  const exportSection = themeJson.export;
760
691
  if (!exportSection)
761
692
  return {};
762
693
  const vars = themeJson.vars ?? {};
694
+ // Export colors end up in CSS, which understands hex and oklch() values directly but not okhsl().
763
695
  const resolve = (value) => {
764
696
  if (value === undefined)
765
697
  return undefined;
766
698
  const resolved = resolveVarRefs(value, vars);
767
699
  if (typeof resolved === "number")
768
- return ansi256ToHex(resolved);
700
+ return colorToHex(indexedColor(resolved));
769
701
  if (resolved === "")
770
702
  return undefined;
703
+ if (/^okhsl\(/i.test(resolved))
704
+ return colorToHex(parseColor(resolved));
771
705
  return resolved;
772
706
  };
773
707
  return {
@@ -927,7 +861,7 @@ export function getMarkdownTheme() {
927
861
  bold: (text) => theme.bold(text),
928
862
  italic: (text) => theme.italic(text),
929
863
  underline: (text) => theme.underline(text),
930
- strikethrough: (text) => chalk.strikethrough(text),
864
+ strikethrough: (text) => theme.strikethrough(text),
931
865
  highlightCode: (code, lang) => {
932
866
  // Validate language before highlighting to avoid stderr spam from cli-highlight
933
867
  const validLang = lang && supportsLanguage(lang) ? lang : undefined;