@bubblebrain-ai/bubble 0.0.63 → 0.0.65

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 (912) hide show
  1. package/README.md +437 -11
  2. package/dist/agent/abort-errors.d.ts +18 -0
  3. package/dist/agent/abort-errors.js +51 -0
  4. package/dist/agent/budget-ledger.d.ts +20 -0
  5. package/dist/agent/budget-ledger.js +45 -0
  6. package/dist/agent/categories.d.ts +100 -0
  7. package/dist/agent/categories.js +203 -0
  8. package/dist/agent/change-tracker.d.ts +40 -0
  9. package/dist/agent/change-tracker.js +89 -0
  10. package/dist/agent/child-runner.d.ts +64 -0
  11. package/dist/agent/child-runner.js +405 -0
  12. package/dist/agent/input-controller.d.ts +14 -0
  13. package/dist/agent/input-controller.js +43 -0
  14. package/dist/agent/internal-reminder-sanitizer.d.ts +25 -0
  15. package/dist/agent/internal-reminder-sanitizer.js +297 -0
  16. package/dist/agent/profiles.d.ts +76 -0
  17. package/dist/agent/profiles.js +526 -0
  18. package/dist/agent/provider-fingerprint.d.ts +6 -0
  19. package/dist/agent/provider-fingerprint.js +89 -0
  20. package/dist/agent/resident-history.d.ts +7 -0
  21. package/dist/agent/resident-history.js +61 -0
  22. package/dist/agent/result-integrator.d.ts +22 -0
  23. package/dist/agent/result-integrator.js +50 -0
  24. package/dist/agent/routing-catalog.d.ts +131 -0
  25. package/dist/agent/routing-catalog.js +260 -0
  26. package/dist/agent/structured-output.d.ts +37 -0
  27. package/dist/agent/structured-output.js +193 -0
  28. package/dist/agent/subagent/router.d.ts +65 -0
  29. package/dist/agent/subagent/router.js +203 -0
  30. package/dist/agent/subagent/runtime.d.ts +235 -0
  31. package/dist/agent/subagent/runtime.js +835 -0
  32. package/dist/agent/subagent-control.d.ts +100 -0
  33. package/dist/agent/subagent-control.js +70 -0
  34. package/dist/agent/subagent-lifecycle-reminder.d.ts +3 -0
  35. package/dist/agent/subagent-lifecycle-reminder.js +112 -0
  36. package/dist/agent/subagent-route-format.d.ts +8 -0
  37. package/dist/agent/subagent-route-format.js +18 -0
  38. package/dist/agent/subagent-scheduler.d.ts +105 -0
  39. package/dist/agent/subagent-scheduler.js +287 -0
  40. package/dist/agent/subagent-store.d.ts +57 -0
  41. package/dist/agent/subagent-store.js +180 -0
  42. package/dist/agent/subagent-summary.d.ts +30 -0
  43. package/dist/agent/subagent-summary.js +74 -0
  44. package/dist/agent/subagent-wait-guidance.d.ts +2 -0
  45. package/dist/agent/subagent-wait-guidance.js +8 -0
  46. package/dist/agent/subtask-policy.d.ts +13 -0
  47. package/dist/agent/subtask-policy.js +56 -0
  48. package/dist/agent/task-lifecycle-reminder.d.ts +26 -0
  49. package/dist/agent/task-lifecycle-reminder.js +59 -0
  50. package/dist/agent/tool-intent.d.ts +45 -0
  51. package/dist/agent/tool-intent.js +318 -0
  52. package/dist/agent/tool-visibility.d.ts +10 -0
  53. package/dist/agent/tool-visibility.js +6 -0
  54. package/dist/agent/transcript-helpers.d.ts +20 -0
  55. package/dist/agent/transcript-helpers.js +63 -0
  56. package/dist/agent/update-queue.d.ts +13 -0
  57. package/dist/agent/update-queue.js +69 -0
  58. package/dist/agent/workflow/control.d.ts +60 -0
  59. package/dist/agent/workflow/control.js +62 -0
  60. package/dist/agent/workflow/errors.d.ts +16 -0
  61. package/dist/agent/workflow/errors.js +24 -0
  62. package/dist/agent/workflow/runs.d.ts +73 -0
  63. package/dist/agent/workflow/runs.js +160 -0
  64. package/dist/agent/workflow/runtime.d.ts +88 -0
  65. package/dist/agent/workflow/runtime.js +319 -0
  66. package/dist/agent/worktree.d.ts +29 -0
  67. package/dist/agent/worktree.js +73 -0
  68. package/dist/agent.d.ts +460 -0
  69. package/dist/agent.js +2210 -0
  70. package/dist/anthropic-thinking.d.ts +4 -0
  71. package/dist/anthropic-thinking.js +11 -0
  72. package/dist/approval/controller.d.ts +71 -0
  73. package/dist/approval/controller.js +286 -0
  74. package/dist/approval/danger.d.ts +13 -0
  75. package/dist/approval/danger.js +55 -0
  76. package/dist/approval/diff-hunks.d.ts +12 -0
  77. package/dist/approval/diff-hunks.js +32 -0
  78. package/dist/approval/protected-paths.d.ts +1 -0
  79. package/dist/approval/protected-paths.js +35 -0
  80. package/dist/approval/session-cache.d.ts +21 -0
  81. package/dist/approval/session-cache.js +38 -0
  82. package/dist/approval/tool-helper.d.ts +14 -0
  83. package/dist/approval/tool-helper.js +47 -0
  84. package/dist/approval/types.d.ts +146 -0
  85. package/dist/approval/types.js +8 -0
  86. package/dist/bin.d.ts +2 -0
  87. package/dist/bin.js +3 -0
  88. package/dist/bubble-home.d.ts +8 -0
  89. package/dist/bubble-home.js +19 -0
  90. package/dist/checkpoints.d.ts +57 -0
  91. package/dist/checkpoints.js +0 -0
  92. package/dist/cli.d.ts +37 -0
  93. package/dist/cli.js +175 -0
  94. package/dist/clipboard.d.ts +14 -0
  95. package/dist/clipboard.js +132 -0
  96. package/dist/config.d.ts +96 -0
  97. package/dist/config.js +287 -0
  98. package/dist/context/budget.d.ts +28 -0
  99. package/dist/context/budget.js +130 -0
  100. package/dist/context/checkpoint.d.ts +18 -0
  101. package/dist/context/checkpoint.js +117 -0
  102. package/dist/context/compact-llm.d.ts +25 -0
  103. package/dist/context/compact-llm.js +175 -0
  104. package/dist/context/compact.d.ts +124 -0
  105. package/dist/context/compact.js +635 -0
  106. package/dist/context/compaction-files.d.ts +44 -0
  107. package/dist/context/compaction-files.js +148 -0
  108. package/dist/context/llm-compactor.d.ts +53 -0
  109. package/dist/context/llm-compactor.js +424 -0
  110. package/dist/context/overflow.d.ts +9 -0
  111. package/dist/context/overflow.js +50 -0
  112. package/dist/context/projector.d.ts +34 -0
  113. package/dist/context/projector.js +251 -0
  114. package/dist/context/prune.d.ts +26 -0
  115. package/dist/context/prune.js +171 -0
  116. package/dist/context/session-write-lock.d.ts +20 -0
  117. package/dist/context/session-write-lock.js +162 -0
  118. package/dist/context/token-estimator.d.ts +14 -0
  119. package/dist/context/token-estimator.js +106 -0
  120. package/dist/context/tool-images.d.ts +3 -0
  121. package/dist/context/tool-images.js +35 -0
  122. package/dist/context/tool-output-truncate.d.ts +24 -0
  123. package/dist/context/tool-output-truncate.js +181 -0
  124. package/dist/context/usage.d.ts +34 -0
  125. package/dist/context/usage.js +230 -0
  126. package/dist/debug-trace.d.ts +27 -0
  127. package/dist/debug-trace.js +401 -0
  128. package/dist/diff-stats.d.ts +5 -0
  129. package/dist/diff-stats.js +21 -0
  130. package/dist/external-runtime/grok-acp.d.ts +56 -0
  131. package/dist/external-runtime/grok-acp.js +386 -0
  132. package/dist/external-runtime/grok-binary.d.ts +25 -0
  133. package/dist/external-runtime/grok-binary.js +108 -0
  134. package/dist/external-runtime/grok-errors.d.ts +7 -0
  135. package/dist/external-runtime/grok-errors.js +15 -0
  136. package/dist/external-runtime/grok-input-policy.d.ts +58 -0
  137. package/dist/external-runtime/grok-input-policy.js +52 -0
  138. package/dist/external-runtime/grok-ndjson.d.ts +14 -0
  139. package/dist/external-runtime/grok-ndjson.js +193 -0
  140. package/dist/external-runtime/grok-network.d.ts +15 -0
  141. package/dist/external-runtime/grok-network.js +81 -0
  142. package/dist/external-runtime/grok-preflight.d.ts +28 -0
  143. package/dist/external-runtime/grok-preflight.js +194 -0
  144. package/dist/external-runtime/grok-process.d.ts +26 -0
  145. package/dist/external-runtime/grok-process.js +184 -0
  146. package/dist/external-runtime/grok-profile.d.ts +32 -0
  147. package/dist/external-runtime/grok-profile.js +419 -0
  148. package/dist/external-runtime/grok-provider.d.ts +31 -0
  149. package/dist/external-runtime/grok-provider.js +41 -0
  150. package/dist/external-runtime/grok-runtime.d.ts +91 -0
  151. package/dist/external-runtime/grok-runtime.js +882 -0
  152. package/dist/external-runtime/index.d.ts +13 -0
  153. package/dist/external-runtime/index.js +13 -0
  154. package/dist/external-runtime/session-policy.d.ts +11 -0
  155. package/dist/external-runtime/session-policy.js +30 -0
  156. package/dist/external-runtime/types.d.ts +65 -0
  157. package/dist/external-runtime/types.js +1 -0
  158. package/dist/feedback/collect.d.ts +7 -0
  159. package/dist/feedback/collect.js +119 -0
  160. package/dist/feedback/config.d.ts +14 -0
  161. package/dist/feedback/config.js +16 -0
  162. package/dist/feedback/redact.d.ts +1 -0
  163. package/dist/feedback/redact.js +25 -0
  164. package/dist/feedback/submit.d.ts +6 -0
  165. package/dist/feedback/submit.js +43 -0
  166. package/dist/feedback/types.d.ts +22 -0
  167. package/dist/feedback/types.js +1 -0
  168. package/dist/feishu/agent-host/approval-card.d.ts +11 -0
  169. package/dist/feishu/agent-host/approval-card.js +85 -0
  170. package/dist/feishu/agent-host/approval-ui.d.ts +59 -0
  171. package/dist/feishu/agent-host/approval-ui.js +214 -0
  172. package/dist/feishu/agent-host/run-driver.d.ts +51 -0
  173. package/dist/feishu/agent-host/run-driver.js +397 -0
  174. package/dist/feishu/agent-host/runtime-deps.d.ts +33 -0
  175. package/dist/feishu/agent-host/runtime-deps.js +8 -0
  176. package/dist/feishu/card/budget.d.ts +40 -0
  177. package/dist/feishu/card/budget.js +134 -0
  178. package/dist/feishu/card/renderer.d.ts +29 -0
  179. package/dist/feishu/card/renderer.js +245 -0
  180. package/dist/feishu/card/run-state-types.d.ts +49 -0
  181. package/dist/feishu/card/run-state-types.js +15 -0
  182. package/dist/feishu/card/run-state.d.ts +21 -0
  183. package/dist/feishu/card/run-state.js +223 -0
  184. package/dist/feishu/channel/channel.d.ts +52 -0
  185. package/dist/feishu/channel/channel.js +74 -0
  186. package/dist/feishu/config.d.ts +24 -0
  187. package/dist/feishu/config.js +97 -0
  188. package/dist/feishu/format.d.ts +6 -0
  189. package/dist/feishu/format.js +14 -0
  190. package/dist/feishu/index.d.ts +4 -0
  191. package/dist/feishu/index.js +4 -0
  192. package/dist/feishu/logger.d.ts +31 -0
  193. package/dist/feishu/logger.js +62 -0
  194. package/dist/feishu/paths.d.ts +12 -0
  195. package/dist/feishu/paths.js +38 -0
  196. package/dist/feishu/process-registry.d.ts +29 -0
  197. package/dist/feishu/process-registry.js +90 -0
  198. package/dist/feishu/router/commands.d.ts +38 -0
  199. package/dist/feishu/router/commands.js +286 -0
  200. package/dist/feishu/router/event-router.d.ts +40 -0
  201. package/dist/feishu/router/event-router.js +208 -0
  202. package/dist/feishu/router/whitelist.d.ts +23 -0
  203. package/dist/feishu/router/whitelist.js +20 -0
  204. package/dist/feishu/runtime/active-runs.d.ts +32 -0
  205. package/dist/feishu/runtime/active-runs.js +84 -0
  206. package/dist/feishu/runtime/pending-queue.d.ts +36 -0
  207. package/dist/feishu/runtime/pending-queue.js +98 -0
  208. package/dist/feishu/runtime/process-pool.d.ts +29 -0
  209. package/dist/feishu/runtime/process-pool.js +49 -0
  210. package/dist/feishu/schema.d.ts +17 -0
  211. package/dist/feishu/schema.js +252 -0
  212. package/dist/feishu/scope/scope-registry.d.ts +39 -0
  213. package/dist/feishu/scope/scope-registry.js +148 -0
  214. package/dist/feishu/scope/session-binder.d.ts +44 -0
  215. package/dist/feishu/scope/session-binder.js +100 -0
  216. package/dist/feishu/scope/session-store.d.ts +24 -0
  217. package/dist/feishu/scope/session-store.js +73 -0
  218. package/dist/feishu/secrets.d.ts +37 -0
  219. package/dist/feishu/secrets.js +129 -0
  220. package/dist/feishu/serve.d.ts +12 -0
  221. package/dist/feishu/serve.js +302 -0
  222. package/dist/feishu/types.d.ts +75 -0
  223. package/dist/feishu/types.js +23 -0
  224. package/dist/feishu/wizard.d.ts +24 -0
  225. package/dist/feishu/wizard.js +121 -0
  226. package/dist/goal/command.d.ts +20 -0
  227. package/dist/goal/command.js +76 -0
  228. package/dist/goal/engine.d.ts +33 -0
  229. package/dist/goal/engine.js +65 -0
  230. package/dist/goal/format.d.ts +18 -0
  231. package/dist/goal/format.js +112 -0
  232. package/dist/goal/prompts.d.ts +13 -0
  233. package/dist/goal/prompts.js +84 -0
  234. package/dist/goal/store.d.ts +64 -0
  235. package/dist/goal/store.js +174 -0
  236. package/dist/goal/tools.d.ts +13 -0
  237. package/dist/goal/tools.js +67 -0
  238. package/dist/goal/usage.d.ts +2 -0
  239. package/dist/goal/usage.js +3 -0
  240. package/dist/hooks/config.d.ts +9 -0
  241. package/dist/hooks/config.js +278 -0
  242. package/dist/hooks/controller.d.ts +24 -0
  243. package/dist/hooks/controller.js +254 -0
  244. package/dist/hooks/index.d.ts +6 -0
  245. package/dist/hooks/index.js +4 -0
  246. package/dist/hooks/log.d.ts +14 -0
  247. package/dist/hooks/log.js +54 -0
  248. package/dist/hooks/runner.d.ts +5 -0
  249. package/dist/hooks/runner.js +225 -0
  250. package/dist/hooks/trust.d.ts +37 -0
  251. package/dist/hooks/trust.js +143 -0
  252. package/dist/hooks/types.d.ts +173 -0
  253. package/dist/hooks/types.js +46 -0
  254. package/dist/loop/engine.d.ts +29 -0
  255. package/dist/loop/engine.js +63 -0
  256. package/dist/lsp/config.d.ts +18 -0
  257. package/dist/lsp/config.js +58 -0
  258. package/dist/lsp/diagnostics.d.ts +24 -0
  259. package/dist/lsp/diagnostics.js +103 -0
  260. package/dist/lsp/index.d.ts +3 -0
  261. package/dist/lsp/index.js +3 -0
  262. package/dist/lsp/service.d.ts +97 -0
  263. package/dist/lsp/service.js +815 -0
  264. package/dist/main.d.ts +5 -0
  265. package/dist/main.js +984 -0
  266. package/dist/mcp/client.d.ts +68 -0
  267. package/dist/mcp/client.js +177 -0
  268. package/dist/mcp/config.d.ts +30 -0
  269. package/dist/mcp/config.js +144 -0
  270. package/dist/mcp/manager.d.ts +67 -0
  271. package/dist/mcp/manager.js +328 -0
  272. package/dist/mcp/name.d.ts +26 -0
  273. package/dist/mcp/name.js +40 -0
  274. package/dist/mcp/transports.d.ts +54 -0
  275. package/dist/mcp/transports.js +267 -0
  276. package/dist/mcp/types.d.ts +111 -0
  277. package/dist/mcp/types.js +14 -0
  278. package/dist/memory/db.d.ts +65 -0
  279. package/dist/memory/db.js +332 -0
  280. package/dist/memory/index.d.ts +10 -0
  281. package/dist/memory/index.js +10 -0
  282. package/dist/memory/paths.d.ts +18 -0
  283. package/dist/memory/paths.js +38 -0
  284. package/dist/memory/phase1.d.ts +23 -0
  285. package/dist/memory/phase1.js +292 -0
  286. package/dist/memory/phase2.d.ts +19 -0
  287. package/dist/memory/phase2.js +119 -0
  288. package/dist/memory/prompts.d.ts +19 -0
  289. package/dist/memory/prompts.js +104 -0
  290. package/dist/memory/reset.d.ts +1 -0
  291. package/dist/memory/reset.js +13 -0
  292. package/dist/memory/session-policy.d.ts +25 -0
  293. package/dist/memory/session-policy.js +55 -0
  294. package/dist/memory/start.d.ts +24 -0
  295. package/dist/memory/start.js +50 -0
  296. package/dist/memory/storage.d.ts +11 -0
  297. package/dist/memory/storage.js +95 -0
  298. package/dist/memory/store.d.ts +43 -0
  299. package/dist/memory/store.js +193 -0
  300. package/dist/memory/usage.d.ts +1 -0
  301. package/dist/memory/usage.js +38 -0
  302. package/dist/model-catalog.d.ts +65 -0
  303. package/dist/model-catalog.js +399 -0
  304. package/dist/model-config.d.ts +40 -0
  305. package/dist/model-config.js +74 -0
  306. package/dist/model-data.generated.d.ts +16 -0
  307. package/dist/model-data.generated.js +275 -0
  308. package/dist/model-pricing.d.ts +54 -0
  309. package/dist/model-pricing.js +256 -0
  310. package/dist/model-selection.d.ts +7 -0
  311. package/dist/model-selection.js +18 -0
  312. package/dist/network/chatgpt-transport.d.ts +16 -0
  313. package/dist/network/chatgpt-transport.js +232 -0
  314. package/dist/network/errors.d.ts +47 -0
  315. package/dist/network/errors.js +48 -0
  316. package/dist/network/provider-transport-log.d.ts +12 -0
  317. package/dist/network/provider-transport-log.js +32 -0
  318. package/dist/network/provider-transport.d.ts +37 -0
  319. package/dist/network/provider-transport.js +256 -0
  320. package/dist/network/retry.d.ts +34 -0
  321. package/dist/network/retry.js +97 -0
  322. package/dist/network/system-proxy.d.ts +18 -0
  323. package/dist/network/system-proxy.js +175 -0
  324. package/dist/oauth/grok.d.ts +26 -0
  325. package/dist/oauth/grok.js +251 -0
  326. package/dist/oauth/index.d.ts +4 -0
  327. package/dist/oauth/index.js +3 -0
  328. package/dist/oauth/openai-codex.d.ts +15 -0
  329. package/dist/oauth/openai-codex.js +193 -0
  330. package/dist/oauth/refresh-control.d.ts +12 -0
  331. package/dist/oauth/refresh-control.js +42 -0
  332. package/dist/oauth/storage.d.ts +88 -0
  333. package/dist/oauth/storage.js +357 -0
  334. package/dist/oauth/types.d.ts +15 -0
  335. package/dist/oauth/types.js +1 -0
  336. package/dist/orchestrator/default-hooks.d.ts +22 -0
  337. package/dist/orchestrator/default-hooks.js +127 -0
  338. package/dist/orchestrator/hooks.d.ts +69 -0
  339. package/dist/orchestrator/hooks.js +52 -0
  340. package/dist/permission/mode.d.ts +19 -0
  341. package/dist/permission/mode.js +16 -0
  342. package/dist/permissions/rule.d.ts +42 -0
  343. package/dist/permissions/rule.js +293 -0
  344. package/dist/permissions/settings.d.ts +97 -0
  345. package/dist/permissions/settings.js +289 -0
  346. package/dist/permissions/shell-command.d.ts +36 -0
  347. package/dist/permissions/shell-command.js +226 -0
  348. package/dist/permissions/trust-prompt.d.ts +10 -0
  349. package/dist/permissions/trust-prompt.js +34 -0
  350. package/dist/permissions/trust.d.ts +26 -0
  351. package/dist/permissions/trust.js +113 -0
  352. package/dist/permissions/types.d.ts +61 -0
  353. package/dist/permissions/types.js +14 -0
  354. package/dist/print-output.d.ts +98 -0
  355. package/dist/print-output.js +117 -0
  356. package/dist/prompt/compose.d.ts +19 -0
  357. package/dist/prompt/compose.js +110 -0
  358. package/dist/prompt/delegation.d.ts +14 -0
  359. package/dist/prompt/delegation.js +100 -0
  360. package/dist/prompt/environment.d.ts +12 -0
  361. package/dist/prompt/environment.js +55 -0
  362. package/dist/prompt/provider-prompts/anthropic.d.ts +1 -0
  363. package/dist/prompt/provider-prompts/anthropic.js +5 -0
  364. package/dist/prompt/provider-prompts/codex.d.ts +1 -0
  365. package/dist/prompt/provider-prompts/codex.js +5 -0
  366. package/dist/prompt/provider-prompts/deepseek.d.ts +1 -0
  367. package/dist/prompt/provider-prompts/deepseek.js +7 -0
  368. package/dist/prompt/provider-prompts/default.d.ts +1 -0
  369. package/dist/prompt/provider-prompts/default.js +6 -0
  370. package/dist/prompt/provider-prompts/gemini.d.ts +1 -0
  371. package/dist/prompt/provider-prompts/gemini.js +5 -0
  372. package/dist/prompt/provider-prompts/glm.d.ts +1 -0
  373. package/dist/prompt/provider-prompts/glm.js +7 -0
  374. package/dist/prompt/provider-prompts/gpt.d.ts +1 -0
  375. package/dist/prompt/provider-prompts/gpt.js +5 -0
  376. package/dist/prompt/provider-prompts/kimi.d.ts +1 -0
  377. package/dist/prompt/provider-prompts/kimi.js +8 -0
  378. package/dist/prompt/reminders.d.ts +33 -0
  379. package/dist/prompt/reminders.js +135 -0
  380. package/dist/prompt/routing.d.ts +14 -0
  381. package/dist/prompt/routing.js +71 -0
  382. package/dist/prompt/runtime.d.ts +12 -0
  383. package/dist/prompt/runtime.js +40 -0
  384. package/dist/prompt/task-reminders.d.ts +12 -0
  385. package/dist/prompt/task-reminders.js +64 -0
  386. package/dist/provider-ai-sdk.d.ts +59 -0
  387. package/dist/provider-ai-sdk.js +584 -0
  388. package/dist/provider-anthropic.d.ts +126 -0
  389. package/dist/provider-anthropic.js +940 -0
  390. package/dist/provider-ark-responses.d.ts +29 -0
  391. package/dist/provider-ark-responses.js +518 -0
  392. package/dist/provider-artifacts.d.ts +7 -0
  393. package/dist/provider-artifacts.js +60 -0
  394. package/dist/provider-error-record.d.ts +43 -0
  395. package/dist/provider-error-record.js +213 -0
  396. package/dist/provider-grok.d.ts +50 -0
  397. package/dist/provider-grok.js +110 -0
  398. package/dist/provider-model-policy.d.ts +16 -0
  399. package/dist/provider-model-policy.js +33 -0
  400. package/dist/provider-openai-codex.d.ts +66 -0
  401. package/dist/provider-openai-codex.js +781 -0
  402. package/dist/provider-registry.d.ts +197 -0
  403. package/dist/provider-registry.js +1194 -0
  404. package/dist/provider-transform.d.ts +12 -0
  405. package/dist/provider-transform.js +293 -0
  406. package/dist/provider-zen-errors.d.ts +9 -0
  407. package/dist/provider-zen-errors.js +36 -0
  408. package/dist/provider.d.ts +85 -0
  409. package/dist/provider.js +925 -0
  410. package/dist/question/controller.d.ts +22 -0
  411. package/dist/question/controller.js +98 -0
  412. package/dist/question/index.d.ts +2 -0
  413. package/dist/question/index.js +2 -0
  414. package/dist/question/normalize.d.ts +6 -0
  415. package/dist/question/normalize.js +11 -0
  416. package/dist/question/types.d.ts +42 -0
  417. package/dist/question/types.js +6 -0
  418. package/dist/reasoning-debug.d.ts +7 -0
  419. package/dist/reasoning-debug.js +33 -0
  420. package/dist/rewind.d.ts +20 -0
  421. package/dist/rewind.js +29 -0
  422. package/dist/sdk/index.d.ts +319 -0
  423. package/dist/sdk/index.js +1068 -0
  424. package/dist/sdk/replay-event-log.d.ts +26 -0
  425. package/dist/sdk/replay-event-log.js +122 -0
  426. package/dist/sdk/session-turn-coordinator.d.ts +45 -0
  427. package/dist/sdk/session-turn-coordinator.js +227 -0
  428. package/dist/session-context-fence.d.ts +16 -0
  429. package/dist/session-context-fence.js +26 -0
  430. package/dist/session-log.d.ts +25 -0
  431. package/dist/session-log.js +444 -0
  432. package/dist/session-title.d.ts +16 -0
  433. package/dist/session-title.js +131 -0
  434. package/dist/session-types.d.ts +86 -0
  435. package/dist/session-types.js +1 -0
  436. package/dist/session.d.ts +135 -0
  437. package/dist/session.js +664 -0
  438. package/dist/skills/discovery.d.ts +12 -0
  439. package/dist/skills/discovery.js +166 -0
  440. package/dist/skills/format.d.ts +32 -0
  441. package/dist/skills/format.js +68 -0
  442. package/dist/skills/frontmatter.d.ts +5 -0
  443. package/dist/skills/frontmatter.js +60 -0
  444. package/dist/skills/invocation.d.ts +8 -0
  445. package/dist/skills/invocation.js +33 -0
  446. package/dist/skills/registry.d.ts +28 -0
  447. package/dist/skills/registry.js +79 -0
  448. package/dist/skills/types.d.ts +34 -0
  449. package/dist/skills/types.js +1 -0
  450. package/dist/slash-commands/commands.d.ts +10 -0
  451. package/dist/slash-commands/commands.js +1251 -0
  452. package/dist/slash-commands/feishu.d.ts +17 -0
  453. package/dist/slash-commands/feishu.js +400 -0
  454. package/dist/slash-commands/index.d.ts +4 -0
  455. package/dist/slash-commands/index.js +8 -0
  456. package/dist/slash-commands/registry.d.ts +32 -0
  457. package/dist/slash-commands/registry.js +73 -0
  458. package/dist/slash-commands/types.d.ts +109 -0
  459. package/dist/slash-commands/types.js +1 -0
  460. package/dist/slash-commands/unified.d.ts +38 -0
  461. package/dist/slash-commands/unified.js +38 -0
  462. package/dist/stats/usage.d.ts +59 -0
  463. package/dist/stats/usage.js +485 -0
  464. package/dist/stream-json.d.ts +13 -0
  465. package/dist/stream-json.js +74 -0
  466. package/dist/system-prompt.d.ts +40 -0
  467. package/dist/system-prompt.js +7 -0
  468. package/dist/tasks/manager.d.ts +145 -0
  469. package/dist/tasks/manager.js +634 -0
  470. package/dist/tasks/process-utils.d.ts +10 -0
  471. package/dist/tasks/process-utils.js +49 -0
  472. package/dist/tasks/promotion.d.ts +17 -0
  473. package/dist/tasks/promotion.js +30 -0
  474. package/dist/tasks/wake.d.ts +53 -0
  475. package/dist/tasks/wake.js +125 -0
  476. package/dist/text-display.d.ts +3 -0
  477. package/dist/text-display.js +25 -0
  478. package/dist/tools/agent-lifecycle.d.ts +30 -0
  479. package/dist/tools/agent-lifecycle.js +790 -0
  480. package/dist/tools/bash.d.ts +23 -0
  481. package/dist/tools/bash.js +443 -0
  482. package/dist/tools/child-tools.d.ts +41 -0
  483. package/dist/tools/child-tools.js +122 -0
  484. package/dist/tools/edit-apply.d.ts +25 -0
  485. package/dist/tools/edit-apply.js +274 -0
  486. package/dist/tools/edit.d.ts +18 -0
  487. package/dist/tools/edit.js +200 -0
  488. package/dist/tools/exa-mcp.d.ts +3 -0
  489. package/dist/tools/exa-mcp.js +74 -0
  490. package/dist/tools/exit-plan-mode.d.ts +22 -0
  491. package/dist/tools/exit-plan-mode.js +79 -0
  492. package/dist/tools/file-mutation-queue.d.ts +2 -0
  493. package/dist/tools/file-mutation-queue.js +43 -0
  494. package/dist/tools/file-state.d.ts +48 -0
  495. package/dist/tools/file-state.js +76 -0
  496. package/dist/tools/grep.d.ts +9 -0
  497. package/dist/tools/grep.js +387 -0
  498. package/dist/tools/index.d.ts +63 -0
  499. package/dist/tools/index.js +76 -0
  500. package/dist/tools/ls.d.ts +3 -0
  501. package/dist/tools/ls.js +85 -0
  502. package/dist/tools/lsp.d.ts +4 -0
  503. package/dist/tools/lsp.js +95 -0
  504. package/dist/tools/memory.d.ts +8 -0
  505. package/dist/tools/memory.js +77 -0
  506. package/dist/tools/path-utils.d.ts +8 -0
  507. package/dist/tools/path-utils.js +53 -0
  508. package/dist/tools/prompt-metadata.d.ts +3 -0
  509. package/dist/tools/prompt-metadata.js +17 -0
  510. package/dist/tools/question.d.ts +3 -0
  511. package/dist/tools/question.js +177 -0
  512. package/dist/tools/read.d.ts +8 -0
  513. package/dist/tools/read.js +309 -0
  514. package/dist/tools/sensitive-paths.d.ts +11 -0
  515. package/dist/tools/sensitive-paths.js +106 -0
  516. package/dist/tools/server-manager.d.ts +6 -0
  517. package/dist/tools/server-manager.js +6 -0
  518. package/dist/tools/server.d.ts +6 -0
  519. package/dist/tools/server.js +249 -0
  520. package/dist/tools/skill-search.d.ts +10 -0
  521. package/dist/tools/skill-search.js +134 -0
  522. package/dist/tools/skill.d.ts +7 -0
  523. package/dist/tools/skill.js +81 -0
  524. package/dist/tools/task-tools.d.ts +10 -0
  525. package/dist/tools/task-tools.js +133 -0
  526. package/dist/tools/tool-search.d.ts +23 -0
  527. package/dist/tools/tool-search.js +145 -0
  528. package/dist/tools/web-fetch.d.ts +6 -0
  529. package/dist/tools/web-fetch.js +76 -0
  530. package/dist/tools/web-search.d.ts +5 -0
  531. package/dist/tools/web-search.js +50 -0
  532. package/dist/tools/write.d.ts +10 -0
  533. package/dist/tools/write.js +155 -0
  534. package/dist/tui/animation-clock.d.ts +14 -0
  535. package/dist/tui/animation-clock.js +34 -0
  536. package/dist/tui/app.d.ts +176 -0
  537. package/dist/tui/app.js +1659 -0
  538. package/dist/tui/components/approval-dialog.d.ts +43 -0
  539. package/dist/tui/components/approval-dialog.js +212 -0
  540. package/dist/tui/components/bottom-sheet.d.ts +9 -0
  541. package/dist/tui/components/bottom-sheet.js +32 -0
  542. package/dist/tui/components/context-info.d.ts +54 -0
  543. package/dist/tui/components/context-info.js +388 -0
  544. package/dist/tui/components/feedback-dialog.d.ts +56 -0
  545. package/dist/tui/components/feedback-dialog.js +262 -0
  546. package/dist/tui/components/feishu-setup-dialog.d.ts +65 -0
  547. package/dist/tui/components/feishu-setup-dialog.js +332 -0
  548. package/dist/tui/components/image-preview.d.ts +32 -0
  549. package/dist/tui/components/image-preview.js +130 -0
  550. package/dist/tui/components/plan-dialog.d.ts +34 -0
  551. package/dist/tui/components/plan-dialog.js +196 -0
  552. package/dist/tui/components/provider-key-input.d.ts +18 -0
  553. package/dist/tui/components/provider-key-input.js +49 -0
  554. package/dist/tui/components/question-dialog.d.ts +25 -0
  555. package/dist/tui/components/question-dialog.js +263 -0
  556. package/dist/tui/components/responsive-transcript.d.ts +31 -0
  557. package/dist/tui/components/responsive-transcript.js +77 -0
  558. package/dist/tui/components/rewind-picker.d.ts +62 -0
  559. package/dist/tui/components/rewind-picker.js +317 -0
  560. package/dist/tui/components/session-picker.d.ts +49 -0
  561. package/dist/tui/components/session-picker.js +303 -0
  562. package/dist/tui/components/skills-panel.d.ts +63 -0
  563. package/dist/tui/components/skills-panel.js +582 -0
  564. package/dist/tui/components/stats-panel.d.ts +40 -0
  565. package/dist/tui/components/stats-panel.js +301 -0
  566. package/dist/tui/components/streaming-message.d.ts +69 -0
  567. package/dist/tui/components/streaming-message.js +398 -0
  568. package/dist/tui/components/subagent-inspector.d.ts +28 -0
  569. package/dist/tui/components/subagent-inspector.js +127 -0
  570. package/dist/tui/components/task-inspector.d.ts +26 -0
  571. package/dist/tui/components/task-inspector.js +70 -0
  572. package/dist/tui/components/tasks-pane.d.ts +126 -0
  573. package/dist/tui/components/tasks-pane.js +566 -0
  574. package/dist/tui/components/transcript.d.ts +103 -0
  575. package/dist/tui/components/transcript.js +858 -0
  576. package/dist/tui/components/welcome.d.ts +20 -0
  577. package/dist/tui/components/welcome.js +133 -0
  578. package/dist/tui/components/workflow-inspector.d.ts +30 -0
  579. package/dist/tui/components/workflow-inspector.js +136 -0
  580. package/dist/tui/composer-autocomplete.d.ts +76 -0
  581. package/dist/tui/composer-autocomplete.js +465 -0
  582. package/dist/tui/composer-style.d.ts +7 -0
  583. package/dist/tui/composer-style.js +29 -0
  584. package/dist/tui/controller/agent-event-reducer.d.ts +75 -0
  585. package/dist/tui/controller/agent-event-reducer.js +239 -0
  586. package/dist/tui/controller/composer-controller.d.ts +95 -0
  587. package/dist/tui/controller/composer-controller.js +502 -0
  588. package/dist/tui/controller/controller.d.ts +199 -0
  589. package/dist/tui/controller/controller.js +1034 -0
  590. package/dist/tui/controller/effects.d.ts +71 -0
  591. package/dist/tui/controller/effects.js +1 -0
  592. package/dist/tui/controller/goal-runtime-controller.d.ts +47 -0
  593. package/dist/tui/controller/goal-runtime-controller.js +202 -0
  594. package/dist/tui/controller/input-queue-machine.d.ts +71 -0
  595. package/dist/tui/controller/input-queue-machine.js +121 -0
  596. package/dist/tui/controller/intents.d.ts +56 -0
  597. package/dist/tui/controller/intents.js +6 -0
  598. package/dist/tui/controller/overlay-controller.d.ts +64 -0
  599. package/dist/tui/controller/overlay-controller.js +129 -0
  600. package/dist/tui/controller/ports.d.ts +57 -0
  601. package/dist/tui/controller/ports.js +9 -0
  602. package/dist/tui/controller/session-transition.d.ts +54 -0
  603. package/dist/tui/controller/session-transition.js +68 -0
  604. package/dist/tui/controller/state.d.ts +14 -0
  605. package/dist/tui/controller/state.js +36 -0
  606. package/dist/tui/controller/task-runtime-controller.d.ts +66 -0
  607. package/dist/tui/controller/task-runtime-controller.js +158 -0
  608. package/dist/tui/detect-theme.d.ts +4 -0
  609. package/dist/tui/detect-theme.js +116 -0
  610. package/dist/tui/display-history.d.ts +64 -0
  611. package/dist/tui/display-history.js +283 -0
  612. package/dist/tui/display-sanitizer.d.ts +3 -0
  613. package/dist/tui/display-sanitizer.js +38 -0
  614. package/dist/tui/edit-diff.d.ts +11 -0
  615. package/dist/tui/edit-diff.js +57 -0
  616. package/dist/tui/file-mentions.d.ts +29 -0
  617. package/dist/tui/file-mentions.js +174 -0
  618. package/dist/tui/footer.d.ts +37 -0
  619. package/dist/tui/footer.js +80 -0
  620. package/dist/tui/formatting/edit-diff.d.ts +11 -0
  621. package/dist/tui/formatting/edit-diff.js +52 -0
  622. package/dist/tui/formatting/summary.d.ts +43 -0
  623. package/dist/tui/formatting/summary.js +150 -0
  624. package/dist/tui/fullscreen.d.ts +48 -0
  625. package/dist/tui/fullscreen.js +256 -0
  626. package/dist/tui/image-display.d.ts +23 -0
  627. package/dist/tui/image-display.js +92 -0
  628. package/dist/tui/image-paste.d.ts +113 -0
  629. package/dist/tui/image-paste.js +565 -0
  630. package/dist/tui/input-history.d.ts +47 -0
  631. package/dist/tui/input-history.js +250 -0
  632. package/dist/tui/markdown-style.d.ts +5 -0
  633. package/dist/tui/markdown-style.js +23 -0
  634. package/dist/tui/model/composer-buffer.d.ts +55 -0
  635. package/dist/tui/model/composer-buffer.js +317 -0
  636. package/dist/tui/model/composer-types.d.ts +17 -0
  637. package/dist/tui/model/composer-types.js +1 -0
  638. package/dist/tui/model/display-history.d.ts +78 -0
  639. package/dist/tui/model/display-history.js +124 -0
  640. package/dist/tui/model/display-reconstruct.d.ts +3 -0
  641. package/dist/tui/model/display-reconstruct.js +130 -0
  642. package/dist/tui/model/file-mentions.d.ts +31 -0
  643. package/dist/tui/model/file-mentions.js +178 -0
  644. package/dist/tui/model/image-attachment.d.ts +15 -0
  645. package/dist/tui/model/image-attachment.js +1 -0
  646. package/dist/tui/model/image-paste.d.ts +119 -0
  647. package/dist/tui/model/image-paste.js +610 -0
  648. package/dist/tui/model/input-history.d.ts +1 -0
  649. package/dist/tui/model/input-history.js +1 -0
  650. package/dist/tui/model/input-queue.d.ts +12 -0
  651. package/dist/tui/model/input-queue.js +17 -0
  652. package/dist/tui/model/key-events.d.ts +9 -0
  653. package/dist/tui/model/key-events.js +8 -0
  654. package/dist/tui/model/paste-operation-tracker.d.ts +13 -0
  655. package/dist/tui/model/paste-operation-tracker.js +25 -0
  656. package/dist/tui/model/recent-activity.d.ts +8 -0
  657. package/dist/tui/model/recent-activity.js +71 -0
  658. package/dist/tui/model/subagent-view.d.ts +87 -0
  659. package/dist/tui/model/subagent-view.js +336 -0
  660. package/dist/tui/model/submit-dedupe.d.ts +5 -0
  661. package/dist/tui/model/submit-dedupe.js +25 -0
  662. package/dist/tui/model/sync-output.d.ts +17 -0
  663. package/dist/tui/model/sync-output.js +35 -0
  664. package/dist/tui/model/task-lifecycle.d.ts +57 -0
  665. package/dist/tui/model/task-lifecycle.js +124 -0
  666. package/dist/tui/model/terminal-env.d.ts +15 -0
  667. package/dist/tui/model/terminal-env.js +22 -0
  668. package/dist/tui/model/terminal-mouse.d.ts +28 -0
  669. package/dist/tui/model/terminal-mouse.js +82 -0
  670. package/dist/tui/model/theme-style.d.ts +10 -0
  671. package/dist/tui/model/theme-style.js +79 -0
  672. package/dist/tui/model/theme.d.ts +72 -0
  673. package/dist/tui/model/theme.js +121 -0
  674. package/dist/tui/model/trace-groups.d.ts +45 -0
  675. package/dist/tui/model/trace-groups.js +558 -0
  676. package/dist/tui/model/trace-interaction.d.ts +63 -0
  677. package/dist/tui/model/trace-interaction.js +87 -0
  678. package/dist/tui/model/width.d.ts +18 -0
  679. package/dist/tui/model/width.js +130 -0
  680. package/dist/tui/model-picker-data.d.ts +9 -0
  681. package/dist/tui/model-picker-data.js +39 -0
  682. package/dist/tui/model-switch.d.ts +49 -0
  683. package/dist/tui/model-switch.js +67 -0
  684. package/dist/tui/paste-placeholder.d.ts +11 -0
  685. package/dist/tui/paste-placeholder.js +52 -0
  686. package/dist/tui/recent-activity.d.ts +8 -0
  687. package/dist/tui/recent-activity.js +71 -0
  688. package/dist/tui/run-session-picker.d.ts +9 -0
  689. package/dist/tui/run-session-picker.js +64 -0
  690. package/dist/tui/run.d.ts +72 -0
  691. package/dist/tui/run.js +139 -0
  692. package/dist/tui/session-display.d.ts +6 -0
  693. package/dist/tui/session-display.js +12 -0
  694. package/dist/tui/session-picker-data.d.ts +18 -0
  695. package/dist/tui/session-picker-data.js +21 -0
  696. package/dist/tui/terminal/multiplexer.d.ts +5 -0
  697. package/dist/tui/terminal/multiplexer.js +14 -0
  698. package/dist/tui/testing/fake-agent.d.ts +24 -0
  699. package/dist/tui/testing/fake-agent.js +22 -0
  700. package/dist/tui/testing/spy-host.d.ts +21 -0
  701. package/dist/tui/testing/spy-host.js +55 -0
  702. package/dist/tui/trace-groups.d.ts +43 -0
  703. package/dist/tui/trace-groups.js +554 -0
  704. package/dist/tui/wordmark.d.ts +18 -0
  705. package/dist/tui/wordmark.js +208 -0
  706. package/dist/types.d.ts +503 -0
  707. package/dist/types.js +4 -0
  708. package/dist/update/index.d.ts +61 -0
  709. package/dist/update/index.js +267 -0
  710. package/dist/variant/thinking-level.d.ts +5 -0
  711. package/dist/variant/thinking-level.js +26 -0
  712. package/dist/variant/variant-resolver.d.ts +28 -0
  713. package/dist/variant/variant-resolver.js +62 -0
  714. package/node_modules/@bubblebrain-ai/pi-tui/LICENSE +21 -0
  715. package/node_modules/@bubblebrain-ai/pi-tui/README.md +854 -0
  716. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/alt-screen-search.d.ts +26 -0
  717. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/alt-screen-search.d.ts.map +1 -0
  718. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/alt-screen-search.js +121 -0
  719. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/alt-screen-search.js.map +1 -0
  720. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/autocomplete.d.ts +86 -0
  721. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/autocomplete.d.ts.map +1 -0
  722. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/autocomplete.js +649 -0
  723. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/autocomplete.js.map +1 -0
  724. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/alt-screen-flash.d.ts +13 -0
  725. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/alt-screen-flash.d.ts.map +1 -0
  726. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/alt-screen-flash.js +36 -0
  727. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/alt-screen-flash.js.map +1 -0
  728. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/box.d.ts +22 -0
  729. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/box.d.ts.map +1 -0
  730. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/box.js +99 -0
  731. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/box.js.map +1 -0
  732. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/cancellable-loader.d.ts +22 -0
  733. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/cancellable-loader.d.ts.map +1 -0
  734. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/cancellable-loader.js +36 -0
  735. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/cancellable-loader.js.map +1 -0
  736. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/editor.d.ts +330 -0
  737. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/editor.d.ts.map +1 -0
  738. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/editor.js +2344 -0
  739. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/editor.js.map +1 -0
  740. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/h-stack.d.ts +7 -0
  741. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/h-stack.d.ts.map +1 -0
  742. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/h-stack.js +43 -0
  743. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/h-stack.js.map +1 -0
  744. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/image.d.ts +28 -0
  745. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/image.d.ts.map +1 -0
  746. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/image.js +82 -0
  747. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/image.js.map +1 -0
  748. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/input.d.ts +48 -0
  749. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/input.d.ts.map +1 -0
  750. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/input.js +390 -0
  751. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/input.js.map +1 -0
  752. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/loader.d.ts +31 -0
  753. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/loader.d.ts.map +1 -0
  754. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/loader.js +67 -0
  755. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/loader.js.map +1 -0
  756. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/markdown.d.ts +103 -0
  757. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/markdown.d.ts.map +1 -0
  758. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/markdown.js +797 -0
  759. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/markdown.js.map +1 -0
  760. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/scroll-view.d.ts +56 -0
  761. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/scroll-view.d.ts.map +1 -0
  762. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/scroll-view.js +179 -0
  763. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/scroll-view.js.map +1 -0
  764. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/select-list.d.ts +53 -0
  765. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/select-list.d.ts.map +1 -0
  766. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/select-list.js +175 -0
  767. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/select-list.js.map +1 -0
  768. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/settings-list.d.ts +50 -0
  769. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/settings-list.d.ts.map +1 -0
  770. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/settings-list.js +174 -0
  771. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/settings-list.js.map +1 -0
  772. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/spacer.d.ts +12 -0
  773. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/spacer.d.ts.map +1 -0
  774. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/spacer.js +22 -0
  775. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/spacer.js.map +1 -0
  776. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/stack.d.ts +32 -0
  777. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/stack.d.ts.map +1 -0
  778. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/stack.js +109 -0
  779. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/stack.js.map +1 -0
  780. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/text.d.ts +19 -0
  781. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/text.d.ts.map +1 -0
  782. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/text.js +81 -0
  783. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/text.js.map +1 -0
  784. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/truncated-text.d.ts +13 -0
  785. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/truncated-text.d.ts.map +1 -0
  786. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/truncated-text.js +48 -0
  787. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/truncated-text.js.map +1 -0
  788. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/v-stack.d.ts +8 -0
  789. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/v-stack.d.ts.map +1 -0
  790. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/v-stack.js +26 -0
  791. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/v-stack.js.map +1 -0
  792. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/editor-component.d.ts +39 -0
  793. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/editor-component.d.ts.map +1 -0
  794. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/editor-component.js +2 -0
  795. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/editor-component.js.map +1 -0
  796. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/fuzzy.d.ts +16 -0
  797. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/fuzzy.d.ts.map +1 -0
  798. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/fuzzy.js +110 -0
  799. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/fuzzy.js.map +1 -0
  800. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/index.d.ts +31 -0
  801. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/index.d.ts.map +1 -0
  802. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/index.js +42 -0
  803. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/index.js.map +1 -0
  804. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/keybindings.d.ts +273 -0
  805. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/keybindings.d.ts.map +1 -0
  806. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/keybindings.js +231 -0
  807. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/keybindings.js.map +1 -0
  808. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/keys.d.ts +184 -0
  809. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/keys.d.ts.map +1 -0
  810. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/keys.js +1174 -0
  811. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/keys.js.map +1 -0
  812. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/kill-ring.d.ts +28 -0
  813. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/kill-ring.d.ts.map +1 -0
  814. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/kill-ring.js +46 -0
  815. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/kill-ring.js.map +1 -0
  816. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/latex.d.ts +10 -0
  817. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/latex.d.ts.map +1 -0
  818. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/latex.js +1268 -0
  819. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/latex.js.map +1 -0
  820. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/layout-node.d.ts +40 -0
  821. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/layout-node.d.ts.map +1 -0
  822. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/layout-node.js +6 -0
  823. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/layout-node.js.map +1 -0
  824. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/layout.d.ts +42 -0
  825. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/layout.d.ts.map +1 -0
  826. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/layout.js +335 -0
  827. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/layout.js.map +1 -0
  828. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/native-modifiers.d.ts +3 -0
  829. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/native-modifiers.d.ts.map +1 -0
  830. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/native-modifiers.js +60 -0
  831. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/native-modifiers.js.map +1 -0
  832. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/stdin-buffer.d.ts +56 -0
  833. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/stdin-buffer.d.ts.map +1 -0
  834. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/stdin-buffer.js +363 -0
  835. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/stdin-buffer.js.map +1 -0
  836. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/terminal-colors.d.ts +10 -0
  837. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/terminal-colors.d.ts.map +1 -0
  838. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/terminal-colors.js +59 -0
  839. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/terminal-colors.js.map +1 -0
  840. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/terminal-image.d.ts +116 -0
  841. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/terminal-image.d.ts.map +1 -0
  842. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/terminal-image.js +518 -0
  843. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/terminal-image.js.map +1 -0
  844. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/terminal.d.ts +142 -0
  845. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/terminal.d.ts.map +1 -0
  846. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/terminal.js +544 -0
  847. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/terminal.js.map +1 -0
  848. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/testing.d.ts +11 -0
  849. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/testing.d.ts.map +1 -0
  850. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/testing.js +11 -0
  851. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/testing.js.map +1 -0
  852. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/tui-alt-screen.d.ts +141 -0
  853. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/tui-alt-screen.d.ts.map +1 -0
  854. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/tui-alt-screen.js +1340 -0
  855. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/tui-alt-screen.js.map +1 -0
  856. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/tui-main-screen.d.ts +39 -0
  857. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/tui-main-screen.d.ts.map +1 -0
  858. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/tui-main-screen.js +536 -0
  859. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/tui-main-screen.js.map +1 -0
  860. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/tui.d.ts +340 -0
  861. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/tui.d.ts.map +1 -0
  862. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/tui.js +1020 -0
  863. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/tui.js.map +1 -0
  864. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/undo-stack.d.ts +17 -0
  865. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/undo-stack.d.ts.map +1 -0
  866. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/undo-stack.js +27 -0
  867. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/undo-stack.js.map +1 -0
  868. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/utils.d.ts +96 -0
  869. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/utils.d.ts.map +1 -0
  870. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/utils.js +1193 -0
  871. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/utils.js.map +1 -0
  872. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/word-navigation.d.ts +25 -0
  873. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/word-navigation.d.ts.map +1 -0
  874. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/word-navigation.js +96 -0
  875. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/word-navigation.js.map +1 -0
  876. package/node_modules/@bubblebrain-ai/pi-tui/dist/test/virtual-terminal.d.ts +73 -0
  877. package/node_modules/@bubblebrain-ai/pi-tui/dist/test/virtual-terminal.d.ts.map +1 -0
  878. package/node_modules/@bubblebrain-ai/pi-tui/dist/test/virtual-terminal.js +188 -0
  879. package/node_modules/@bubblebrain-ai/pi-tui/dist/test/virtual-terminal.js.map +1 -0
  880. package/node_modules/@bubblebrain-ai/pi-tui/native/darwin/README.md +20 -0
  881. package/node_modules/@bubblebrain-ai/pi-tui/native/darwin/build.sh +62 -0
  882. package/node_modules/@bubblebrain-ai/pi-tui/native/darwin/prebuilds/darwin-arm64/darwin-modifiers.node +0 -0
  883. package/node_modules/@bubblebrain-ai/pi-tui/native/darwin/prebuilds/darwin-x64/darwin-modifiers.node +0 -0
  884. package/node_modules/@bubblebrain-ai/pi-tui/native/darwin/src/darwin-modifiers.c +70 -0
  885. package/node_modules/@bubblebrain-ai/pi-tui/native/win32/README.md +22 -0
  886. package/node_modules/@bubblebrain-ai/pi-tui/native/win32/build.mjs +229 -0
  887. package/node_modules/@bubblebrain-ai/pi-tui/native/win32/prebuilds/win32-arm64/win32-console-mode.node +0 -0
  888. package/node_modules/@bubblebrain-ai/pi-tui/native/win32/prebuilds/win32-x64/win32-console-mode.node +0 -0
  889. package/node_modules/@bubblebrain-ai/pi-tui/native/win32/src/win32-console-mode.c +119 -0
  890. package/node_modules/@bubblebrain-ai/pi-tui/package.json +66 -0
  891. package/node_modules/get-east-asian-width/index.d.ts +60 -0
  892. package/node_modules/get-east-asian-width/index.js +30 -0
  893. package/node_modules/get-east-asian-width/license +9 -0
  894. package/node_modules/get-east-asian-width/lookup-data.js +21 -0
  895. package/node_modules/get-east-asian-width/lookup.js +138 -0
  896. package/node_modules/get-east-asian-width/package.json +71 -0
  897. package/node_modules/get-east-asian-width/readme.md +65 -0
  898. package/node_modules/get-east-asian-width/utilities.js +24 -0
  899. package/node_modules/marked/LICENSE +44 -0
  900. package/node_modules/marked/README.md +115 -0
  901. package/node_modules/marked/bin/main.js +284 -0
  902. package/node_modules/marked/bin/marked.js +16 -0
  903. package/node_modules/marked/lib/marked.d.ts +760 -0
  904. package/node_modules/marked/lib/marked.esm.js +77 -0
  905. package/node_modules/marked/lib/marked.esm.js.map +7 -0
  906. package/node_modules/marked/lib/marked.umd.js +79 -0
  907. package/node_modules/marked/lib/marked.umd.js.map +7 -0
  908. package/node_modules/marked/man/marked.1 +113 -0
  909. package/node_modules/marked/man/marked.1.md +93 -0
  910. package/node_modules/marked/package.json +103 -0
  911. package/package.json +96 -17
  912. package/bin/bubble.js +0 -39
@@ -0,0 +1,858 @@
1
+ /**
2
+ * Transcript row renderer (Phase 5): DisplayMessage[] -> styled terminal
3
+ * rows. Pure — no pi-tui/Ink imports; the pi app feeds rows into Text
4
+ * components and unit tests assert the strings directly.
5
+ *
6
+ * Visual parity targets from the legacy renderer (message-list.tsx):
7
+ * - user message: highlighted card, '›' marker, vertical padding
8
+ * - assistant: plain wrapped text, blank-line separated
9
+ * - reasoning: dim, collapsed to one line unless expanded
10
+ * - tool calls: single-line trace with status glyph, name, arg preview,
11
+ * error result preview
12
+ * - synthetic rows (interrupt, compaction, notices) rendered as notices
13
+ *
14
+ * Horizontal geometry: every surface shares one left rail (see
15
+ * TRANSCRIPT_RAIL_COLUMNS). The rail carries per-surface chrome and the body
16
+ * always starts at the same column, so user text, tool entries, reasoning and
17
+ * the final answer line up no matter which projector drew the row.
18
+ */
19
+ import chalk from "chalk";
20
+ import stringWidth from "string-width";
21
+ import { truncateVisual } from "../../text-display.js";
22
+ import { darkTheme } from "../model/theme.js";
23
+ import { themeBackground, themeDim, themeForeground } from "../model/theme-style.js";
24
+ import { buildTraceGroups, formatTracePath } from "../model/trace-groups.js";
25
+ import { splitImageDisplayContent } from "../image-display.js";
26
+ function toolTraceLabel(tool) {
27
+ return tool.name;
28
+ }
29
+ function plainProjection(rows) {
30
+ return {
31
+ rows: [...rows],
32
+ traceTargets: rows.map(() => undefined),
33
+ leadingSpacer: rows.length > 0 && stringWidth(rows[0] ?? "") === 0,
34
+ trailingSpacer: rows.length > 0 && stringWidth(rows.at(-1) ?? "") === 0,
35
+ };
36
+ }
37
+ export function joinTranscriptProjections(blocks) {
38
+ const rows = [];
39
+ const traceTargets = [];
40
+ let leadingSpacer = false;
41
+ let trailingSpacer = false;
42
+ for (const block of blocks) {
43
+ let start = 0;
44
+ let end = block.rows.length;
45
+ while (start < end && block.rows[start] === "")
46
+ start += 1;
47
+ while (end > start && block.rows[end - 1] === "")
48
+ end -= 1;
49
+ if (start === end)
50
+ continue;
51
+ const blockHasLeadingSpacer = start === 0
52
+ ? (block.leadingSpacer ?? stringWidth(block.rows[start] ?? "") === 0)
53
+ : stringWidth(block.rows[start] ?? "") === 0;
54
+ if (rows.length === 0)
55
+ leadingSpacer = blockHasLeadingSpacer;
56
+ const previousHasSpacer = rows.length > 0 && trailingSpacer;
57
+ if (rows.length > 0 && !previousHasSpacer && !blockHasLeadingSpacer) {
58
+ rows.push("");
59
+ traceTargets.push(undefined);
60
+ }
61
+ rows.push(...block.rows.slice(start, end));
62
+ traceTargets.push(...block.traceTargets.slice(start, end));
63
+ trailingSpacer = end === block.rows.length
64
+ ? (block.trailingSpacer ?? stringWidth(block.rows[end - 1] ?? "") === 0)
65
+ : stringWidth(block.rows[end - 1] ?? "") === 0;
66
+ }
67
+ return { rows, traceTargets, leadingSpacer, trailingSpacer };
68
+ }
69
+ export function createTranscriptTheme(getTheme) {
70
+ return {
71
+ userBg: (text) => themeBackground(getTheme().userMessageBg, text),
72
+ userText: (text) => themeForeground(getTheme().userMessageText, text),
73
+ accent: (text) => themeForeground(getTheme().accent, text),
74
+ dim: (text) => themeDim(getTheme().dim, text),
75
+ error: (text) => themeForeground(getTheme().error, text),
76
+ success: (text) => themeForeground(getTheme().success, text),
77
+ hoverBorder: (text) => themeDim(getTheme().border, text),
78
+ selectionBorder: (text) => themeForeground(getTheme().border, text),
79
+ hoverBackground: (text) => themeBackground(getTheme().traceHoverBg, text),
80
+ selectionBackground: (text) => themeBackground(getTheme().traceSelectedBg, text),
81
+ imageChip: (text, active) => themeForeground(getTheme().inputText, themeBackground(active ? getTheme().traceSelectedBg : getTheme().backgroundElement, text)),
82
+ };
83
+ }
84
+ export const defaultTranscriptTheme = createTranscriptTheme(() => darkTheme);
85
+ /**
86
+ * Width of the shared left rail. Column 0..2 belong to surface chrome
87
+ * (user `›`, hovered tool `│`, reasoning `┃`); the body starts at column 3.
88
+ * Changing this moves every transcript surface together.
89
+ */
90
+ export const TRANSCRIPT_RAIL_COLUMNS = 3;
91
+ /**
92
+ * Cells left unpainted on the right. Painting the physical last column can
93
+ * trigger an automatic wrap in several terminals and leaves a broken bg patch.
94
+ */
95
+ const TRANSCRIPT_RIGHT_MARGIN = 2;
96
+ const TRACE_BORDER_MIN_COLUMNS = 4;
97
+ const IMAGE_LABEL_SPACE_SENTINEL = "\uE000";
98
+ const TRACE_CONTENT_LEFT_PAD = TRANSCRIPT_RAIL_COLUMNS - 1; // cells between the hover border and the body
99
+ const TRACE_RESERVED_COLUMNS = TRANSCRIPT_RAIL_COLUMNS + 1; // rail + right border
100
+ // Keep a zero-width row in projection joins without painting a terminal cell.
101
+ // The row exists in layout at rest, so hover can add corners without reflow.
102
+ const TRACE_IDLE_VPAD = "\x1b[0m";
103
+ /** Visible-width-preserving truncation (input is unstyled at this point). */
104
+ function truncateVisible(text, maxColumns) {
105
+ return truncateVisual(text, maxColumns);
106
+ }
107
+ /**
108
+ * Compose one transcript row from rail chrome and body. `rail` may be styled
109
+ * and is padded to exactly TRANSCRIPT_RAIL_COLUMNS cells, so the body column
110
+ * is identical for every surface regardless of which glyph the rail carries.
111
+ */
112
+ function railRow(rail, body) {
113
+ const pad = Math.max(0, TRANSCRIPT_RAIL_COLUMNS - stringWidth(rail));
114
+ return `${rail}${" ".repeat(pad)}${body}`;
115
+ }
116
+ /**
117
+ * Shared body-width computation. Below the same threshold the tool frame uses
118
+ * to drop its border, surfaces give up the rail rather than squeezing text
119
+ * into a one-cell column.
120
+ */
121
+ function railGeometry(columns) {
122
+ const width = Math.max(1, Math.floor(columns));
123
+ const frameColumns = width > TRANSCRIPT_RIGHT_MARGIN ? width - TRANSCRIPT_RIGHT_MARGIN : width;
124
+ const rail = frameColumns >= TRACE_BORDER_MIN_COLUMNS;
125
+ return {
126
+ rail,
127
+ bodyColumns: rail ? Math.max(1, frameColumns - TRANSCRIPT_RAIL_COLUMNS) : frameColumns,
128
+ };
129
+ }
130
+ export function renderUserCard(content, options, images = [], messageKey = "user") {
131
+ const theme = options.theme ?? defaultTranscriptTheme;
132
+ const terminalWidth = Math.max(1, Math.floor(options.columns));
133
+ // At one or two columns there is no room to reserve the right margin, so
134
+ // use every available cell.
135
+ const width = terminalWidth > TRANSCRIPT_RIGHT_MARGIN ? terminalWidth - TRANSCRIPT_RIGHT_MARGIN : terminalWidth;
136
+ // The card gutter is the shared rail plus one trailing pad cell. On an
137
+ // extremely narrow terminal, degrade to a plain painted row; forcing the
138
+ // historical 20-column minimum is what made settled rows overflow after a
139
+ // 20x5 resize even though the live trace itself was width-safe.
140
+ if (width < TRANSCRIPT_RAIL_COLUMNS + 2) {
141
+ return wrapPlain(content, width).map((line) => theme.userBg(truncateVisible(line, width)));
142
+ }
143
+ const textWidth = width - TRANSCRIPT_RAIL_COLUMNS - 1; // rail + trailing pad
144
+ const split = images.length > 0 ? splitImageDisplayContent(content) : undefined;
145
+ const body = split?.bodyLines.join("\n") ?? content;
146
+ // Preserve the label's visible width while preventing the generic word
147
+ // wrapper from splitting `[Image #1]` at its internal ASCII space.
148
+ const protectedBody = images.reduce((value, image) => value.replaceAll(image.label, image.label.replaceAll(" ", IMAGE_LABEL_SPACE_SENTINEL)), body);
149
+ const lines = body.length > 0
150
+ ? wrapPlain(protectedBody, textWidth).map((line) => line.replaceAll(IMAGE_LABEL_SPACE_SENTINEL, " "))
151
+ : [];
152
+ if (split) {
153
+ for (const reference of split.referenceLines) {
154
+ if (images.some((image) => reference === `└ ${image.label}`))
155
+ lines.push(reference);
156
+ else
157
+ lines.push(...wrapPlain(reference, textWidth));
158
+ }
159
+ }
160
+ const rows = [];
161
+ const pad = " ".repeat(width);
162
+ rows.push(theme.userBg(pad));
163
+ lines.forEach((line, index) => {
164
+ // JS length/padEnd counts code units, not terminal cells: CJK characters
165
+ // occupy two columns. Visual padding prevents the line from overflowing,
166
+ // hard-wrapping, and resetting the painted background before the edge.
167
+ let renderedLine = line;
168
+ for (const image of images) {
169
+ if (!renderedLine.includes(image.label))
170
+ continue;
171
+ const groupKey = `image:${messageKey}:${image.label}`;
172
+ const chip = (theme.imageChip ?? ((text) => text))(image.label, options.traceInteraction?.isGroupHovered(groupKey) === true
173
+ || options.traceInteraction?.isGroupSelected(groupKey) === true);
174
+ renderedLine = renderedLine.replace(image.label, chip);
175
+ }
176
+ const padded = `${renderedLine}${" ".repeat(Math.max(0, textWidth - stringWidth(renderedLine)))}`;
177
+ const filled = railRow(index === 0 ? theme.accent(" › ") : "", theme.userText(padded)) + " ";
178
+ rows.push(theme.userBg(filled));
179
+ });
180
+ // Keep the painted padding symmetric so the message body is vertically
181
+ // centered. Separation from the following trace belongs outside the card;
182
+ // removing only the bottom pad shifts every message down by half a row.
183
+ rows.push(theme.userBg(pad));
184
+ return rows;
185
+ }
186
+ function projectUserCard(message, options) {
187
+ const rows = renderUserCard(message.content, options, message.images ?? [], message.key ?? "user");
188
+ const targets = rows.map(() => undefined);
189
+ if (!message.images?.length)
190
+ return { rows, traceTargets: targets };
191
+ // User-card geometry is top padding + wrapped source lines + bottom padding.
192
+ // Inline chips retain their composer row; legacy reconstructed attachments
193
+ // may still occupy standalone reference rows.
194
+ for (let index = 0; index < message.images.length; index += 1) {
195
+ const image = message.images[index];
196
+ const row = rows.findIndex((line) => line.includes(image.label));
197
+ // At widths too narrow to show the complete atomic label, do not attach an
198
+ // action to an unrelated wrapped fragment.
199
+ if (row <= 0 || row >= rows.length - 1)
200
+ continue;
201
+ const messageKey = message.key ?? "user";
202
+ const groupKey = `image:${messageKey}:${image.label}`;
203
+ // The current interaction model is row-oriented. If multiple chips share
204
+ // one row, keep the first stable target rather than changing action order.
205
+ targets[row] ??= {
206
+ kind: "image",
207
+ key: groupKey,
208
+ groupKey,
209
+ imageLabel: image.label,
210
+ foldable: false,
211
+ action: { kind: "open-image", messageKey, imageLabel: image.label },
212
+ };
213
+ }
214
+ return { rows, traceTargets: targets };
215
+ }
216
+ export function wrapPlain(text, columns) {
217
+ return Array.from(iteratePlainRows(text, columns));
218
+ }
219
+ /** Stream rows so collapsed reasoning need not retain its entire wrapped body. */
220
+ function* iteratePlainRows(text, columns) {
221
+ const widths = new Map();
222
+ const ascii = { width: 1, additive: true };
223
+ const measureChar = (char) => {
224
+ const code = char.charCodeAt(0);
225
+ if (code >= 0x20 && code <= 0x7e)
226
+ return ascii;
227
+ let cached = widths.get(char);
228
+ if (!cached) {
229
+ cached = {
230
+ width: stringWidth(char),
231
+ // These scalars cannot combine with each other. Other text (marks,
232
+ // emoji, joiners, ANSI, Jamo, etc.) still uses whole-chunk measurement.
233
+ additive: /^[\p{Unified_Ideograph}\p{Punctuation}]$/u.test(char),
234
+ };
235
+ widths.set(char, cached);
236
+ }
237
+ return cached;
238
+ };
239
+ function* splitToken(token) {
240
+ let chunk = "";
241
+ let width = 0;
242
+ let additive = true;
243
+ for (const char of token) {
244
+ const metric = measureChar(char);
245
+ if (chunk && width + metric.width > columns) {
246
+ yield { text: chunk, width: additive ? width : stringWidth(chunk) };
247
+ chunk = "";
248
+ width = 0;
249
+ additive = true;
250
+ }
251
+ chunk += char;
252
+ width += metric.width;
253
+ additive &&= metric.additive;
254
+ }
255
+ if (chunk)
256
+ yield { text: chunk, width: additive ? width : stringWidth(chunk) };
257
+ }
258
+ // Scan paragraphs/tokens lazily: a head preview can stop early, and a tail
259
+ // preview never allocates arrays for all paragraphs, tokens or wrapped rows.
260
+ let start = 0;
261
+ while (start <= text.length) {
262
+ const newline = text.indexOf("\n", start);
263
+ const end = newline === -1 ? text.length : newline;
264
+ const paragraph = text.slice(start, end);
265
+ if (paragraph === "")
266
+ yield "";
267
+ let line = "";
268
+ let lineWidth = 0;
269
+ for (const match of paragraph.matchAll(/\S+/g)) {
270
+ for (const chunk of splitToken(match[0])) {
271
+ const candidateWidth = line ? lineWidth + 1 + chunk.width : chunk.width;
272
+ if (line && candidateWidth > columns) {
273
+ yield line;
274
+ line = chunk.text;
275
+ lineWidth = chunk.width;
276
+ }
277
+ else {
278
+ line = line ? `${line} ${chunk.text}` : chunk.text;
279
+ lineWidth = candidateWidth;
280
+ }
281
+ }
282
+ }
283
+ if (line)
284
+ yield line;
285
+ if (newline === -1)
286
+ break;
287
+ start = newline + 1;
288
+ }
289
+ }
290
+ /**
291
+ * Project assistant prose without transcript spacing. Live streaming and
292
+ * settled history both call this function, so completing a turn cannot change
293
+ * the answer gutter or wrapping width. Prose carries an empty rail: its body
294
+ * sits in the same column as user text and tool entries.
295
+ */
296
+ export function projectAssistantRows(content, options) {
297
+ const geometry = railGeometry(options.columns);
298
+ const body = options.markdownRenderer
299
+ ? options.markdownRenderer(content, geometry.bodyColumns)
300
+ : wrapPlain(content, geometry.bodyColumns);
301
+ return body.map((row) => {
302
+ const clipped = truncateVisible(row, geometry.bodyColumns);
303
+ // Paragraph breaks stay genuinely empty so projection joins still treat
304
+ // them as spacers instead of three painted cells.
305
+ if (stringWidth(clipped) === 0)
306
+ return "";
307
+ return geometry.rail ? railRow("", clipped) : clipped;
308
+ });
309
+ }
310
+ export function renderAssistant(content, options) {
311
+ return [...projectAssistantRows(content, options), ""];
312
+ }
313
+ /**
314
+ * Join reasoning, tool, and prose surfaces with one semantic separator.
315
+ * Individual projectors own only their visible rows; this composition layer
316
+ * owns vertical rhythm, so live and settled timelines cannot drift apart.
317
+ */
318
+ export function joinTranscriptBlocks(blocks) {
319
+ const rows = [];
320
+ for (const block of blocks) {
321
+ let start = 0;
322
+ let end = block.length;
323
+ while (start < end && block[start] === "")
324
+ start += 1;
325
+ while (end > start && block[end - 1] === "")
326
+ end -= 1;
327
+ if (start === end)
328
+ continue;
329
+ if (rows.length > 0 && rows.at(-1) !== "")
330
+ rows.push("");
331
+ rows.push(...block.slice(start, end));
332
+ }
333
+ return rows;
334
+ }
335
+ /** Grok minimal mode keeps the same rolling reasoning surface live/settled. */
336
+ export const MINIMAL_REASONING_BODY_ROWS = 5;
337
+ /**
338
+ * Grok-style reasoning surface. Reasoning paints a `┃` in the shared rail so
339
+ * its body lines up with prose and tool entries. The same projection is used
340
+ * by the live row pool and committed transcript.
341
+ */
342
+ export function projectReasoningRows(content, options, projection = {}) {
343
+ const theme = options.theme ?? defaultTranscriptTheme;
344
+ const geometry = railGeometry(options.columns);
345
+ const limit = Math.max(0, Math.floor(projection.maxBodyRows ?? (options.showReasoning ? Infinity : MINIMAL_REASONING_BODY_ROWS)));
346
+ const fromEnd = projection.fromEnd ?? !options.showReasoning;
347
+ const body = [];
348
+ let count = 0;
349
+ for (const line of iteratePlainRows(content, geometry.bodyColumns)) {
350
+ if (!line)
351
+ continue;
352
+ count += 1;
353
+ if (limit === 0)
354
+ break;
355
+ if (limit === Infinity || !fromEnd)
356
+ body.push(line);
357
+ else
358
+ body[(count - 1) % limit] = line;
359
+ // One extra row suffices to detect hidden content in a head preview.
360
+ if (!fromEnd && count > limit)
361
+ break;
362
+ }
363
+ if (count === 0)
364
+ return [];
365
+ const visible = limit === 0 ? []
366
+ : fromEnd && count > limit
367
+ ? [...body.slice(count % limit), ...body.slice(0, count % limit)]
368
+ : body.slice(0, limit);
369
+ const style = (text) => theme.dim(chalk.italic(text));
370
+ const row = (text) => style(geometry.rail
371
+ ? railRow("┃", truncateVisible(text, geometry.bodyColumns))
372
+ : truncateVisible(text, geometry.bodyColumns));
373
+ const rows = [row(`◆ Thinking${projection.running ? "…" : ""}`)];
374
+ for (const line of visible)
375
+ rows.push(row(line));
376
+ if (count > visible.length) {
377
+ rows.push(row(options.showReasoning ? "…" : "… (Ctrl+T to expand)"));
378
+ }
379
+ return rows;
380
+ }
381
+ export function renderReasoning(content, options) {
382
+ const rows = projectReasoningRows(content, options);
383
+ if (rows.length === 0)
384
+ return [];
385
+ rows.push("");
386
+ return rows;
387
+ }
388
+ function argPreview(tool) {
389
+ const args = tool.args;
390
+ const firstString = ["command", "path", "pattern", "file_path", "url", "query"].find((key) => typeof args?.[key] === "string");
391
+ if (firstString)
392
+ return String(args[firstString]);
393
+ const raw = Object.keys(args ?? {})[0];
394
+ return raw ? String(args[raw]).slice(0, 40) : "";
395
+ }
396
+ export function renderToolTrace(tool, options) {
397
+ const theme = options.theme ?? defaultTranscriptTheme;
398
+ const label = toolTraceLabel(tool) || tool.name;
399
+ const preview = argPreview(tool);
400
+ const columns = Math.max(1, Math.floor(options.columns));
401
+ const text = truncateVisible(`◆ ${label}${preview ? ` ${preview}` : ""}`, columns);
402
+ const parts = [tool.isError ? theme.error(text) : `${theme.accent("◆")}${text.slice(1)}`];
403
+ if (tool.isError && tool.result !== undefined && options.verboseTrace) {
404
+ const errPreview = String(tool.result).split("\n")[0] ?? "";
405
+ parts.push(`\n${theme.error(truncateVisible(` ↳ ${errPreview}`, columns))}`);
406
+ }
407
+ else if (!tool.isError && options.verboseTrace && tool.result !== undefined) {
408
+ const okPreview = String(tool.result).split("\n")[0] ?? "";
409
+ parts.push(`\n${theme.dim(truncateVisible(` ↳ ${okPreview}`, columns))}`);
410
+ }
411
+ return parts.join("");
412
+ }
413
+ /**
414
+ * Render the same semantic trace groups used by the Ink TUI. This is shared
415
+ * by the live row pool and settled transcript so tool_start/tool_update/
416
+ * tool_end cannot change from a rich trace into an unrelated one-line row at
417
+ * the commit boundary.
418
+ */
419
+ export function renderToolTraceGroups(toolCalls, options, renderOptions = {}) {
420
+ return projectToolTraceGroups(toolCalls, options, renderOptions).rows;
421
+ }
422
+ export function projectToolTraceGroups(toolCalls, options, renderOptions = {}) {
423
+ const groups = buildTraceGroups([...toolCalls]);
424
+ const rows = [];
425
+ const traceTargets = [];
426
+ // `showActivity` remains part of the call contract, but Grok expresses
427
+ // activity by mutating the tool entry itself (`running`) instead of adding
428
+ // a second Working heading with a different marker.
429
+ void renderOptions.showActivity;
430
+ for (const group of groups) {
431
+ const projected = projectTraceGroup(group, options);
432
+ rows.push(...projected.rows);
433
+ traceTargets.push(...projected.traceTargets);
434
+ }
435
+ return {
436
+ rows,
437
+ traceTargets,
438
+ leadingSpacer: groups.length > 0,
439
+ trailingSpacer: groups.length > 0,
440
+ };
441
+ }
442
+ function projectTraceGroup(group, options) {
443
+ const theme = options.theme ?? defaultTranscriptTheme;
444
+ const columns = Math.max(1, options.columns);
445
+ const frameColumns = columns > TRANSCRIPT_RIGHT_MARGIN ? columns - TRANSCRIPT_RIGHT_MARGIN : columns;
446
+ const contentColumns = frameColumns >= TRACE_BORDER_MIN_COLUMNS
447
+ ? Math.max(1, frameColumns - TRACE_RESERVED_COLUMNS)
448
+ : frameColumns;
449
+ const interaction = options.traceInteraction;
450
+ const groupKey = interaction?.groupKey(group);
451
+ const readInteraction = group.kind === "read" ? interaction : undefined;
452
+ const singleRead = readInteraction && groupKey && group.raw.length === 1 ? group.raw[0] : undefined;
453
+ const singleItemKey = singleRead && interaction ? interaction.itemKey(group, singleRead.id) : undefined;
454
+ const interactive = interaction !== undefined && groupKey !== undefined;
455
+ const groupFoldable = isTraceGroupFoldable(group);
456
+ const singleItemFoldable = singleRead ? isTraceItemFoldable(singleRead) : false;
457
+ const expanded = interactive
458
+ ? singleItemKey
459
+ ? interaction.isItemExpanded(singleItemKey)
460
+ : interaction.isGroupExpanded(groupKey)
461
+ : false;
462
+ const selected = interaction?.isSelected(singleItemKey ?? groupKey ?? "") ?? false;
463
+ const marker = expanded ? "⌄" : selected ? "›" : "◆";
464
+ const status = group.pending
465
+ ? " running"
466
+ : group.statusLabel
467
+ ? ` ${group.statusLabel}`
468
+ : group.hasError
469
+ ? ` ${group.errorCount || 1} error${(group.errorCount || 1) === 1 ? "" : "s"}`
470
+ : "";
471
+ const detail = singleRead
472
+ ? ` ${readTraceLabel(singleRead)}`
473
+ : group.description
474
+ ? ` ${group.description}`
475
+ : group.command
476
+ ? ` ${group.command.replace(/\s+/g, " ")}`
477
+ : group.count !== undefined && group.noun
478
+ ? ` ${group.count} ${group.noun}`
479
+ : "";
480
+ const header = `${marker} ${group.title}${detail}${status}`;
481
+ const rows = [group.hasError
482
+ ? theme.error(truncateVisible(header, contentColumns))
483
+ : `${theme.accent(marker)}${truncateVisible(header.slice(marker.length), Math.max(0, contentColumns - stringWidth(marker)))}`];
484
+ const subagentIds = group.kind === "subagent"
485
+ ? group.raw[0]?.metadata?.subagents
486
+ ?.map((member) => typeof member?.subAgentId === "string" ? member.subAgentId : "")
487
+ .filter(Boolean) ?? []
488
+ : [];
489
+ const groupAction = subagentIds.length === 1
490
+ ? { kind: "open-subagent", subAgentId: subagentIds[0] }
491
+ : typeof group.raw[0]?.metadata?.taskId === "string"
492
+ ? { kind: "open-task", taskId: group.raw[0].metadata.taskId }
493
+ : undefined;
494
+ const groupTarget = groupKey
495
+ ? { kind: "group", key: groupKey, groupKey, foldable: groupFoldable, action: groupAction }
496
+ : undefined;
497
+ const singleTarget = singleItemKey && groupKey && singleRead
498
+ ? { kind: "item", key: singleItemKey, groupKey, toolId: singleRead.id, foldable: singleItemFoldable }
499
+ : undefined;
500
+ const traceTargets = [singleTarget ?? groupTarget];
501
+ const finish = () => decorateTraceGroup({ rows, traceTargets }, singleTarget ?? groupTarget, groupKey, frameColumns, theme, interaction);
502
+ // Interactive Read groups follow Grok's scrollback model: the summary row
503
+ // is collapsed by default; double-click reveals member rows. Individual
504
+ // members then own their file preview fold without changing the whole group.
505
+ if (readInteraction && groupKey) {
506
+ if (singleRead && singleTarget) {
507
+ if (expanded)
508
+ appendReadPreview(rows, traceTargets, singleRead, singleTarget, contentColumns, theme, " ");
509
+ return finish();
510
+ }
511
+ if (!expanded)
512
+ return finish();
513
+ for (const tool of group.raw) {
514
+ const itemKey = readInteraction.itemKey(group, tool.id);
515
+ const itemExpanded = readInteraction.isItemExpanded(itemKey);
516
+ const itemSelected = readInteraction.isSelected(itemKey);
517
+ const itemMarker = itemExpanded ? "⌄" : itemSelected ? "›" : "◆";
518
+ const label = readTraceLabel(tool);
519
+ const itemText = truncateVisible(` ${itemMarker} ${label}`, contentColumns);
520
+ rows.push(tool.isError ? theme.error(itemText) : theme.dim(itemText));
521
+ const itemTarget = {
522
+ kind: "item",
523
+ key: itemKey,
524
+ groupKey,
525
+ toolId: tool.id,
526
+ foldable: isTraceItemFoldable(tool),
527
+ };
528
+ traceTargets.push(itemTarget);
529
+ if (itemExpanded) {
530
+ appendReadPreview(rows, traceTargets, tool, itemTarget, contentColumns, theme, " ");
531
+ }
532
+ }
533
+ return finish();
534
+ }
535
+ // Grok tool blocks are collapsed by default. A single click selects the
536
+ // entry; a double-click reveals the detail surface only when the block has
537
+ // something meaningful to reveal. Failed List/Search blocks are deliberately
538
+ // non-foldable and keep their error detail visible in-place.
539
+ if (interactive && groupFoldable && !expanded)
540
+ return finish();
541
+ // While Execute is running, retain the command's own lines just like Ink.
542
+ // The header is only a summary and may be truncated on a narrow terminal.
543
+ const commandLines = group.commandLines ?? [];
544
+ const commandNeedsBlock = group.kind === "execute"
545
+ && (!!group.description
546
+ || commandLines.length > 1
547
+ || stringWidth(`◆ ${group.title} ${group.command ?? ""}`) > contentColumns);
548
+ if (commandNeedsBlock) {
549
+ const wrappedCommand = commandLines.flatMap((line) => wrapPlain(line || " ", Math.max(1, contentColumns - 2)));
550
+ for (const line of wrappedCommand.slice(0, 4)) {
551
+ rows.push(theme.dim(truncateVisible(` ${line}`, contentColumns)));
552
+ traceTargets.push(groupTarget);
553
+ }
554
+ if (wrappedCommand.length > 4) {
555
+ rows.push(theme.dim(truncateVisible(` … ${wrappedCommand.length - 4} more lines`, contentColumns)));
556
+ traceTargets.push(groupTarget);
557
+ }
558
+ }
559
+ const collapseSuccessfulExecute = !interactive
560
+ && group.kind === "execute"
561
+ && !group.pending
562
+ && !group.hasError
563
+ && !options.verboseTrace;
564
+ const details = group.kind === "search"
565
+ ? [...group.items, ...group.previewLines]
566
+ : group.previewLines.length > 0
567
+ ? group.previewLines
568
+ : group.items;
569
+ if (collapseSuccessfulExecute) {
570
+ const outputLines = group.previewLines.length + group.omitted;
571
+ rows.push(theme.dim(truncateVisible(` ⎿ ${outputLines > 0
572
+ ? `${outputLines} line${outputLines === 1 ? "" : "s"} output · Ctrl+O to view`
573
+ : "no output"}`, contentColumns)));
574
+ traceTargets.push(groupTarget);
575
+ }
576
+ else {
577
+ for (let index = 0; index < details.length; index += 1) {
578
+ const prefix = index === 0 ? " ↳ " : " ";
579
+ const line = truncateVisible(`${prefix}${details[index] ?? ""}`, contentColumns);
580
+ rows.push(group.hasError ? theme.error(line) : theme.dim(line));
581
+ traceTargets.push(groupTarget);
582
+ }
583
+ }
584
+ for (let index = 0; index < group.errorLines.length; index += 1) {
585
+ const prefix = index === 0 ? " ↳ " : " ";
586
+ rows.push(theme.error(truncateVisible(`${prefix}${group.errorLines[index] ?? ""}`, contentColumns)));
587
+ traceTargets.push(groupTarget);
588
+ }
589
+ if (group.omitted > 0) {
590
+ rows.push(theme.dim(truncateVisible(` … ${group.omitted} more`, contentColumns)));
591
+ traceTargets.push(groupTarget);
592
+ }
593
+ return finish();
594
+ }
595
+ function decorateTraceGroup(projection, target, groupKey, columns, theme, interaction) {
596
+ const selected = groupKey !== undefined && interaction?.isGroupSelected(groupKey) === true;
597
+ const hovered = groupKey !== undefined
598
+ && interaction?.isGroupHovered(groupKey) === true
599
+ && !selected;
600
+ const active = selected || hovered;
601
+ const border = selected
602
+ ? (theme.selectionBorder ?? theme.hoverBorder ?? theme.dim)
603
+ : (theme.hoverBorder ?? theme.dim);
604
+ const background = selected
605
+ ? (theme.selectionBackground ?? theme.hoverBackground ?? ((text) => text))
606
+ : (theme.hoverBackground ?? ((text) => text));
607
+ if (columns < TRACE_BORDER_MIN_COLUMNS) {
608
+ return {
609
+ rows: [
610
+ TRACE_IDLE_VPAD,
611
+ ...projection.rows.map((row) => {
612
+ if (!active)
613
+ return row;
614
+ const clipped = truncateVisible(row, columns);
615
+ return background(`${clipped}${" ".repeat(Math.max(0, columns - stringWidth(clipped)))}`);
616
+ }),
617
+ TRACE_IDLE_VPAD,
618
+ ],
619
+ traceTargets: [target, ...projection.traceTargets, target],
620
+ leadingSpacer: true,
621
+ trailingSpacer: true,
622
+ };
623
+ }
624
+ const top = active
625
+ ? border(`┌${" ".repeat(columns - 2)}┐`)
626
+ : TRACE_IDLE_VPAD;
627
+ const bottom = active
628
+ ? border(`└${" ".repeat(columns - 2)}┘`)
629
+ : TRACE_IDLE_VPAD;
630
+ const rows = projection.rows.map((row) => {
631
+ if (!active)
632
+ return railRow("", row);
633
+ const interior = `${" ".repeat(TRACE_CONTENT_LEFT_PAD)}${row}`;
634
+ const padding = " ".repeat(Math.max(0, columns - 2 - stringWidth(interior)));
635
+ return `${border("│")}${background(`${interior}${padding}`)}${border("│")}`;
636
+ });
637
+ return {
638
+ rows: [top, ...rows, bottom],
639
+ traceTargets: [target, ...projection.traceTargets, target],
640
+ leadingSpacer: true,
641
+ trailingSpacer: true,
642
+ };
643
+ }
644
+ function isTraceItemFoldable(tool) {
645
+ return typeof tool.result === "string" && tool.result.trim().length > 0;
646
+ }
647
+ function isTraceGroupFoldable(group) {
648
+ switch (group.kind) {
649
+ case "read":
650
+ return group.raw.length > 1 || group.raw.some(isTraceItemFoldable);
651
+ case "list":
652
+ return !group.hasError && (group.items.length > 0 || group.omitted > 0);
653
+ case "search":
654
+ // Grok keeps successful Search entries foldable even for zero results so
655
+ // the expanded view can still reveal the query metadata / no-result state.
656
+ return !group.hasError;
657
+ case "execute":
658
+ return !!group.description
659
+ || (group.commandLines?.length ?? 0) > 1
660
+ || group.previewLines.length > 0
661
+ || group.errorLines.length > 0
662
+ || group.omitted > 0;
663
+ default:
664
+ return false;
665
+ }
666
+ }
667
+ function readTraceLabel(tool) {
668
+ const value = tool.args.path ?? tool.args.file ?? tool.metadata?.path ?? argPreview(tool);
669
+ return formatTracePath(value || tool.name);
670
+ }
671
+ function appendReadPreview(rows, traceTargets, tool, target, columns, theme, indent) {
672
+ if (tool.result === undefined)
673
+ return;
674
+ const normalized = tool.result.replace(/\r\n/g, "\n");
675
+ const source = tool.name === "bash" && normalized.startsWith("stdout:\n")
676
+ ? normalized.slice("stdout:\n".length)
677
+ : normalized;
678
+ const preview = source
679
+ .split("\n")
680
+ .filter((line) => line.trim() !== "")
681
+ .flatMap((line) => wrapPlain(line, Math.max(1, columns - indent.length)));
682
+ for (const line of preview.slice(0, 8)) {
683
+ rows.push((tool.isError ? theme.error : theme.dim)(truncateVisible(`${indent}${line}`, columns)));
684
+ traceTargets.push(target);
685
+ }
686
+ if (preview.length > 8) {
687
+ rows.push(theme.dim(truncateVisible(`${indent}… ${preview.length - 8} more lines`, columns)));
688
+ traceTargets.push(target);
689
+ }
690
+ }
691
+ /**
692
+ * Manual Compact keeps its terminal event deliberately terse, but the summary
693
+ * that replaced the old context remains inspectable. Treat the event as the
694
+ * same scrollback surface as a settled tool trace: hover/select paint the
695
+ * complete row and double-click folds the real summary in place.
696
+ */
697
+ function projectCompactionSummary(message, options) {
698
+ const theme = options.theme ?? defaultTranscriptTheme;
699
+ const columns = Math.max(1, options.columns);
700
+ const frameColumns = columns > TRANSCRIPT_RIGHT_MARGIN ? columns - TRANSCRIPT_RIGHT_MARGIN : columns;
701
+ const contentColumns = frameColumns >= TRACE_BORDER_MIN_COLUMNS
702
+ ? Math.max(1, frameColumns - TRACE_RESERVED_COLUMNS)
703
+ : frameColumns;
704
+ const interaction = options.traceInteraction;
705
+ const groupKey = `compact:${message.key ?? `${message.content}:${message.compactionSummary ?? ""}`}`;
706
+ const target = {
707
+ kind: "group",
708
+ key: groupKey,
709
+ groupKey,
710
+ foldable: true,
711
+ };
712
+ const expanded = interaction?.isGroupExpanded(groupKey) ?? false;
713
+ const selected = interaction?.isSelected(groupKey) ?? false;
714
+ const marker = expanded ? "⌄" : selected ? "›" : "◆";
715
+ const label = message.content.trim() || "Compaction completed.";
716
+ const header = `${marker} ${label}`;
717
+ const rows = [
718
+ `${theme.accent(marker)}${truncateVisible(header.slice(marker.length), Math.max(0, contentColumns - stringWidth(marker)))}`,
719
+ ];
720
+ const traceTargets = [target];
721
+ if (expanded) {
722
+ const summary = message.compactionSummary?.trim() ?? "";
723
+ const bodyWidth = Math.max(1, contentColumns - 2);
724
+ const bodyRows = options.markdownRenderer
725
+ ? options.markdownRenderer(summary, bodyWidth)
726
+ : wrapPlain(summary, bodyWidth);
727
+ for (const row of bodyRows) {
728
+ rows.push(theme.dim(truncateVisible(` ${row}`, contentColumns)));
729
+ traceTargets.push(target);
730
+ }
731
+ }
732
+ return decorateTraceGroup({ rows, traceTargets }, target, groupKey, frameColumns, theme, interaction);
733
+ }
734
+ export function renderMessage(message, options) {
735
+ return projectMessage(message, options).rows;
736
+ }
737
+ export function projectMessage(message, options) {
738
+ const theme = options.theme ?? defaultTranscriptTheme;
739
+ if (message.role === "user") {
740
+ return projectUserCard(message, options);
741
+ }
742
+ if (message.role === "error") {
743
+ return plainProjection([...projectAssistantRows(message.content, options).map(theme.error), ""]);
744
+ }
745
+ if (message.syntheticKind === "ui_compact_summary" && message.compactionSummary?.trim()) {
746
+ return projectCompactionSummary(message, options);
747
+ }
748
+ if (message.syntheticKind) {
749
+ return plainProjection([
750
+ ...projectAssistantRows(message.content, { ...options, markdownRenderer: undefined }).map(theme.dim),
751
+ "",
752
+ ]);
753
+ }
754
+ const blocks = [];
755
+ if (message.reasoning)
756
+ blocks.push(plainProjection(projectReasoningRows(message.reasoning, options)));
757
+ if (message.toolCalls?.length)
758
+ blocks.push(projectToolTraceGroups(message.toolCalls, options));
759
+ if (message.content?.trim())
760
+ blocks.push(plainProjection(projectAssistantRows(message.content, options)));
761
+ const projection = joinTranscriptProjections(blocks);
762
+ if (projection.rows.length === 0)
763
+ return plainProjection([""]);
764
+ projection.rows.push("");
765
+ projection.traceTargets.push(undefined);
766
+ projection.trailingSpacer = true;
767
+ return projection;
768
+ }
769
+ /**
770
+ * Render one assistant provider-turn as part of the surrounding user request.
771
+ *
772
+ * One agent run may contain many provider turns (`turn_end.willContinue`) —
773
+ * normally one before every tool call. Rendering every turn independently
774
+ * exposes the implementation boundary as `thinking → tool → thinking → tool`.
775
+ * The user-facing tool trace is grouped into one request lifecycle, while
776
+ * every provider turn's reasoning remains visible. Live rendering exposes
777
+ * each new reasoning segment, so suppressing later segments only after settle
778
+ * would create another disappear-at-finalize jump.
779
+ *
780
+ * Thinking
781
+ * ◆ tool
782
+ * Thinking (a later provider turn, if present)
783
+ * tool
784
+ * final answer
785
+ *
786
+ * Expanded mode still retains every reasoning segment for diagnostics.
787
+ */
788
+ function projectAssistantInRequest(message, options) {
789
+ const blocks = [];
790
+ if (message.reasoning) {
791
+ blocks.push(plainProjection(projectReasoningRows(message.reasoning, options)));
792
+ }
793
+ const appendTools = (tools) => {
794
+ blocks.push(projectToolTraceGroups(tools, options));
795
+ };
796
+ // Preserve the model's real commentary/tool timeline. `parts` is the
797
+ // canonical ordered stream; the top-level fields are only the fallback for
798
+ // restored/legacy messages. Rendering toolCalls first and content second
799
+ // inverted commentary that was emitted before a tool call.
800
+ if (message.parts?.length) {
801
+ for (const part of message.parts) {
802
+ if (part.type === "tools") {
803
+ appendTools(part.toolCalls);
804
+ }
805
+ else if (part.content.trim()) {
806
+ blocks.push(plainProjection(projectAssistantRows(part.content, options)));
807
+ }
808
+ }
809
+ }
810
+ else {
811
+ if (message.toolCalls?.length)
812
+ appendTools(message.toolCalls);
813
+ if (message.content?.trim())
814
+ blocks.push(plainProjection(projectAssistantRows(message.content, options)));
815
+ }
816
+ return joinTranscriptProjections(blocks);
817
+ }
818
+ export function renderTranscript(messages, options) {
819
+ return projectTranscript(messages, options).rows;
820
+ }
821
+ export function projectTranscript(messages, options) {
822
+ const messageBlocks = [];
823
+ for (let messageIndex = 0; messageIndex < messages.length; messageIndex += 1) {
824
+ const message = messages[messageIndex];
825
+ let block;
826
+ if (message.role === "user") {
827
+ block = projectUserCard(message, options);
828
+ }
829
+ else if (message.role === "assistant" && !message.syntheticKind) {
830
+ block = projectAssistantInRequest(message, options);
831
+ }
832
+ else {
833
+ block = projectMessage(message, options);
834
+ }
835
+ if (options.dimFromMessageIndex !== undefined && messageIndex >= options.dimFromMessageIndex) {
836
+ block = {
837
+ ...block,
838
+ rows: block.rows.map((row) => row ? chalk.dim(row) : row),
839
+ };
840
+ }
841
+ messageBlocks.push(block);
842
+ }
843
+ const projection = joinTranscriptProjections(messageBlocks);
844
+ // The transcript owns the sole separator before a live assistant surface.
845
+ // When that surface settles, the same row becomes the transcript's trailing
846
+ // separator, so user -> Thinking geometry cannot change at commit time.
847
+ // A transcript that already ends in a spacer (a tool group's bottom padding)
848
+ // must not gain a second one, or the next turn's live Thinking sits one row
849
+ // lower than it will after commit.
850
+ if (projection.rows.length === 0)
851
+ return projection;
852
+ if (options.trailingSpacer !== false && !projection.trailingSpacer) {
853
+ projection.rows.push("");
854
+ projection.traceTargets.push(undefined);
855
+ projection.trailingSpacer = true;
856
+ }
857
+ return projection;
858
+ }