pulseed 0.5.1 → 0.5.3

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 (573) hide show
  1. package/dist/adapters/types/a2a.d.ts +6 -6
  2. package/dist/base/config/identity-loader.d.ts +6 -0
  3. package/dist/base/config/identity-loader.d.ts.map +1 -1
  4. package/dist/base/config/identity-loader.js +34 -8
  5. package/dist/base/config/identity-loader.js.map +1 -1
  6. package/dist/grounding/gateway.d.ts.map +1 -1
  7. package/dist/grounding/gateway.js +2 -1
  8. package/dist/grounding/gateway.js.map +1 -1
  9. package/dist/grounding/providers/static-policy-provider.d.ts +1 -1
  10. package/dist/grounding/providers/static-policy-provider.d.ts.map +1 -1
  11. package/dist/grounding/providers/static-policy-provider.js +12 -8
  12. package/dist/grounding/providers/static-policy-provider.js.map +1 -1
  13. package/dist/index.d.ts +2 -0
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +1 -0
  16. package/dist/index.js.map +1 -1
  17. package/dist/interface/chat/chat-event-state.d.ts +10 -0
  18. package/dist/interface/chat/chat-event-state.d.ts.map +1 -1
  19. package/dist/interface/chat/chat-event-state.js +184 -9
  20. package/dist/interface/chat/chat-event-state.js.map +1 -1
  21. package/dist/interface/chat/chat-events.d.ts +3 -1
  22. package/dist/interface/chat/chat-events.d.ts.map +1 -1
  23. package/dist/interface/chat/chat-runner.d.ts +25 -1
  24. package/dist/interface/chat/chat-runner.d.ts.map +1 -1
  25. package/dist/interface/chat/chat-runner.js +751 -83
  26. package/dist/interface/chat/chat-runner.js.map +1 -1
  27. package/dist/interface/chat/chat-verifier.d.ts +3 -1
  28. package/dist/interface/chat/chat-verifier.d.ts.map +1 -1
  29. package/dist/interface/chat/chat-verifier.js +2 -2
  30. package/dist/interface/chat/chat-verifier.js.map +1 -1
  31. package/dist/interface/chat/cross-platform-session.d.ts +4 -0
  32. package/dist/interface/chat/cross-platform-session.d.ts.map +1 -1
  33. package/dist/interface/chat/cross-platform-session.js +33 -0
  34. package/dist/interface/chat/cross-platform-session.js.map +1 -1
  35. package/dist/interface/chat/failure-recovery.d.ts +11 -0
  36. package/dist/interface/chat/failure-recovery.d.ts.map +1 -0
  37. package/dist/interface/chat/failure-recovery.js +115 -0
  38. package/dist/interface/chat/failure-recovery.js.map +1 -0
  39. package/dist/interface/chat/grounding.d.ts +1 -1
  40. package/dist/interface/chat/grounding.d.ts.map +1 -1
  41. package/dist/interface/chat/grounding.js +2 -2
  42. package/dist/interface/chat/grounding.js.map +1 -1
  43. package/dist/interface/chat/ingress-router.d.ts +11 -0
  44. package/dist/interface/chat/ingress-router.d.ts.map +1 -1
  45. package/dist/interface/chat/ingress-router.js +46 -2
  46. package/dist/interface/chat/ingress-router.js.map +1 -1
  47. package/dist/interface/chat/tend-command.d.ts +8 -0
  48. package/dist/interface/chat/tend-command.d.ts.map +1 -1
  49. package/dist/interface/chat/tend-command.js +80 -4
  50. package/dist/interface/chat/tend-command.js.map +1 -1
  51. package/dist/interface/cli/cli-command-registry.d.ts.map +1 -1
  52. package/dist/interface/cli/cli-command-registry.js +4 -0
  53. package/dist/interface/cli/cli-command-registry.js.map +1 -1
  54. package/dist/interface/cli/commands/daemon.d.ts.map +1 -1
  55. package/dist/interface/cli/commands/daemon.js +41 -7
  56. package/dist/interface/cli/commands/daemon.js.map +1 -1
  57. package/dist/interface/cli/commands/runtime.d.ts +3 -0
  58. package/dist/interface/cli/commands/runtime.d.ts.map +1 -0
  59. package/dist/interface/cli/commands/runtime.js +231 -0
  60. package/dist/interface/cli/commands/runtime.js.map +1 -0
  61. package/dist/interface/cli/commands/setup/steps-identity.d.ts.map +1 -1
  62. package/dist/interface/cli/commands/setup/steps-identity.js +5 -0
  63. package/dist/interface/cli/commands/setup/steps-identity.js.map +1 -1
  64. package/dist/interface/cli/commands/setup/steps-runtime.d.ts +2 -0
  65. package/dist/interface/cli/commands/setup/steps-runtime.d.ts.map +1 -1
  66. package/dist/interface/cli/commands/setup/steps-runtime.js +11 -2
  67. package/dist/interface/cli/commands/setup/steps-runtime.js.map +1 -1
  68. package/dist/interface/cli/setup.d.ts.map +1 -1
  69. package/dist/interface/cli/setup.js +14 -1
  70. package/dist/interface/cli/setup.js.map +1 -1
  71. package/dist/interface/cli/utils.d.ts.map +1 -1
  72. package/dist/interface/cli/utils.js +4 -0
  73. package/dist/interface/cli/utils.js.map +1 -1
  74. package/dist/interface/tui/app.d.ts +2 -0
  75. package/dist/interface/tui/app.d.ts.map +1 -1
  76. package/dist/interface/tui/app.js +73 -16
  77. package/dist/interface/tui/app.js.map +1 -1
  78. package/dist/interface/tui/chat/scroll.d.ts +3 -0
  79. package/dist/interface/tui/chat/scroll.d.ts.map +1 -1
  80. package/dist/interface/tui/chat/scroll.js +15 -0
  81. package/dist/interface/tui/chat/scroll.js.map +1 -1
  82. package/dist/interface/tui/chat/types.d.ts +1 -1
  83. package/dist/interface/tui/chat/types.d.ts.map +1 -1
  84. package/dist/interface/tui/chat/viewport.d.ts.map +1 -1
  85. package/dist/interface/tui/chat/viewport.js +8 -2
  86. package/dist/interface/tui/chat/viewport.js.map +1 -1
  87. package/dist/interface/tui/chat-surface.d.ts +2 -0
  88. package/dist/interface/tui/chat-surface.d.ts.map +1 -1
  89. package/dist/interface/tui/chat-surface.js +11 -0
  90. package/dist/interface/tui/chat-surface.js.map +1 -1
  91. package/dist/interface/tui/chat.d.ts.map +1 -1
  92. package/dist/interface/tui/chat.js +15 -7
  93. package/dist/interface/tui/chat.js.map +1 -1
  94. package/dist/interface/tui/clipboard.d.ts +6 -1
  95. package/dist/interface/tui/clipboard.d.ts.map +1 -1
  96. package/dist/interface/tui/clipboard.js +24 -5
  97. package/dist/interface/tui/clipboard.js.map +1 -1
  98. package/dist/interface/tui/entry.d.ts.map +1 -1
  99. package/dist/interface/tui/entry.js +28 -3
  100. package/dist/interface/tui/entry.js.map +1 -1
  101. package/dist/interface/tui/flicker/MouseTracking.d.ts +1 -1
  102. package/dist/interface/tui/flicker/MouseTracking.d.ts.map +1 -1
  103. package/dist/interface/tui/flicker/MouseTracking.js +8 -4
  104. package/dist/interface/tui/flicker/MouseTracking.js.map +1 -1
  105. package/dist/interface/tui/fullscreen-chat.d.ts +86 -5
  106. package/dist/interface/tui/fullscreen-chat.d.ts.map +1 -1
  107. package/dist/interface/tui/fullscreen-chat.js +586 -32
  108. package/dist/interface/tui/fullscreen-chat.js.map +1 -1
  109. package/dist/interface/tui/help-overlay.d.ts.map +1 -1
  110. package/dist/interface/tui/help-overlay.js +1 -1
  111. package/dist/interface/tui/help-overlay.js.map +1 -1
  112. package/dist/interface/tui/markdown-renderer.d.ts.map +1 -1
  113. package/dist/interface/tui/markdown-renderer.js +40 -12
  114. package/dist/interface/tui/markdown-renderer.js.map +1 -1
  115. package/dist/interface/tui/test-entry.js +1 -1
  116. package/dist/interface/tui/test-entry.js.map +1 -1
  117. package/dist/orchestrator/execution/adapter-layer.d.ts +2 -0
  118. package/dist/orchestrator/execution/adapter-layer.d.ts.map +1 -1
  119. package/dist/orchestrator/execution/adapter-layer.js.map +1 -1
  120. package/dist/orchestrator/execution/agent-loop/agent-loop-context-assembler.d.ts.map +1 -1
  121. package/dist/orchestrator/execution/agent-loop/agent-loop-context-assembler.js +1 -0
  122. package/dist/orchestrator/execution/agent-loop/agent-loop-context-assembler.js.map +1 -1
  123. package/dist/orchestrator/execution/agent-loop/agent-loop-default-profile.d.ts.map +1 -1
  124. package/dist/orchestrator/execution/agent-loop/agent-loop-default-profile.js +53 -12
  125. package/dist/orchestrator/execution/agent-loop/agent-loop-default-profile.js.map +1 -1
  126. package/dist/orchestrator/execution/agent-loop/agent-loop-dogfood-benchmark.d.ts.map +1 -1
  127. package/dist/orchestrator/execution/agent-loop/agent-loop-dogfood-benchmark.js +7 -4
  128. package/dist/orchestrator/execution/agent-loop/agent-loop-dogfood-benchmark.js.map +1 -1
  129. package/dist/orchestrator/execution/agent-loop/agent-loop-prompts.d.ts +1 -0
  130. package/dist/orchestrator/execution/agent-loop/agent-loop-prompts.d.ts.map +1 -1
  131. package/dist/orchestrator/execution/agent-loop/agent-loop-prompts.js +10 -3
  132. package/dist/orchestrator/execution/agent-loop/agent-loop-prompts.js.map +1 -1
  133. package/dist/orchestrator/execution/agent-loop/agent-loop-session-factory.d.ts.map +1 -1
  134. package/dist/orchestrator/execution/agent-loop/agent-loop-session-factory.js +2 -1
  135. package/dist/orchestrator/execution/agent-loop/agent-loop-session-factory.js.map +1 -1
  136. package/dist/orchestrator/execution/agent-loop/agent-loop-turn-context.d.ts +2 -0
  137. package/dist/orchestrator/execution/agent-loop/agent-loop-turn-context.d.ts.map +1 -1
  138. package/dist/orchestrator/execution/agent-loop/agent-loop-turn-context.js.map +1 -1
  139. package/dist/orchestrator/execution/agent-loop/bounded-agent-loop-runner.d.ts.map +1 -1
  140. package/dist/orchestrator/execution/agent-loop/bounded-agent-loop-runner.js +51 -0
  141. package/dist/orchestrator/execution/agent-loop/bounded-agent-loop-runner.js.map +1 -1
  142. package/dist/orchestrator/execution/agent-loop/chat-agent-loop-runner.d.ts +13 -4
  143. package/dist/orchestrator/execution/agent-loop/chat-agent-loop-runner.d.ts.map +1 -1
  144. package/dist/orchestrator/execution/agent-loop/chat-agent-loop-runner.js +44 -126
  145. package/dist/orchestrator/execution/agent-loop/chat-agent-loop-runner.js.map +1 -1
  146. package/dist/orchestrator/execution/agent-loop/chat-display-output.d.ts +27 -0
  147. package/dist/orchestrator/execution/agent-loop/chat-display-output.d.ts.map +1 -0
  148. package/dist/orchestrator/execution/agent-loop/chat-display-output.js +157 -0
  149. package/dist/orchestrator/execution/agent-loop/chat-display-output.js.map +1 -0
  150. package/dist/orchestrator/execution/agent-loop/core-phase-runner.d.ts +1 -1
  151. package/dist/orchestrator/execution/agent-loop/core-phase-runner.d.ts.map +1 -1
  152. package/dist/orchestrator/execution/agent-loop/core-phase-runner.js.map +1 -1
  153. package/dist/orchestrator/execution/agent-loop/index.d.ts +1 -0
  154. package/dist/orchestrator/execution/agent-loop/index.d.ts.map +1 -1
  155. package/dist/orchestrator/execution/agent-loop/index.js +1 -0
  156. package/dist/orchestrator/execution/agent-loop/index.js.map +1 -1
  157. package/dist/orchestrator/execution/agent-loop/kaggle-training-benchmark.d.ts +34 -0
  158. package/dist/orchestrator/execution/agent-loop/kaggle-training-benchmark.d.ts.map +1 -0
  159. package/dist/orchestrator/execution/agent-loop/kaggle-training-benchmark.js +54 -0
  160. package/dist/orchestrator/execution/agent-loop/kaggle-training-benchmark.js.map +1 -0
  161. package/dist/orchestrator/execution/agent-loop/task-agent-loop-factory.d.ts +2 -0
  162. package/dist/orchestrator/execution/agent-loop/task-agent-loop-factory.d.ts.map +1 -1
  163. package/dist/orchestrator/execution/agent-loop/task-agent-loop-factory.js +10 -0
  164. package/dist/orchestrator/execution/agent-loop/task-agent-loop-factory.js.map +1 -1
  165. package/dist/orchestrator/goal/goal-suggest.d.ts +4 -4
  166. package/dist/orchestrator/goal/types/goal-tree.d.ts +2 -2
  167. package/dist/orchestrator/loop/core-loop/contracts.d.ts +19 -0
  168. package/dist/orchestrator/loop/core-loop/contracts.d.ts.map +1 -1
  169. package/dist/orchestrator/loop/core-loop/contracts.js.map +1 -1
  170. package/dist/orchestrator/loop/core-loop/iteration-kernel.d.ts +1 -0
  171. package/dist/orchestrator/loop/core-loop/iteration-kernel.d.ts.map +1 -1
  172. package/dist/orchestrator/loop/core-loop/iteration-kernel.js +61 -2
  173. package/dist/orchestrator/loop/core-loop/iteration-kernel.js.map +1 -1
  174. package/dist/orchestrator/loop/core-loop/phase-policy.d.ts.map +1 -1
  175. package/dist/orchestrator/loop/core-loop/phase-policy.js +27 -0
  176. package/dist/orchestrator/loop/core-loop/phase-policy.js.map +1 -1
  177. package/dist/orchestrator/loop/core-loop/phase-specs.d.ts +37 -0
  178. package/dist/orchestrator/loop/core-loop/phase-specs.d.ts.map +1 -1
  179. package/dist/orchestrator/loop/core-loop/phase-specs.js +28 -0
  180. package/dist/orchestrator/loop/core-loop/phase-specs.js.map +1 -1
  181. package/dist/orchestrator/loop/core-loop/task-cycle.d.ts +12 -0
  182. package/dist/orchestrator/loop/core-loop/task-cycle.d.ts.map +1 -1
  183. package/dist/orchestrator/loop/core-loop/task-cycle.js +170 -23
  184. package/dist/orchestrator/loop/core-loop/task-cycle.js.map +1 -1
  185. package/dist/orchestrator/loop/core-loop.d.ts +2 -1
  186. package/dist/orchestrator/loop/core-loop.d.ts.map +1 -1
  187. package/dist/orchestrator/loop/core-loop.js +3 -0
  188. package/dist/orchestrator/loop/core-loop.js.map +1 -1
  189. package/dist/orchestrator/loop/loop-report-helper.d.ts.map +1 -1
  190. package/dist/orchestrator/loop/loop-report-helper.js +24 -0
  191. package/dist/orchestrator/loop/loop-report-helper.js.map +1 -1
  192. package/dist/orchestrator/loop/loop-result-types.d.ts +7 -0
  193. package/dist/orchestrator/loop/loop-result-types.d.ts.map +1 -1
  194. package/dist/orchestrator/loop/loop-result-types.js.map +1 -1
  195. package/dist/orchestrator/strategy/portfolio-manager.d.ts +2 -2
  196. package/dist/orchestrator/strategy/portfolio-manager.d.ts.map +1 -1
  197. package/dist/orchestrator/strategy/portfolio-manager.js +11 -1
  198. package/dist/orchestrator/strategy/portfolio-manager.js.map +1 -1
  199. package/dist/orchestrator/strategy/portfolio-rebalance.d.ts +4 -2
  200. package/dist/orchestrator/strategy/portfolio-rebalance.d.ts.map +1 -1
  201. package/dist/orchestrator/strategy/portfolio-rebalance.js +490 -12
  202. package/dist/orchestrator/strategy/portfolio-rebalance.js.map +1 -1
  203. package/dist/orchestrator/strategy/strategy-manager.js +3 -3
  204. package/dist/orchestrator/strategy/strategy-manager.js.map +1 -1
  205. package/dist/orchestrator/strategy/types/cross-portfolio.d.ts +2 -2
  206. package/dist/orchestrator/strategy/types/portfolio.d.ts +12 -12
  207. package/dist/orchestrator/strategy/types/strategy.d.ts +639 -8
  208. package/dist/orchestrator/strategy/types/strategy.d.ts.map +1 -1
  209. package/dist/orchestrator/strategy/types/strategy.js +122 -0
  210. package/dist/orchestrator/strategy/types/strategy.js.map +1 -1
  211. package/dist/platform/code-search/candidate-normalizer.d.ts +3 -0
  212. package/dist/platform/code-search/candidate-normalizer.d.ts.map +1 -0
  213. package/dist/platform/code-search/candidate-normalizer.js +61 -0
  214. package/dist/platform/code-search/candidate-normalizer.js.map +1 -0
  215. package/dist/platform/code-search/candidate.d.ts +25 -0
  216. package/dist/platform/code-search/candidate.d.ts.map +1 -0
  217. package/dist/platform/code-search/candidate.js +61 -0
  218. package/dist/platform/code-search/candidate.js.map +1 -0
  219. package/dist/platform/code-search/contracts.d.ts +275 -0
  220. package/dist/platform/code-search/contracts.d.ts.map +1 -0
  221. package/dist/platform/code-search/contracts.js +22 -0
  222. package/dist/platform/code-search/contracts.js.map +1 -0
  223. package/dist/platform/code-search/eval/fixtures.d.ts +14 -0
  224. package/dist/platform/code-search/eval/fixtures.d.ts.map +1 -0
  225. package/dist/platform/code-search/eval/fixtures.js +24 -0
  226. package/dist/platform/code-search/eval/fixtures.js.map +1 -0
  227. package/dist/platform/code-search/eval/metrics.d.ts +10 -0
  228. package/dist/platform/code-search/eval/metrics.d.ts.map +1 -0
  229. package/dist/platform/code-search/eval/metrics.js +20 -0
  230. package/dist/platform/code-search/eval/metrics.js.map +1 -0
  231. package/dist/platform/code-search/eval/runner.d.ts +3 -0
  232. package/dist/platform/code-search/eval/runner.d.ts.map +1 -0
  233. package/dist/platform/code-search/eval/runner.js +13 -0
  234. package/dist/platform/code-search/eval/runner.js.map +1 -0
  235. package/dist/platform/code-search/fusion.d.ts +6 -0
  236. package/dist/platform/code-search/fusion.d.ts.map +1 -0
  237. package/dist/platform/code-search/fusion.js +12 -0
  238. package/dist/platform/code-search/fusion.js.map +1 -0
  239. package/dist/platform/code-search/generated-detector.d.ts +15 -0
  240. package/dist/platform/code-search/generated-detector.d.ts.map +1 -0
  241. package/dist/platform/code-search/generated-detector.js +42 -0
  242. package/dist/platform/code-search/generated-detector.js.map +1 -0
  243. package/dist/platform/code-search/indexes/call-graph.d.ts +3 -0
  244. package/dist/platform/code-search/indexes/call-graph.d.ts.map +1 -0
  245. package/dist/platform/code-search/indexes/call-graph.js +13 -0
  246. package/dist/platform/code-search/indexes/call-graph.js.map +1 -0
  247. package/dist/platform/code-search/indexes/config-index.d.ts +3 -0
  248. package/dist/platform/code-search/indexes/config-index.d.ts.map +1 -0
  249. package/dist/platform/code-search/indexes/config-index.js +7 -0
  250. package/dist/platform/code-search/indexes/config-index.js.map +1 -0
  251. package/dist/platform/code-search/indexes/file-index.d.ts +5 -0
  252. package/dist/platform/code-search/indexes/file-index.d.ts.map +1 -0
  253. package/dist/platform/code-search/indexes/file-index.js +106 -0
  254. package/dist/platform/code-search/indexes/file-index.js.map +1 -0
  255. package/dist/platform/code-search/indexes/index-store.d.ts +6 -0
  256. package/dist/platform/code-search/indexes/index-store.d.ts.map +1 -0
  257. package/dist/platform/code-search/indexes/index-store.js +14 -0
  258. package/dist/platform/code-search/indexes/index-store.js.map +1 -0
  259. package/dist/platform/code-search/indexes/indexer.d.ts +3 -0
  260. package/dist/platform/code-search/indexes/indexer.d.ts.map +1 -0
  261. package/dist/platform/code-search/indexes/indexer.js +27 -0
  262. package/dist/platform/code-search/indexes/indexer.js.map +1 -0
  263. package/dist/platform/code-search/indexes/package-graph.d.ts +3 -0
  264. package/dist/platform/code-search/indexes/package-graph.d.ts.map +1 -0
  265. package/dist/platform/code-search/indexes/package-graph.js +26 -0
  266. package/dist/platform/code-search/indexes/package-graph.js.map +1 -0
  267. package/dist/platform/code-search/indexes/repo-map-index.d.ts +3 -0
  268. package/dist/platform/code-search/indexes/repo-map-index.d.ts.map +1 -0
  269. package/dist/platform/code-search/indexes/repo-map-index.js +26 -0
  270. package/dist/platform/code-search/indexes/repo-map-index.js.map +1 -0
  271. package/dist/platform/code-search/indexes/semantic-index.d.ts +3 -0
  272. package/dist/platform/code-search/indexes/semantic-index.d.ts.map +1 -0
  273. package/dist/platform/code-search/indexes/semantic-index.js +4 -0
  274. package/dist/platform/code-search/indexes/semantic-index.js.map +1 -0
  275. package/dist/platform/code-search/indexes/symbol-index.d.ts +3 -0
  276. package/dist/platform/code-search/indexes/symbol-index.d.ts.map +1 -0
  277. package/dist/platform/code-search/indexes/symbol-index.js +84 -0
  278. package/dist/platform/code-search/indexes/symbol-index.js.map +1 -0
  279. package/dist/platform/code-search/indexes/test-index.d.ts +3 -0
  280. package/dist/platform/code-search/indexes/test-index.d.ts.map +1 -0
  281. package/dist/platform/code-search/indexes/test-index.js +22 -0
  282. package/dist/platform/code-search/indexes/test-index.js.map +1 -0
  283. package/dist/platform/code-search/orchestrator.d.ts +9 -0
  284. package/dist/platform/code-search/orchestrator.d.ts.map +1 -0
  285. package/dist/platform/code-search/orchestrator.js +81 -0
  286. package/dist/platform/code-search/orchestrator.js.map +1 -0
  287. package/dist/platform/code-search/path-policy.d.ts +6 -0
  288. package/dist/platform/code-search/path-policy.d.ts.map +1 -0
  289. package/dist/platform/code-search/path-policy.js +60 -0
  290. package/dist/platform/code-search/path-policy.js.map +1 -0
  291. package/dist/platform/code-search/progressive-reader.d.ts +8 -0
  292. package/dist/platform/code-search/progressive-reader.d.ts.map +1 -0
  293. package/dist/platform/code-search/progressive-reader.js +173 -0
  294. package/dist/platform/code-search/progressive-reader.js.map +1 -0
  295. package/dist/platform/code-search/query-planner.d.ts +4 -0
  296. package/dist/platform/code-search/query-planner.d.ts.map +1 -0
  297. package/dist/platform/code-search/query-planner.js +107 -0
  298. package/dist/platform/code-search/query-planner.js.map +1 -0
  299. package/dist/platform/code-search/reranker.d.ts +4 -0
  300. package/dist/platform/code-search/reranker.d.ts.map +1 -0
  301. package/dist/platform/code-search/reranker.js +57 -0
  302. package/dist/platform/code-search/reranker.js.map +1 -0
  303. package/dist/platform/code-search/retrievers/callgraph-retriever.d.ts +6 -0
  304. package/dist/platform/code-search/retrievers/callgraph-retriever.d.ts.map +1 -0
  305. package/dist/platform/code-search/retrievers/callgraph-retriever.js +31 -0
  306. package/dist/platform/code-search/retrievers/callgraph-retriever.js.map +1 -0
  307. package/dist/platform/code-search/retrievers/config-retriever.d.ts +6 -0
  308. package/dist/platform/code-search/retrievers/config-retriever.d.ts.map +1 -0
  309. package/dist/platform/code-search/retrievers/config-retriever.js +23 -0
  310. package/dist/platform/code-search/retrievers/config-retriever.js.map +1 -0
  311. package/dist/platform/code-search/retrievers/lexical-retriever.d.ts +6 -0
  312. package/dist/platform/code-search/retrievers/lexical-retriever.d.ts.map +1 -0
  313. package/dist/platform/code-search/retrievers/lexical-retriever.js +49 -0
  314. package/dist/platform/code-search/retrievers/lexical-retriever.js.map +1 -0
  315. package/dist/platform/code-search/retrievers/package-retriever.d.ts +6 -0
  316. package/dist/platform/code-search/retrievers/package-retriever.d.ts.map +1 -0
  317. package/dist/platform/code-search/retrievers/package-retriever.js +29 -0
  318. package/dist/platform/code-search/retrievers/package-retriever.js.map +1 -0
  319. package/dist/platform/code-search/retrievers/repo-map-retriever.d.ts +6 -0
  320. package/dist/platform/code-search/retrievers/repo-map-retriever.d.ts.map +1 -0
  321. package/dist/platform/code-search/retrievers/repo-map-retriever.js +30 -0
  322. package/dist/platform/code-search/retrievers/repo-map-retriever.js.map +1 -0
  323. package/dist/platform/code-search/retrievers/semantic-retriever.d.ts +6 -0
  324. package/dist/platform/code-search/retrievers/semantic-retriever.d.ts.map +1 -0
  325. package/dist/platform/code-search/retrievers/semantic-retriever.js +18 -0
  326. package/dist/platform/code-search/retrievers/semantic-retriever.js.map +1 -0
  327. package/dist/platform/code-search/retrievers/stacktrace-retriever.d.ts +6 -0
  328. package/dist/platform/code-search/retrievers/stacktrace-retriever.d.ts.map +1 -0
  329. package/dist/platform/code-search/retrievers/stacktrace-retriever.js +30 -0
  330. package/dist/platform/code-search/retrievers/stacktrace-retriever.js.map +1 -0
  331. package/dist/platform/code-search/retrievers/symbol-retriever.d.ts +6 -0
  332. package/dist/platform/code-search/retrievers/symbol-retriever.d.ts.map +1 -0
  333. package/dist/platform/code-search/retrievers/symbol-retriever.js +32 -0
  334. package/dist/platform/code-search/retrievers/symbol-retriever.js.map +1 -0
  335. package/dist/platform/code-search/retrievers/test-retriever.d.ts +6 -0
  336. package/dist/platform/code-search/retrievers/test-retriever.d.ts.map +1 -0
  337. package/dist/platform/code-search/retrievers/test-retriever.js +30 -0
  338. package/dist/platform/code-search/retrievers/test-retriever.js.map +1 -0
  339. package/dist/platform/code-search/session-store.d.ts +11 -0
  340. package/dist/platform/code-search/session-store.d.ts.map +1 -0
  341. package/dist/platform/code-search/session-store.js +41 -0
  342. package/dist/platform/code-search/session-store.js.map +1 -0
  343. package/dist/platform/code-search/trace.d.ts +9 -0
  344. package/dist/platform/code-search/trace.d.ts.map +1 -0
  345. package/dist/platform/code-search/trace.js +25 -0
  346. package/dist/platform/code-search/trace.js.map +1 -0
  347. package/dist/platform/code-search/verification-retrieval.d.ts +3 -0
  348. package/dist/platform/code-search/verification-retrieval.d.ts.map +1 -0
  349. package/dist/platform/code-search/verification-retrieval.js +33 -0
  350. package/dist/platform/code-search/verification-retrieval.js.map +1 -0
  351. package/dist/platform/dream/dream-types.d.ts +52 -52
  352. package/dist/platform/drive/types/satisficing.d.ts +2 -2
  353. package/dist/platform/knowledge/types/memory-lifecycle.d.ts +2 -2
  354. package/dist/platform/observation/context-provider.d.ts.map +1 -1
  355. package/dist/platform/observation/context-provider.js +37 -0
  356. package/dist/platform/observation/context-provider.js.map +1 -1
  357. package/dist/platform/observation/observation-helpers.d.ts +2 -2
  358. package/dist/platform/observation/workspace-context.d.ts.map +1 -1
  359. package/dist/platform/observation/workspace-context.js +27 -0
  360. package/dist/platform/observation/workspace-context.js.map +1 -1
  361. package/dist/platform/soil/contracts.d.ts +47 -47
  362. package/dist/platform/traits/types/curiosity.d.ts +24 -24
  363. package/dist/prompt/purposes/learning.d.ts +4 -4
  364. package/dist/reporting/report-formatters.d.ts.map +1 -1
  365. package/dist/reporting/report-formatters.js +33 -2
  366. package/dist/reporting/report-formatters.js.map +1 -1
  367. package/dist/reporting/reporting-engine.d.ts.map +1 -1
  368. package/dist/reporting/reporting-engine.js +2 -1
  369. package/dist/reporting/reporting-engine.js.map +1 -1
  370. package/dist/reporting/reporting-types.d.ts +11 -0
  371. package/dist/reporting/reporting-types.d.ts.map +1 -1
  372. package/dist/reporting/types/report.d.ts +72 -4
  373. package/dist/reporting/types/report.d.ts.map +1 -1
  374. package/dist/reporting/types/report.js +10 -0
  375. package/dist/reporting/types/report.js.map +1 -1
  376. package/dist/runtime/approval-broker.d.ts +1 -1
  377. package/dist/runtime/approval-broker.d.ts.map +1 -1
  378. package/dist/runtime/approval-broker.js +1 -2
  379. package/dist/runtime/approval-broker.js.map +1 -1
  380. package/dist/runtime/control/index.d.ts +1 -0
  381. package/dist/runtime/control/index.d.ts.map +1 -1
  382. package/dist/runtime/control/index.js +1 -0
  383. package/dist/runtime/control/index.js.map +1 -1
  384. package/dist/runtime/control/runtime-control-intent.d.ts.map +1 -1
  385. package/dist/runtime/control/runtime-control-intent.js +0 -8
  386. package/dist/runtime/control/runtime-control-intent.js.map +1 -1
  387. package/dist/runtime/control/runtime-control-result-routing.d.ts +28 -0
  388. package/dist/runtime/control/runtime-control-result-routing.d.ts.map +1 -0
  389. package/dist/runtime/control/runtime-control-result-routing.js +47 -0
  390. package/dist/runtime/control/runtime-control-result-routing.js.map +1 -0
  391. package/dist/runtime/control/runtime-control-service.d.ts +2 -1
  392. package/dist/runtime/control/runtime-control-service.d.ts.map +1 -1
  393. package/dist/runtime/control/runtime-control-service.js +32 -4
  394. package/dist/runtime/control/runtime-control-service.js.map +1 -1
  395. package/dist/runtime/daemon/client.d.ts +13 -1
  396. package/dist/runtime/daemon/client.d.ts.map +1 -1
  397. package/dist/runtime/daemon/client.js +2 -2
  398. package/dist/runtime/daemon/client.js.map +1 -1
  399. package/dist/runtime/daemon/index.d.ts +1 -0
  400. package/dist/runtime/daemon/index.d.ts.map +1 -1
  401. package/dist/runtime/daemon/index.js +1 -0
  402. package/dist/runtime/daemon/index.js.map +1 -1
  403. package/dist/runtime/daemon/runner-commands.d.ts +9 -1
  404. package/dist/runtime/daemon/runner-commands.d.ts.map +1 -1
  405. package/dist/runtime/daemon/runner-commands.js +33 -2
  406. package/dist/runtime/daemon/runner-commands.js.map +1 -1
  407. package/dist/runtime/daemon/runner-goal-cycle.d.ts.map +1 -1
  408. package/dist/runtime/daemon/runner-goal-cycle.js +55 -8
  409. package/dist/runtime/daemon/runner-goal-cycle.js.map +1 -1
  410. package/dist/runtime/daemon/runner-startup.d.ts +2 -1
  411. package/dist/runtime/daemon/runner-startup.d.ts.map +1 -1
  412. package/dist/runtime/daemon/runner-startup.js +32 -5
  413. package/dist/runtime/daemon/runner-startup.js.map +1 -1
  414. package/dist/runtime/daemon/runner.d.ts +2 -0
  415. package/dist/runtime/daemon/runner.d.ts.map +1 -1
  416. package/dist/runtime/daemon/runner.js +18 -3
  417. package/dist/runtime/daemon/runner.js.map +1 -1
  418. package/dist/runtime/daemon/runtime-root.d.ts +5 -0
  419. package/dist/runtime/daemon/runtime-root.d.ts.map +1 -0
  420. package/dist/runtime/daemon/runtime-root.js +60 -0
  421. package/dist/runtime/daemon/runtime-root.js.map +1 -0
  422. package/dist/runtime/daemon/wait-deadline-resolver.d.ts +25 -0
  423. package/dist/runtime/daemon/wait-deadline-resolver.d.ts.map +1 -0
  424. package/dist/runtime/daemon/wait-deadline-resolver.js +88 -0
  425. package/dist/runtime/daemon/wait-deadline-resolver.js.map +1 -0
  426. package/dist/runtime/event/server-command-handler.d.ts.map +1 -1
  427. package/dist/runtime/event/server-command-handler.js +47 -3
  428. package/dist/runtime/event/server-command-handler.js.map +1 -1
  429. package/dist/runtime/executor/goal-worker.d.ts +1 -0
  430. package/dist/runtime/executor/goal-worker.d.ts.map +1 -1
  431. package/dist/runtime/executor/goal-worker.js +1 -0
  432. package/dist/runtime/executor/goal-worker.js.map +1 -1
  433. package/dist/runtime/executor/loop-supervisor.d.ts +24 -1
  434. package/dist/runtime/executor/loop-supervisor.d.ts.map +1 -1
  435. package/dist/runtime/executor/loop-supervisor.js +191 -12
  436. package/dist/runtime/executor/loop-supervisor.js.map +1 -1
  437. package/dist/runtime/gateway/chat-session-dispatch.d.ts +1 -0
  438. package/dist/runtime/gateway/chat-session-dispatch.d.ts.map +1 -1
  439. package/dist/runtime/gateway/chat-session-dispatch.js +1 -0
  440. package/dist/runtime/gateway/chat-session-dispatch.js.map +1 -1
  441. package/dist/runtime/gateway/discord-gateway-adapter.d.ts.map +1 -1
  442. package/dist/runtime/gateway/discord-gateway-adapter.js +1 -0
  443. package/dist/runtime/gateway/discord-gateway-adapter.js.map +1 -1
  444. package/dist/runtime/gateway/signal-gateway-adapter.d.ts.map +1 -1
  445. package/dist/runtime/gateway/signal-gateway-adapter.js +1 -0
  446. package/dist/runtime/gateway/signal-gateway-adapter.js.map +1 -1
  447. package/dist/runtime/gateway/slack-channel-adapter.d.ts +4 -0
  448. package/dist/runtime/gateway/slack-channel-adapter.d.ts.map +1 -1
  449. package/dist/runtime/gateway/slack-channel-adapter.js +105 -10
  450. package/dist/runtime/gateway/slack-channel-adapter.js.map +1 -1
  451. package/dist/runtime/gateway/telegram-gateway-adapter.d.ts.map +1 -1
  452. package/dist/runtime/gateway/telegram-gateway-adapter.js +3 -1
  453. package/dist/runtime/gateway/telegram-gateway-adapter.js.map +1 -1
  454. package/dist/runtime/gateway/whatsapp-gateway-adapter.d.ts.map +1 -1
  455. package/dist/runtime/gateway/whatsapp-gateway-adapter.js +1 -0
  456. package/dist/runtime/gateway/whatsapp-gateway-adapter.js.map +1 -1
  457. package/dist/runtime/session-registry/index.d.ts +3 -0
  458. package/dist/runtime/session-registry/index.d.ts.map +1 -0
  459. package/dist/runtime/session-registry/index.js +3 -0
  460. package/dist/runtime/session-registry/index.js.map +1 -0
  461. package/dist/runtime/session-registry/registry.d.ts +39 -0
  462. package/dist/runtime/session-registry/registry.d.ts.map +1 -0
  463. package/dist/runtime/session-registry/registry.js +761 -0
  464. package/dist/runtime/session-registry/registry.js.map +1 -0
  465. package/dist/runtime/session-registry/types.d.ts +985 -0
  466. package/dist/runtime/session-registry/types.d.ts.map +1 -0
  467. package/dist/runtime/session-registry/types.js +108 -0
  468. package/dist/runtime/session-registry/types.js.map +1 -0
  469. package/dist/runtime/store/background-run-store.d.ts +75 -0
  470. package/dist/runtime/store/background-run-store.d.ts.map +1 -0
  471. package/dist/runtime/store/background-run-store.js +157 -0
  472. package/dist/runtime/store/background-run-store.js.map +1 -0
  473. package/dist/runtime/store/index.d.ts +2 -0
  474. package/dist/runtime/store/index.d.ts.map +1 -1
  475. package/dist/runtime/store/index.js +1 -0
  476. package/dist/runtime/store/index.js.map +1 -1
  477. package/dist/runtime/store/runtime-operation-schemas.d.ts +62 -22
  478. package/dist/runtime/store/runtime-operation-schemas.d.ts.map +1 -1
  479. package/dist/runtime/store/runtime-operation-schemas.js +5 -0
  480. package/dist/runtime/store/runtime-operation-schemas.js.map +1 -1
  481. package/dist/runtime/store/runtime-paths.d.ts +2 -0
  482. package/dist/runtime/store/runtime-paths.d.ts.map +1 -1
  483. package/dist/runtime/store/runtime-paths.js +6 -0
  484. package/dist/runtime/store/runtime-paths.js.map +1 -1
  485. package/dist/runtime/store/runtime-schemas.d.ts +6 -6
  486. package/dist/runtime/types/cron.d.ts +4 -4
  487. package/dist/runtime/types/daemon.d.ts +60 -0
  488. package/dist/runtime/types/daemon.d.ts.map +1 -1
  489. package/dist/runtime/types/daemon.js +14 -0
  490. package/dist/runtime/types/daemon.js.map +1 -1
  491. package/dist/runtime/types/envelope.d.ts +2 -2
  492. package/dist/runtime/types/notification.d.ts +1 -1
  493. package/dist/tools/builtin/exports.d.ts +4 -0
  494. package/dist/tools/builtin/exports.d.ts.map +1 -1
  495. package/dist/tools/builtin/exports.js +4 -0
  496. package/dist/tools/builtin/exports.js.map +1 -1
  497. package/dist/tools/builtin/factory.d.ts.map +1 -1
  498. package/dist/tools/builtin/factory.js +18 -0
  499. package/dist/tools/builtin/factory.js.map +1 -1
  500. package/dist/tools/fs/GlobTool/GlobTool.js +2 -2
  501. package/dist/tools/fs/GlobTool/GlobTool.js.map +1 -1
  502. package/dist/tools/fs/GrepTool/GrepTool.js +2 -2
  503. package/dist/tools/fs/GrepTool/GrepTool.js.map +1 -1
  504. package/dist/tools/fs/ReadTool/ReadTool.js +2 -2
  505. package/dist/tools/fs/ReadTool/ReadTool.js.map +1 -1
  506. package/dist/tools/kaggle/KaggleExperimentTools.d.ts +395 -0
  507. package/dist/tools/kaggle/KaggleExperimentTools.d.ts.map +1 -0
  508. package/dist/tools/kaggle/KaggleExperimentTools.js +923 -0
  509. package/dist/tools/kaggle/KaggleExperimentTools.js.map +1 -0
  510. package/dist/tools/kaggle/KaggleSubmissionTools.d.ts +241 -0
  511. package/dist/tools/kaggle/KaggleSubmissionTools.d.ts.map +1 -0
  512. package/dist/tools/kaggle/KaggleSubmissionTools.js +558 -0
  513. package/dist/tools/kaggle/KaggleSubmissionTools.js.map +1 -0
  514. package/dist/tools/kaggle/KaggleWorkspacePrepareTool.d.ts +105 -0
  515. package/dist/tools/kaggle/KaggleWorkspacePrepareTool.d.ts.map +1 -0
  516. package/dist/tools/kaggle/KaggleWorkspacePrepareTool.js +135 -0
  517. package/dist/tools/kaggle/KaggleWorkspacePrepareTool.js.map +1 -0
  518. package/dist/tools/kaggle/index.d.ts +6 -0
  519. package/dist/tools/kaggle/index.d.ts.map +1 -0
  520. package/dist/tools/kaggle/index.js +6 -0
  521. package/dist/tools/kaggle/index.js.map +1 -0
  522. package/dist/tools/kaggle/metrics.d.ts +89 -0
  523. package/dist/tools/kaggle/metrics.d.ts.map +1 -0
  524. package/dist/tools/kaggle/metrics.js +51 -0
  525. package/dist/tools/kaggle/metrics.js.map +1 -0
  526. package/dist/tools/kaggle/paths.d.ts +15 -0
  527. package/dist/tools/kaggle/paths.d.ts.map +1 -0
  528. package/dist/tools/kaggle/paths.js +136 -0
  529. package/dist/tools/kaggle/paths.js.map +1 -0
  530. package/dist/tools/network/GitHubCliTool/GitHubCliTool.d.ts +2 -2
  531. package/dist/tools/query/ArchitectureTool/ArchitectureTool.js +1 -1
  532. package/dist/tools/query/ArchitectureTool/ArchitectureTool.js.map +1 -1
  533. package/dist/tools/query/CodeReadContextTool/CodeReadContextTool.d.ts +801 -0
  534. package/dist/tools/query/CodeReadContextTool/CodeReadContextTool.d.ts.map +1 -0
  535. package/dist/tools/query/CodeReadContextTool/CodeReadContextTool.js +147 -0
  536. package/dist/tools/query/CodeReadContextTool/CodeReadContextTool.js.map +1 -0
  537. package/dist/tools/query/CodeReadContextTool/constants.d.ts +5 -0
  538. package/dist/tools/query/CodeReadContextTool/constants.d.ts.map +1 -0
  539. package/dist/tools/query/CodeReadContextTool/constants.js +5 -0
  540. package/dist/tools/query/CodeReadContextTool/constants.js.map +1 -0
  541. package/dist/tools/query/CodeReadContextTool/prompt.d.ts +2 -0
  542. package/dist/tools/query/CodeReadContextTool/prompt.d.ts.map +1 -0
  543. package/dist/tools/query/CodeReadContextTool/prompt.js +6 -0
  544. package/dist/tools/query/CodeReadContextTool/prompt.js.map +1 -0
  545. package/dist/tools/query/CodeSearchRepairTool/CodeSearchRepairTool.d.ts +125 -0
  546. package/dist/tools/query/CodeSearchRepairTool/CodeSearchRepairTool.d.ts.map +1 -0
  547. package/dist/tools/query/CodeSearchRepairTool/CodeSearchRepairTool.js +97 -0
  548. package/dist/tools/query/CodeSearchRepairTool/CodeSearchRepairTool.js.map +1 -0
  549. package/dist/tools/query/CodeSearchRepairTool/constants.d.ts +5 -0
  550. package/dist/tools/query/CodeSearchRepairTool/constants.d.ts.map +1 -0
  551. package/dist/tools/query/CodeSearchRepairTool/constants.js +5 -0
  552. package/dist/tools/query/CodeSearchRepairTool/constants.js.map +1 -0
  553. package/dist/tools/query/CodeSearchRepairTool/prompt.d.ts +2 -0
  554. package/dist/tools/query/CodeSearchRepairTool/prompt.d.ts.map +1 -0
  555. package/dist/tools/query/CodeSearchRepairTool/prompt.js +5 -0
  556. package/dist/tools/query/CodeSearchRepairTool/prompt.js.map +1 -0
  557. package/dist/tools/query/CodeSearchTool/CodeSearchTool.d.ts +123 -0
  558. package/dist/tools/query/CodeSearchTool/CodeSearchTool.d.ts.map +1 -0
  559. package/dist/tools/query/CodeSearchTool/CodeSearchTool.js +95 -0
  560. package/dist/tools/query/CodeSearchTool/CodeSearchTool.js.map +1 -0
  561. package/dist/tools/query/CodeSearchTool/constants.d.ts +5 -0
  562. package/dist/tools/query/CodeSearchTool/constants.d.ts.map +1 -0
  563. package/dist/tools/query/CodeSearchTool/constants.js +5 -0
  564. package/dist/tools/query/CodeSearchTool/constants.js.map +1 -0
  565. package/dist/tools/query/CodeSearchTool/prompt.d.ts +2 -0
  566. package/dist/tools/query/CodeSearchTool/prompt.d.ts.map +1 -0
  567. package/dist/tools/query/CodeSearchTool/prompt.js +6 -0
  568. package/dist/tools/query/CodeSearchTool/prompt.js.map +1 -0
  569. package/dist/tools/system/ProcessSessionTool/ProcessSessionTool.d.ts +35 -7
  570. package/dist/tools/system/ProcessSessionTool/ProcessSessionTool.d.ts.map +1 -1
  571. package/dist/tools/system/ProcessSessionTool/ProcessSessionTool.js +128 -3
  572. package/dist/tools/system/ProcessSessionTool/ProcessSessionTool.js.map +1 -1
  573. package/package.json +2 -1
@@ -1,7 +1,11 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import React, { useCallback, useState } from "react";
3
+ import { spawnSync } from "child_process";
4
+ import { mkdtempSync, writeFileSync } from "fs";
5
+ import { tmpdir } from "os";
6
+ import path from "path";
3
7
  import { Box, Text, useInput } from "ink";
4
- import { getClipboardContent } from "./clipboard.js";
8
+ import { copyToClipboard, getClipboardContent } from "./clipboard.js";
5
9
  import { logTuiDebug } from "./debug-log.js";
6
10
  import { theme } from "./theme.js";
7
11
  import { pickSpinnerVerb } from "./spinner-verbs.js";
@@ -9,8 +13,10 @@ import { buildHiddenCursorEscapeFromPosition, CARET_MARKER, PROTECTED_ROW_MARKER
9
13
  import { measureCharWidth, measureTextWidth } from "./text-width.js";
10
14
  import { isBashModeInput } from "./bash-mode.js";
11
15
  import { buildChatViewport } from "./chat/viewport.js";
12
- import { getScrollRequest, normalizeTerminalInputChunk, parseMouseEvent, } from "./chat/scroll.js";
16
+ import { getScrollLineStep, getScrollRequest, normalizeTerminalInputChunk, parseMouseEvent, } from "./chat/scroll.js";
13
17
  import { getMatchingSuggestions } from "./chat/suggestions.js";
18
+ import { writeTrustedTuiControl } from "./terminal-output.js";
19
+ import { CURSOR_HOME, ENTER_ALT_SCREEN, ERASE_SCREEN, EXIT_ALT_SCREEN, HIDE_CURSOR, SHOW_CURSOR, } from "./flicker/dec.js";
14
20
  const SCROLL_LINE_STEP = 1;
15
21
  const SCROLL_ANIMATION_INTERVAL_MS = 16;
16
22
  const DEFAULT_PROMPT = "◉";
@@ -22,6 +28,8 @@ const SELECTION_FOREGROUND = "#1F2329";
22
28
  const FAKE_CURSOR_GLYPH = "▌";
23
29
  const PROCESSING_SPINNER_FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
24
30
  const PROCESSING_SPINNER_INTERVAL_MS = 80;
31
+ const COLLAPSED_PASTE_MIN_CHARS = 120;
32
+ const COLLAPSED_PASTE_MIN_MULTILINE_CHARS = 40;
25
33
  function charWidth(ch) {
26
34
  return measureCharWidth(ch);
27
35
  }
@@ -100,6 +108,31 @@ function formatSuggestionLabel(suggestion) {
100
108
  ? ` ${suggestion.name} ${suggestion.description.padEnd(20)} [goal]`
101
109
  : ` ${suggestion.name.padEnd(20)}${suggestion.description}`;
102
110
  }
111
+ function countTextLines(text) {
112
+ return text.length === 0 ? 0 : text.split("\n").length;
113
+ }
114
+ export function shouldCollapsePastedText(rawInput, normalizedInput) {
115
+ const isBracketedPaste = rawInput.includes("[200~") || rawInput.includes("\u001b[200~");
116
+ if (normalizedInput.length >= COLLAPSED_PASTE_MIN_CHARS) {
117
+ return true;
118
+ }
119
+ if (normalizedInput.includes("\n") && normalizedInput.length >= COLLAPSED_PASTE_MIN_MULTILINE_CHARS) {
120
+ return true;
121
+ }
122
+ return isBracketedPaste && normalizedInput.length >= COLLAPSED_PASTE_MIN_MULTILINE_CHARS;
123
+ }
124
+ export function buildCollapsedPasteRange(text, start) {
125
+ const lineCount = countTextLines(text);
126
+ const charCount = Array.from(text).length;
127
+ const label = lineCount > 1
128
+ ? `[pasted ${lineCount} lines, ${charCount} chars]`
129
+ : `[pasted ${charCount} chars]`;
130
+ return {
131
+ start,
132
+ end: start + text.length,
133
+ label,
134
+ };
135
+ }
103
136
  function normalizeSelection(selection) {
104
137
  if (!selection || selection.anchor === selection.focus) {
105
138
  return null;
@@ -109,6 +142,21 @@ function normalizeSelection(selection) {
109
142
  end: Math.max(selection.anchor, selection.focus),
110
143
  };
111
144
  }
145
+ export function getSelectedInputText(input, selection) {
146
+ const range = normalizeSelection(selection);
147
+ return range ? input.slice(range.start, range.end) : "";
148
+ }
149
+ export async function copySelectedInputText(input, selection, copy = copyToClipboard) {
150
+ const selectedText = getSelectedInputText(input, selection);
151
+ if (!selectedText) {
152
+ return { ok: false };
153
+ }
154
+ return copy(selectedText);
155
+ }
156
+ function formatCopyToast(charCount, result) {
157
+ const suffix = result.method ? ` via ${result.method}` : "";
158
+ return `copied ${charCount} chars${suffix}`;
159
+ }
112
160
  function pushSegment(segments, text, style = {}) {
113
161
  if (text.length === 0)
114
162
  return;
@@ -123,7 +171,7 @@ function pushSegment(segments, text, style = {}) {
123
171
  }
124
172
  segments.push({ text, ...style });
125
173
  }
126
- function buildInputRows(input, cursorOffset, contentWidth, placeholder, selection) {
174
+ function buildInputRows(input, cursorOffset, contentWidth, placeholder, selection, collapsedPaste) {
127
175
  if (contentWidth <= 0) {
128
176
  return {
129
177
  rows: [{
@@ -167,6 +215,11 @@ function buildInputRows(input, cursorOffset, contentWidth, placeholder, selectio
167
215
  let currentWidth = 0;
168
216
  let rowStartOffset = 0;
169
217
  let rowEndOffset = 0;
218
+ const activeCollapsedPaste = collapsedPaste
219
+ && !(cursorOffset > collapsedPaste.start && cursorOffset < collapsedPaste.end)
220
+ && !(selection && selection.start < collapsedPaste.end && selection.end > collapsedPaste.start)
221
+ ? collapsedPaste
222
+ : null;
170
223
  const pushRow = () => {
171
224
  rows.push({
172
225
  cells: currentCells,
@@ -194,6 +247,28 @@ function buildInputRows(input, cursorOffset, contentWidth, placeholder, selectio
194
247
  if (offset === input.length) {
195
248
  break;
196
249
  }
250
+ if (activeCollapsedPaste && offset === activeCollapsedPaste.start) {
251
+ const label = stringWidth(activeCollapsedPaste.label) <= contentWidth
252
+ ? activeCollapsedPaste.label
253
+ : trimToWidth("[paste]", contentWidth);
254
+ const labelWidth = stringWidth(label);
255
+ if (currentWidth + labelWidth > contentWidth && currentCells.length > 0) {
256
+ pushRow();
257
+ rowStartOffset = offset;
258
+ rowEndOffset = offset;
259
+ }
260
+ currentCells.push({
261
+ text: label,
262
+ width: labelWidth,
263
+ offsetBefore: activeCollapsedPaste.start,
264
+ offsetAfter: activeCollapsedPaste.end,
265
+ dim: true,
266
+ });
267
+ currentWidth += labelWidth;
268
+ rowEndOffset = activeCollapsedPaste.end;
269
+ offset = activeCollapsedPaste.end;
270
+ continue;
271
+ }
197
272
  const codePoint = input.codePointAt(offset) ?? 0;
198
273
  const ch = String.fromCodePoint(codePoint);
199
274
  const nextOffset = offset + ch.length;
@@ -253,7 +328,7 @@ function buildInputContentSegments(row, contentWidth, bashMode) {
253
328
  }
254
329
  pushSegment(segments, cell.text, {
255
330
  color: defaultColor,
256
- dim: cell.placeholder,
331
+ dim: cell.placeholder || cell.dim,
257
332
  });
258
333
  }
259
334
  if (usedWidth < contentWidth) {
@@ -263,6 +338,222 @@ function buildInputContentSegments(row, contentWidth, bashMode) {
263
338
  }
264
339
  return segments;
265
340
  }
341
+ function compareBodySelectionPoints(a, b) {
342
+ if (a.rowIndex !== b.rowIndex) {
343
+ return a.rowIndex - b.rowIndex;
344
+ }
345
+ return a.offset - b.offset;
346
+ }
347
+ function normalizeBodySelection(selection) {
348
+ if (!selection || compareBodySelectionPoints(selection.anchor, selection.focus) === 0) {
349
+ return null;
350
+ }
351
+ return compareBodySelectionPoints(selection.anchor, selection.focus) <= 0
352
+ ? { start: selection.anchor, end: selection.focus }
353
+ : { start: selection.focus, end: selection.anchor };
354
+ }
355
+ function getBodySelectionForRow(selection, rowIndex, textLength) {
356
+ if (!selection || rowIndex < selection.start.rowIndex || rowIndex > selection.end.rowIndex) {
357
+ return null;
358
+ }
359
+ const start = rowIndex === selection.start.rowIndex ? selection.start.offset : 0;
360
+ const end = rowIndex === selection.end.rowIndex ? selection.end.offset : textLength;
361
+ if (start === end)
362
+ return null;
363
+ return { start: Math.max(0, start), end: Math.min(textLength, end) };
364
+ }
365
+ function getDisplayOffsetForText(text, col) {
366
+ if (col <= 0)
367
+ return 0;
368
+ let usedWidth = 0;
369
+ let offset = 0;
370
+ for (const ch of text) {
371
+ const width = charWidth(ch);
372
+ const midpoint = usedWidth + width / 2;
373
+ if (col <= midpoint)
374
+ return offset;
375
+ offset += ch.length;
376
+ usedWidth += width;
377
+ if (col <= usedWidth)
378
+ return offset;
379
+ }
380
+ return text.length;
381
+ }
382
+ function applySelectionToTextSegments(text, selection, style) {
383
+ if (!selection) {
384
+ return [{ text, ...style }];
385
+ }
386
+ const segments = [];
387
+ const before = text.slice(0, selection.start);
388
+ const selected = text.slice(selection.start, selection.end);
389
+ const after = text.slice(selection.end);
390
+ pushSegment(segments, before, style);
391
+ pushSegment(segments, selected, {
392
+ ...style,
393
+ color: SELECTION_FOREGROUND,
394
+ backgroundColor: SELECTION_BACKGROUND,
395
+ });
396
+ pushSegment(segments, after, style);
397
+ return segments;
398
+ }
399
+ export function getSelectedBodyText(rows, selection) {
400
+ const range = normalizeBodySelection(selection);
401
+ if (!range)
402
+ return "";
403
+ const selectedRows = [];
404
+ for (let rowIndex = range.start.rowIndex; rowIndex <= range.end.rowIndex; rowIndex += 1) {
405
+ const row = rows[rowIndex];
406
+ if (!row || row.kind === "spacer")
407
+ continue;
408
+ const rowRange = getBodySelectionForRow(range, rowIndex, row.text.length);
409
+ if (!rowRange)
410
+ continue;
411
+ selectedRows.push(row.text.slice(rowRange.start, rowRange.end).trimEnd());
412
+ }
413
+ return selectedRows.join("\n").trim();
414
+ }
415
+ export function extractClickableTargetAt(text, offset) {
416
+ const patterns = [
417
+ /https?:\/\/[^\s)>\]}]+/g,
418
+ /(?:\.{1,2}\/|\/)[^\s:]+(?::\d+)?/g,
419
+ ];
420
+ for (const pattern of patterns) {
421
+ for (const match of text.matchAll(pattern)) {
422
+ const value = match[0];
423
+ const start = match.index ?? 0;
424
+ const end = start + value.length;
425
+ if (offset >= start && offset <= end) {
426
+ return value;
427
+ }
428
+ }
429
+ }
430
+ return null;
431
+ }
432
+ function openClickableTarget(target) {
433
+ if (/^https?:\/\//.test(target)) {
434
+ if (process.platform === "darwin") {
435
+ return spawnSync("open", [target], { stdio: "ignore" }).status === 0;
436
+ }
437
+ if (process.platform === "linux") {
438
+ return spawnSync("xdg-open", [target], { stdio: "ignore" }).status === 0;
439
+ }
440
+ return false;
441
+ }
442
+ const [filePart, linePart] = target.split(/:(\d+)$/);
443
+ const resolvedPath = path.resolve(process.cwd(), filePart || target);
444
+ const editor = process.env.VISUAL || process.env.EDITOR;
445
+ if (editor) {
446
+ const editorTarget = linePart ? `${resolvedPath}:${linePart}` : resolvedPath;
447
+ return spawnSync(editor, [editorTarget], { stdio: "ignore", shell: true }).status === 0;
448
+ }
449
+ if (process.platform === "darwin") {
450
+ return spawnSync("open", [resolvedPath], { stdio: "ignore" }).status === 0;
451
+ }
452
+ if (process.platform === "linux") {
453
+ return spawnSync("xdg-open", [resolvedPath], { stdio: "ignore" }).status === 0;
454
+ }
455
+ return false;
456
+ }
457
+ export function formatTranscript(messages) {
458
+ return messages
459
+ .map((message) => {
460
+ const label = message.role === "user" ? "User" : "PulSeed";
461
+ return `${label}:\n${message.text.trimEnd()}`;
462
+ })
463
+ .join("\n\n");
464
+ }
465
+ function wrapPlainTextToRows(text, width) {
466
+ const rows = [];
467
+ for (const sourceLine of text.split("\n")) {
468
+ if (sourceLine.length === 0) {
469
+ rows.push("");
470
+ continue;
471
+ }
472
+ let current = "";
473
+ let currentWidth = 0;
474
+ for (const ch of sourceLine) {
475
+ const widthOfChar = charWidth(ch);
476
+ if (currentWidth + widthOfChar > width && current.length > 0) {
477
+ rows.push(current);
478
+ current = "";
479
+ currentWidth = 0;
480
+ }
481
+ current += ch;
482
+ currentWidth += widthOfChar;
483
+ }
484
+ rows.push(current);
485
+ }
486
+ return rows;
487
+ }
488
+ function buildTranscriptRows(messages, cols) {
489
+ const rows = [];
490
+ for (const message of messages) {
491
+ const label = message.role === "user" ? "User" : "PulSeed";
492
+ rows.push(...wrapPlainTextToRows(`${label}:`, cols));
493
+ rows.push(...wrapPlainTextToRows(message.text.trimEnd(), cols));
494
+ rows.push("");
495
+ }
496
+ return rows;
497
+ }
498
+ export function buildTranscriptRenderLines(args) {
499
+ const { messages, cols, rows, scrollOffset, searchQuery, searchMode, status } = args;
500
+ const bodyRows = Math.max(1, rows - 2);
501
+ const transcriptRows = buildTranscriptRows(messages, cols);
502
+ const maxScrollOffset = Math.max(0, transcriptRows.length - bodyRows);
503
+ const clampedOffset = Math.max(0, Math.min(maxScrollOffset, scrollOffset));
504
+ const visibleRows = transcriptRows.slice(clampedOffset, clampedOffset + bodyRows);
505
+ const lines = [{
506
+ key: "transcript-header",
507
+ text: padToWidth("transcript / search n/N next [ write scrollback v editor Esc return", cols),
508
+ color: theme.command,
509
+ }];
510
+ visibleRows.forEach((row, index) => {
511
+ lines.push({
512
+ key: `transcript-${clampedOffset + index}`,
513
+ text: padToWidth(row, cols),
514
+ backgroundColor: searchQuery.length > 0 && row.toLowerCase().includes(searchQuery.toLowerCase())
515
+ ? "#3A3A22"
516
+ : undefined,
517
+ });
518
+ });
519
+ while (lines.length < rows - 1) {
520
+ lines.push({ key: `transcript-filler-${lines.length}`, text: " ".repeat(cols) });
521
+ }
522
+ lines.push({
523
+ key: "transcript-footer",
524
+ text: padToWidth(searchMode
525
+ ? `/${searchQuery}`
526
+ : status
527
+ ? status
528
+ : `${clampedOffset + 1}-${Math.min(clampedOffset + bodyRows, transcriptRows.length)} / ${transcriptRows.length}`, cols),
529
+ dim: !searchMode && !status,
530
+ color: searchMode ? theme.command : undefined,
531
+ });
532
+ return { lines: lines.slice(0, rows), totalRows: transcriptRows.length, maxScrollOffset };
533
+ }
534
+ function writeTranscriptToNativeScrollback(messages) {
535
+ const transcript = formatTranscript(messages);
536
+ writeTrustedTuiControl(SHOW_CURSOR +
537
+ EXIT_ALT_SCREEN +
538
+ `\n${transcript}\n` +
539
+ ENTER_ALT_SCREEN +
540
+ ERASE_SCREEN +
541
+ CURSOR_HOME +
542
+ HIDE_CURSOR);
543
+ }
544
+ function openTranscriptInEditor(messages) {
545
+ const editor = process.env.VISUAL || process.env.EDITOR;
546
+ if (!editor) {
547
+ return { ok: false };
548
+ }
549
+ const dir = mkdtempSync(path.join(tmpdir(), "pulseed-transcript-"));
550
+ const filePath = path.join(dir, "transcript.md");
551
+ writeFileSync(filePath, formatTranscript(messages), "utf8");
552
+ writeTrustedTuiControl(SHOW_CURSOR + EXIT_ALT_SCREEN);
553
+ const result = spawnSync(editor, [filePath], { stdio: "inherit", shell: true });
554
+ writeTrustedTuiControl(ENTER_ALT_SCREEN + ERASE_SCREEN + CURSOR_HOME + HIDE_CURSOR);
555
+ return result.status === 0 ? { ok: true, method: "osc52" } : { ok: false };
556
+ }
266
557
  function getCursorPositionFromComposerLayout(layout) {
267
558
  for (let rowIndex = 0; rowIndex < layout.rows.length; rowIndex += 1) {
268
559
  const row = layout.rows[rowIndex];
@@ -281,8 +572,8 @@ function getCursorPositionFromComposerLayout(layout) {
281
572
  }
282
573
  return null;
283
574
  }
284
- function buildComposerLines(args) {
285
- const { cols, input, cursorOffset, bashMode, emptyHint, matches, selectedIdx, copyToast, selection, } = args;
575
+ export function buildComposerLines(args) {
576
+ const { cols, input, cursorOffset, bashMode, emptyHint, matches, selectedIdx, copyToast, selection, collapsedPaste, } = args;
286
577
  const lines = [];
287
578
  lines.push({
288
579
  key: "copy-toast",
@@ -294,7 +585,7 @@ function buildComposerLines(args) {
294
585
  const prompt = `${promptLabel} `;
295
586
  const promptWidth = stringWidth(prompt);
296
587
  const contentWidth = Math.max(1, innerWidth - INPUT_MARGIN - promptWidth);
297
- const inputRender = buildInputRows(input, cursorOffset, contentWidth, getPlaceholder(bashMode), selection);
588
+ const inputRender = buildInputRows(input, cursorOffset, contentWidth, getPlaceholder(bashMode), selection, collapsedPaste);
298
589
  const inputRows = inputRender.rows;
299
590
  lines.push({
300
591
  key: "composer-top",
@@ -363,10 +654,23 @@ function buildComposerLines(args) {
363
654
  contentStartCol: 3 + promptWidth,
364
655
  };
365
656
  }
366
- function renderMessageRow(row, cols) {
657
+ function renderMessageRow(row, cols, rowIndex, bodySelection) {
367
658
  if (row.kind === "spacer") {
368
659
  return { key: row.key, text: " ".repeat(cols) };
369
660
  }
661
+ const selection = getBodySelectionForRow(bodySelection, rowIndex, row.text.length);
662
+ if (selection) {
663
+ const text = padToWidth(row.text, cols);
664
+ return {
665
+ key: row.key,
666
+ segments: applySelectionToTextSegments(text, selection, {
667
+ color: row.color,
668
+ backgroundColor: row.backgroundColor,
669
+ bold: row.bold,
670
+ dim: row.dim,
671
+ }),
672
+ };
673
+ }
370
674
  return {
371
675
  key: row.key,
372
676
  text: padToWidth(row.text, cols),
@@ -376,14 +680,14 @@ function renderMessageRow(row, cols) {
376
680
  dim: row.dim,
377
681
  };
378
682
  }
379
- export function buildFullscreenChatRenderLines({ availableCols, availableRows, viewport, composerLines, isProcessing, spinnerGlyph, spinnerVerb, }) {
683
+ export function buildFullscreenChatRenderLines({ availableCols, availableRows, viewport, composerLines, isProcessing, spinnerGlyph, spinnerVerb, bodySelection, transcriptStatus, }) {
380
684
  const lines = [];
381
685
  lines.push({
382
686
  key: "indicator-top",
383
687
  text: padToWidth(viewport.hiddenAboveRows > 0 ? `↑ ${viewport.hiddenAboveRows} earlier lines` : "", availableCols),
384
688
  dim: true,
385
689
  });
386
- const renderedRows = viewport.rows.map((row) => renderMessageRow(row, availableCols));
690
+ const renderedRows = viewport.rows.map((row, index) => (renderMessageRow(row, availableCols, index, bodySelection ?? null)));
387
691
  const fillerCount = Math.max(0, viewport.maxVisibleRows - renderedRows.length);
388
692
  for (let index = 0; index < fillerCount; index += 1) {
389
693
  lines.push({ key: `filler-${index}`, text: " ".repeat(availableCols) });
@@ -396,9 +700,9 @@ export function buildFullscreenChatRenderLines({ availableCols, availableRows, v
396
700
  });
397
701
  lines.push({
398
702
  key: "processing",
399
- text: padToWidth(isProcessing ? `${spinnerGlyph} ${spinnerVerb}...` : "", availableCols),
703
+ text: padToWidth(transcriptStatus ?? (isProcessing ? `${spinnerGlyph} ${spinnerVerb}...` : ""), availableCols),
400
704
  color: isProcessing ? theme.command : undefined,
401
- dim: !isProcessing,
705
+ dim: !isProcessing && !transcriptStatus,
402
706
  });
403
707
  lines.push(...composerLines);
404
708
  while (lines.length < availableRows) {
@@ -451,10 +755,25 @@ function getMouseOffsetFromComposer(layout, x, y, clampOutside) {
451
755
  }
452
756
  return row.endOffset;
453
757
  }
758
+ function getMousePositionFromBody(rows, x, y, fillerRows) {
759
+ const rowIndex = y - 2 - fillerRows;
760
+ if (rowIndex < 0 || rowIndex >= rows.length) {
761
+ return null;
762
+ }
763
+ const row = rows[rowIndex];
764
+ if (!row || row.kind === "spacer") {
765
+ return null;
766
+ }
767
+ return {
768
+ rowIndex,
769
+ offset: getDisplayOffsetForText(row.text, x - 1),
770
+ };
771
+ }
454
772
  export function FullscreenChat({ messages, onSubmit, onClear, isProcessing, goalNames = [], availableRows, availableCols, cursorOriginX = 0, cursorOriginY = 0, }) {
455
773
  const [input, setInput] = useState("");
456
774
  const [cursorOffset, setCursorOffset] = useState(0);
457
775
  const [selection, setSelection] = useState(null);
776
+ const [collapsedPaste, setCollapsedPaste] = useState(null);
458
777
  const selectionAnchor = React.useRef(null);
459
778
  const [selectedIdx, setSelectedIdx] = useState(0);
460
779
  const justSelected = React.useRef(false);
@@ -466,6 +785,12 @@ export function FullscreenChat({ messages, onSubmit, onClear, isProcessing, goal
466
785
  const emptyHintTimer = React.useRef(null);
467
786
  const [scrollOffset, setScrollOffset] = React.useState(0);
468
787
  const [targetScrollOffset, setTargetScrollOffset] = React.useState(0);
788
+ const [bodySelection, setBodySelection] = React.useState(null);
789
+ const bodySelectionAnchor = React.useRef(null);
790
+ const [transcriptMode, setTranscriptMode] = React.useState(false);
791
+ const [transcriptScrollOffset, setTranscriptScrollOffset] = React.useState(0);
792
+ const [transcriptSearchQuery, setTranscriptSearchQuery] = React.useState("");
793
+ const [transcriptSearchMode, setTranscriptSearchMode] = React.useState(false);
469
794
  const [spinnerVerb, setSpinnerVerb] = React.useState(() => pickSpinnerVerb());
470
795
  const [spinnerFrameIndex, setSpinnerFrameIndex] = React.useState(0);
471
796
  React.useEffect(() => {
@@ -515,22 +840,32 @@ export function FullscreenChat({ messages, onSubmit, onClear, isProcessing, goal
515
840
  selectionAnchor.current = null;
516
841
  setSelection(null);
517
842
  }, []);
518
- const replaceInputRange = useCallback((start, end, replacement) => {
843
+ const clearBodySelection = useCallback(() => {
844
+ bodySelectionAnchor.current = null;
845
+ setBodySelection(null);
846
+ }, []);
847
+ const replaceInputRange = useCallback((start, end, replacement, nextCollapsedPaste = null) => {
519
848
  const next = input.slice(0, start) + replacement + input.slice(end);
520
849
  setInput(next);
521
850
  setCursorOffset(start + replacement.length);
851
+ setCollapsedPaste(nextCollapsedPaste);
522
852
  clearSelection();
523
853
  }, [clearSelection, input]);
524
- const insertText = useCallback((text) => {
854
+ const insertText = useCallback((text, options = {}) => {
525
855
  justSelected.current = false;
526
856
  const selectedRange = normalizeSelection(selection);
857
+ const start = selectedRange ? selectedRange.start : cursorOffset;
858
+ const nextCollapsedPaste = options.collapsePaste
859
+ ? buildCollapsedPasteRange(text, start)
860
+ : null;
527
861
  if (selectedRange) {
528
- replaceInputRange(selectedRange.start, selectedRange.end, text);
862
+ replaceInputRange(selectedRange.start, selectedRange.end, text, nextCollapsedPaste);
529
863
  return;
530
864
  }
531
865
  const next = input.slice(0, cursorOffset) + text + input.slice(cursorOffset);
532
866
  setInput(next);
533
867
  setCursorOffset(cursorOffset + text.length);
868
+ setCollapsedPaste(nextCollapsedPaste);
534
869
  clearSelection();
535
870
  }, [clearSelection, cursorOffset, input, replaceInputRange, selection]);
536
871
  const deleteSelection = useCallback(() => {
@@ -541,6 +876,19 @@ export function FullscreenChat({ messages, onSubmit, onClear, isProcessing, goal
541
876
  replaceInputRange(selectedRange.start, selectedRange.end, "");
542
877
  return true;
543
878
  }, [replaceInputRange, selection]);
879
+ const copySelectedInput = useCallback((nextSelection) => {
880
+ const selectedText = getSelectedInputText(input, nextSelection);
881
+ if (!selectedText) {
882
+ return;
883
+ }
884
+ void copySelectedInputText(input, nextSelection).then((result) => {
885
+ if (!result.ok) {
886
+ return;
887
+ }
888
+ setCopyToast(formatCopyToast(selectedText.length, result));
889
+ setTimeout(() => setCopyToast(null), 2000);
890
+ });
891
+ }, [input]);
544
892
  const matches = justSelected.current ? [] : getMatchingSuggestions(input, goalNames);
545
893
  const hasMatches = matches.length > 0;
546
894
  const bashMode = isBashModeInput(input);
@@ -555,10 +903,22 @@ export function FullscreenChat({ messages, onSubmit, onClear, isProcessing, goal
555
903
  selectedIdx,
556
904
  copyToast,
557
905
  selection: normalizedSelection,
906
+ collapsedPaste,
558
907
  });
559
908
  const messageRows = Math.max(1, availableRows - composer.lines.length - 3);
560
909
  const viewport = buildChatViewport(messages, availableCols, messageRows, scrollOffset);
561
910
  const maxScrollOffset = Math.max(0, viewport.totalRows - viewport.maxVisibleRows);
911
+ const bodySelectionRange = normalizeBodySelection(bodySelection);
912
+ const viewportFillerRows = Math.max(0, viewport.maxVisibleRows - viewport.rows.length);
913
+ const transcript = buildTranscriptRenderLines({
914
+ messages,
915
+ cols: availableCols,
916
+ rows: availableRows,
917
+ scrollOffset: transcriptScrollOffset,
918
+ searchQuery: transcriptSearchQuery,
919
+ searchMode: transcriptSearchMode,
920
+ status: copyToast,
921
+ });
562
922
  const composerLayout = {
563
923
  startLine: viewport.maxVisibleRows + 3 + composer.inputRowStartIndex + 1,
564
924
  contentStartCol: composer.contentStartCol,
@@ -583,6 +943,9 @@ export function FullscreenChat({ messages, onSubmit, onClear, isProcessing, goal
583
943
  setScrollOffset((prev) => Math.min(prev, maxScrollOffset));
584
944
  setTargetScrollOffset((prev) => Math.min(prev, maxScrollOffset));
585
945
  }, [maxScrollOffset]);
946
+ React.useEffect(() => {
947
+ setTranscriptScrollOffset((prev) => Math.min(prev, transcript.maxScrollOffset));
948
+ }, [transcript.maxScrollOffset]);
586
949
  React.useEffect(() => {
587
950
  if (scrollOffset === targetScrollOffset) {
588
951
  return;
@@ -601,18 +964,63 @@ export function FullscreenChat({ messages, onSubmit, onClear, isProcessing, goal
601
964
  }, [scrollOffset, targetScrollOffset]);
602
965
  const applyScroll = useCallback((direction, kind) => {
603
966
  setTargetScrollOffset((prev) => {
967
+ if (kind === "top")
968
+ return maxScrollOffset;
969
+ if (kind === "bottom")
970
+ return 0;
604
971
  const amount = kind === "page" ? viewport.maxVisibleRows : SCROLL_LINE_STEP;
605
- const delta = direction === "up" ? amount : -amount;
972
+ const effectiveAmount = kind === "line" ? amount * getScrollLineStep() : amount;
973
+ const delta = direction === "up" ? effectiveAmount : -effectiveAmount;
606
974
  return Math.max(0, Math.min(maxScrollOffset, prev + delta));
607
975
  });
608
976
  }, [maxScrollOffset, viewport.maxVisibleRows]);
977
+ const applyTranscriptScroll = useCallback((direction, kind) => {
978
+ setTranscriptScrollOffset((prev) => {
979
+ if (kind === "top")
980
+ return 0;
981
+ if (kind === "bottom")
982
+ return transcript.maxScrollOffset;
983
+ const pageRows = Math.max(1, availableRows - 2);
984
+ const amount = kind === "page" ? pageRows : getScrollLineStep();
985
+ const delta = direction === "up" ? -amount : amount;
986
+ return Math.max(0, Math.min(transcript.maxScrollOffset, prev + delta));
987
+ });
988
+ }, [availableRows, transcript.maxScrollOffset]);
989
+ const jumpToTranscriptMatch = useCallback((direction) => {
990
+ if (!transcriptSearchQuery)
991
+ return;
992
+ const rows = buildTranscriptRows(messages, availableCols);
993
+ const query = transcriptSearchQuery.toLowerCase();
994
+ const matches = rows
995
+ .map((row, index) => ({ row, index }))
996
+ .filter(({ row }) => row.toLowerCase().includes(query))
997
+ .map(({ index }) => index);
998
+ if (matches.length === 0)
999
+ return;
1000
+ const current = direction === "next"
1001
+ ? matches.find((index) => index > transcriptScrollOffset)
1002
+ : [...matches].reverse().find((index) => index < transcriptScrollOffset);
1003
+ setTranscriptScrollOffset(current ?? (direction === "next" ? matches[0] : matches[matches.length - 1]));
1004
+ }, [availableCols, messages, transcriptScrollOffset, transcriptSearchQuery]);
1005
+ useInput((inputChar, key) => {
1006
+ if (transcriptMode)
1007
+ return;
1008
+ const scrollRequest = getScrollRequest(inputChar, key);
1009
+ if (!scrollRequest)
1010
+ return;
1011
+ logTuiDebug("fullscreen-chat", "processing-scroll-request", {
1012
+ direction: scrollRequest.direction,
1013
+ kind: scrollRequest.kind,
1014
+ });
1015
+ applyScroll(scrollRequest.direction, scrollRequest.kind);
1016
+ }, { isActive: isProcessing });
609
1017
  const handleSubmit = useCallback((value) => {
610
1018
  logTuiDebug("fullscreen-chat", "submit-attempt", {
611
1019
  value,
612
1020
  hasMatches,
613
1021
  isProcessing,
614
1022
  });
615
- if (hasMatches || isProcessing)
1023
+ if (hasMatches)
616
1024
  return;
617
1025
  if (!value.trim()) {
618
1026
  setEmptyHint(true);
@@ -626,6 +1034,7 @@ export function FullscreenChat({ messages, onSubmit, onClear, isProcessing, goal
626
1034
  onClear?.();
627
1035
  setInput("");
628
1036
  setCursorOffset(0);
1037
+ setCollapsedPaste(null);
629
1038
  clearSelection();
630
1039
  setHistory((prev) => [...prev, trimmed]);
631
1040
  setHistoryIdx(-1);
@@ -633,16 +1042,102 @@ export function FullscreenChat({ messages, onSubmit, onClear, isProcessing, goal
633
1042
  setTargetScrollOffset(0);
634
1043
  return;
635
1044
  }
636
- onSubmit(trimmed);
1045
+ onSubmit(value);
637
1046
  setInput("");
638
1047
  setCursorOffset(0);
1048
+ setCollapsedPaste(null);
639
1049
  clearSelection();
640
- setHistory((prev) => [...prev, trimmed]);
1050
+ setHistory((prev) => [...prev, value]);
641
1051
  setHistoryIdx(-1);
642
1052
  setScrollOffset(0);
643
1053
  setTargetScrollOffset(0);
644
1054
  }, [clearSelection, hasMatches, isProcessing, onClear, onSubmit]);
645
1055
  useInput((inputChar, key) => {
1056
+ if (key.ctrl && (inputChar === "o" || inputChar === "O")) {
1057
+ setTranscriptMode((prev) => !prev);
1058
+ setTranscriptSearchMode(false);
1059
+ return;
1060
+ }
1061
+ if (transcriptMode) {
1062
+ if (transcriptSearchMode) {
1063
+ if (key.escape) {
1064
+ setTranscriptSearchMode(false);
1065
+ return;
1066
+ }
1067
+ if (key.return) {
1068
+ setTranscriptSearchMode(false);
1069
+ jumpToTranscriptMatch("next");
1070
+ return;
1071
+ }
1072
+ if (isBackspaceInput(inputChar, key)) {
1073
+ setTranscriptSearchQuery((prev) => prev.slice(0, -1));
1074
+ return;
1075
+ }
1076
+ if (inputChar && !key.ctrl && !key.meta) {
1077
+ setTranscriptSearchQuery((prev) => prev + inputChar);
1078
+ }
1079
+ return;
1080
+ }
1081
+ if (key.escape || inputChar === "q") {
1082
+ setTranscriptMode(false);
1083
+ return;
1084
+ }
1085
+ if (inputChar === "/") {
1086
+ setTranscriptSearchMode(true);
1087
+ setTranscriptSearchQuery("");
1088
+ return;
1089
+ }
1090
+ if (inputChar === "n") {
1091
+ jumpToTranscriptMatch("next");
1092
+ return;
1093
+ }
1094
+ if (inputChar === "N") {
1095
+ jumpToTranscriptMatch("previous");
1096
+ return;
1097
+ }
1098
+ if (inputChar === "[") {
1099
+ writeTranscriptToNativeScrollback(messages);
1100
+ setCopyToast("wrote transcript to terminal scrollback");
1101
+ setTimeout(() => setCopyToast(null), 2000);
1102
+ return;
1103
+ }
1104
+ if (inputChar === "v") {
1105
+ const result = openTranscriptInEditor(messages);
1106
+ setCopyToast(result.ok ? "opened transcript in editor" : "set VISUAL or EDITOR to open transcript");
1107
+ setTimeout(() => setCopyToast(null), 2000);
1108
+ return;
1109
+ }
1110
+ if (inputChar === "g" || key.home) {
1111
+ applyTranscriptScroll("up", "top");
1112
+ return;
1113
+ }
1114
+ if (inputChar === "G" || key.end) {
1115
+ applyTranscriptScroll("down", "bottom");
1116
+ return;
1117
+ }
1118
+ if (inputChar === "j" || key.downArrow) {
1119
+ applyTranscriptScroll("down", "line");
1120
+ return;
1121
+ }
1122
+ if (inputChar === "k" || key.upArrow) {
1123
+ applyTranscriptScroll("up", "line");
1124
+ return;
1125
+ }
1126
+ const transcriptScrollRequest = getScrollRequest(inputChar, key);
1127
+ if (transcriptScrollRequest) {
1128
+ applyTranscriptScroll(transcriptScrollRequest.direction, transcriptScrollRequest.kind);
1129
+ return;
1130
+ }
1131
+ if (inputChar === " " || (key.ctrl && inputChar === "f")) {
1132
+ applyTranscriptScroll("down", "page");
1133
+ return;
1134
+ }
1135
+ if (inputChar === "b" || (key.ctrl && inputChar === "b")) {
1136
+ applyTranscriptScroll("up", "page");
1137
+ return;
1138
+ }
1139
+ return;
1140
+ }
646
1141
  logTuiDebug("fullscreen-chat", "input-event", {
647
1142
  inputChar,
648
1143
  key: summarizeKey(key),
@@ -657,12 +1152,16 @@ export function FullscreenChat({ messages, onSubmit, onClear, isProcessing, goal
657
1152
  direction: scrollRequest.direction,
658
1153
  kind: scrollRequest.kind,
659
1154
  });
660
- applyScroll(scrollRequest.direction, scrollRequest.kind);
1155
+ if (!isProcessing) {
1156
+ applyScroll(scrollRequest.direction, scrollRequest.kind);
1157
+ }
661
1158
  return;
662
1159
  }
663
1160
  const mouseEvent = parseMouseEvent(inputChar);
664
1161
  if (mouseEvent && mouseEvent.kind !== "wheel" && mouseEvent.button === "left") {
665
- const offset = getMouseOffsetFromComposer(composerLayout, mouseEvent.x, mouseEvent.y, mouseEvent.kind !== "press" && selectionAnchor.current !== null);
1162
+ const localMouseX = mouseEvent.x - cursorOriginX;
1163
+ const localMouseY = mouseEvent.y - cursorOriginY;
1164
+ const offset = getMouseOffsetFromComposer(composerLayout, localMouseX, localMouseY, mouseEvent.kind !== "press" && selectionAnchor.current !== null);
666
1165
  if (mouseEvent.kind === "release" && offset === null) {
667
1166
  selectionAnchor.current = null;
668
1167
  return;
@@ -681,12 +1180,51 @@ export function FullscreenChat({ messages, onSubmit, onClear, isProcessing, goal
681
1180
  const nextSelection = { anchor: selectionAnchor.current, focus: offset };
682
1181
  selectionAnchor.current = null;
683
1182
  setSelection(nextSelection.anchor === nextSelection.focus ? null : nextSelection);
1183
+ copySelectedInput(nextSelection);
684
1184
  }
685
1185
  return;
686
1186
  }
1187
+ const bodyPosition = getMousePositionFromBody(viewport.rows, localMouseX, localMouseY, viewportFillerRows);
1188
+ if (bodyPosition !== null) {
1189
+ clearSelection();
1190
+ if (mouseEvent.kind === "press") {
1191
+ bodySelectionAnchor.current = bodyPosition;
1192
+ setBodySelection({ anchor: bodyPosition, focus: bodyPosition });
1193
+ return;
1194
+ }
1195
+ if (mouseEvent.kind === "drag" && bodySelectionAnchor.current !== null) {
1196
+ setBodySelection({ anchor: bodySelectionAnchor.current, focus: bodyPosition });
1197
+ return;
1198
+ }
1199
+ if (mouseEvent.kind === "release" && bodySelectionAnchor.current !== null) {
1200
+ const nextSelection = { anchor: bodySelectionAnchor.current, focus: bodyPosition };
1201
+ bodySelectionAnchor.current = null;
1202
+ setBodySelection(nextSelection);
1203
+ const selectedText = getSelectedBodyText(viewport.rows, nextSelection);
1204
+ if (selectedText) {
1205
+ void copyToClipboard(selectedText).then((result) => {
1206
+ if (!result.ok)
1207
+ return;
1208
+ setCopyToast(formatCopyToast(selectedText.length, result));
1209
+ setTimeout(() => setCopyToast(null), 2000);
1210
+ });
1211
+ }
1212
+ else {
1213
+ const row = viewport.rows[bodyPosition.rowIndex];
1214
+ const target = row ? extractClickableTargetAt(row.text, bodyPosition.offset) : null;
1215
+ if (target) {
1216
+ const opened = openClickableTarget(target);
1217
+ setCopyToast(opened ? `opened ${target}` : `could not open ${target}`);
1218
+ setTimeout(() => setCopyToast(null), 2000);
1219
+ }
1220
+ }
1221
+ return;
1222
+ }
1223
+ }
687
1224
  }
688
1225
  if (key.return && key.shift) {
689
1226
  logTuiDebug("fullscreen-chat", "insert-newline", { cursorOffset });
1227
+ clearBodySelection();
690
1228
  insertText("\n");
691
1229
  return;
692
1230
  }
@@ -707,6 +1245,7 @@ export function FullscreenChat({ messages, onSubmit, onClear, isProcessing, goal
707
1245
  : selected.name;
708
1246
  setInput(value);
709
1247
  setCursorOffset(value.length);
1248
+ setCollapsedPaste(null);
710
1249
  clearSelection();
711
1250
  setSelectedIdx(0);
712
1251
  justSelected.current = true;
@@ -717,7 +1256,9 @@ export function FullscreenChat({ messages, onSubmit, onClear, isProcessing, goal
717
1256
  setSelectedIdx(0);
718
1257
  setInput("");
719
1258
  setCursorOffset(0);
1259
+ setCollapsedPaste(null);
720
1260
  clearSelection();
1261
+ clearBodySelection();
721
1262
  return;
722
1263
  }
723
1264
  }
@@ -770,6 +1311,7 @@ export function FullscreenChat({ messages, onSubmit, onClear, isProcessing, goal
770
1311
  const next = input.slice(0, previousOffset) + input.slice(cursorOffset);
771
1312
  setInput(next);
772
1313
  setCursorOffset(previousOffset);
1314
+ setCollapsedPaste(null);
773
1315
  logTuiDebug("fullscreen-chat", "backspace-applied", {
774
1316
  previousOffset,
775
1317
  next,
@@ -796,6 +1338,7 @@ export function FullscreenChat({ messages, onSubmit, onClear, isProcessing, goal
796
1338
  const nextOffset = getNextOffset(input, cursorOffset);
797
1339
  const next = input.slice(0, cursorOffset) + input.slice(nextOffset);
798
1340
  setInput(next);
1341
+ setCollapsedPaste(null);
799
1342
  logTuiDebug("fullscreen-chat", "delete-applied", {
800
1343
  nextOffset,
801
1344
  next,
@@ -815,12 +1358,14 @@ export function FullscreenChat({ messages, onSubmit, onClear, isProcessing, goal
815
1358
  setHistoryIdx(idx);
816
1359
  setInput(history[idx]);
817
1360
  setCursorOffset(history[idx].length);
1361
+ setCollapsedPaste(null);
818
1362
  }
819
1363
  else if (historyIdx > 0) {
820
1364
  const idx = historyIdx - 1;
821
1365
  setHistoryIdx(idx);
822
1366
  setInput(history[idx]);
823
1367
  setCursorOffset(history[idx].length);
1368
+ setCollapsedPaste(null);
824
1369
  }
825
1370
  }
826
1371
  return;
@@ -832,11 +1377,13 @@ export function FullscreenChat({ messages, onSubmit, onClear, isProcessing, goal
832
1377
  setHistoryIdx(idx);
833
1378
  setInput(history[idx]);
834
1379
  setCursorOffset(history[idx].length);
1380
+ setCollapsedPaste(null);
835
1381
  }
836
1382
  else {
837
1383
  setHistoryIdx(-1);
838
1384
  setInput(draft);
839
1385
  setCursorOffset(draft.length);
1386
+ setCollapsedPaste(null);
840
1387
  }
841
1388
  return;
842
1389
  }
@@ -844,9 +1391,12 @@ export function FullscreenChat({ messages, onSubmit, onClear, isProcessing, goal
844
1391
  const clean = normalizeTerminalInputChunk(inputChar);
845
1392
  if (clean.length === 0)
846
1393
  return;
847
- insertText(clean);
1394
+ clearBodySelection();
1395
+ insertText(clean, {
1396
+ collapsePaste: shouldCollapsePastedText(inputChar, clean),
1397
+ });
848
1398
  }
849
- }, { isActive: !isProcessing });
1399
+ }, { isActive: true });
850
1400
  React.useEffect(() => {
851
1401
  setSelectedIdx(0);
852
1402
  }, [matches.map((match) => match.name).join(",")]);
@@ -857,15 +1407,19 @@ export function FullscreenChat({ messages, onSubmit, onClear, isProcessing, goal
857
1407
  };
858
1408
  }, []);
859
1409
  const spinnerGlyph = PROCESSING_SPINNER_FRAMES[spinnerFrameIndex] ?? PROCESSING_SPINNER_FRAMES[0];
860
- const visibleLines = buildFullscreenChatRenderLines({
861
- availableCols,
862
- availableRows,
863
- viewport,
864
- composerLines: composer.lines,
865
- isProcessing,
866
- spinnerGlyph,
867
- spinnerVerb,
868
- });
1410
+ const visibleLines = transcriptMode
1411
+ ? transcript.lines
1412
+ : buildFullscreenChatRenderLines({
1413
+ availableCols,
1414
+ availableRows,
1415
+ viewport,
1416
+ composerLines: composer.lines,
1417
+ isProcessing,
1418
+ spinnerGlyph,
1419
+ spinnerVerb,
1420
+ bodySelection: bodySelectionRange,
1421
+ transcriptStatus: copyToast,
1422
+ });
869
1423
  return (_jsx(Box, { flexDirection: "column", flexGrow: 1, overflow: "hidden", children: visibleLines.map((line) => (_jsx(Box, { height: 1, overflow: "hidden", children: line.segments ? (line.segments.map((segment, index) => (_jsx(Text, { color: segment.color ?? line.color, backgroundColor: segment.backgroundColor ?? line.backgroundColor, bold: segment.bold ?? line.bold, dimColor: segment.dim ?? line.dim, children: index === 0 && line.protected
870
1424
  ? `${PROTECTED_ROW_MARKER}${segment.text}`
871
1425
  : segment.text }, `${line.key}-${index}`)))) : (_jsx(Text, { color: line.color, backgroundColor: line.backgroundColor, bold: line.bold, dimColor: line.dim, children: line.protected