whale-code 6.5.5 → 6.5.6

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 (847) hide show
  1. package/README.md +39 -31
  2. package/bin/{swagmanager-mcp.js → whale-code.js} +17 -2
  3. package/dist/cli/app.js +148 -72
  4. package/dist/cli/app.js.map +1 -0
  5. package/dist/cli/chat/AgentSelector.js +105 -10
  6. package/dist/cli/chat/AgentSelector.js.map +1 -0
  7. package/dist/cli/chat/ChatApp.d.ts +31 -0
  8. package/dist/cli/chat/ChatApp.js +539 -286
  9. package/dist/cli/chat/ChatApp.js.map +1 -0
  10. package/dist/cli/chat/ChatInput.js +1088 -770
  11. package/dist/cli/chat/ChatInput.js.map +1 -0
  12. package/dist/cli/chat/MarkdownText.js +39 -14
  13. package/dist/cli/chat/MarkdownText.js.map +1 -0
  14. package/dist/cli/chat/MemoryManager.js +181 -46
  15. package/dist/cli/chat/MemoryManager.js.map +1 -0
  16. package/dist/cli/chat/MessageList.d.ts +2 -3
  17. package/dist/cli/chat/MessageList.js +186 -45
  18. package/dist/cli/chat/MessageList.js.map +1 -0
  19. package/dist/cli/chat/ModelSelector.js +282 -63
  20. package/dist/cli/chat/ModelSelector.js.map +1 -0
  21. package/dist/cli/chat/NodeManager.js +165 -75
  22. package/dist/cli/chat/NodeManager.js.map +1 -0
  23. package/dist/cli/chat/NodeSelector.js +171 -30
  24. package/dist/cli/chat/NodeSelector.js.map +1 -0
  25. package/dist/cli/chat/PlanApproval.js +281 -57
  26. package/dist/cli/chat/PlanApproval.js.map +1 -0
  27. package/dist/cli/chat/RewindViewer.js +559 -144
  28. package/dist/cli/chat/RewindViewer.js.map +1 -0
  29. package/dist/cli/chat/SessionManager.js +137 -30
  30. package/dist/cli/chat/SessionManager.js.map +1 -0
  31. package/dist/cli/chat/SlashMenu.js +293 -164
  32. package/dist/cli/chat/SlashMenu.js.map +1 -0
  33. package/dist/cli/chat/StatusBar.js +172 -9
  34. package/dist/cli/chat/StatusBar.js.map +1 -0
  35. package/dist/cli/chat/StoreSelector.js +147 -18
  36. package/dist/cli/chat/StoreSelector.js.map +1 -0
  37. package/dist/cli/chat/StreamingText.d.ts +1 -5
  38. package/dist/cli/chat/StreamingText.js +22 -7
  39. package/dist/cli/chat/StreamingText.js.map +1 -0
  40. package/dist/cli/chat/SubagentPanel.d.ts +1 -2
  41. package/dist/cli/chat/SubagentPanel.js +612 -72
  42. package/dist/cli/chat/SubagentPanel.js.map +1 -0
  43. package/dist/cli/chat/TeamPanel.d.ts +1 -0
  44. package/dist/cli/chat/TeamPanel.js +230 -30
  45. package/dist/cli/chat/TeamPanel.js.map +1 -0
  46. package/dist/cli/chat/ThemeSelector.js +84 -24
  47. package/dist/cli/chat/ThemeSelector.js.map +1 -0
  48. package/dist/cli/chat/ToolIndicator.js +1476 -371
  49. package/dist/cli/chat/ToolIndicator.js.map +1 -0
  50. package/dist/cli/chat/hooks/useAgentLoop.d.ts +1 -0
  51. package/dist/cli/chat/hooks/useAgentLoop.js +481 -367
  52. package/dist/cli/chat/hooks/useAgentLoop.js.map +1 -0
  53. package/dist/cli/chat/hooks/useSlashCommands.d.ts +3 -14
  54. package/dist/cli/chat/hooks/useSlashCommands.js +744 -572
  55. package/dist/cli/chat/hooks/useSlashCommands.js.map +1 -0
  56. package/dist/cli/commands/config-cmd.js +56 -57
  57. package/dist/cli/commands/config-cmd.js.map +1 -0
  58. package/dist/cli/commands/db.js +184 -169
  59. package/dist/cli/commands/db.js.map +1 -0
  60. package/dist/cli/commands/doctor.js +212 -122
  61. package/dist/cli/commands/doctor.js.map +1 -0
  62. package/dist/cli/commands/init.js +211 -244
  63. package/dist/cli/commands/init.js.map +1 -0
  64. package/dist/cli/commands/mcp.js +127 -122
  65. package/dist/cli/commands/mcp.js.map +1 -0
  66. package/dist/cli/login/LoginApp.js +355 -141
  67. package/dist/cli/login/LoginApp.js.map +1 -0
  68. package/dist/cli/print-mode.js +196 -177
  69. package/dist/cli/print-mode.js.map +1 -0
  70. package/dist/cli/serve-mode.js +615 -530
  71. package/dist/cli/serve-mode.js.map +1 -0
  72. package/dist/cli/services/agent-config.d.ts +5 -1
  73. package/dist/cli/services/agent-config.js +66 -36
  74. package/dist/cli/services/agent-config.js.map +1 -0
  75. package/dist/cli/services/agent-definitions.d.ts +4 -1
  76. package/dist/cli/services/agent-definitions.js +97 -56
  77. package/dist/cli/services/agent-definitions.js.map +1 -0
  78. package/dist/cli/services/agent-events.js +225 -162
  79. package/dist/cli/services/agent-events.js.map +1 -0
  80. package/dist/cli/services/agent-loop.js +976 -688
  81. package/dist/cli/services/agent-loop.js.map +1 -0
  82. package/dist/cli/services/agent-worker-base.d.ts +35 -5
  83. package/dist/cli/services/agent-worker-base.js +337 -153
  84. package/dist/cli/services/agent-worker-base.js.map +1 -0
  85. package/dist/cli/services/api-retry.js +69 -64
  86. package/dist/cli/services/api-retry.js.map +1 -0
  87. package/dist/cli/services/auth-service.d.ts +3 -3
  88. package/dist/cli/services/auth-service.js +209 -132
  89. package/dist/cli/services/auth-service.js.map +1 -0
  90. package/dist/cli/services/background-processes.js +343 -267
  91. package/dist/cli/services/background-processes.js.map +1 -0
  92. package/dist/cli/services/browser-auth.d.ts +2 -2
  93. package/dist/cli/services/browser-auth.js +159 -118
  94. package/dist/cli/services/browser-auth.js.map +1 -0
  95. package/dist/cli/services/claude-md-loader.js +40 -36
  96. package/dist/cli/services/claude-md-loader.js.map +1 -0
  97. package/dist/cli/services/config-store.d.ts +9 -4
  98. package/dist/cli/services/config-store.js +164 -117
  99. package/dist/cli/services/config-store.js.map +1 -0
  100. package/dist/cli/services/debug-log.d.ts +1 -1
  101. package/dist/cli/services/debug-log.js +34 -35
  102. package/dist/cli/services/debug-log.js.map +1 -0
  103. package/dist/cli/services/env-detect.d.ts +7 -0
  104. package/dist/cli/services/env-detect.js +9 -0
  105. package/dist/cli/services/env-detect.js.map +1 -0
  106. package/dist/cli/services/error-logger.js +187 -169
  107. package/dist/cli/services/error-logger.js.map +1 -0
  108. package/dist/cli/services/file-history.d.ts +1 -1
  109. package/dist/cli/services/file-history.js +50 -54
  110. package/dist/cli/services/file-history.js.map +1 -0
  111. package/dist/cli/services/format-server-response.js +332 -372
  112. package/dist/cli/services/format-server-response.js.map +1 -0
  113. package/dist/cli/services/git-context.js +61 -45
  114. package/dist/cli/services/git-context.js.map +1 -0
  115. package/dist/cli/services/hooks.d.ts +2 -2
  116. package/dist/cli/services/hooks.js +195 -180
  117. package/dist/cli/services/hooks.js.map +1 -0
  118. package/dist/cli/services/ink-incremental.d.ts +19 -0
  119. package/dist/cli/services/ink-incremental.js +59 -0
  120. package/dist/cli/services/ink-incremental.js.map +1 -0
  121. package/dist/cli/services/ink-resize-fix.js +54 -44
  122. package/dist/cli/services/ink-resize-fix.js.map +1 -0
  123. package/dist/cli/services/ink-sync-output.d.ts +12 -0
  124. package/dist/cli/services/ink-sync-output.js +16 -0
  125. package/dist/cli/services/ink-sync-output.js.map +1 -0
  126. package/dist/cli/services/interactive-tools.js +268 -212
  127. package/dist/cli/services/interactive-tools.js.map +1 -0
  128. package/dist/cli/services/keybinding-manager.d.ts +11 -1
  129. package/dist/cli/services/keybinding-manager.js +126 -63
  130. package/dist/cli/services/keybinding-manager.js.map +1 -0
  131. package/dist/cli/services/local-tools.d.ts +1 -1
  132. package/dist/cli/services/local-tools.js +939 -656
  133. package/dist/cli/services/local-tools.js.map +1 -0
  134. package/dist/cli/services/lsp-manager.js +757 -594
  135. package/dist/cli/services/lsp-manager.js.map +1 -0
  136. package/dist/cli/services/mcp-client.d.ts +1 -1
  137. package/dist/cli/services/mcp-client.js +173 -134
  138. package/dist/cli/services/mcp-client.js.map +1 -0
  139. package/dist/cli/services/memory-manager.js +53 -40
  140. package/dist/cli/services/memory-manager.js.map +1 -0
  141. package/dist/cli/services/model-manager.js +55 -40
  142. package/dist/cli/services/model-manager.js.map +1 -0
  143. package/dist/cli/services/model-router.js +115 -85
  144. package/dist/cli/services/model-router.js.map +1 -0
  145. package/dist/cli/services/paths.d.ts +30 -0
  146. package/dist/cli/services/paths.js +81 -0
  147. package/dist/cli/services/paths.js.map +1 -0
  148. package/dist/cli/services/permission-modes.js +32 -25
  149. package/dist/cli/services/permission-modes.js.map +1 -0
  150. package/dist/cli/services/rewind.js +182 -168
  151. package/dist/cli/services/rewind.js.map +1 -0
  152. package/dist/cli/services/ripgrep.js +115 -115
  153. package/dist/cli/services/ripgrep.js.map +1 -0
  154. package/dist/cli/services/sandbox.d.ts +1 -1
  155. package/dist/cli/services/sandbox.js +58 -37
  156. package/dist/cli/services/sandbox.js.map +1 -0
  157. package/dist/cli/services/server-tools.js +738 -565
  158. package/dist/cli/services/server-tools.js.map +1 -0
  159. package/dist/cli/services/session-persistence.js +69 -74
  160. package/dist/cli/services/session-persistence.js.map +1 -0
  161. package/dist/cli/services/subagent-worker.js +42 -27
  162. package/dist/cli/services/subagent-worker.js.map +1 -0
  163. package/dist/cli/services/subagent.d.ts +2 -0
  164. package/dist/cli/services/subagent.js +605 -433
  165. package/dist/cli/services/subagent.js.map +1 -0
  166. package/dist/cli/services/system-prompt.js +86 -78
  167. package/dist/cli/services/system-prompt.js.map +1 -0
  168. package/dist/cli/services/task-decomposer.d.ts +1 -1
  169. package/dist/cli/services/task-decomposer.js +172 -139
  170. package/dist/cli/services/task-decomposer.js.map +1 -0
  171. package/dist/cli/services/team-lead.d.ts +2 -2
  172. package/dist/cli/services/team-lead.js +727 -529
  173. package/dist/cli/services/team-lead.js.map +1 -0
  174. package/dist/cli/services/team-state.js +319 -319
  175. package/dist/cli/services/team-state.js.map +1 -0
  176. package/dist/cli/services/teammate.d.ts +8 -2
  177. package/dist/cli/services/teammate.js +857 -569
  178. package/dist/cli/services/teammate.js.map +1 -0
  179. package/dist/cli/services/telemetry.d.ts +6 -1
  180. package/dist/cli/services/telemetry.js +180 -157
  181. package/dist/cli/services/telemetry.js.map +1 -0
  182. package/dist/cli/services/tools/agent-tools.d.ts +3 -3
  183. package/dist/cli/services/tools/agent-tools.js +480 -322
  184. package/dist/cli/services/tools/agent-tools.js.map +1 -0
  185. package/dist/cli/services/tools/file-ops.js +563 -450
  186. package/dist/cli/services/tools/file-ops.js.map +1 -0
  187. package/dist/cli/services/tools/search-tools.js +231 -162
  188. package/dist/cli/services/tools/search-tools.js.map +1 -0
  189. package/dist/cli/services/tools/shell-exec.js +197 -151
  190. package/dist/cli/services/tools/shell-exec.js.map +1 -0
  191. package/dist/cli/services/tools/task-manager.js +206 -173
  192. package/dist/cli/services/tools/task-manager.js.map +1 -0
  193. package/dist/cli/services/tools/web-tools.js +388 -341
  194. package/dist/cli/services/tools/web-tools.js.map +1 -0
  195. package/dist/cli/setup/SetupApp.d.ts +2 -2
  196. package/dist/cli/setup/SetupApp.js +608 -160
  197. package/dist/cli/setup/SetupApp.js.map +1 -0
  198. package/dist/cli/shared/ErrorBoundary.d.ts +22 -0
  199. package/dist/cli/shared/ErrorBoundary.js +73 -0
  200. package/dist/cli/shared/ErrorBoundary.js.map +1 -0
  201. package/dist/cli/shared/MatrixIntro.js +66 -69
  202. package/dist/cli/shared/MatrixIntro.js.map +1 -0
  203. package/dist/cli/shared/SpinnerSlot.d.ts +14 -0
  204. package/dist/cli/shared/SpinnerSlot.js +63 -0
  205. package/dist/cli/shared/SpinnerSlot.js.map +1 -0
  206. package/dist/cli/shared/Theme.d.ts +1 -1
  207. package/dist/cli/shared/Theme.js +136 -92
  208. package/dist/cli/shared/Theme.js.map +1 -0
  209. package/dist/cli/shared/WhaleBanner.js +99 -11
  210. package/dist/cli/shared/WhaleBanner.js.map +1 -0
  211. package/dist/cli/shared/markdown.d.ts +3 -1
  212. package/dist/cli/shared/markdown.js +736 -674
  213. package/dist/cli/shared/markdown.js.map +1 -0
  214. package/dist/cli/shared/marked-terminal.d.js +2 -0
  215. package/dist/cli/shared/marked-terminal.d.js.map +1 -0
  216. package/dist/cli/shared/theme-manager.js +99 -90
  217. package/dist/cli/shared/theme-manager.js.map +1 -0
  218. package/dist/cli/shared/theme-presets.js +256 -254
  219. package/dist/cli/shared/theme-presets.js.map +1 -0
  220. package/dist/cli/status/StatusApp.js +235 -86
  221. package/dist/cli/status/StatusApp.js.map +1 -0
  222. package/dist/cli/stores/StoreApp.js +275 -65
  223. package/dist/cli/stores/StoreApp.js.map +1 -0
  224. package/dist/index.d.ts +2 -2
  225. package/dist/index.js +509 -396
  226. package/dist/index.js.map +1 -0
  227. package/dist/local-agent/connection.d.ts +2 -2
  228. package/dist/local-agent/connection.js +352 -293
  229. package/dist/local-agent/connection.js.map +1 -0
  230. package/dist/local-agent/discovery.js +259 -122
  231. package/dist/local-agent/discovery.js.map +1 -0
  232. package/dist/local-agent/executor.js +216 -193
  233. package/dist/local-agent/executor.js.map +1 -0
  234. package/dist/local-agent/index.d.ts +2 -2
  235. package/dist/local-agent/index.js +156 -156
  236. package/dist/local-agent/index.js.map +1 -0
  237. package/dist/node/adapters/base.js +18 -8
  238. package/dist/node/adapters/base.js.map +1 -0
  239. package/dist/node/adapters/discord.js +286 -275
  240. package/dist/node/adapters/discord.js.map +1 -0
  241. package/dist/node/adapters/email.js +189 -202
  242. package/dist/node/adapters/email.js.map +1 -0
  243. package/dist/node/adapters/imessage.js +145 -142
  244. package/dist/node/adapters/imessage.js.map +1 -0
  245. package/dist/node/adapters/slack.js +237 -236
  246. package/dist/node/adapters/slack.js.map +1 -0
  247. package/dist/node/adapters/sms.js +149 -151
  248. package/dist/node/adapters/sms.js.map +1 -0
  249. package/dist/node/adapters/telegram.js +88 -92
  250. package/dist/node/adapters/telegram.js.map +1 -0
  251. package/dist/node/adapters/webchat.js +160 -136
  252. package/dist/node/adapters/webchat.js.map +1 -0
  253. package/dist/node/adapters/whatsapp.js +212 -215
  254. package/dist/node/adapters/whatsapp.js.map +1 -0
  255. package/dist/node/cli.js +884 -653
  256. package/dist/node/cli.js.map +1 -0
  257. package/dist/node/config.js +20 -18
  258. package/dist/node/config.js.map +1 -0
  259. package/dist/node/gateway-client.js +191 -181
  260. package/dist/node/gateway-client.js.map +1 -0
  261. package/dist/node/portal/clipboard.js +161 -130
  262. package/dist/node/portal/clipboard.js.map +1 -0
  263. package/dist/node/portal/discovery.js +51 -45
  264. package/dist/node/portal/discovery.js.map +1 -0
  265. package/dist/node/portal/forward.js +64 -58
  266. package/dist/node/portal/forward.js.map +1 -0
  267. package/dist/node/portal/index.js +246 -221
  268. package/dist/node/portal/index.js.map +1 -0
  269. package/dist/node/portal/multiplexer.js +192 -182
  270. package/dist/node/portal/multiplexer.js.map +1 -0
  271. package/dist/node/portal/permissions.js +102 -70
  272. package/dist/node/portal/permissions.js.map +1 -0
  273. package/dist/node/portal/protocol.js +153 -116
  274. package/dist/node/portal/protocol.js.map +1 -0
  275. package/dist/node/portal/screen.js +80 -69
  276. package/dist/node/portal/screen.js.map +1 -0
  277. package/dist/node/portal/session.js +124 -117
  278. package/dist/node/portal/session.js.map +1 -0
  279. package/dist/node/portal/shell.js +140 -113
  280. package/dist/node/portal/shell.js.map +1 -0
  281. package/dist/node/portal/stream.js +77 -75
  282. package/dist/node/portal/stream.js.map +1 -0
  283. package/dist/node/portal/transfer.js +190 -167
  284. package/dist/node/portal/transfer.js.map +1 -0
  285. package/dist/node/portal/ui.js +124 -99
  286. package/dist/node/portal/ui.js.map +1 -0
  287. package/dist/node/remote-desktop/compile-helper.js +50 -45
  288. package/dist/node/remote-desktop/compile-helper.js.map +1 -0
  289. package/dist/node/remote-desktop/index.js +215 -187
  290. package/dist/node/remote-desktop/index.js.map +1 -0
  291. package/dist/node/remote-desktop/protocol.js +45 -29
  292. package/dist/node/remote-desktop/protocol.js.map +1 -0
  293. package/dist/node/runtime.js +493 -410
  294. package/dist/node/runtime.js.map +1 -0
  295. package/dist/server/handlers/__test-utils__/test-db.js +39 -89
  296. package/dist/server/handlers/__test-utils__/test-db.js.map +1 -0
  297. package/dist/server/handlers/analytics.js +467 -261
  298. package/dist/server/handlers/analytics.js.map +1 -0
  299. package/dist/server/handlers/api-docs.js +1030 -895
  300. package/dist/server/handlers/api-docs.js.map +1 -0
  301. package/dist/server/handlers/api-keys.js +291 -242
  302. package/dist/server/handlers/api-keys.js.map +1 -0
  303. package/dist/server/handlers/billing.js +330 -239
  304. package/dist/server/handlers/billing.js.map +1 -0
  305. package/dist/server/handlers/browser.js +468 -395
  306. package/dist/server/handlers/browser.js.map +1 -0
  307. package/dist/server/handlers/catalog.js +1377 -978
  308. package/dist/server/handlers/catalog.js.map +1 -0
  309. package/dist/server/handlers/clickhouse.js +157 -109
  310. package/dist/server/handlers/clickhouse.js.map +1 -0
  311. package/dist/server/handlers/comms.js +1439 -984
  312. package/dist/server/handlers/comms.js.map +1 -0
  313. package/dist/server/handlers/creations.js +461 -394
  314. package/dist/server/handlers/creations.js.map +1 -0
  315. package/dist/server/handlers/crm.js +1082 -791
  316. package/dist/server/handlers/crm.js.map +1 -0
  317. package/dist/server/handlers/discovery.js +251 -232
  318. package/dist/server/handlers/discovery.js.map +1 -0
  319. package/dist/server/handlers/embeddings.js +241 -164
  320. package/dist/server/handlers/embeddings.js.map +1 -0
  321. package/dist/server/handlers/enrichment.js +887 -718
  322. package/dist/server/handlers/enrichment.js.map +1 -0
  323. package/dist/server/handlers/image-gen.js +467 -376
  324. package/dist/server/handlers/image-gen.js.map +1 -0
  325. package/dist/server/handlers/inventory.js +797 -424
  326. package/dist/server/handlers/inventory.js.map +1 -0
  327. package/dist/server/handlers/kali.js +272 -230
  328. package/dist/server/handlers/kali.js.map +1 -0
  329. package/dist/server/handlers/llm-providers.js +803 -580
  330. package/dist/server/handlers/llm-providers.js.map +1 -0
  331. package/dist/server/handlers/local-agent.js +133 -105
  332. package/dist/server/handlers/local-agent.js.map +1 -0
  333. package/dist/server/handlers/media.js +1179 -857
  334. package/dist/server/handlers/media.js.map +1 -0
  335. package/dist/server/handlers/meta-ads.js +2669 -2093
  336. package/dist/server/handlers/meta-ads.js.map +1 -0
  337. package/dist/server/handlers/nodes.js +1321 -913
  338. package/dist/server/handlers/nodes.js.map +1 -0
  339. package/dist/server/handlers/operations.js +183 -157
  340. package/dist/server/handlers/operations.js.map +1 -0
  341. package/dist/server/handlers/platform.js +346 -210
  342. package/dist/server/handlers/platform.js.map +1 -0
  343. package/dist/server/handlers/remove-bg.js +118 -86
  344. package/dist/server/handlers/remove-bg.js.map +1 -0
  345. package/dist/server/handlers/storefront.js +586 -446
  346. package/dist/server/handlers/storefront.js.map +1 -0
  347. package/dist/server/handlers/supply-chain.js +546 -326
  348. package/dist/server/handlers/supply-chain.js.map +1 -0
  349. package/dist/server/handlers/transcription.js +106 -97
  350. package/dist/server/handlers/transcription.js.map +1 -0
  351. package/dist/server/handlers/video-gen.js +593 -424
  352. package/dist/server/handlers/video-gen.js.map +1 -0
  353. package/dist/server/handlers/voice.js +1458 -1039
  354. package/dist/server/handlers/voice.js.map +1 -0
  355. package/dist/server/handlers/workflow-steps.js +2837 -2116
  356. package/dist/server/handlers/workflow-steps.js.map +1 -0
  357. package/dist/server/handlers/workflows.js +1630 -933
  358. package/dist/server/handlers/workflows.js.map +1 -0
  359. package/dist/server/index.js +3167 -2422
  360. package/dist/server/index.js.map +1 -0
  361. package/dist/server/lib/batch-client.js +471 -409
  362. package/dist/server/lib/batch-client.js.map +1 -0
  363. package/dist/server/lib/clickhouse-buffer.js +118 -104
  364. package/dist/server/lib/clickhouse-buffer.js.map +1 -0
  365. package/dist/server/lib/clickhouse-client.js +107 -107
  366. package/dist/server/lib/clickhouse-client.js.map +1 -0
  367. package/dist/server/lib/coa-renderer.js +1786 -356
  368. package/dist/server/lib/coa-renderer.js.map +1 -0
  369. package/dist/server/lib/code-worker-pool.js +227 -177
  370. package/dist/server/lib/code-worker-pool.js.map +1 -0
  371. package/dist/server/lib/code-worker.js +174 -164
  372. package/dist/server/lib/code-worker.js.map +1 -0
  373. package/dist/server/lib/compaction-service.d.ts +2 -12
  374. package/dist/server/lib/compaction-service.js +74 -184
  375. package/dist/server/lib/compaction-service.js.map +1 -0
  376. package/dist/server/lib/logger.js +36 -24
  377. package/dist/server/lib/logger.js.map +1 -0
  378. package/dist/server/lib/otel.js +101 -80
  379. package/dist/server/lib/otel.js.map +1 -0
  380. package/dist/server/lib/pdf-renderer.js +952 -788
  381. package/dist/server/lib/pdf-renderer.js.map +1 -0
  382. package/dist/server/lib/prompt-sanitizer.js +188 -108
  383. package/dist/server/lib/prompt-sanitizer.js.map +1 -0
  384. package/dist/server/lib/provider-capabilities.js +136 -138
  385. package/dist/server/lib/provider-capabilities.js.map +1 -0
  386. package/dist/server/lib/provider-failover.js +190 -168
  387. package/dist/server/lib/provider-failover.js.map +1 -0
  388. package/dist/server/lib/rate-limiter.js +186 -117
  389. package/dist/server/lib/rate-limiter.js.map +1 -0
  390. package/dist/server/lib/react-pdf-layout.js +551 -382
  391. package/dist/server/lib/react-pdf-layout.js.map +1 -0
  392. package/dist/server/lib/server-agent-loop.d.ts +4 -1
  393. package/dist/server/lib/server-agent-loop.js +906 -634
  394. package/dist/server/lib/server-agent-loop.js.map +1 -0
  395. package/dist/server/lib/server-subagent.js +260 -164
  396. package/dist/server/lib/server-subagent.js.map +1 -0
  397. package/dist/server/lib/session-checkpoint.js +105 -96
  398. package/dist/server/lib/session-checkpoint.js.map +1 -0
  399. package/dist/server/lib/ssrf-guard.js +193 -184
  400. package/dist/server/lib/ssrf-guard.js.map +1 -0
  401. package/dist/server/lib/supabase-client.js +94 -82
  402. package/dist/server/lib/supabase-client.js.map +1 -0
  403. package/dist/server/lib/template-resolver.js +154 -176
  404. package/dist/server/lib/template-resolver.js.map +1 -0
  405. package/dist/server/lib/utils.js +242 -133
  406. package/dist/server/lib/utils.js.map +1 -0
  407. package/dist/server/local-agent-gateway.d.ts +2 -2
  408. package/dist/server/local-agent-gateway.js +785 -627
  409. package/dist/server/local-agent-gateway.js.map +1 -0
  410. package/dist/server/providers/anthropic.js +250 -172
  411. package/dist/server/providers/anthropic.js.map +1 -0
  412. package/dist/server/providers/bedrock.js +217 -158
  413. package/dist/server/providers/bedrock.js.map +1 -0
  414. package/dist/server/providers/gemini.js +548 -418
  415. package/dist/server/providers/gemini.js.map +1 -0
  416. package/dist/server/providers/openai.js +571 -437
  417. package/dist/server/providers/openai.js.map +1 -0
  418. package/dist/server/providers/registry.js +23 -18
  419. package/dist/server/providers/registry.js.map +1 -0
  420. package/dist/server/providers/shared.js +123 -95
  421. package/dist/server/providers/shared.js.map +1 -0
  422. package/dist/server/providers/types.js +1 -11
  423. package/dist/server/providers/types.js.map +1 -0
  424. package/dist/server/proxy-handlers.js +209 -165
  425. package/dist/server/proxy-handlers.js.map +1 -0
  426. package/dist/server/tool-router.js +959 -599
  427. package/dist/server/tool-router.js.map +1 -0
  428. package/dist/server/validation.js +248 -188
  429. package/dist/server/validation.js.map +1 -0
  430. package/dist/server/worker.js +202 -133
  431. package/dist/server/worker.js.map +1 -0
  432. package/dist/setup.d.ts +2 -2
  433. package/dist/setup.js +151 -147
  434. package/dist/setup.js.map +1 -0
  435. package/dist/shared/agent-core.d.ts +115 -26
  436. package/dist/shared/agent-core.js +956 -522
  437. package/dist/shared/agent-core.js.map +1 -0
  438. package/dist/shared/anthropic-types.js +1 -6
  439. package/dist/shared/anthropic-types.js.map +1 -0
  440. package/dist/shared/api-client.d.ts +16 -9
  441. package/dist/shared/api-client.js +419 -327
  442. package/dist/shared/api-client.js.map +1 -0
  443. package/dist/shared/compaction.d.ts +36 -0
  444. package/dist/shared/compaction.js +138 -0
  445. package/dist/shared/compaction.js.map +1 -0
  446. package/dist/shared/constants.js +67 -64
  447. package/dist/shared/constants.js.map +1 -0
  448. package/dist/shared/sse-parser.js +221 -219
  449. package/dist/shared/sse-parser.js.map +1 -0
  450. package/dist/shared/tool-dispatch.d.ts +4 -0
  451. package/dist/shared/tool-dispatch.js +226 -165
  452. package/dist/shared/tool-dispatch.js.map +1 -0
  453. package/dist/shared/types.js +1 -6
  454. package/dist/shared/types.js.map +1 -0
  455. package/dist/types/cli-highlight.d.js +2 -0
  456. package/dist/types/cli-highlight.d.js.map +1 -0
  457. package/dist/types/diff.d.js +2 -0
  458. package/dist/types/diff.d.js.map +1 -0
  459. package/dist/types/pdf-parse.d.js +2 -0
  460. package/dist/types/pdf-parse.d.js.map +1 -0
  461. package/dist/updater.d.ts +1 -1
  462. package/dist/updater.js +118 -92
  463. package/dist/updater.js.map +1 -0
  464. package/dist/webchat/widget.js +227 -380
  465. package/dist/webchat/widget.js.map +1 -0
  466. package/package.json +22 -10
  467. package/vendor/ink/build/ansi-tokenizer.d.ts +38 -0
  468. package/vendor/ink/build/ansi-tokenizer.js +316 -0
  469. package/vendor/ink/build/ansi-tokenizer.js.map +1 -0
  470. package/vendor/ink/build/apply-styles.js +175 -0
  471. package/vendor/ink/build/build-layout.js +77 -0
  472. package/vendor/ink/build/calculate-wrapped-text.js +53 -0
  473. package/vendor/ink/build/colorize.d.ts +3 -0
  474. package/vendor/ink/build/colorize.js +48 -0
  475. package/vendor/ink/build/colorize.js.map +1 -0
  476. package/vendor/ink/build/components/AccessibilityContext.d.ts +3 -0
  477. package/vendor/ink/build/components/AccessibilityContext.js +5 -0
  478. package/vendor/ink/build/components/AccessibilityContext.js.map +1 -0
  479. package/vendor/ink/build/components/App.d.ts +18 -0
  480. package/vendor/ink/build/components/App.js +351 -0
  481. package/vendor/ink/build/components/App.js.map +1 -0
  482. package/vendor/ink/build/components/AppContext.d.ts +15 -0
  483. package/vendor/ink/build/components/AppContext.js +11 -0
  484. package/vendor/ink/build/components/AppContext.js.map +1 -0
  485. package/vendor/ink/build/components/BackgroundContext.d.ts +4 -0
  486. package/vendor/ink/build/components/BackgroundContext.js +3 -0
  487. package/vendor/ink/build/components/BackgroundContext.js.map +1 -0
  488. package/vendor/ink/build/components/Box.d.ts +117 -0
  489. package/vendor/ink/build/components/Box.js +34 -0
  490. package/vendor/ink/build/components/Box.js.map +1 -0
  491. package/vendor/ink/build/components/Color.js +62 -0
  492. package/vendor/ink/build/components/Cursor.d.ts +83 -0
  493. package/vendor/ink/build/components/Cursor.js +53 -0
  494. package/vendor/ink/build/components/Cursor.js.map +1 -0
  495. package/vendor/ink/build/components/CursorContext.d.ts +11 -0
  496. package/vendor/ink/build/components/CursorContext.js +8 -0
  497. package/vendor/ink/build/components/CursorContext.js.map +1 -0
  498. package/vendor/ink/build/components/ErrorBoundary.d.ts +18 -0
  499. package/vendor/ink/build/components/ErrorBoundary.js +23 -0
  500. package/vendor/ink/build/components/ErrorBoundary.js.map +1 -0
  501. package/vendor/ink/build/components/ErrorOverview.d.ts +6 -0
  502. package/vendor/ink/build/components/ErrorOverview.js +84 -0
  503. package/vendor/ink/build/components/ErrorOverview.js.map +1 -0
  504. package/vendor/ink/build/components/FocusContext.d.ts +16 -0
  505. package/vendor/ink/build/components/FocusContext.js +17 -0
  506. package/vendor/ink/build/components/FocusContext.js.map +1 -0
  507. package/vendor/ink/build/components/Newline.d.ts +13 -0
  508. package/vendor/ink/build/components/Newline.js +8 -0
  509. package/vendor/ink/build/components/Newline.js.map +1 -0
  510. package/vendor/ink/build/components/Spacer.d.ts +7 -0
  511. package/vendor/ink/build/components/Spacer.js +11 -0
  512. package/vendor/ink/build/components/Spacer.js.map +1 -0
  513. package/vendor/ink/build/components/Static.d.ts +24 -0
  514. package/vendor/ink/build/components/Static.js +28 -0
  515. package/vendor/ink/build/components/Static.js.map +1 -0
  516. package/vendor/ink/build/components/StderrContext.d.ts +15 -0
  517. package/vendor/ink/build/components/StderrContext.js +13 -0
  518. package/vendor/ink/build/components/StderrContext.js.map +1 -0
  519. package/vendor/ink/build/components/StdinContext.d.ts +22 -0
  520. package/vendor/ink/build/components/StdinContext.js +19 -0
  521. package/vendor/ink/build/components/StdinContext.js.map +1 -0
  522. package/vendor/ink/build/components/StdoutContext.d.ts +15 -0
  523. package/vendor/ink/build/components/StdoutContext.js +13 -0
  524. package/vendor/ink/build/components/StdoutContext.js.map +1 -0
  525. package/vendor/ink/build/components/Text.d.ts +55 -0
  526. package/vendor/ink/build/components/Text.js +50 -0
  527. package/vendor/ink/build/components/Text.js.map +1 -0
  528. package/vendor/ink/build/components/Transform.d.ts +16 -0
  529. package/vendor/ink/build/components/Transform.js +15 -0
  530. package/vendor/ink/build/components/Transform.js.map +1 -0
  531. package/vendor/ink/build/cursor-helpers.d.ts +38 -0
  532. package/vendor/ink/build/cursor-helpers.js +56 -0
  533. package/vendor/ink/build/cursor-helpers.js.map +1 -0
  534. package/vendor/ink/build/devtools-window-polyfill.d.ts +1 -0
  535. package/vendor/ink/build/devtools-window-polyfill.js +65 -0
  536. package/vendor/ink/build/devtools-window-polyfill.js.map +1 -0
  537. package/vendor/ink/build/devtools.d.ts +1 -0
  538. package/vendor/ink/build/devtools.js +11 -0
  539. package/vendor/ink/build/devtools.js.map +1 -0
  540. package/vendor/ink/build/dom.d.ts +56 -0
  541. package/vendor/ink/build/dom.js +124 -0
  542. package/vendor/ink/build/dom.js.map +1 -0
  543. package/vendor/ink/build/experimental/apply-style.js +140 -0
  544. package/vendor/ink/build/experimental/dom.js +123 -0
  545. package/vendor/ink/build/experimental/output.js +91 -0
  546. package/vendor/ink/build/experimental/reconciler.js +141 -0
  547. package/vendor/ink/build/experimental/renderer.js +81 -0
  548. package/vendor/ink/build/get-max-width.d.ts +3 -0
  549. package/vendor/ink/build/get-max-width.js +10 -0
  550. package/vendor/ink/build/get-max-width.js.map +1 -0
  551. package/vendor/ink/build/hooks/use-app.d.ts +5 -0
  552. package/vendor/ink/build/hooks/use-app.js +8 -0
  553. package/vendor/ink/build/hooks/use-app.js.map +1 -0
  554. package/vendor/ink/build/hooks/use-cursor.d.ts +12 -0
  555. package/vendor/ink/build/hooks/use-cursor.js +29 -0
  556. package/vendor/ink/build/hooks/use-cursor.js.map +1 -0
  557. package/vendor/ink/build/hooks/use-focus-manager.d.ts +28 -0
  558. package/vendor/ink/build/hooks/use-focus-manager.js +17 -0
  559. package/vendor/ink/build/hooks/use-focus-manager.js.map +1 -0
  560. package/vendor/ink/build/hooks/use-focus.d.ts +29 -0
  561. package/vendor/ink/build/hooks/use-focus.js +42 -0
  562. package/vendor/ink/build/hooks/use-focus.js.map +1 -0
  563. package/vendor/ink/build/hooks/use-input.d.ts +131 -0
  564. package/vendor/ink/build/hooks/use-input.js +124 -0
  565. package/vendor/ink/build/hooks/use-input.js.map +1 -0
  566. package/vendor/ink/build/hooks/use-is-screen-reader-enabled.d.ts +5 -0
  567. package/vendor/ink/build/hooks/use-is-screen-reader-enabled.js +11 -0
  568. package/vendor/ink/build/hooks/use-is-screen-reader-enabled.js.map +1 -0
  569. package/vendor/ink/build/hooks/use-stderr.d.ts +5 -0
  570. package/vendor/ink/build/hooks/use-stderr.js +8 -0
  571. package/vendor/ink/build/hooks/use-stderr.js.map +1 -0
  572. package/vendor/ink/build/hooks/use-stdin.d.ts +5 -0
  573. package/vendor/ink/build/hooks/use-stdin.js +8 -0
  574. package/vendor/ink/build/hooks/use-stdin.js.map +1 -0
  575. package/vendor/ink/build/hooks/use-stdout.d.ts +5 -0
  576. package/vendor/ink/build/hooks/use-stdout.js +8 -0
  577. package/vendor/ink/build/hooks/use-stdout.js.map +1 -0
  578. package/vendor/ink/build/hooks/useInput.js +38 -0
  579. package/vendor/ink/build/index.d.ts +34 -0
  580. package/vendor/ink/build/index.js +20 -0
  581. package/vendor/ink/build/index.js.map +1 -0
  582. package/vendor/ink/build/ink.d.ts +90 -0
  583. package/vendor/ink/build/ink.js +654 -0
  584. package/vendor/ink/build/ink.js.map +1 -0
  585. package/vendor/ink/build/input-parser.d.ts +7 -0
  586. package/vendor/ink/build/input-parser.js +154 -0
  587. package/vendor/ink/build/input-parser.js.map +1 -0
  588. package/vendor/ink/build/instance.js +205 -0
  589. package/vendor/ink/build/instances.d.ts +3 -0
  590. package/vendor/ink/build/instances.js +8 -0
  591. package/vendor/ink/build/instances.js.map +1 -0
  592. package/vendor/ink/build/kitty-keyboard.d.ts +23 -0
  593. package/vendor/ink/build/kitty-keyboard.js +32 -0
  594. package/vendor/ink/build/kitty-keyboard.js.map +1 -0
  595. package/vendor/ink/build/layout.d.ts +7 -0
  596. package/vendor/ink/build/layout.js +33 -0
  597. package/vendor/ink/build/layout.js.map +1 -0
  598. package/vendor/ink/build/log-update.d.ts +19 -0
  599. package/vendor/ink/build/log-update.js +243 -0
  600. package/vendor/ink/build/log-update.js.map +1 -0
  601. package/vendor/ink/build/measure-element.d.ts +16 -0
  602. package/vendor/ink/build/measure-element.js +9 -0
  603. package/vendor/ink/build/measure-element.js.map +1 -0
  604. package/vendor/ink/build/measure-text.d.ts +6 -0
  605. package/vendor/ink/build/measure-text.js +21 -0
  606. package/vendor/ink/build/measure-text.js.map +1 -0
  607. package/vendor/ink/build/options.d.ts +52 -0
  608. package/vendor/ink/build/options.js +2 -0
  609. package/vendor/ink/build/options.js.map +1 -0
  610. package/vendor/ink/build/output.d.ts +35 -0
  611. package/vendor/ink/build/output.js +183 -0
  612. package/vendor/ink/build/output.js.map +1 -0
  613. package/vendor/ink/build/parse-keypress.d.ts +22 -0
  614. package/vendor/ink/build/parse-keypress.js +493 -0
  615. package/vendor/ink/build/parse-keypress.js.map +1 -0
  616. package/vendor/ink/build/reconciler.d.ts +4 -0
  617. package/vendor/ink/build/reconciler.js +274 -0
  618. package/vendor/ink/build/reconciler.js.map +1 -0
  619. package/vendor/ink/build/render-background.d.ts +4 -0
  620. package/vendor/ink/build/render-background.js +25 -0
  621. package/vendor/ink/build/render-background.js.map +1 -0
  622. package/vendor/ink/build/render-border.d.ts +4 -0
  623. package/vendor/ink/build/render-border.js +73 -0
  624. package/vendor/ink/build/render-border.js.map +1 -0
  625. package/vendor/ink/build/render-node-to-output.d.ts +14 -0
  626. package/vendor/ink/build/render-node-to-output.js +147 -0
  627. package/vendor/ink/build/render-node-to-output.js.map +1 -0
  628. package/vendor/ink/build/render-to-string.d.ts +38 -0
  629. package/vendor/ink/build/render-to-string.js +115 -0
  630. package/vendor/ink/build/render-to-string.js.map +1 -0
  631. package/vendor/ink/build/render.d.ts +121 -0
  632. package/vendor/ink/build/render.js +55 -0
  633. package/vendor/ink/build/render.js.map +1 -0
  634. package/vendor/ink/build/renderer.d.ts +8 -0
  635. package/vendor/ink/build/renderer.js +55 -0
  636. package/vendor/ink/build/renderer.js.map +1 -0
  637. package/vendor/ink/build/sanitize-ansi.d.ts +2 -0
  638. package/vendor/ink/build/sanitize-ansi.js +27 -0
  639. package/vendor/ink/build/sanitize-ansi.js.map +1 -0
  640. package/vendor/ink/build/screen-reader-update.d.ts +13 -0
  641. package/vendor/ink/build/screen-reader-update.js +38 -0
  642. package/vendor/ink/build/screen-reader-update.js.map +1 -0
  643. package/vendor/ink/build/squash-text-nodes.d.ts +3 -0
  644. package/vendor/ink/build/squash-text-nodes.js +36 -0
  645. package/vendor/ink/build/squash-text-nodes.js.map +1 -0
  646. package/vendor/ink/build/styles.d.ts +240 -0
  647. package/vendor/ink/build/styles.js +232 -0
  648. package/vendor/ink/build/styles.js.map +1 -0
  649. package/vendor/ink/build/utils.d.ts +2 -0
  650. package/vendor/ink/build/utils.js +4 -0
  651. package/vendor/ink/build/utils.js.map +1 -0
  652. package/vendor/ink/build/wrap-text.d.ts +3 -0
  653. package/vendor/ink/build/wrap-text.js +31 -0
  654. package/vendor/ink/build/wrap-text.js.map +1 -0
  655. package/vendor/ink/build/write-synchronized.d.ts +4 -0
  656. package/vendor/ink/build/write-synchronized.js +7 -0
  657. package/vendor/ink/build/write-synchronized.js.map +1 -0
  658. package/vendor/ink/license +10 -0
  659. package/vendor/ink/node_modules/@types/node/LICENSE +21 -0
  660. package/vendor/ink/node_modules/@types/node/README.md +15 -0
  661. package/vendor/ink/node_modules/@types/node/assert/strict.d.ts +105 -0
  662. package/vendor/ink/node_modules/@types/node/assert.d.ts +955 -0
  663. package/vendor/ink/node_modules/@types/node/async_hooks.d.ts +623 -0
  664. package/vendor/ink/node_modules/@types/node/buffer.buffer.d.ts +466 -0
  665. package/vendor/ink/node_modules/@types/node/buffer.d.ts +1810 -0
  666. package/vendor/ink/node_modules/@types/node/child_process.d.ts +1428 -0
  667. package/vendor/ink/node_modules/@types/node/cluster.d.ts +486 -0
  668. package/vendor/ink/node_modules/@types/node/compatibility/iterators.d.ts +21 -0
  669. package/vendor/ink/node_modules/@types/node/console.d.ts +151 -0
  670. package/vendor/ink/node_modules/@types/node/constants.d.ts +20 -0
  671. package/vendor/ink/node_modules/@types/node/crypto.d.ts +4065 -0
  672. package/vendor/ink/node_modules/@types/node/dgram.d.ts +564 -0
  673. package/vendor/ink/node_modules/@types/node/diagnostics_channel.d.ts +576 -0
  674. package/vendor/ink/node_modules/@types/node/dns/promises.d.ts +503 -0
  675. package/vendor/ink/node_modules/@types/node/dns.d.ts +922 -0
  676. package/vendor/ink/node_modules/@types/node/domain.d.ts +166 -0
  677. package/vendor/ink/node_modules/@types/node/events.d.ts +1054 -0
  678. package/vendor/ink/node_modules/@types/node/fs/promises.d.ts +1329 -0
  679. package/vendor/ink/node_modules/@types/node/fs.d.ts +4676 -0
  680. package/vendor/ink/node_modules/@types/node/globals.d.ts +150 -0
  681. package/vendor/ink/node_modules/@types/node/globals.typedarray.d.ts +101 -0
  682. package/vendor/ink/node_modules/@types/node/http.d.ts +2167 -0
  683. package/vendor/ink/node_modules/@types/node/http2.d.ts +2480 -0
  684. package/vendor/ink/node_modules/@types/node/https.d.ts +405 -0
  685. package/vendor/ink/node_modules/@types/node/index.d.ts +115 -0
  686. package/vendor/ink/node_modules/@types/node/inspector/promises.d.ts +41 -0
  687. package/vendor/ink/node_modules/@types/node/inspector.d.ts +224 -0
  688. package/vendor/ink/node_modules/@types/node/inspector.generated.d.ts +4226 -0
  689. package/vendor/ink/node_modules/@types/node/module.d.ts +819 -0
  690. package/vendor/ink/node_modules/@types/node/net.d.ts +933 -0
  691. package/vendor/ink/node_modules/@types/node/os.d.ts +507 -0
  692. package/vendor/ink/node_modules/@types/node/package.json +155 -0
  693. package/vendor/ink/node_modules/@types/node/path/posix.d.ts +8 -0
  694. package/vendor/ink/node_modules/@types/node/path/win32.d.ts +8 -0
  695. package/vendor/ink/node_modules/@types/node/path.d.ts +187 -0
  696. package/vendor/ink/node_modules/@types/node/perf_hooks.d.ts +643 -0
  697. package/vendor/ink/node_modules/@types/node/process.d.ts +2156 -0
  698. package/vendor/ink/node_modules/@types/node/punycode.d.ts +117 -0
  699. package/vendor/ink/node_modules/@types/node/querystring.d.ts +152 -0
  700. package/vendor/ink/node_modules/@types/node/quic.d.ts +910 -0
  701. package/vendor/ink/node_modules/@types/node/readline/promises.d.ts +161 -0
  702. package/vendor/ink/node_modules/@types/node/readline.d.ts +541 -0
  703. package/vendor/ink/node_modules/@types/node/repl.d.ts +415 -0
  704. package/vendor/ink/node_modules/@types/node/sea.d.ts +162 -0
  705. package/vendor/ink/node_modules/@types/node/sqlite.d.ts +955 -0
  706. package/vendor/ink/node_modules/@types/node/stream/consumers.d.ts +38 -0
  707. package/vendor/ink/node_modules/@types/node/stream/promises.d.ts +211 -0
  708. package/vendor/ink/node_modules/@types/node/stream/web.d.ts +296 -0
  709. package/vendor/ink/node_modules/@types/node/stream.d.ts +1760 -0
  710. package/vendor/ink/node_modules/@types/node/string_decoder.d.ts +67 -0
  711. package/vendor/ink/node_modules/@types/node/test/reporters.d.ts +96 -0
  712. package/vendor/ink/node_modules/@types/node/test.d.ts +2240 -0
  713. package/vendor/ink/node_modules/@types/node/timers/promises.d.ts +108 -0
  714. package/vendor/ink/node_modules/@types/node/timers.d.ts +159 -0
  715. package/vendor/ink/node_modules/@types/node/tls.d.ts +1198 -0
  716. package/vendor/ink/node_modules/@types/node/trace_events.d.ts +197 -0
  717. package/vendor/ink/node_modules/@types/node/ts5.6/buffer.buffer.d.ts +462 -0
  718. package/vendor/ink/node_modules/@types/node/ts5.6/compatibility/float16array.d.ts +71 -0
  719. package/vendor/ink/node_modules/@types/node/ts5.6/globals.typedarray.d.ts +36 -0
  720. package/vendor/ink/node_modules/@types/node/ts5.6/index.d.ts +117 -0
  721. package/vendor/ink/node_modules/@types/node/ts5.7/compatibility/float16array.d.ts +72 -0
  722. package/vendor/ink/node_modules/@types/node/ts5.7/index.d.ts +117 -0
  723. package/vendor/ink/node_modules/@types/node/tty.d.ts +250 -0
  724. package/vendor/ink/node_modules/@types/node/url.d.ts +519 -0
  725. package/vendor/ink/node_modules/@types/node/util/types.d.ts +558 -0
  726. package/vendor/ink/node_modules/@types/node/util.d.ts +1662 -0
  727. package/vendor/ink/node_modules/@types/node/v8.d.ts +983 -0
  728. package/vendor/ink/node_modules/@types/node/vm.d.ts +1208 -0
  729. package/vendor/ink/node_modules/@types/node/wasi.d.ts +202 -0
  730. package/vendor/ink/node_modules/@types/node/web-globals/abortcontroller.d.ts +59 -0
  731. package/vendor/ink/node_modules/@types/node/web-globals/blob.d.ts +23 -0
  732. package/vendor/ink/node_modules/@types/node/web-globals/console.d.ts +9 -0
  733. package/vendor/ink/node_modules/@types/node/web-globals/crypto.d.ts +39 -0
  734. package/vendor/ink/node_modules/@types/node/web-globals/domexception.d.ts +68 -0
  735. package/vendor/ink/node_modules/@types/node/web-globals/encoding.d.ts +11 -0
  736. package/vendor/ink/node_modules/@types/node/web-globals/events.d.ts +106 -0
  737. package/vendor/ink/node_modules/@types/node/web-globals/fetch.d.ts +69 -0
  738. package/vendor/ink/node_modules/@types/node/web-globals/importmeta.d.ts +13 -0
  739. package/vendor/ink/node_modules/@types/node/web-globals/messaging.d.ts +23 -0
  740. package/vendor/ink/node_modules/@types/node/web-globals/navigator.d.ts +25 -0
  741. package/vendor/ink/node_modules/@types/node/web-globals/performance.d.ts +45 -0
  742. package/vendor/ink/node_modules/@types/node/web-globals/storage.d.ts +24 -0
  743. package/vendor/ink/node_modules/@types/node/web-globals/streams.d.ts +115 -0
  744. package/vendor/ink/node_modules/@types/node/web-globals/timers.d.ts +44 -0
  745. package/vendor/ink/node_modules/@types/node/web-globals/url.d.ts +24 -0
  746. package/vendor/ink/node_modules/@types/node/worker_threads.d.ts +717 -0
  747. package/vendor/ink/node_modules/@types/node/zlib.d.ts +618 -0
  748. package/vendor/ink/node_modules/node-pty/LICENSE +69 -0
  749. package/vendor/ink/node_modules/node-pty/README.md +164 -0
  750. package/vendor/ink/node_modules/node-pty/binding.gyp +150 -0
  751. package/vendor/ink/node_modules/node-pty/lib/conpty_console_list_agent.js +25 -0
  752. package/vendor/ink/node_modules/node-pty/lib/eventEmitter2.js +47 -0
  753. package/vendor/ink/node_modules/node-pty/lib/index.js +52 -0
  754. package/vendor/ink/node_modules/node-pty/lib/interfaces.js +7 -0
  755. package/vendor/ink/node_modules/node-pty/lib/shared/conout.js +11 -0
  756. package/vendor/ink/node_modules/node-pty/lib/terminal.js +190 -0
  757. package/vendor/ink/node_modules/node-pty/lib/types.js +7 -0
  758. package/vendor/ink/node_modules/node-pty/lib/unixTerminal.js +349 -0
  759. package/vendor/ink/node_modules/node-pty/lib/utils.js +39 -0
  760. package/vendor/ink/node_modules/node-pty/lib/windowsConoutConnection.js +125 -0
  761. package/vendor/ink/node_modules/node-pty/lib/windowsPtyAgent.js +287 -0
  762. package/vendor/ink/node_modules/node-pty/lib/windowsTerminal.js +201 -0
  763. package/vendor/ink/node_modules/node-pty/lib/worker/conoutSocketWorker.js +22 -0
  764. package/vendor/ink/node_modules/node-pty/package.json +65 -0
  765. package/vendor/ink/node_modules/node-pty/prebuilds/darwin-arm64/pty.node +0 -0
  766. package/vendor/ink/node_modules/node-pty/prebuilds/darwin-arm64/spawn-helper +0 -0
  767. package/vendor/ink/node_modules/node-pty/prebuilds/darwin-x64/pty.node +0 -0
  768. package/vendor/ink/node_modules/node-pty/prebuilds/darwin-x64/spawn-helper +0 -0
  769. package/vendor/ink/node_modules/node-pty/prebuilds/linux-arm64/pty.node +0 -0
  770. package/vendor/ink/node_modules/node-pty/prebuilds/linux-x64/pty.node +0 -0
  771. package/vendor/ink/node_modules/node-pty/prebuilds/win32-arm64/conpty/OpenConsole.exe +0 -0
  772. package/vendor/ink/node_modules/node-pty/prebuilds/win32-arm64/conpty/conpty.dll +0 -0
  773. package/vendor/ink/node_modules/node-pty/prebuilds/win32-arm64/conpty.node +0 -0
  774. package/vendor/ink/node_modules/node-pty/prebuilds/win32-arm64/conpty.pdb +0 -0
  775. package/vendor/ink/node_modules/node-pty/prebuilds/win32-arm64/conpty_console_list.node +0 -0
  776. package/vendor/ink/node_modules/node-pty/prebuilds/win32-arm64/conpty_console_list.pdb +0 -0
  777. package/vendor/ink/node_modules/node-pty/prebuilds/win32-x64/conpty/OpenConsole.exe +0 -0
  778. package/vendor/ink/node_modules/node-pty/prebuilds/win32-x64/conpty/conpty.dll +0 -0
  779. package/vendor/ink/node_modules/node-pty/prebuilds/win32-x64/conpty.node +0 -0
  780. package/vendor/ink/node_modules/node-pty/prebuilds/win32-x64/conpty.pdb +0 -0
  781. package/vendor/ink/node_modules/node-pty/prebuilds/win32-x64/conpty_console_list.node +0 -0
  782. package/vendor/ink/node_modules/node-pty/prebuilds/win32-x64/conpty_console_list.pdb +0 -0
  783. package/vendor/ink/node_modules/node-pty/scripts/post-install.js +76 -0
  784. package/vendor/ink/node_modules/node-pty/scripts/prebuild.js +34 -0
  785. package/vendor/ink/node_modules/node-pty/src/unix/pty.cc +875 -0
  786. package/vendor/ink/node_modules/node-pty/src/unix/spawn-helper.cc +23 -0
  787. package/vendor/ink/node_modules/node-pty/src/win/conpty.cc +582 -0
  788. package/vendor/ink/node_modules/node-pty/src/win/conpty.h +41 -0
  789. package/vendor/ink/node_modules/node-pty/src/win/conpty_console_list.cc +44 -0
  790. package/vendor/ink/node_modules/node-pty/src/win/path_util.cc +95 -0
  791. package/vendor/ink/node_modules/node-pty/src/win/path_util.h +26 -0
  792. package/vendor/ink/node_modules/node-pty/third_party/conpty/1.23.251008001/win10-arm64/OpenConsole.exe +0 -0
  793. package/vendor/ink/node_modules/node-pty/third_party/conpty/1.23.251008001/win10-arm64/conpty.dll +0 -0
  794. package/vendor/ink/node_modules/node-pty/third_party/conpty/1.23.251008001/win10-x64/OpenConsole.exe +0 -0
  795. package/vendor/ink/node_modules/node-pty/third_party/conpty/1.23.251008001/win10-x64/conpty.dll +0 -0
  796. package/vendor/ink/node_modules/node-pty/typings/node-pty.d.ts +215 -0
  797. package/vendor/ink/node_modules/undici-types/LICENSE +21 -0
  798. package/vendor/ink/node_modules/undici-types/README.md +6 -0
  799. package/vendor/ink/node_modules/undici-types/agent.d.ts +32 -0
  800. package/vendor/ink/node_modules/undici-types/api.d.ts +43 -0
  801. package/vendor/ink/node_modules/undici-types/balanced-pool.d.ts +30 -0
  802. package/vendor/ink/node_modules/undici-types/cache-interceptor.d.ts +173 -0
  803. package/vendor/ink/node_modules/undici-types/cache.d.ts +36 -0
  804. package/vendor/ink/node_modules/undici-types/client-stats.d.ts +15 -0
  805. package/vendor/ink/node_modules/undici-types/client.d.ts +108 -0
  806. package/vendor/ink/node_modules/undici-types/connector.d.ts +34 -0
  807. package/vendor/ink/node_modules/undici-types/content-type.d.ts +21 -0
  808. package/vendor/ink/node_modules/undici-types/cookies.d.ts +30 -0
  809. package/vendor/ink/node_modules/undici-types/diagnostics-channel.d.ts +74 -0
  810. package/vendor/ink/node_modules/undici-types/dispatcher.d.ts +276 -0
  811. package/vendor/ink/node_modules/undici-types/env-http-proxy-agent.d.ts +22 -0
  812. package/vendor/ink/node_modules/undici-types/errors.d.ts +161 -0
  813. package/vendor/ink/node_modules/undici-types/eventsource.d.ts +66 -0
  814. package/vendor/ink/node_modules/undici-types/fetch.d.ts +211 -0
  815. package/vendor/ink/node_modules/undici-types/formdata.d.ts +108 -0
  816. package/vendor/ink/node_modules/undici-types/global-dispatcher.d.ts +9 -0
  817. package/vendor/ink/node_modules/undici-types/global-origin.d.ts +7 -0
  818. package/vendor/ink/node_modules/undici-types/h2c-client.d.ts +73 -0
  819. package/vendor/ink/node_modules/undici-types/handlers.d.ts +15 -0
  820. package/vendor/ink/node_modules/undici-types/header.d.ts +160 -0
  821. package/vendor/ink/node_modules/undici-types/index.d.ts +88 -0
  822. package/vendor/ink/node_modules/undici-types/interceptors.d.ts +73 -0
  823. package/vendor/ink/node_modules/undici-types/mock-agent.d.ts +68 -0
  824. package/vendor/ink/node_modules/undici-types/mock-call-history.d.ts +111 -0
  825. package/vendor/ink/node_modules/undici-types/mock-client.d.ts +27 -0
  826. package/vendor/ink/node_modules/undici-types/mock-errors.d.ts +12 -0
  827. package/vendor/ink/node_modules/undici-types/mock-interceptor.d.ts +94 -0
  828. package/vendor/ink/node_modules/undici-types/mock-pool.d.ts +27 -0
  829. package/vendor/ink/node_modules/undici-types/package.json +55 -0
  830. package/vendor/ink/node_modules/undici-types/patch.d.ts +29 -0
  831. package/vendor/ink/node_modules/undici-types/pool-stats.d.ts +19 -0
  832. package/vendor/ink/node_modules/undici-types/pool.d.ts +41 -0
  833. package/vendor/ink/node_modules/undici-types/proxy-agent.d.ts +29 -0
  834. package/vendor/ink/node_modules/undici-types/readable.d.ts +68 -0
  835. package/vendor/ink/node_modules/undici-types/retry-agent.d.ts +8 -0
  836. package/vendor/ink/node_modules/undici-types/retry-handler.d.ts +125 -0
  837. package/vendor/ink/node_modules/undici-types/round-robin-pool.d.ts +41 -0
  838. package/vendor/ink/node_modules/undici-types/snapshot-agent.d.ts +109 -0
  839. package/vendor/ink/node_modules/undici-types/util.d.ts +18 -0
  840. package/vendor/ink/node_modules/undici-types/utility.d.ts +7 -0
  841. package/vendor/ink/node_modules/undici-types/webidl.d.ts +341 -0
  842. package/vendor/ink/node_modules/undici-types/websocket.d.ts +186 -0
  843. package/vendor/ink/package.json +201 -0
  844. package/vendor/ink/readme.md +2636 -0
  845. package/bin/swag-agent.js +0 -9
  846. package/dist/server/lib/pg-rate-limiter.d.ts +0 -21
  847. package/dist/server/lib/pg-rate-limiter.js +0 -86
@@ -5,794 +5,856 @@
5
5
  * All chalk instances are rebuilt on theme switch via rebuildMarkdownRenderer().
6
6
  * Uses marked + marked-terminal for markdown structure.
7
7
  */
8
+
8
9
  import { Marked } from "marked";
9
10
  import { markedTerminal } from "marked-terminal";
10
11
  import chalk from "chalk";
11
12
  import { colors } from "./Theme.js";
12
13
  import { highlightCode, setRebuildCallback } from "./theme-manager.js";
13
14
  import { diffWords } from "diff";
15
+
14
16
  // Note: chalk.level is auto-detected by supports-color.
15
17
  // Apple_Terminal → level 2 (256-color), iTerm.app v3+ → level 3 (24-bit).
16
18
  // Do NOT force level 3 — Terminal.app can't render 24-bit codes (shows gray).
19
+
17
20
  // ============================================================================
18
21
  // Palette factory — rebuilt on theme switch
19
22
  // ============================================================================
23
+
20
24
  function buildPalette() {
21
- return {
22
- systemBlue: chalk.hex(colors.brand),
23
- systemCyan: chalk.hex(colors.info),
24
- systemPink: chalk.hex(colors.pink),
25
- systemPurple: chalk.hex(colors.purple),
26
- systemIndigo: chalk.hex(colors.indigo),
27
- systemGreen: chalk.hex(colors.success),
28
- systemMint: chalk.hex(colors.mint),
29
- systemRed: chalk.hex(colors.error),
30
- systemOrange: chalk.hex(colors.warning),
31
- text: chalk.hex(colors.text),
32
- secondary: chalk.hex(colors.secondary),
33
- tertiary: chalk.hex(colors.tertiary),
34
- separator: chalk.hex(colors.separator),
35
- lavender: chalk.hex(colors.lavender),
36
- roseGold: chalk.hex(colors.roseGold),
37
- };
25
+ return {
26
+ systemBlue: chalk.hex(colors.brand),
27
+ systemCyan: chalk.hex(colors.info),
28
+ systemPink: chalk.hex(colors.pink),
29
+ systemPurple: chalk.hex(colors.purple),
30
+ systemIndigo: chalk.hex(colors.indigo),
31
+ systemGreen: chalk.hex(colors.success),
32
+ systemMint: chalk.hex(colors.mint),
33
+ systemRed: chalk.hex(colors.error),
34
+ systemOrange: chalk.hex(colors.warning),
35
+ text: chalk.hex(colors.text),
36
+ secondary: chalk.hex(colors.secondary),
37
+ tertiary: chalk.hex(colors.tertiary),
38
+ separator: chalk.hex(colors.separator),
39
+ lavender: chalk.hex(colors.lavender),
40
+ roseGold: chalk.hex(colors.roseGold)
41
+ };
38
42
  }
39
43
  let p = buildPalette();
44
+
40
45
  // ============================================================================
41
46
  // Terminal width helpers — single source of truth for layout widths
42
47
  // ============================================================================
43
- function termWidth() {
44
- return process.stdout.columns || 80;
48
+
49
+ /** Raw terminal width — use for elements at the outermost level (separators). */
50
+ export function termWidth() {
51
+ return process.stdout.columns || 80;
45
52
  }
46
- /** Width for top-level assistant text (accounts for MessageList marginLeft=2) */
53
+
54
+ /** Width for assistant message text (outer padding=2 + message marginLeft=2 = 4). */
47
55
  export function contentWidth() {
48
- return termWidth() - 2;
56
+ return termWidth() - 4;
49
57
  }
58
+
50
59
  /** Width for content nested inside tool results (MessageList=2 + ToolIndicator=2 + safety=2) */
51
60
  export function toolContentWidth() {
52
- return termWidth() - 6;
61
+ return termWidth() - 6;
53
62
  }
63
+
54
64
  // ============================================================================
55
65
  // OSC 8 hyperlinks — only in terminals that support them
56
66
  // ============================================================================
67
+
57
68
  /** Detect if terminal supports OSC 8 clickable hyperlinks */
58
69
  const supportsOsc8 = (() => {
59
- const tp = process.env.TERM_PROGRAM || "";
60
- if (/iterm|wezterm|kitty|hyper|warp|foot|alacritty/i.test(tp))
61
- return true;
62
- if (process.env.VTE_VERSION)
63
- return true; // GNOME Terminal, Tilix
64
- if (process.env.WT_SESSION)
65
- return true; // Windows Terminal
66
- if (process.env.KONSOLE_VERSION)
67
- return true; // Konsole
68
- // Apple Terminal.app does NOT support OSC 8
69
- return false;
70
+ const tp = process.env.TERM_PROGRAM || "";
71
+ if (/iterm|wezterm|kitty|hyper|warp|foot|alacritty/i.test(tp)) return true;
72
+ if (process.env.VTE_VERSION) return true; // GNOME Terminal, Tilix
73
+ if (process.env.WT_SESSION) return true; // Windows Terminal
74
+ if (process.env.KONSOLE_VERSION) return true; // Konsole
75
+ // Apple Terminal.app does NOT support OSC 8
76
+ return false;
70
77
  })();
71
78
  function hyperlink(url, text) {
72
- // mailto: → clean email address, no protocol prefix, no OSC 8
73
- if (url.startsWith("mailto:")) {
74
- const email = text || url.slice(7);
75
- return p.systemCyan(email);
76
- }
77
- // tel: → clean phone number
78
- if (url.startsWith("tel:")) {
79
- return p.systemCyan(text || url.slice(4));
80
- }
81
- const display = text || url;
82
- // OSC 8 clickable links — only where terminal supports them
83
- if (supportsOsc8) {
84
- return `\x1B]8;;${url}\x07${p.systemCyan.underline(display)}\x1B]8;;\x07`;
85
- }
86
- // Fallback: colored underlined text (no escape sequences)
87
- return p.systemCyan.underline(display);
79
+ // mailto: → clean email address, no protocol prefix, no OSC 8
80
+ if (url.startsWith("mailto:")) {
81
+ const email = text || url.slice(7);
82
+ return p.systemCyan(email);
83
+ }
84
+
85
+ // tel: → clean phone number
86
+ if (url.startsWith("tel:")) {
87
+ return p.systemCyan(text || url.slice(4));
88
+ }
89
+ const display = text || url;
90
+
91
+ // OSC 8 clickable links — only where terminal supports them
92
+ if (supportsOsc8) {
93
+ return `\x1B]8;;${url}\x07${p.systemCyan.underline(display)}\x1B]8;;\x07`;
94
+ }
95
+
96
+ // Fallback: colored underlined text (no escape sequences)
97
+ return p.systemCyan.underline(display);
88
98
  }
99
+
89
100
  // ============================================================================
90
101
  // Path helpers
91
102
  // ============================================================================
103
+
92
104
  /** Shorten a file path for code block headers */
93
105
  function shortenPathForHeader(fullPath, maxLen = 40) {
94
- let fp = fullPath;
95
- const cwd = process.cwd();
96
- const home = process.env.HOME || "";
97
- if (fp.startsWith(cwd + "/"))
98
- fp = fp.slice(cwd.length + 1);
99
- else if (fp.startsWith(cwd))
100
- fp = fp.slice(cwd.length);
101
- else if (home && fp.startsWith(home))
102
- fp = "~" + fp.slice(home.length);
103
- if (fp.length <= maxLen)
104
- return fp;
105
- const parts = fp.split("/");
106
- const file = parts.pop();
107
- if (file.length >= maxLen - 4)
108
- return "…/" + file.slice(-(maxLen - 4));
109
- const parent = parts.pop();
110
- return parent ? "…/" + parent + "/" + file : "…/" + file;
106
+ let fp = fullPath;
107
+ const cwd = process.cwd();
108
+ const home = process.env.HOME || "";
109
+ if (fp.startsWith(cwd + "/")) fp = fp.slice(cwd.length + 1);else if (fp.startsWith(cwd)) fp = fp.slice(cwd.length);else if (home && fp.startsWith(home)) fp = "~" + fp.slice(home.length);
110
+ if (fp.length <= maxLen) return fp;
111
+ const parts = fp.split("/");
112
+ const file = parts.pop();
113
+ if (file.length >= maxLen - 4) return "…/" + file.slice(-(maxLen - 4));
114
+ const parent = parts.pop();
115
+ return parent ? "…/" + parent + "/" + file : "…/" + file;
111
116
  }
117
+
112
118
  // ============================================================================
113
119
  // Financial coloring
114
120
  // ============================================================================
121
+
115
122
  function colorizeFinancials(str) {
116
- return str
117
- // NOTE: URL hyperlinking is handled by marked's GFM autolink + link/href handlers.
118
- // Do NOT add URL patterns here — it causes links to render 3-5x.
119
- // Negative dollar amounts → red (-$1,234.56) — require digit after $
120
- .replace(/(-\$\d[\d,]*\.?\d*)/g, (m) => p.systemRed(m))
121
- // Positive dollar amounts → green ($1,234.56) — require digit after $
122
- .replace(/((?:^|[^-])\$\d[\d,]*\.?\d*)/g, (m) => p.systemGreen(m))
123
- // Negative percentages → red
124
- .replace(/(-\d+\.?\d*%)/g, (m) => p.systemRed(m))
125
- // Positive percentages → cyan
126
- .replace(/((?:^|[^-])\d+\.?\d*%)/g, (m) => p.systemCyan(m))
127
- // Explicit positive → green
128
- .replace(/(\+\$?[\d,]+\.?\d*)/g, (m) => p.systemGreen(m))
129
- // Financial-specific words → green (no generic words like running/ready/started)
130
- .replace(/\b(profit|revenue|gain|in stock|available)\b/gi, (m) => p.systemGreen(m))
131
- // Financial/status negatives → red
132
- .replace(/\b(loss|deduction|deficit|expense|out of stock|low stock|overdue|expired|cancelled|failed|error|crashed|EADDRINUSE|ENOENT)\b/gi, (m) => p.systemRed(m));
123
+ return str
124
+ // NOTE: URL hyperlinking is handled by marked's GFM autolink + link/href handlers.
125
+ // Do NOT add URL patterns here — it causes links to render 3-5x.
126
+ // Negative dollar amounts → red (-$1,234.56) — require digit after $
127
+ .replace(/(-\$\d[\d,]*\.?\d*)/g, m => p.systemRed(m))
128
+ // Positive dollar amounts → green ($1,234.56) — require digit after $
129
+ .replace(/((?:^|[^-])\$\d[\d,]*\.?\d*)/g, m => p.systemGreen(m))
130
+ // Negative percentages → red
131
+ .replace(/(-\d+\.?\d*%)/g, m => p.systemRed(m))
132
+ // Positive percentages → cyan
133
+ .replace(/((?:^|[^-])\d+\.?\d*%)/g, m => p.systemCyan(m))
134
+ // Explicit positive → green
135
+ .replace(/(\+\$?[\d,]+\.?\d*)/g, m => p.systemGreen(m))
136
+ // Financial-specific words → green (no generic words like running/ready/started)
137
+ .replace(/\b(profit|revenue|gain|in stock|available)\b/gi, m => p.systemGreen(m))
138
+ // Financial/status negatives → red
139
+ .replace(/\b(loss|deduction|deficit|expense|out of stock|low stock|overdue|expired|cancelled|failed|error|crashed|EADDRINUSE|ENOENT)\b/gi, m => p.systemRed(m));
133
140
  }
141
+
134
142
  // ============================================================================
135
143
  // Markdown renderer factory — rebuilt on theme switch
136
144
  // ============================================================================
145
+
137
146
  function buildMarkedInstance() {
138
- const md = new Marked();
139
- md.use(markedTerminal({
140
- // Headings — bold blue
141
- firstHeading: p.systemBlue.bold,
142
- heading: p.systemBlue.bold,
143
- // Inline
144
- codespan: p.systemPink,
145
- strong: p.text.bold,
146
- em: p.lavender.italic,
147
- // Blocks
148
- blockquote: p.secondary.italic,
149
- paragraph: (body) => colorizeFinancials(body),
150
- hr: () => p.separator("─".repeat(50)),
151
- // Links — OSC 8 clickable (single source of truth for URL rendering)
152
- // NOTE: Only use `link` handler, NOT `href` — having both causes double-hyperlinking
153
- link: (href, _title, text) => hyperlink(href, text !== href ? text : undefined),
154
- // Lists — purple bullets, financial-aware
155
- list: (body, ordered) => {
156
- if (ordered) {
157
- let n = 0;
158
- return body.replace(/^\* /gm, () => {
159
- n++;
160
- return `${p.systemIndigo(String(n) + ".")} `;
161
- });
147
+ const md = new Marked();
148
+ md.use(markedTerminal({
149
+ // Headings — bold blue
150
+ firstHeading: p.systemBlue.bold,
151
+ heading: p.systemBlue.bold,
152
+ // Inline
153
+ codespan: p.systemPink,
154
+ strong: p.text.bold,
155
+ em: p.lavender.italic,
156
+ // Blocks
157
+ blockquote: p.secondary.italic,
158
+ paragraph: body => colorizeFinancials(body),
159
+ hr: () => p.separator("─".repeat(50)),
160
+ // Links — OSC 8 clickable (single source of truth for URL rendering)
161
+ // NOTE: Only use `link` handler, NOT `href` — having both causes double-hyperlinking
162
+ link: (href, _title, text) => hyperlink(href, text !== href ? text : undefined),
163
+ // Lists — purple bullets, financial-aware
164
+ list: (body, ordered) => {
165
+ if (ordered) {
166
+ let n = 0;
167
+ return body.replace(/^\* /gm, () => {
168
+ n++;
169
+ return `${p.systemIndigo(String(n) + ".")} `;
170
+ });
171
+ }
172
+ return body.replace(/^\* /gm, `${p.systemPurple("●")} `);
173
+ },
174
+ listitem: itemText => {
175
+ return colorizeFinancials(itemText);
176
+ },
177
+ // Layout — adapt to terminal width
178
+ reflowText: false,
179
+ showSectionPrefix: false,
180
+ width: Math.min(120, contentWidth()),
181
+ tab: 2
182
+ }));
183
+
184
+ // Register chart + table + code block extensions
185
+ md.use({
186
+ renderer: {
187
+ code(token) {
188
+ const rawLang = token.lang || "";
189
+ const code = token.text;
190
+
191
+ // Parse lang:subtitle (e.g. "typescript:src/foo.ts")
192
+ const colonIdx = rawLang.indexOf(":");
193
+ const lang = colonIdx > 0 ? rawLang.slice(0, colonIdx) : rawLang;
194
+ const subtitle = colonIdx > 0 ? rawLang.slice(colonIdx + 1) : "";
195
+ if (lang === "chart" || lang === "bar") {
196
+ return renderBarChart(code);
197
+ }
198
+ if (lang === "diff") {
199
+ return renderDiff(code);
200
+ }
201
+ {
202
+ // Command output mode: bash without subtitle = run_command output
203
+ // → no line numbers, wider content area, clean indent
204
+ const isCommandOutput = (lang === "bash" || lang === "terminal") && !subtitle;
205
+ const highlightLang = lang === "terminal" ? "bash" : lang;
206
+
207
+ // Build header: ── lang ── subtitle ──────
208
+ const cw = contentWidth();
209
+ const headerWidth = Math.max(20, cw - 6);
210
+ const displayLang = isCommandOutput ? "bash" : lang;
211
+ let header;
212
+ if (displayLang && subtitle) {
213
+ const shortSub = shortenPathForHeader(subtitle, headerWidth - displayLang.length - 10);
214
+ const pad = Math.max(2, headerWidth - displayLang.length - shortSub.length - 6);
215
+ header = p.separator(" ── ") + p.tertiary(displayLang) + p.separator(" ── ") + p.secondary(shortSub) + p.separator(` ${"─".repeat(pad)}`);
216
+ } else if (displayLang) {
217
+ const pad = Math.max(2, headerWidth - displayLang.length - 3);
218
+ header = p.separator(" ── ") + p.tertiary(displayLang) + p.separator(` ${"─".repeat(pad)}`);
219
+ } else {
220
+ header = p.separator(" ──" + "─".repeat(headerWidth - 2));
221
+ }
222
+
223
+ // Calculate max line width to prevent wrapping
224
+ const lineCount = code.split("\n").length;
225
+ const gutterW = isCommandOutput ? 0 : String(lineCount).length;
226
+ const gutterOverhead = isCommandOutput ? 4 : 2 + gutterW + 3; // " " or " 123 │ "
227
+ const maxLineWidth = Math.max(20, cw - gutterOverhead - 2);
228
+
229
+ // Pre-truncate lines BEFORE highlighting (avoids cutting ANSI codes)
230
+ const truncatedCode = code.split("\n").map(line => {
231
+ if (line.length > maxLineWidth) {
232
+ return line.slice(0, maxLineWidth - 1) + "…";
162
233
  }
163
- return body.replace(/^\* /gm, `${p.systemPurple("●")} `);
164
- },
165
- listitem: (itemText) => {
166
- return colorizeFinancials(itemText);
167
- },
168
- // Layout adapt to terminal width
169
- reflowText: false,
170
- showSectionPrefix: false,
171
- width: Math.min(120, contentWidth()),
172
- tab: 2,
173
- }));
174
- // Register chart + table + code block extensions
175
- md.use({
176
- renderer: {
177
- code(token) {
178
- const rawLang = token.lang || "";
179
- const code = token.text;
180
- // Parse lang:subtitle (e.g. "typescript:src/foo.ts")
181
- const colonIdx = rawLang.indexOf(":");
182
- const lang = colonIdx > 0 ? rawLang.slice(0, colonIdx) : rawLang;
183
- const subtitle = colonIdx > 0 ? rawLang.slice(colonIdx + 1) : "";
184
- if (lang === "chart" || lang === "bar") {
185
- return renderBarChart(code);
186
- }
187
- if (lang === "diff") {
188
- return renderDiff(code);
189
- }
190
- {
191
- // Command output mode: bash without subtitle = run_command output
192
- // → no line numbers, wider content area, clean indent
193
- const isCommandOutput = (lang === "bash" || lang === "terminal") && !subtitle;
194
- const highlightLang = lang === "terminal" ? "bash" : lang;
195
- // Build header: ── lang ── subtitle ──────
196
- const cw = contentWidth();
197
- const headerWidth = Math.max(20, cw - 6);
198
- const displayLang = isCommandOutput ? "bash" : lang;
199
- let header;
200
- if (displayLang && subtitle) {
201
- const shortSub = shortenPathForHeader(subtitle, headerWidth - displayLang.length - 10);
202
- const pad = Math.max(2, headerWidth - displayLang.length - shortSub.length - 6);
203
- header = p.separator(" ── ") + p.tertiary(displayLang) + p.separator(" ── ") + p.secondary(shortSub) + p.separator(` ${"─".repeat(pad)}`);
204
- }
205
- else if (displayLang) {
206
- const pad = Math.max(2, headerWidth - displayLang.length - 3);
207
- header = p.separator(" ── ") + p.tertiary(displayLang) + p.separator(` ${"─".repeat(pad)}`);
208
- }
209
- else {
210
- header = p.separator(" ──" + "─".repeat(headerWidth - 2));
211
- }
212
- // Calculate max line width to prevent wrapping
213
- const lineCount = code.split("\n").length;
214
- const gutterW = isCommandOutput ? 0 : String(lineCount).length;
215
- const gutterOverhead = isCommandOutput ? 4 : (2 + gutterW + 3); // " " or " 123 │ "
216
- const maxLineWidth = Math.max(20, cw - gutterOverhead - 2);
217
- // Pre-truncate lines BEFORE highlighting (avoids cutting ANSI codes)
218
- const truncatedCode = code.split("\n").map((line) => {
219
- if (line.length > maxLineWidth) {
220
- return line.slice(0, maxLineWidth - 1) + "…";
221
- }
222
- return line;
223
- }).join("\n");
224
- // Highlight with shiki
225
- const highlighted = highlightLang
226
- ? highlightCode(truncatedCode, highlightLang)
227
- : truncatedCode;
228
- const hLines = highlighted.split("\n");
229
- if (isCommandOutput) {
230
- // Command output: no line numbers, 4-space indent
231
- const body = hLines.map(l => " " + l).join("\n");
232
- return "\n" + header + "\n" + body + "\n";
233
- }
234
- else {
235
- // Code with line numbers + gutter
236
- const numbered = hLines.map((l, i) => {
237
- const num = p.tertiary(String(i + 1).padStart(gutterW));
238
- return " " + num + p.separator(" │ ") + l;
239
- }).join("\n");
240
- return "\n" + header + "\n" + numbered + "\n";
241
- }
242
- }
243
- },
244
- table(token) {
245
- return renderTable(token);
246
- },
247
- },
248
- });
249
- return md;
234
+ return line;
235
+ }).join("\n");
236
+
237
+ // Highlight with shiki
238
+ const highlighted = highlightLang ? highlightCode(truncatedCode, highlightLang) : truncatedCode;
239
+ const hLines = highlighted.split("\n");
240
+ if (isCommandOutput) {
241
+ // Command output: no line numbers, 4-space indent
242
+ const body = hLines.map(l => " " + l).join("\n");
243
+ return "\n" + header + "\n" + body + "\n";
244
+ } else {
245
+ // Code with line numbers + gutter
246
+ const numbered = hLines.map((l, i) => {
247
+ const num = p.tertiary(String(i + 1).padStart(gutterW));
248
+ return " " + num + p.separator(" │ ") + l;
249
+ }).join("\n");
250
+ return "\n" + header + "\n" + numbered + "\n";
251
+ }
252
+ }
253
+ },
254
+ table(token) {
255
+ return renderTable(token);
256
+ }
257
+ }
258
+ });
259
+ return md;
250
260
  }
251
261
  let md = buildMarkedInstance();
262
+
252
263
  // ============================================================================
253
264
  // Diff renderer — background colors + word-level diff (Claude Code parity)
254
265
  // ============================================================================
266
+
255
267
  function buildDiffStyles() {
256
- return {
257
- diffAddedBg: chalk.bgHex(colors.diffAddedBg).white,
258
- diffRemovedBg: chalk.bgHex(colors.diffRemovedBg).white,
259
- diffWordAdded: chalk.bgHex(colors.diffWordAdded).whiteBright.bold,
260
- diffWordRemoved: chalk.bgHex(colors.diffWordRemoved).whiteBright.bold,
261
- };
268
+ return {
269
+ diffAddedBg: chalk.bgHex(colors.diffAddedBg).white,
270
+ diffRemovedBg: chalk.bgHex(colors.diffRemovedBg).white,
271
+ diffWordAdded: chalk.bgHex(colors.diffWordAdded).whiteBright.bold,
272
+ diffWordRemoved: chalk.bgHex(colors.diffWordRemoved).whiteBright.bold
273
+ };
262
274
  }
263
275
  let d = buildDiffStyles();
276
+
264
277
  /** Compute word-level diff between two lines using the `diff` library. */
265
278
  function wordDiff(oldLine, newLine) {
266
- const changes = diffWords(oldLine, newLine);
267
- const oldSegs = [];
268
- const newSegs = [];
269
- for (const change of changes) {
270
- if (change.added) {
271
- newSegs.push({ text: change.value, changed: true });
272
- }
273
- else if (change.removed) {
274
- oldSegs.push({ text: change.value, changed: true });
275
- }
276
- else {
277
- oldSegs.push({ text: change.value, changed: false });
278
- newSegs.push({ text: change.value, changed: false });
279
- }
280
- }
281
- // If >60% of either line changed, fall back to full-line highlight
282
- const oldChanged = oldSegs.filter(s => s.changed).reduce((n, s) => n + s.text.length, 0);
283
- const newChanged = newSegs.filter(s => s.changed).reduce((n, s) => n + s.text.length, 0);
284
- if ((oldLine.length > 0 && oldChanged / oldLine.length > 0.6) ||
285
- (newLine.length > 0 && newChanged / newLine.length > 0.6)) {
286
- return { old: [{ text: oldLine, changed: true }], new: [{ text: newLine, changed: true }] };
287
- }
288
- return { old: oldSegs, new: newSegs };
279
+ const changes = diffWords(oldLine, newLine);
280
+ const oldSegs = [];
281
+ const newSegs = [];
282
+ for (const change of changes) {
283
+ if (change.added) {
284
+ newSegs.push({
285
+ text: change.value,
286
+ changed: true
287
+ });
288
+ } else if (change.removed) {
289
+ oldSegs.push({
290
+ text: change.value,
291
+ changed: true
292
+ });
293
+ } else {
294
+ oldSegs.push({
295
+ text: change.value,
296
+ changed: false
297
+ });
298
+ newSegs.push({
299
+ text: change.value,
300
+ changed: false
301
+ });
302
+ }
303
+ }
304
+
305
+ // If >60% of either line changed, fall back to full-line highlight
306
+ const oldChanged = oldSegs.filter(s => s.changed).reduce((n, s) => n + s.text.length, 0);
307
+ const newChanged = newSegs.filter(s => s.changed).reduce((n, s) => n + s.text.length, 0);
308
+ if (oldLine.length > 0 && oldChanged / oldLine.length > 0.6 || newLine.length > 0 && newChanged / newLine.length > 0.6) {
309
+ return {
310
+ old: [{
311
+ text: oldLine,
312
+ changed: true
313
+ }],
314
+ new: [{
315
+ text: newLine,
316
+ changed: true
317
+ }]
318
+ };
319
+ }
320
+ return {
321
+ old: oldSegs,
322
+ new: newSegs
323
+ };
289
324
  }
325
+
290
326
  /** Render segments with word-level highlighting */
291
327
  function renderSegments(segs, wordStyle, lineStyle) {
292
- return segs.map(s => s.changed ? wordStyle(s.text) : lineStyle(s.text)).join("");
328
+ return segs.map(s => s.changed ? wordStyle(s.text) : lineStyle(s.text)).join("");
293
329
  }
294
330
  function renderDiff(code) {
295
- const lines = code.split("\n");
296
- const tw = toolContentWidth();
297
- const segments = [];
298
- let oldLineNo = 1, newLineNo = 1;
299
- let seenDiff = false;
300
- for (const line of lines) {
301
- // Skip file headers (--- a/file, +++ b/file)
302
- if (line.startsWith("---") || line.startsWith("+++"))
303
- continue;
304
- // Hunk header extract line numbers
305
- const hunkMatch = line.match(/^@@\s*-(\d+)(?:,\d+)?\s*\+(\d+)(?:,\d+)?\s*@@/);
306
- if (hunkMatch) {
307
- oldLineNo = parseInt(hunkMatch[1]);
308
- newLineNo = parseInt(hunkMatch[2]);
309
- seenDiff = true;
310
- continue;
311
- }
312
- // Skip non-diff header lines (e.g., "File edited:", "Applied N edits")
313
- if (!seenDiff && !line.startsWith("-") && !line.startsWith("+") && !line.startsWith(" ")) {
314
- continue;
315
- }
316
- seenDiff = true;
317
- if (line.startsWith("-")) {
318
- segments.push({ type: "remove", content: line.slice(1), lineNo: oldLineNo });
319
- oldLineNo++;
320
- }
321
- else if (line.startsWith("+")) {
322
- segments.push({ type: "add", content: line.slice(1), lineNo: newLineNo });
323
- newLineNo++;
324
- }
325
- else {
326
- const content = line.startsWith(" ") ? line.slice(1) : line;
327
- segments.push({ type: "context", content, lineNo: newLineNo });
328
- oldLineNo++;
329
- newLineNo++;
330
- }
331
- }
332
- if (segments.length === 0)
333
- return code; // fallback
334
- // Gutter width from max line number
335
- const maxLineNo = segments.reduce((max, s) => Math.max(max, s.lineNo), 0);
336
- const gutterW = Math.max(3, String(maxLineNo).length);
337
- const out = [];
338
- let i = 0;
339
- while (i < segments.length) {
340
- const seg = segments[i];
341
- if (seg.type === "remove") {
342
- // Collect consecutive removes
343
- const removes = [];
344
- while (i < segments.length && segments[i].type === "remove") {
345
- removes.push(segments[i]);
346
- i++;
347
- }
348
- // Collect consecutive adds
349
- const adds = [];
350
- while (i < segments.length && segments[i].type === "add") {
351
- adds.push(segments[i]);
352
- i++;
353
- }
354
- // Pair for word-level diff
355
- const pairCount = Math.min(removes.length, adds.length);
356
- for (let j = 0; j < removes.length; j++) {
357
- const r = removes[j];
358
- const rPrefix = `${String(r.lineNo).padStart(gutterW)} - `;
359
- if (j < pairCount) {
360
- const a = adds[j];
361
- const aPrefix = `${String(a.lineNo).padStart(gutterW)} + `;
362
- const wd = wordDiff(r.content, a.content);
363
- // Removed line with word highlights
364
- const rPad = Math.max(0, tw - rPrefix.length - r.content.length);
365
- out.push(d.diffRemovedBg(rPrefix) + renderSegments(wd.old, d.diffWordRemoved, d.diffRemovedBg) + d.diffRemovedBg(" ".repeat(rPad)));
366
- // Added line with word highlights
367
- const aPad = Math.max(0, tw - aPrefix.length - a.content.length);
368
- out.push(d.diffAddedBg(aPrefix) + renderSegments(wd.new, d.diffWordAdded, d.diffAddedBg) + d.diffAddedBg(" ".repeat(aPad)));
369
- }
370
- else {
371
- // Unpaired remove
372
- const raw = rPrefix + r.content;
373
- const pad = Math.max(0, tw - raw.length);
374
- out.push(d.diffRemovedBg(raw + " ".repeat(pad)));
375
- }
376
- }
377
- // Unpaired adds
378
- for (let j = pairCount; j < adds.length; j++) {
379
- const a = adds[j];
380
- const prefix = `${String(a.lineNo).padStart(gutterW)} + `;
381
- const raw = prefix + a.content;
382
- const pad = Math.max(0, tw - raw.length);
383
- out.push(d.diffAddedBg(raw + " ".repeat(pad)));
384
- }
385
- continue;
386
- }
387
- if (seg.type === "add") {
388
- // Standalone add (no preceding remove)
389
- const prefix = `${String(seg.lineNo).padStart(gutterW)} + `;
390
- const raw = prefix + seg.content;
391
- const pad = Math.max(0, tw - raw.length);
392
- out.push(d.diffAddedBg(raw + " ".repeat(pad)));
393
- i++;
394
- continue;
395
- }
396
- // Context line — dim line number, plain content, no background
397
- const prefix = p.tertiary(`${String(seg.lineNo).padStart(gutterW)} `);
398
- out.push(prefix + seg.content);
331
+ const lines = code.split("\n");
332
+ const tw = toolContentWidth();
333
+
334
+ // Parse into segments from unified diff format
335
+
336
+ const segments = [];
337
+ let oldLineNo = 1,
338
+ newLineNo = 1;
339
+ let seenDiff = false;
340
+ for (const line of lines) {
341
+ // Skip file headers (--- a/file, +++ b/file)
342
+ if (line.startsWith("---") || line.startsWith("+++")) continue;
343
+
344
+ // Hunk header — extract line numbers
345
+ const hunkMatch = line.match(/^@@\s*-(\d+)(?:,\d+)?\s*\+(\d+)(?:,\d+)?\s*@@/);
346
+ if (hunkMatch) {
347
+ oldLineNo = parseInt(hunkMatch[1]);
348
+ newLineNo = parseInt(hunkMatch[2]);
349
+ seenDiff = true;
350
+ continue;
351
+ }
352
+
353
+ // Skip non-diff header lines (e.g., "File edited:", "Applied N edits")
354
+ if (!seenDiff && !line.startsWith("-") && !line.startsWith("+") && !line.startsWith(" ")) {
355
+ continue;
356
+ }
357
+ seenDiff = true;
358
+ if (line.startsWith("-")) {
359
+ segments.push({
360
+ type: "remove",
361
+ content: line.slice(1),
362
+ lineNo: oldLineNo
363
+ });
364
+ oldLineNo++;
365
+ } else if (line.startsWith("+")) {
366
+ segments.push({
367
+ type: "add",
368
+ content: line.slice(1),
369
+ lineNo: newLineNo
370
+ });
371
+ newLineNo++;
372
+ } else {
373
+ const content = line.startsWith(" ") ? line.slice(1) : line;
374
+ segments.push({
375
+ type: "context",
376
+ content,
377
+ lineNo: newLineNo
378
+ });
379
+ oldLineNo++;
380
+ newLineNo++;
381
+ }
382
+ }
383
+ if (segments.length === 0) return code; // fallback
384
+
385
+ // Gutter width from max line number
386
+ const maxLineNo = segments.reduce((max, s) => Math.max(max, s.lineNo), 0);
387
+ const gutterW = Math.max(3, String(maxLineNo).length);
388
+ const out = [];
389
+ let i = 0;
390
+ while (i < segments.length) {
391
+ const seg = segments[i];
392
+ if (seg.type === "remove") {
393
+ // Collect consecutive removes
394
+ const removes = [];
395
+ while (i < segments.length && segments[i].type === "remove") {
396
+ removes.push(segments[i]);
399
397
  i++;
400
- }
401
- return out.join("\n") + "\n";
398
+ }
399
+ // Collect consecutive adds
400
+ const adds = [];
401
+ while (i < segments.length && segments[i].type === "add") {
402
+ adds.push(segments[i]);
403
+ i++;
404
+ }
405
+
406
+ // Pair for word-level diff
407
+ const pairCount = Math.min(removes.length, adds.length);
408
+ for (let j = 0; j < removes.length; j++) {
409
+ const r = removes[j];
410
+ const rPrefix = `${String(r.lineNo).padStart(gutterW)} - `;
411
+ if (j < pairCount) {
412
+ const a = adds[j];
413
+ const aPrefix = `${String(a.lineNo).padStart(gutterW)} + `;
414
+ const wd = wordDiff(r.content, a.content);
415
+
416
+ // Removed line with word highlights
417
+ const rPad = Math.max(0, tw - rPrefix.length - r.content.length);
418
+ out.push(d.diffRemovedBg(rPrefix) + renderSegments(wd.old, d.diffWordRemoved, d.diffRemovedBg) + d.diffRemovedBg(" ".repeat(rPad)));
419
+
420
+ // Added line with word highlights
421
+ const aPad = Math.max(0, tw - aPrefix.length - a.content.length);
422
+ out.push(d.diffAddedBg(aPrefix) + renderSegments(wd.new, d.diffWordAdded, d.diffAddedBg) + d.diffAddedBg(" ".repeat(aPad)));
423
+ } else {
424
+ // Unpaired remove
425
+ const raw = rPrefix + r.content;
426
+ const pad = Math.max(0, tw - raw.length);
427
+ out.push(d.diffRemovedBg(raw + " ".repeat(pad)));
428
+ }
429
+ }
430
+
431
+ // Unpaired adds
432
+ for (let j = pairCount; j < adds.length; j++) {
433
+ const a = adds[j];
434
+ const prefix = `${String(a.lineNo).padStart(gutterW)} + `;
435
+ const raw = prefix + a.content;
436
+ const pad = Math.max(0, tw - raw.length);
437
+ out.push(d.diffAddedBg(raw + " ".repeat(pad)));
438
+ }
439
+ continue;
440
+ }
441
+ if (seg.type === "add") {
442
+ // Standalone add (no preceding remove)
443
+ const prefix = `${String(seg.lineNo).padStart(gutterW)} + `;
444
+ const raw = prefix + seg.content;
445
+ const pad = Math.max(0, tw - raw.length);
446
+ out.push(d.diffAddedBg(raw + " ".repeat(pad)));
447
+ i++;
448
+ continue;
449
+ }
450
+
451
+ // Context line — dim line number, plain content, no background
452
+ const prefix = p.tertiary(`${String(seg.lineNo).padStart(gutterW)} `);
453
+ out.push(prefix + seg.content);
454
+ i++;
455
+ }
456
+ return out.join("\n") + "\n";
402
457
  }
458
+
403
459
  // ============================================================================
404
460
  // Bar chart renderer — ```chart code blocks
405
461
  // ============================================================================
462
+
406
463
  function buildBarGradient() {
407
- return [
408
- chalk.hex(colors.purple),
409
- chalk.hex(colors.indigo),
410
- chalk.hex(colors.brand),
411
- chalk.hex(colors.info),
412
- chalk.hex(colors.teal),
413
- chalk.hex(colors.success),
414
- chalk.hex(colors.warning),
415
- chalk.hex(colors.pink),
416
- ];
464
+ return [chalk.hex(colors.purple), chalk.hex(colors.indigo), chalk.hex(colors.brand), chalk.hex(colors.info), chalk.hex(colors.teal), chalk.hex(colors.success), chalk.hex(colors.warning), chalk.hex(colors.pink)];
417
465
  }
418
466
  let barGradient = buildBarGradient();
419
467
  function renderBarChart(code) {
420
- const lines = code.trim().split("\n").filter(l => l.trim());
421
- // Optional title — first line without "label: number" pattern
422
- let title = "";
423
- let dataLines = lines;
424
- if (lines.length > 1 && !/:\s*[$\-+]?[\d,]+/.test(lines[0])) {
425
- title = lines[0].trim();
426
- dataLines = lines.slice(1);
427
- }
428
- // Parse "Label: $1,234.56" or "Label: 42%" or "Label: 1000"
429
- const entries = [];
430
- for (const line of dataLines) {
431
- const m = line.match(/^(.+?):\s*([+\-]?\$?[\d,]+\.?\d*%?)\s*$/);
432
- if (!m)
433
- continue;
434
- const label = m[1].trim();
435
- const raw = m[2].trim();
436
- const value = Math.abs(parseFloat(raw.replace(/[$,%]/g, "")));
437
- if (!isNaN(value))
438
- entries.push({ label, value, raw });
439
- }
440
- if (entries.length === 0)
441
- return code;
442
- const maxVal = Math.max(...entries.map(e => e.value));
443
- const maxRaw = Math.max(...entries.map(e => e.raw.length));
444
- const cw = contentWidth();
445
- // Responsive label width truncate labels to fit
446
- const idealLabelW = Math.max(...entries.map(e => e.label.length));
447
- // Fixed overhead: indent(2) + gap(2) + gap(2) + value(maxRaw) + safety(2)
448
- const fixedOverhead = 2 + 2 + 2 + maxRaw + 2;
449
- const spaceForLabelAndBar = cw - fixedOverhead;
450
- // Allocate: label gets up to half, bar gets the rest (min 4)
451
- const maxLabelW = Math.min(idealLabelW, Math.max(6, Math.floor(spaceForLabelAndBar * 0.4)));
452
- const barWidth = Math.max(4, spaceForLabelAndBar - maxLabelW);
453
- // If even 4-char bars don't fit, fall back to compact list (no bars)
454
- const compact = spaceForLabelAndBar < 12;
455
- const out = [];
456
- if (title) {
457
- const displayTitle = title.length > cw - 4 ? title.slice(0, cw - 5) + "…" : title;
458
- out.push(` ${p.systemBlue.bold(displayTitle)}`);
459
- out.push("");
460
- }
461
- function colorVal(raw) {
462
- return raw.includes("$") ? p.systemGreen(raw)
463
- : raw.includes("%") ? p.systemCyan(raw)
464
- : p.systemMint(raw);
465
- }
466
- if (compact) {
467
- // Compact mode: just "label value" with color dot
468
- for (let i = 0; i < entries.length; i++) {
469
- const e = entries[i];
470
- const color = barGradient[i % barGradient.length];
471
- const labelStr = e.label.length > cw - maxRaw - 8
472
- ? e.label.slice(0, cw - maxRaw - 9) + "…"
473
- : e.label;
474
- out.push(` ${color("●")} ${p.secondary(labelStr)} ${colorVal(e.raw)}`);
475
- }
476
- }
477
- else {
478
- for (let i = 0; i < entries.length; i++) {
479
- const e = entries[i];
480
- const ratio = maxVal > 0 ? e.value / maxVal : 0;
481
- const filled = Math.round(ratio * barWidth);
482
- const color = barGradient[i % barGradient.length];
483
- const labelStr = e.label.length > maxLabelW
484
- ? e.label.slice(0, maxLabelW - 1) + "…"
485
- : e.label;
486
- const label = p.secondary(labelStr.padStart(maxLabelW));
487
- const bar = color("█".repeat(filled)) + chalk.hex("#2C2C2E")("░".repeat(barWidth - filled));
488
- const val = colorVal(e.raw.padStart(maxRaw));
489
- out.push(` ${label} ${bar} ${val}`);
490
- }
491
- }
492
- return "\n" + out.join("\n") + "\n";
468
+ const lines = code.trim().split("\n").filter(l => l.trim());
469
+
470
+ // Optional title first line without "label: number" pattern
471
+ let title = "";
472
+ let dataLines = lines;
473
+ if (lines.length > 1 && !/:\s*[$\-+]?[\d,]+/.test(lines[0])) {
474
+ title = lines[0].trim();
475
+ dataLines = lines.slice(1);
476
+ }
477
+
478
+ // Parse "Label: $1,234.56" or "Label: 42%" or "Label: 1000"
479
+ const entries = [];
480
+ for (const line of dataLines) {
481
+ const m = line.match(/^(.+?):\s*([+\-]?\$?[\d,]+\.?\d*%?)\s*$/);
482
+ if (!m) continue;
483
+ const label = m[1].trim();
484
+ const raw = m[2].trim();
485
+ const value = Math.abs(parseFloat(raw.replace(/[$,%]/g, "")));
486
+ if (!isNaN(value)) entries.push({
487
+ label,
488
+ value,
489
+ raw
490
+ });
491
+ }
492
+ if (entries.length === 0) return code;
493
+ const maxVal = Math.max(...entries.map(e => e.value));
494
+ const maxRaw = Math.max(...entries.map(e => e.raw.length));
495
+ const cw = contentWidth();
496
+
497
+ // Responsive label width truncate labels to fit
498
+ const idealLabelW = Math.max(...entries.map(e => e.label.length));
499
+ // Fixed overhead: indent(2) + gap(2) + gap(2) + value(maxRaw) + safety(2)
500
+ const fixedOverhead = 2 + 2 + 2 + maxRaw + 2;
501
+ const spaceForLabelAndBar = cw - fixedOverhead;
502
+
503
+ // Allocate: label gets up to half, bar gets the rest (min 4)
504
+ const maxLabelW = Math.min(idealLabelW, Math.max(6, Math.floor(spaceForLabelAndBar * 0.4)));
505
+ const barWidth = Math.max(4, spaceForLabelAndBar - maxLabelW);
506
+
507
+ // If even 4-char bars don't fit, fall back to compact list (no bars)
508
+ const compact = spaceForLabelAndBar < 12;
509
+ const out = [];
510
+ if (title) {
511
+ const displayTitle = title.length > cw - 4 ? title.slice(0, cw - 5) + "…" : title;
512
+ out.push(` ${p.systemBlue.bold(displayTitle)}`);
513
+ out.push("");
514
+ }
515
+ function colorVal(raw) {
516
+ return raw.includes("$") ? p.systemGreen(raw) : raw.includes("%") ? p.systemCyan(raw) : p.systemMint(raw);
517
+ }
518
+ if (compact) {
519
+ // Compact mode: just "label value" with color dot
520
+ for (let i = 0; i < entries.length; i++) {
521
+ const e = entries[i];
522
+ const color = barGradient[i % barGradient.length];
523
+ const labelStr = e.label.length > cw - maxRaw - 8 ? e.label.slice(0, cw - maxRaw - 9) + "…" : e.label;
524
+ out.push(` ${color("●")} ${p.secondary(labelStr)} ${colorVal(e.raw)}`);
525
+ }
526
+ } else {
527
+ for (let i = 0; i < entries.length; i++) {
528
+ const e = entries[i];
529
+ const ratio = maxVal > 0 ? e.value / maxVal : 0;
530
+ const filled = Math.round(ratio * barWidth);
531
+ const color = barGradient[i % barGradient.length];
532
+ const labelStr = e.label.length > maxLabelW ? e.label.slice(0, maxLabelW - 1) + "…" : e.label;
533
+ const label = p.secondary(labelStr.padStart(maxLabelW));
534
+ const bar = color("█".repeat(filled)) + chalk.hex("#2C2C2E")("░".repeat(barWidth - filled));
535
+ const val = colorVal(e.raw.padStart(maxRaw));
536
+ out.push(` ${label} ${bar} ${val}`);
537
+ }
538
+ }
539
+ return "\n" + out.join("\n") + "\n";
493
540
  }
541
+
542
+ // ============================================================================
543
+ // Table renderer — polished TUI tables with theme-aware styling
544
+ // ============================================================================
545
+
546
+ // Row tone detection for background tinting
547
+
494
548
  function getRowTone(cells) {
495
- for (const cell of cells) {
496
- const t = cell.trim();
497
- if (/^-\$[\d,]+/.test(t) || /^-\d+\.?\d*%/.test(t))
498
- return "negative";
499
- if (/^\+\d/.test(t) || /^\+\$/.test(t))
500
- return "positive";
501
- if (/^`?[✕✗]/.test(t) || /cancelled|failed|rejected|error|out of stock|low stock/i.test(t))
502
- return "negative";
503
- if (/^`?[✓●]/.test(t) || /completed|received|approved|active|success|paid|published/i.test(t))
504
- return "positive";
505
- }
506
- return "neutral";
549
+ for (const cell of cells) {
550
+ const t = cell.trim();
551
+ if (/^-\$[\d,]+/.test(t) || /^-\d+\.?\d*%/.test(t)) return "negative";
552
+ if (/^\+\d/.test(t) || /^\+\$/.test(t)) return "positive";
553
+ if (/^`?[✕✗]/.test(t) || /cancelled|failed|rejected|error|out of stock|low stock/i.test(t)) return "negative";
554
+ if (/^`?[✓●]/.test(t) || /completed|received|approved|active|success|paid|published/i.test(t)) return "positive";
555
+ }
556
+ return "neutral";
507
557
  }
558
+
508
559
  /** Detect if a column is numeric (for right-alignment) */
509
560
  function isNumericColumn(rows, colIndex) {
510
- let numericCount = 0;
511
- let total = 0;
512
- for (const row of rows) {
513
- const val = (row[colIndex] || "").trim();
514
- if (!val)
515
- continue;
516
- total++;
517
- if (/^[+\-]?\$?[\d,]+\.?\d*%?$/.test(val))
518
- numericCount++;
519
- }
520
- return total > 0 && numericCount / total > 0.5;
561
+ let numericCount = 0;
562
+ let total = 0;
563
+ for (const row of rows) {
564
+ const val = (row[colIndex] || "").trim();
565
+ if (!val) continue;
566
+ total++;
567
+ if (/^[+\-]?\$?[\d,]+\.?\d*%?$/.test(val)) numericCount++;
568
+ }
569
+ return total > 0 && numericCount / total > 0.5;
521
570
  }
571
+
522
572
  /** Blend two hex colors by ratio (0 = colorA, 1 = colorB) */
523
573
  function blendHex(a, b, ratio) {
524
- const parse = (h) => {
525
- const c = h.replace("#", "");
526
- return [parseInt(c.slice(0, 2), 16), parseInt(c.slice(2, 4), 16), parseInt(c.slice(4, 6), 16)];
527
- };
528
- const [ar, ag, ab] = parse(a);
529
- const [br, bg, bb] = parse(b);
530
- const r = Math.round(ar + (br - ar) * ratio);
531
- const g = Math.round(ag + (bg - ag) * ratio);
532
- const bv = Math.round(ab + (bb - ab) * ratio);
533
- return `#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${bv.toString(16).padStart(2, "0")}`;
574
+ const parse = h => {
575
+ const c = h.replace("#", "");
576
+ return [parseInt(c.slice(0, 2), 16), parseInt(c.slice(2, 4), 16), parseInt(c.slice(4, 6), 16)];
577
+ };
578
+ const [ar, ag, ab] = parse(a);
579
+ const [br, bg, bb] = parse(b);
580
+ const r = Math.round(ar + (br - ar) * ratio);
581
+ const g = Math.round(ag + (bg - ag) * ratio);
582
+ const bv = Math.round(ab + (bb - ab) * ratio);
583
+ return `#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${bv.toString(16).padStart(2, "0")}`;
534
584
  }
535
585
  function colorizeCell(val, isHeader) {
536
- const trimmed = val.trim();
537
- if (!trimmed)
538
- return p.text("");
539
- if (isHeader)
540
- return p.systemBlue.bold(trimmed);
541
- // Badge format: `✓ status` or `◆ status` or `○ status` or `✕ status`
542
- const badgeMatch = trimmed.match(/^`([✓●◆○✕◦])\s+(.+)`$/);
543
- if (badgeMatch) {
544
- const [, icon, label] = badgeMatch;
545
- if (icon === "" || icon === "●")
546
- return p.systemGreen(`${icon} ${label}`);
547
- if (icon === "")
548
- return p.systemCyan(`${icon} ${label}`);
549
- if (icon === "○")
550
- return p.systemOrange(`${icon} ${label}`);
551
- if (icon === "✕")
552
- return p.systemRed(`${icon} ${label}`);
553
- return p.secondary(`${icon} ${label}`);
554
- }
555
- // Inline code (UUID, SKU, transfer number)
556
- if (trimmed.startsWith("`") && trimmed.endsWith("`")) {
557
- return p.systemPurple(trimmed.slice(1, -1));
558
- }
559
- // Bold text
560
- if (trimmed.startsWith("**") && trimmed.endsWith("**")) {
561
- return p.text.bold(trimmed.slice(2, -2));
562
- }
563
- // Negative values → red
564
- if (/^-\$?[\d,]+\.?\d*$/.test(trimmed) || /^-\d+\.?\d*%$/.test(trimmed)) {
565
- return p.systemRed(trimmed);
566
- }
567
- // Positive financial → green
568
- if (/^\+?\$[\d,]+\.?\d*$/.test(trimmed) || /^\$[\d,]+\.?\d*$/.test(trimmed)) {
569
- return p.systemGreen(trimmed);
570
- }
571
- // Percentages → cyan
572
- if (/^\d+\.?\d*%$/.test(trimmed)) {
573
- return p.systemCyan(trimmed);
574
- }
575
- // Plain numbers → mint
576
- if (/^[\d,]+\.?\d*$/.test(trimmed)) {
577
- return p.systemMint(trimmed);
578
- }
579
- // Status words
580
- if (/^(active|success|complete|approved|in stock|available)/i.test(trimmed)) {
581
- return p.systemGreen(trimmed);
582
- }
583
- if (/^(inactive|error|failed|cancelled|out of stock|low|overdue|expired)/i.test(trimmed)) {
584
- return p.systemRed(trimmed);
585
- }
586
- if (/^(pending|draft|processing)/i.test(trimmed)) {
587
- return p.systemOrange(trimmed);
588
- }
589
- return p.text(trimmed);
586
+ const trimmed = val.trim();
587
+ if (!trimmed) return p.text("");
588
+ if (isHeader) return p.systemBlue.bold(trimmed);
589
+
590
+ // Badge format: `✓ status` or `◆ status` or `○ status` or `✕ status`
591
+ const badgeMatch = trimmed.match(/^`([✓●◆○✕◦])\s+(.+)`$/);
592
+ if (badgeMatch) {
593
+ const [, icon, label] = badgeMatch;
594
+ if (icon === "✓" || icon === "●") return p.systemGreen(`${icon} ${label}`);
595
+ if (icon === "") return p.systemCyan(`${icon} ${label}`);
596
+ if (icon === "○") return p.systemOrange(`${icon} ${label}`);
597
+ if (icon === "") return p.systemRed(`${icon} ${label}`);
598
+ return p.secondary(`${icon} ${label}`);
599
+ }
600
+
601
+ // Inline code (UUID, SKU, transfer number)
602
+ if (trimmed.startsWith("`") && trimmed.endsWith("`")) {
603
+ return p.systemPurple(trimmed.slice(1, -1));
604
+ }
605
+
606
+ // Bold text
607
+ if (trimmed.startsWith("**") && trimmed.endsWith("**")) {
608
+ return p.text.bold(trimmed.slice(2, -2));
609
+ }
610
+
611
+ // Negative values → red
612
+ if (/^-\$?[\d,]+\.?\d*$/.test(trimmed) || /^-\d+\.?\d*%$/.test(trimmed)) {
613
+ return p.systemRed(trimmed);
614
+ }
615
+ // Positive financial → green
616
+ if (/^\+?\$[\d,]+\.?\d*$/.test(trimmed) || /^\$[\d,]+\.?\d*$/.test(trimmed)) {
617
+ return p.systemGreen(trimmed);
618
+ }
619
+ // Percentages → cyan
620
+ if (/^\d+\.?\d*%$/.test(trimmed)) {
621
+ return p.systemCyan(trimmed);
622
+ }
623
+ // Plain numbers → mint
624
+ if (/^[\d,]+\.?\d*$/.test(trimmed)) {
625
+ return p.systemMint(trimmed);
626
+ }
627
+ // Status words
628
+ if (/^(active|success|complete|approved|in stock|available)/i.test(trimmed)) {
629
+ return p.systemGreen(trimmed);
630
+ }
631
+ if (/^(inactive|error|failed|cancelled|out of stock|low|overdue|expired)/i.test(trimmed)) {
632
+ return p.systemRed(trimmed);
633
+ }
634
+ if (/^(pending|draft|processing)/i.test(trimmed)) {
635
+ return p.systemOrange(trimmed);
636
+ }
637
+ return p.text(trimmed);
590
638
  }
591
639
  function renderTable(token) {
592
- function getCellText(cell) {
593
- if (!cell)
594
- return "";
595
- if (typeof cell === "string")
596
- return cell;
597
- if (cell.text !== undefined)
598
- return String(cell.text);
599
- if (cell.tokens) {
600
- return cell.tokens.map((t) => t.raw || t.text || "").join("");
601
- }
602
- return String(cell);
603
- }
604
- const headers = (token.header || []).map((h) => getCellText(h));
605
- const rows = (token.rows || []).map((row) => row.map((cell) => getCellText(cell)));
606
- if (headers.length === 0)
607
- return "";
608
- const cw = contentWidth();
609
- const N = headers.length;
610
- // ── Check if box table can fit ──
611
- // Minimum box table width: indent(2) + borders(N+1) + N * (minCol + 2 padding)
612
- const MIN_COL = 3;
613
- const minBoxWidth = 2 + (N + 1) + N * (MIN_COL + 2);
614
- if (minBoxWidth > cw) {
615
- // ── Card layout — graceful fallback for narrow terminals ──
616
- return renderTableCards(headers, rows, cw);
617
- }
618
- // ── Box table layout ──
619
- const overhead = 2 + 1 + (N - 1) + 1 + (N * 2);
620
- const availableForContent = cw - overhead;
621
- const minCol = cw < 70 ? MIN_COL : cw < 90 ? 5 : 6;
622
- const maxPerCol = Math.max(minCol, Math.floor(availableForContent / N));
623
- // Detect numeric columns for right-alignment
624
- const numericCols = headers.map((_, i) => isNumericColumn(rows, i));
625
- // Size columns: fit content up to maxPerCol, respect minCol
626
- const colWidths = headers.map((h, i) => {
627
- const dataMax = rows.reduce((max, row) => Math.max(max, (row[i] || "").length), 0);
628
- return Math.min(maxPerCol, Math.max(minCol, h.length, dataMax) + 2);
629
- });
630
- // Double-check total width won't overflow (defensive)
631
- const totalWidth = 2 + 1 + colWidths.reduce((s, w) => s + w + 2, 0) + (N - 1) + 1;
632
- if (totalWidth > cw) {
633
- // Shrink largest columns until we fit
634
- let excess = totalWidth - cw;
635
- while (excess > 0) {
636
- const maxIdx = colWidths.indexOf(Math.max(...colWidths));
637
- if (colWidths[maxIdx] <= MIN_COL)
638
- break; // can't shrink further
639
- colWidths[maxIdx]--;
640
- excess--;
641
- }
642
- }
643
- // ── Colors ──
644
- const borderColor = blendHex(colors.separator, colors.brand, 0.25);
645
- const border = chalk.hex(borderColor);
646
- const headerBg = chalk.bgHex(blendHex(colors.panel, colors.brand, 0.15));
647
- const evenRowBg = chalk.bgHex(blendHex(colors.panel, colors.text, 0.04));
648
- const oddRowBg = chalk.bgHex(colors.panel);
649
- const positiveBg = chalk.bgHex(blendHex(colors.panel, colors.success, 0.12));
650
- const negativeBg = chalk.bgHex(blendHex(colors.panel, colors.error, 0.12));
651
- const out = [];
652
- // Top border
653
- out.push(border(" ╭" + colWidths.map((w) => "─".repeat(w + 2)).join("┬") + "╮"));
654
- // Header row
655
- const hdrCells = headers.map((h, i) => {
656
- const display = h.length > colWidths[i] ? h.slice(0, colWidths[i] - 1) + "…" : h;
657
- const padded = numericCols[i] ? display.padStart(colWidths[i]) : display.padEnd(colWidths[i]);
658
- return headerBg(" " + chalk.hex(colors.brand).bold(padded) + " ");
640
+ function getCellText(cell) {
641
+ if (!cell) return "";
642
+ if (typeof cell === "string") return cell;
643
+ if (cell.text !== undefined) return String(cell.text);
644
+ if (cell.tokens) {
645
+ return cell.tokens.map(t => t.raw || t.text || "").join("");
646
+ }
647
+ return String(cell);
648
+ }
649
+ const headers = (token.header || []).map(h => getCellText(h));
650
+ const rows = (token.rows || []).map(row => row.map(cell => getCellText(cell)));
651
+ if (headers.length === 0) return "";
652
+ const cw = contentWidth();
653
+ const N = headers.length;
654
+
655
+ // ── Check if box table can fit ──
656
+ // Minimum box table width: indent(2) + borders(N+1) + N * (minCol + 2 padding)
657
+ const MIN_COL = 3;
658
+ const minBoxWidth = 2 + (N + 1) + N * (MIN_COL + 2);
659
+ if (minBoxWidth > cw) {
660
+ // ── Card layout — graceful fallback for narrow terminals ──
661
+ return renderTableCards(headers, rows, cw);
662
+ }
663
+
664
+ // ── Box table layout ──
665
+ const overhead = 2 + 1 + (N - 1) + 1 + N * 2;
666
+ const availableForContent = cw - overhead;
667
+ const minCol = cw < 70 ? MIN_COL : cw < 90 ? 5 : 6;
668
+ const maxPerCol = Math.max(minCol, Math.floor(availableForContent / N));
669
+
670
+ // Detect numeric columns for right-alignment
671
+ const numericCols = headers.map((_, i) => isNumericColumn(rows, i));
672
+
673
+ // Size columns: fit content up to maxPerCol, respect minCol
674
+ const colWidths = headers.map((h, i) => {
675
+ const dataMax = rows.reduce((max, row) => Math.max(max, (row[i] || "").length), 0);
676
+ return Math.min(maxPerCol, Math.max(minCol, h.length, dataMax) + 2);
677
+ });
678
+
679
+ // Double-check total width won't overflow (defensive)
680
+ const totalWidth = 2 + 1 + colWidths.reduce((s, w) => s + w + 2, 0) + (N - 1) + 1;
681
+ if (totalWidth > cw) {
682
+ // Shrink largest columns until we fit
683
+ let excess = totalWidth - cw;
684
+ while (excess > 0) {
685
+ const maxIdx = colWidths.indexOf(Math.max(...colWidths));
686
+ if (colWidths[maxIdx] <= MIN_COL) break; // can't shrink further
687
+ colWidths[maxIdx]--;
688
+ excess--;
689
+ }
690
+ }
691
+
692
+ // ── Colors ──
693
+ const borderColor = blendHex(colors.separator, colors.brand, 0.25);
694
+ const border = chalk.hex(borderColor);
695
+ const headerBg = chalk.bgHex(blendHex(colors.panel, colors.brand, 0.15));
696
+ const evenRowBg = chalk.bgHex(blendHex(colors.panel, colors.text, 0.04));
697
+ const oddRowBg = chalk.bgHex(colors.panel);
698
+ const positiveBg = chalk.bgHex(blendHex(colors.panel, colors.success, 0.12));
699
+ const negativeBg = chalk.bgHex(blendHex(colors.panel, colors.error, 0.12));
700
+ const out = [];
701
+
702
+ // Top border
703
+ out.push(border(" ╭" + colWidths.map(w => "─".repeat(w + 2)).join("┬") + "╮"));
704
+
705
+ // Header row
706
+ const hdrCells = headers.map((h, i) => {
707
+ const display = h.length > colWidths[i] ? h.slice(0, colWidths[i] - 1) + "…" : h;
708
+ const padded = numericCols[i] ? display.padStart(colWidths[i]) : display.padEnd(colWidths[i]);
709
+ return headerBg(" " + chalk.hex(colors.brand).bold(padded) + " ");
710
+ }).join(border("│"));
711
+ out.push(border(" │") + hdrCells + border("│"));
712
+
713
+ // Header divider
714
+ out.push(border(" ├" + colWidths.map(w => "━".repeat(w + 2)).join("┿") + "┤"));
715
+
716
+ // Data rows
717
+ for (let rowIdx = 0; rowIdx < rows.length; rowIdx++) {
718
+ const row = rows[rowIdx];
719
+ const tone = getRowTone(row);
720
+ const rowBg = tone === "positive" ? positiveBg : tone === "negative" ? negativeBg : rowIdx % 2 === 0 ? evenRowBg : oddRowBg;
721
+ const cells = headers.map((_, i) => {
722
+ const raw = row[i] || "";
723
+ const display = raw.length > colWidths[i] ? raw.slice(0, colWidths[i] - 1) + "…" : raw;
724
+ const colored = colorizeCell(display, false);
725
+ const extraPad = Math.max(0, colWidths[i] - display.length);
726
+ if (numericCols[i]) {
727
+ return rowBg(" ".repeat(extraPad) + " " + colored + " ");
728
+ }
729
+ return rowBg(" " + colored + " ".repeat(extraPad) + " ");
659
730
  }).join(border("│"));
660
- out.push(border(" │") + hdrCells + border("│"));
661
- // Header divider
662
- out.push(border(" ├" + colWidths.map((w) => "━".repeat(w + 2)).join("┿") + "┤"));
663
- // Data rows
664
- for (let rowIdx = 0; rowIdx < rows.length; rowIdx++) {
665
- const row = rows[rowIdx];
666
- const tone = getRowTone(row);
667
- const rowBg = tone === "positive" ? positiveBg
668
- : tone === "negative" ? negativeBg
669
- : rowIdx % 2 === 0 ? evenRowBg : oddRowBg;
670
- const cells = headers.map((_, i) => {
671
- const raw = row[i] || "";
672
- const display = raw.length > colWidths[i] ? raw.slice(0, colWidths[i] - 1) + "…" : raw;
673
- const colored = colorizeCell(display, false);
674
- const extraPad = Math.max(0, colWidths[i] - display.length);
675
- if (numericCols[i]) {
676
- return rowBg(" ".repeat(extraPad) + " " + colored + " ");
677
- }
678
- return rowBg(" " + colored + " ".repeat(extraPad) + " ");
679
- }).join(border("│"));
680
- out.push(border(" │") + cells + border("│"));
681
- }
682
- // Bottom border
683
- out.push(border(" ╰" + colWidths.map((w) => "─".repeat(w + 2)).join("┴") + "╯"));
684
- return "\n" + out.join("\n") + "\n";
731
+ out.push(border(" │") + cells + border("│"));
732
+ }
733
+
734
+ // Bottom border
735
+ out.push(border(" ╰" + colWidths.map(w => "─".repeat(w + 2)).join("┴") + "╯"));
736
+ return "\n" + out.join("\n") + "\n";
685
737
  }
738
+
686
739
  /** Card layout fallback — renders each row as a key: value block. Never overflows. */
687
740
  function renderTableCards(headers, rows, cw) {
688
- const border = chalk.hex(blendHex(colors.separator, colors.brand, 0.25));
689
- const out = [];
690
- const innerW = Math.max(8, cw - 6); // indent(2) + border(2) + padding(2)
691
- const divider = border(" " + "─".repeat(innerW + 2));
692
- // Find longest header for label alignment
693
- const maxHdrLen = Math.min(Math.max(...headers.map(h => h.length)), Math.floor(innerW * 0.4));
694
- out.push(divider);
695
- for (let rowIdx = 0; rowIdx < rows.length; rowIdx++) {
696
- const row = rows[rowIdx];
697
- if (rowIdx > 0)
698
- out.push(divider);
699
- for (let i = 0; i < headers.length; i++) {
700
- const hdr = headers[i].length > maxHdrLen
701
- ? headers[i].slice(0, maxHdrLen - 1) + ""
702
- : headers[i];
703
- const val = row[i] || "";
704
- const maxValLen = innerW - maxHdrLen - 3; // " label value"
705
- const displayVal = val.length > maxValLen
706
- ? val.slice(0, maxValLen - 1) + "…"
707
- : val;
708
- const labelStr = p.tertiary(hdr.padEnd(maxHdrLen));
709
- const valStr = colorizeCell(displayVal, false);
710
- out.push(` ${labelStr} ${valStr}`);
711
- }
712
- }
713
- out.push(divider);
714
- return "\n" + out.join("\n") + "\n";
741
+ const border = chalk.hex(blendHex(colors.separator, colors.brand, 0.25));
742
+ const out = [];
743
+ const innerW = Math.max(8, cw - 6); // indent(2) + border(2) + padding(2)
744
+ const divider = border(" " + "─".repeat(innerW + 2));
745
+
746
+ // Find longest header for label alignment
747
+ const maxHdrLen = Math.min(Math.max(...headers.map(h => h.length)), Math.floor(innerW * 0.4));
748
+ out.push(divider);
749
+ for (let rowIdx = 0; rowIdx < rows.length; rowIdx++) {
750
+ const row = rows[rowIdx];
751
+ if (rowIdx > 0) out.push(divider);
752
+ for (let i = 0; i < headers.length; i++) {
753
+ const hdr = headers[i].length > maxHdrLen ? headers[i].slice(0, maxHdrLen - 1) + "…" : headers[i];
754
+ const val = row[i] || "";
755
+ const maxValLen = innerW - maxHdrLen - 3; // " label value"
756
+ const displayVal = val.length > maxValLen ? val.slice(0, maxValLen - 1) + "" : val;
757
+ const labelStr = p.tertiary(hdr.padEnd(maxHdrLen));
758
+ const valStr = colorizeCell(displayVal, false);
759
+ out.push(` ${labelStr} ${valStr}`);
760
+ }
761
+ }
762
+ out.push(divider);
763
+ return "\n" + out.join("\n") + "\n";
715
764
  }
765
+
716
766
  // ============================================================================
717
767
  // Rebuild — called on theme switch to refresh all chalk instances
718
768
  // ============================================================================
769
+
719
770
  export function rebuildMarkdownRenderer() {
720
- p = buildPalette();
721
- d = buildDiffStyles();
722
- barGradient = buildBarGradient();
723
- md = buildMarkedInstance();
771
+ p = buildPalette();
772
+ d = buildDiffStyles();
773
+ barGradient = buildBarGradient();
774
+ md = buildMarkedInstance();
724
775
  }
776
+
725
777
  // Register rebuild callback with theme manager
726
778
  setRebuildCallback(rebuildMarkdownRenderer);
779
+
727
780
  // ============================================================================
728
781
  // Streaming fence closure — state-tracking approach
729
782
  // ============================================================================
783
+
730
784
  /** Extract text outside fenced code blocks */
731
785
  function getNonFencedText(input) {
732
- const lines = input.split("\n");
733
- const parts = [];
734
- let inFence = false;
735
- for (const line of lines) {
736
- if (line.trimStart().startsWith("```")) {
737
- inFence = !inFence;
738
- continue;
739
- }
740
- if (!inFence)
741
- parts.push(line);
742
- }
743
- return parts.join("\n");
786
+ const lines = input.split("\n");
787
+ const parts = [];
788
+ let inFence = false;
789
+ for (const line of lines) {
790
+ if (line.trimStart().startsWith("```")) {
791
+ inFence = !inFence;
792
+ continue;
793
+ }
794
+ if (!inFence) parts.push(line);
795
+ }
796
+ return parts.join("\n");
744
797
  }
798
+
745
799
  /** Strip complete inline code spans from text */
746
800
  function getNonCodeText(t) {
747
- return t.replace(/``[^`]*``/g, "").replace(/`[^`\n]*`/g, "");
801
+ return t.replace(/``[^`]*``/g, "").replace(/`[^`\n]*`/g, "");
748
802
  }
803
+
749
804
  /**
750
805
  * Close incomplete markdown fences for safe streaming rendering.
751
806
  * State-tracking approach: handles nested fences, escaped markers, double-backtick spans.
752
807
  */
753
808
  export function closeIncompleteFences(input) {
754
- let result = input;
755
- // 1. Code fences — walk lines, track open/close state
756
- let inFence = false;
757
- for (const line of result.split("\n")) {
758
- const trimmed = line.trimStart();
759
- if (trimmed.startsWith("```")) {
760
- inFence = !inFence;
761
- }
762
- }
763
- if (inFence) {
764
- result += "\n```";
765
- }
766
- // 2. For inline markers, only examine text OUTSIDE fenced code blocks
767
- const outside = getNonFencedText(result);
768
- // 3. Inline backticks remove escaped, remove complete spans, count remainder
769
- let forBacktick = outside.replace(/\\`/g, "");
770
- forBacktick = forBacktick.replace(/``[^`]*``/g, ""); // double-backtick spans
771
- forBacktick = forBacktick.replace(/`[^`\n]*`/g, ""); // single-backtick spans
772
- const unmatched = (forBacktick.match(/`/g) || []).length;
773
- if (unmatched % 2 !== 0) {
774
- result += "`";
775
- }
776
- // 4. Bold count ** in non-code text
777
- const forBold = getNonCodeText(outside);
778
- const boldCount = (forBold.match(/\*\*/g) || []).length;
779
- if (boldCount % 2 !== 0) {
780
- result += "**";
781
- }
782
- // 5. Italic — count standalone * (not part of **) with escape awareness
783
- const forItalic = forBold.replace(/\*\*/g, "");
784
- const italicCount = (forItalic.match(/(?<!\\)\*/g) || []).length;
785
- if (italicCount % 2 !== 0) {
786
- result += "*";
787
- }
788
- return result;
809
+ let result = input;
810
+
811
+ // 1. Code fences — walk lines, track open/close state
812
+ let inFence = false;
813
+ for (const line of result.split("\n")) {
814
+ const trimmed = line.trimStart();
815
+ if (trimmed.startsWith("```")) {
816
+ inFence = !inFence;
817
+ }
818
+ }
819
+ if (inFence) {
820
+ result += "\n```";
821
+ }
822
+
823
+ // 2. For inline markers, only examine text OUTSIDE fenced code blocks
824
+ const outside = getNonFencedText(result);
825
+
826
+ // 3. Inline backticks — remove escaped, remove complete spans, count remainder
827
+ let forBacktick = outside.replace(/\\`/g, "");
828
+ forBacktick = forBacktick.replace(/``[^`]*``/g, ""); // double-backtick spans
829
+ forBacktick = forBacktick.replace(/`[^`\n]*`/g, ""); // single-backtick spans
830
+ const unmatched = (forBacktick.match(/`/g) || []).length;
831
+ if (unmatched % 2 !== 0) {
832
+ result += "`";
833
+ }
834
+
835
+ // 4. Bold — count ** in non-code text
836
+ const forBold = getNonCodeText(outside);
837
+ const boldCount = (forBold.match(/\*\*/g) || []).length;
838
+ if (boldCount % 2 !== 0) {
839
+ result += "**";
840
+ }
841
+
842
+ // 5. Italic — count standalone * (not part of **) with escape awareness
843
+ const forItalic = forBold.replace(/\*\*/g, "");
844
+ const italicCount = (forItalic.match(/(?<!\\)\*/g) || []).length;
845
+ if (italicCount % 2 !== 0) {
846
+ result += "*";
847
+ }
848
+ return result;
789
849
  }
850
+
790
851
  /**
791
852
  * Render markdown to ANSI-styled terminal string.
792
853
  * Optionally applies streaming-safe fence closing.
793
854
  */
794
855
  export function renderMarkdown(input, streaming = false) {
795
- const safe = streaming ? closeIncompleteFences(input) : input;
796
- const result = md.parse(safe);
797
- return result.replace(/\n+$/, "");
856
+ const safe = streaming ? closeIncompleteFences(input) : input;
857
+ const result = md.parse(safe);
858
+ return result.replace(/\n+$/, "");
798
859
  }
860
+ //# sourceMappingURL=markdown.js.map