berry-agent-sdk 0.1.0-alpha.2

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 (263) hide show
  1. package/README.md +78 -0
  2. package/dist/packages/berry-agent-sdk/src/client.d.ts +6 -0
  3. package/dist/packages/berry-agent-sdk/src/client.js +59 -0
  4. package/dist/packages/berry-agent-sdk/src/client.js.map +1 -0
  5. package/dist/packages/berry-agent-sdk/src/http.d.ts +24 -0
  6. package/dist/packages/berry-agent-sdk/src/http.js +232 -0
  7. package/dist/packages/berry-agent-sdk/src/http.js.map +1 -0
  8. package/dist/packages/berry-agent-sdk/src/index.d.ts +25 -0
  9. package/dist/packages/berry-agent-sdk/src/index.js +22 -0
  10. package/dist/packages/berry-agent-sdk/src/index.js.map +1 -0
  11. package/dist/packages/berry-agent-sdk/src/stdio.d.ts +23 -0
  12. package/dist/packages/berry-agent-sdk/src/stdio.js +238 -0
  13. package/dist/packages/berry-agent-sdk/src/stdio.js.map +1 -0
  14. package/dist/packages/berry-agent-sdk/src/types.d.ts +117 -0
  15. package/dist/packages/berry-agent-sdk/src/types.js +19 -0
  16. package/dist/packages/berry-agent-sdk/src/types.js.map +1 -0
  17. package/dist/src/agent/events.d.ts +11 -0
  18. package/dist/src/agent/events.js +2 -0
  19. package/dist/src/agent/events.js.map +1 -0
  20. package/dist/src/agent/index.d.ts +13 -0
  21. package/dist/src/agent/index.js +3 -0
  22. package/dist/src/agent/index.js.map +1 -0
  23. package/dist/src/agent/loop.d.ts +19 -0
  24. package/dist/src/agent/loop.js +140 -0
  25. package/dist/src/agent/loop.js.map +1 -0
  26. package/dist/src/agent/queue.d.ts +105 -0
  27. package/dist/src/agent/queue.js +120 -0
  28. package/dist/src/agent/queue.js.map +1 -0
  29. package/dist/src/agent/stream.d.ts +21 -0
  30. package/dist/src/agent/stream.js +80 -0
  31. package/dist/src/agent/stream.js.map +1 -0
  32. package/dist/src/agent/tools-batch.d.ts +49 -0
  33. package/dist/src/agent/tools-batch.js +222 -0
  34. package/dist/src/agent/tools-batch.js.map +1 -0
  35. package/dist/src/agent/types.d.ts +104 -0
  36. package/dist/src/agent/types.js +9 -0
  37. package/dist/src/agent/types.js.map +1 -0
  38. package/dist/src/channels/ask-queue.d.ts +44 -0
  39. package/dist/src/channels/ask-queue.js +83 -0
  40. package/dist/src/channels/ask-queue.js.map +1 -0
  41. package/dist/src/channels/commands.d.ts +56 -0
  42. package/dist/src/channels/commands.js +130 -0
  43. package/dist/src/channels/commands.js.map +1 -0
  44. package/dist/src/channels/engine/cell.d.ts +55 -0
  45. package/dist/src/channels/engine/cell.js +144 -0
  46. package/dist/src/channels/engine/cell.js.map +1 -0
  47. package/dist/src/channels/engine/diff.d.ts +3 -0
  48. package/dist/src/channels/engine/diff.js +144 -0
  49. package/dist/src/channels/engine/diff.js.map +1 -0
  50. package/dist/src/channels/engine/engine.d.ts +151 -0
  51. package/dist/src/channels/engine/engine.js +417 -0
  52. package/dist/src/channels/engine/engine.js.map +1 -0
  53. package/dist/src/channels/engine/index.d.ts +22 -0
  54. package/dist/src/channels/engine/index.js +9 -0
  55. package/dist/src/channels/engine/index.js.map +1 -0
  56. package/dist/src/channels/engine/input-keys.d.ts +39 -0
  57. package/dist/src/channels/engine/input-keys.js +87 -0
  58. package/dist/src/channels/engine/input-keys.js.map +1 -0
  59. package/dist/src/channels/engine/input.d.ts +174 -0
  60. package/dist/src/channels/engine/input.js +597 -0
  61. package/dist/src/channels/engine/input.js.map +1 -0
  62. package/dist/src/channels/engine/memory-io.d.ts +46 -0
  63. package/dist/src/channels/engine/memory-io.js +72 -0
  64. package/dist/src/channels/engine/memory-io.js.map +1 -0
  65. package/dist/src/channels/engine/process-io.d.ts +23 -0
  66. package/dist/src/channels/engine/process-io.js +39 -0
  67. package/dist/src/channels/engine/process-io.js.map +1 -0
  68. package/dist/src/channels/engine/types.d.ts +202 -0
  69. package/dist/src/channels/engine/types.js +18 -0
  70. package/dist/src/channels/engine/types.js.map +1 -0
  71. package/dist/src/channels/engine/width.d.ts +23 -0
  72. package/dist/src/channels/engine/width.js +123 -0
  73. package/dist/src/channels/engine/width.js.map +1 -0
  74. package/dist/src/channels/index.d.ts +25 -0
  75. package/dist/src/channels/index.js +16 -0
  76. package/dist/src/channels/index.js.map +1 -0
  77. package/dist/src/channels/registry.d.ts +33 -0
  78. package/dist/src/channels/registry.js +57 -0
  79. package/dist/src/channels/registry.js.map +1 -0
  80. package/dist/src/channels/sdk/admit.d.ts +32 -0
  81. package/dist/src/channels/sdk/admit.js +30 -0
  82. package/dist/src/channels/sdk/admit.js.map +1 -0
  83. package/dist/src/channels/sdk/backend.d.ts +19 -0
  84. package/dist/src/channels/sdk/backend.js +103 -0
  85. package/dist/src/channels/sdk/backend.js.map +1 -0
  86. package/dist/src/channels/sdk/cursor.d.ts +51 -0
  87. package/dist/src/channels/sdk/cursor.js +57 -0
  88. package/dist/src/channels/sdk/cursor.js.map +1 -0
  89. package/dist/src/channels/sdk/index.d.ts +20 -0
  90. package/dist/src/channels/sdk/index.js +21 -0
  91. package/dist/src/channels/sdk/index.js.map +1 -0
  92. package/dist/src/channels/sdk/jsonl.d.ts +47 -0
  93. package/dist/src/channels/sdk/jsonl.js +201 -0
  94. package/dist/src/channels/sdk/jsonl.js.map +1 -0
  95. package/dist/src/channels/sdk/protocol.d.ts +297 -0
  96. package/dist/src/channels/sdk/protocol.js +25 -0
  97. package/dist/src/channels/sdk/protocol.js.map +1 -0
  98. package/dist/src/channels/sdk/schema.d.ts +12 -0
  99. package/dist/src/channels/sdk/schema.js +92 -0
  100. package/dist/src/channels/sdk/schema.js.map +1 -0
  101. package/dist/src/channels/sdk/wire-core.d.ts +199 -0
  102. package/dist/src/channels/sdk/wire-core.js +447 -0
  103. package/dist/src/channels/sdk/wire-core.js.map +1 -0
  104. package/dist/src/channels/service.d.ts +66 -0
  105. package/dist/src/channels/service.js +170 -0
  106. package/dist/src/channels/service.js.map +1 -0
  107. package/dist/src/channels/tui/autocomplete/autocomplete.d.ts +32 -0
  108. package/dist/src/channels/tui/autocomplete/autocomplete.js +43 -0
  109. package/dist/src/channels/tui/autocomplete/autocomplete.js.map +1 -0
  110. package/dist/src/channels/tui/autocomplete/file-mentions.d.ts +18 -0
  111. package/dist/src/channels/tui/autocomplete/file-mentions.js +107 -0
  112. package/dist/src/channels/tui/autocomplete/file-mentions.js.map +1 -0
  113. package/dist/src/channels/tui/autocomplete/popup.d.ts +47 -0
  114. package/dist/src/channels/tui/autocomplete/popup.js +149 -0
  115. package/dist/src/channels/tui/autocomplete/popup.js.map +1 -0
  116. package/dist/src/channels/tui/autocomplete/provider.d.ts +38 -0
  117. package/dist/src/channels/tui/autocomplete/provider.js +8 -0
  118. package/dist/src/channels/tui/autocomplete/provider.js.map +1 -0
  119. package/dist/src/channels/tui/autocomplete/token.d.ts +22 -0
  120. package/dist/src/channels/tui/autocomplete/token.js +69 -0
  121. package/dist/src/channels/tui/autocomplete/token.js.map +1 -0
  122. package/dist/src/channels/tui/backend/ansi-rows.d.ts +86 -0
  123. package/dist/src/channels/tui/backend/ansi-rows.js +209 -0
  124. package/dist/src/channels/tui/backend/ansi-rows.js.map +1 -0
  125. package/dist/src/channels/tui/backend/main-screen.d.ts +90 -0
  126. package/dist/src/channels/tui/backend/main-screen.js +208 -0
  127. package/dist/src/channels/tui/backend/main-screen.js.map +1 -0
  128. package/dist/src/channels/tui/backend/osc.d.ts +79 -0
  129. package/dist/src/channels/tui/backend/osc.js +92 -0
  130. package/dist/src/channels/tui/backend/osc.js.map +1 -0
  131. package/dist/src/channels/tui/backend/transcript.d.ts +98 -0
  132. package/dist/src/channels/tui/backend/transcript.js +231 -0
  133. package/dist/src/channels/tui/backend/transcript.js.map +1 -0
  134. package/dist/src/channels/tui/backend/tui-backend.d.ts +324 -0
  135. package/dist/src/channels/tui/backend/tui-backend.js +916 -0
  136. package/dist/src/channels/tui/backend/tui-backend.js.map +1 -0
  137. package/dist/src/channels/tui/editor/editor-model.d.ts +141 -0
  138. package/dist/src/channels/tui/editor/editor-model.js +544 -0
  139. package/dist/src/channels/tui/editor/editor-model.js.map +1 -0
  140. package/dist/src/channels/tui/editor/editor-view.d.ts +36 -0
  141. package/dist/src/channels/tui/editor/editor-view.js +141 -0
  142. package/dist/src/channels/tui/editor/editor-view.js.map +1 -0
  143. package/dist/src/channels/tui/editor/editor.d.ts +50 -0
  144. package/dist/src/channels/tui/editor/editor.js +276 -0
  145. package/dist/src/channels/tui/editor/editor.js.map +1 -0
  146. package/dist/src/channels/tui/editor/undo-stack.d.ts +22 -0
  147. package/dist/src/channels/tui/editor/undo-stack.js +36 -0
  148. package/dist/src/channels/tui/editor/undo-stack.js.map +1 -0
  149. package/dist/src/channels/tui/editor/visual-lines.d.ts +39 -0
  150. package/dist/src/channels/tui/editor/visual-lines.js +127 -0
  151. package/dist/src/channels/tui/editor/visual-lines.js.map +1 -0
  152. package/dist/src/channels/tui/editor/word-nav.d.ts +10 -0
  153. package/dist/src/channels/tui/editor/word-nav.js +107 -0
  154. package/dist/src/channels/tui/editor/word-nav.js.map +1 -0
  155. package/dist/src/channels/tui/history/history-viewer.d.ts +133 -0
  156. package/dist/src/channels/tui/history/history-viewer.js +404 -0
  157. package/dist/src/channels/tui/history/history-viewer.js.map +1 -0
  158. package/dist/src/channels/tui/index.d.ts +16 -0
  159. package/dist/src/channels/tui/index.js +4 -0
  160. package/dist/src/channels/tui/index.js.map +1 -0
  161. package/dist/src/channels/tui/markdown/blocks.d.ts +42 -0
  162. package/dist/src/channels/tui/markdown/blocks.js +112 -0
  163. package/dist/src/channels/tui/markdown/blocks.js.map +1 -0
  164. package/dist/src/channels/tui/markdown/inline.d.ts +24 -0
  165. package/dist/src/channels/tui/markdown/inline.js +76 -0
  166. package/dist/src/channels/tui/markdown/inline.js.map +1 -0
  167. package/dist/src/channels/tui/markdown/markdown.d.ts +34 -0
  168. package/dist/src/channels/tui/markdown/markdown.js +183 -0
  169. package/dist/src/channels/tui/markdown/markdown.js.map +1 -0
  170. package/dist/src/channels/tui/memory/memory-viewer.d.ts +235 -0
  171. package/dist/src/channels/tui/memory/memory-viewer.js +541 -0
  172. package/dist/src/channels/tui/memory/memory-viewer.js.map +1 -0
  173. package/dist/src/channels/tui/overlay/alt-screen.d.ts +79 -0
  174. package/dist/src/channels/tui/overlay/alt-screen.js +106 -0
  175. package/dist/src/channels/tui/overlay/alt-screen.js.map +1 -0
  176. package/dist/src/channels/tui/overlay/overlay.d.ts +53 -0
  177. package/dist/src/channels/tui/overlay/overlay.js +58 -0
  178. package/dist/src/channels/tui/overlay/overlay.js.map +1 -0
  179. package/dist/src/channels/tui/overlay/select-confirm.d.ts +73 -0
  180. package/dist/src/channels/tui/overlay/select-confirm.js +157 -0
  181. package/dist/src/channels/tui/overlay/select-confirm.js.map +1 -0
  182. package/dist/src/channels/tui/panels/todo-panel.d.ts +24 -0
  183. package/dist/src/channels/tui/panels/todo-panel.js +55 -0
  184. package/dist/src/channels/tui/panels/todo-panel.js.map +1 -0
  185. package/dist/src/channels/tui/panels/tool-progress-panel.d.ts +37 -0
  186. package/dist/src/channels/tui/panels/tool-progress-panel.js +94 -0
  187. package/dist/src/channels/tui/panels/tool-progress-panel.js.map +1 -0
  188. package/dist/src/channels/tui/scroll/scroll-view.d.ts +96 -0
  189. package/dist/src/channels/tui/scroll/scroll-view.js +255 -0
  190. package/dist/src/channels/tui/scroll/scroll-view.js.map +1 -0
  191. package/dist/src/channels/tui/status/status-line.d.ts +46 -0
  192. package/dist/src/channels/tui/status/status-line.js +77 -0
  193. package/dist/src/channels/tui/status/status-line.js.map +1 -0
  194. package/dist/src/channels/tui/theme.d.ts +27 -0
  195. package/dist/src/channels/tui/theme.js +42 -0
  196. package/dist/src/channels/tui/theme.js.map +1 -0
  197. package/dist/src/channels/types.d.ts +84 -0
  198. package/dist/src/channels/types.js +12 -0
  199. package/dist/src/channels/types.js.map +1 -0
  200. package/dist/src/channels/ui-core.d.ts +80 -0
  201. package/dist/src/channels/ui-core.js +210 -0
  202. package/dist/src/channels/ui-core.js.map +1 -0
  203. package/dist/src/context/codes.d.ts +1 -0
  204. package/dist/src/context/codes.js +41 -0
  205. package/dist/src/context/codes.js.map +1 -0
  206. package/dist/src/context/events.d.ts +62 -0
  207. package/dist/src/context/events.js +161 -0
  208. package/dist/src/context/events.js.map +1 -0
  209. package/dist/src/context/index.d.ts +16 -0
  210. package/dist/src/context/index.js +14 -0
  211. package/dist/src/context/index.js.map +1 -0
  212. package/dist/src/context/logger.d.ts +67 -0
  213. package/dist/src/context/logger.js +137 -0
  214. package/dist/src/context/logger.js.map +1 -0
  215. package/dist/src/context/scope.d.ts +78 -0
  216. package/dist/src/context/scope.js +183 -0
  217. package/dist/src/context/scope.js.map +1 -0
  218. package/dist/src/context/workspace.d.ts +8 -0
  219. package/dist/src/context/workspace.js +105 -0
  220. package/dist/src/context/workspace.js.map +1 -0
  221. package/dist/src/contracts/agent-events.d.ts +73 -0
  222. package/dist/src/contracts/agent-events.js +17 -0
  223. package/dist/src/contracts/agent-events.js.map +1 -0
  224. package/dist/src/contracts/api.d.ts +249 -0
  225. package/dist/src/contracts/api.js +334 -0
  226. package/dist/src/contracts/api.js.map +1 -0
  227. package/dist/src/contracts/approval.d.ts +37 -0
  228. package/dist/src/contracts/approval.js +10 -0
  229. package/dist/src/contracts/approval.js.map +1 -0
  230. package/dist/src/contracts/env-ref.d.ts +41 -0
  231. package/dist/src/contracts/env-ref.js +33 -0
  232. package/dist/src/contracts/env-ref.js.map +1 -0
  233. package/dist/src/contracts/errors.d.ts +56 -0
  234. package/dist/src/contracts/errors.js +267 -0
  235. package/dist/src/contracts/errors.js.map +1 -0
  236. package/dist/src/contracts/events.d.ts +70 -0
  237. package/dist/src/contracts/events.js +330 -0
  238. package/dist/src/contracts/events.js.map +1 -0
  239. package/dist/src/contracts/index.d.ts +32 -0
  240. package/dist/src/contracts/index.js +27 -0
  241. package/dist/src/contracts/index.js.map +1 -0
  242. package/dist/src/contracts/llm.d.ts +278 -0
  243. package/dist/src/contracts/llm.js +13 -0
  244. package/dist/src/contracts/llm.js.map +1 -0
  245. package/dist/src/contracts/messages.d.ts +63 -0
  246. package/dist/src/contracts/messages.js +66 -0
  247. package/dist/src/contracts/messages.js.map +1 -0
  248. package/dist/src/contracts/redact.d.ts +46 -0
  249. package/dist/src/contracts/redact.js +224 -0
  250. package/dist/src/contracts/redact.js.map +1 -0
  251. package/dist/src/contracts/tools.d.ts +198 -0
  252. package/dist/src/contracts/tools.js +35 -0
  253. package/dist/src/contracts/tools.js.map +1 -0
  254. package/dist/src/contracts/types.d.ts +304 -0
  255. package/dist/src/contracts/types.js +51 -0
  256. package/dist/src/contracts/types.js.map +1 -0
  257. package/dist/src/contracts/ui.d.ts +122 -0
  258. package/dist/src/contracts/ui.js +16 -0
  259. package/dist/src/contracts/ui.js.map +1 -0
  260. package/dist/src/sdk/types.d.ts +144 -0
  261. package/dist/src/sdk/types.js +33 -0
  262. package/dist/src/sdk/types.js.map +1 -0
  263. package/package.json +29 -0
@@ -0,0 +1,90 @@
1
+ /**
2
+ * 主屏 inline 形态编舞件(07 §4.1「屏幕模型双形态」主屏条——批 10e)。
3
+ *
4
+ * 物理形态(与副屏全屏网格分立、共用 cell/diff/width 基座——07 篇定形):
5
+ * - **DECSTBM 滚动区**承载正文(顶行到固定区上方):区底写满自动滚、
6
+ * 滚出视口整行交终端原生 scrollback(历史真相在 durable 事件日志,行集
7
+ * 是帽内最近段的内存上限语义);
8
+ * - **固定区钉屏底**(区外行不被滚动卷入、绝对位可知):输入框 + 状态行,
9
+ * 行级差分重画(变行整行重写、未变行零写出——擦除只走 EL 禁空格填充);
10
+ * - **正文块直写**:块 → 行序列化 → 追加写(追加不回改——直播路「消息事件
11
+ * 唯一渲染源」的物理形);流式槽原位换装是视口内唯一差分。序列化单源走
12
+ * renderBlockLines(批 10f-4 提取——件 8 回看器全量档复用同一渲染管线,
13
+ * 零第二渲染器)。
14
+ *
15
+ * 编舞状态模型:**绝对行跟踪**。件内维护光标绝对行 cursorRow 与 durable
16
+ * 末行 durableEndRow(= 下一条追加的落笔行 = 流式槽首行),每次写行经
17
+ * writeLine 单点维护(区底 LF 触滚钉区底——滚动量不外显);present 尾光标
18
+ * 归固定区末行行首(呈现不变式——编舞内相对定位全由此出发;固定区自身用
19
+ * 绝对 CUP,钉屏底位可知)。
20
+ *
21
+ * v1 已知边界:流式槽 partial 回缩(新行数少于旧)按余行 EL 清——inline
22
+ * 终端无删行机制;固定区高度变化时光标账按区底钳制(内容可能被固定区
23
+ * 覆盖——装配宜随高度变化触发 repaint 重建)。
24
+ */
25
+ import { CellGrid, type TerminalIO } from '../../engine/index.js';
26
+ import { type TranscriptBlock } from './transcript.js';
27
+ /** 主屏选项 */
28
+ export interface MainScreenOptions {
29
+ /** 固定区高(行——输入框 + 状态行;随内容折行动态变化经 setFixed 更新) */
30
+ readonly fixedHeight: number;
31
+ }
32
+ /**
33
+ * 主屏编舞:正文直写 + 槽换装 + 固定区差分。无自驱时钟(请求合并归装配),
34
+ * 所有公开方法同步产写出(测试经 MemoryTerminalIO 收帧断言)。
35
+ */
36
+ export declare class MainScreen {
37
+ private readonly io;
38
+ private columns;
39
+ private rows;
40
+ private fixedHeight;
41
+ /** 已直写 durable 块数(增量追加起点——repaint 归零全量重写) */
42
+ private writtenBlocks;
43
+ /** 光标绝对行(0 基——写行/定位单点维护) */
44
+ private cursorRow;
45
+ /** durable 末行(追加落笔行 = 槽首行;滚动时钉区底) */
46
+ private durableEndRow;
47
+ /** 当前槽直写行数(余行清除上界依据) */
48
+ private slotLineCount;
49
+ /** 固定区网格(装配画好交入——null = 固定区未装配只归位光标) */
50
+ private fixedGrid;
51
+ /** 固定区上次呈现网格(行级差分基准;null = 全量重画) */
52
+ private prevFixed;
53
+ constructor(io: TerminalIO, options: MainScreenOptions);
54
+ /** 几何观测(装配层 resize 编舞消费) */
55
+ get geometry(): {
56
+ columns: number;
57
+ rows: number;
58
+ };
59
+ /** 启动编舞:清屏 + 滚动区确立 + 光标归位(呈现不变式自洽) */
60
+ start(): void;
61
+ /**
62
+ * 增量呈现(追加块直写 → 槽换装 → 余行清除 → 固定区差分)。
63
+ * 前置:光标在固定区末行行首(start / setFixed / 上次 present 归位)。
64
+ */
65
+ present(blocks: readonly TranscriptBlock[]): void;
66
+ /**
67
+ * 瞬时行直写(非聚焦摘要行 / notify 通知行——不进行集不记 writtenBlocks,
68
+ * repaint 不重建)。编舞同追加块:归 durable 末 → 写行 → 余行清除 → 归位。
69
+ * 行内容由调用方(TuiBackend)序列化——本件纯编舞不做着色决策。
70
+ */
71
+ appendTransient(lines: readonly string[]): void;
72
+ /** 固定区网格更新(装配直呼——行级差分;几何变化时滚动区重设 + 差分基准失效) */
73
+ setFixed(grid: CellGrid): void;
74
+ /** repaint(焦点切换):清屏 + 行集全量重写(投影即真相——scrollback 旧内容不参与) */
75
+ repaint(blocks: readonly TranscriptBlock[]): void;
76
+ /** resize 编舞:几何重取 + 滚动区重设 + 全量重画(弃旧换新——宽字符 reflow 必失真) */
77
+ handleResize(blocks: readonly TranscriptBlock[]): void;
78
+ /** 滚动区确立/重设(DECSTBM 规范行为是光标归 home——随后显式归位呈现不变式位) */
79
+ private applyScrollRegion;
80
+ /** 写一行(CR 起笔 + LF 推进)并维护 cursorRow;区底 LF 触滚——内容整体上移一格、durableEndRow 同步减一(账不漂移) */
81
+ private writeLine;
82
+ /** 光标归行(present 入口光标在固定区末行——CUU 相对定位即可达全屏任意行) */
83
+ private gotoRow;
84
+ /** 固定区差分重画 + 光标落位(编辑光标外显的物理位) */
85
+ private redrawFixed;
86
+ /** 块 → 行序列化直写(序列化单源 renderBlockLines——件 8 回看器复用同一管线,批 10f-4) */
87
+ private writeBlockLines;
88
+ /** 流式槽行(纯文本直推——性能:不走网格不走样式;序列化同源 renderBlockLines) */
89
+ private renderSlotLines;
90
+ }
@@ -0,0 +1,208 @@
1
+ /**
2
+ * 主屏 inline 形态编舞件(07 §4.1「屏幕模型双形态」主屏条——批 10e)。
3
+ *
4
+ * 物理形态(与副屏全屏网格分立、共用 cell/diff/width 基座——07 篇定形):
5
+ * - **DECSTBM 滚动区**承载正文(顶行到固定区上方):区底写满自动滚、
6
+ * 滚出视口整行交终端原生 scrollback(历史真相在 durable 事件日志,行集
7
+ * 是帽内最近段的内存上限语义);
8
+ * - **固定区钉屏底**(区外行不被滚动卷入、绝对位可知):输入框 + 状态行,
9
+ * 行级差分重画(变行整行重写、未变行零写出——擦除只走 EL 禁空格填充);
10
+ * - **正文块直写**:块 → 行序列化 → 追加写(追加不回改——直播路「消息事件
11
+ * 唯一渲染源」的物理形);流式槽原位换装是视口内唯一差分。序列化单源走
12
+ * renderBlockLines(批 10f-4 提取——件 8 回看器全量档复用同一渲染管线,
13
+ * 零第二渲染器)。
14
+ *
15
+ * 编舞状态模型:**绝对行跟踪**。件内维护光标绝对行 cursorRow 与 durable
16
+ * 末行 durableEndRow(= 下一条追加的落笔行 = 流式槽首行),每次写行经
17
+ * writeLine 单点维护(区底 LF 触滚钉区底——滚动量不外显);present 尾光标
18
+ * 归固定区末行行首(呈现不变式——编舞内相对定位全由此出发;固定区自身用
19
+ * 绝对 CUP,钉屏底位可知)。
20
+ *
21
+ * v1 已知边界:流式槽 partial 回缩(新行数少于旧)按余行 EL 清——inline
22
+ * 终端无删行机制;固定区高度变化时光标账按区底钳制(内容可能被固定区
23
+ * 覆盖——装配宜随高度变化触发 repaint 重建)。
24
+ */
25
+ import { CellGrid } from '../../engine/index.js';
26
+ import { CLEAR_SCREEN, CR, cud, cuu, EL_TO_EOL, LF, renderFixedRegionDiff, setScrollRegion, cup } from './ansi-rows.js';
27
+ import { renderBlockLines } from './transcript.js';
28
+ /** 缺省几何(真值以 io.size() 为准——resize 路装配调 handleResize) */
29
+ const DEFAULT_COLUMNS = 80;
30
+ const DEFAULT_ROWS = 24;
31
+ /**
32
+ * 主屏编舞:正文直写 + 槽换装 + 固定区差分。无自驱时钟(请求合并归装配),
33
+ * 所有公开方法同步产写出(测试经 MemoryTerminalIO 收帧断言)。
34
+ */
35
+ export class MainScreen {
36
+ io;
37
+ columns = DEFAULT_COLUMNS;
38
+ rows = DEFAULT_ROWS;
39
+ fixedHeight;
40
+ /** 已直写 durable 块数(增量追加起点——repaint 归零全量重写) */
41
+ writtenBlocks = 0;
42
+ /** 光标绝对行(0 基——写行/定位单点维护) */
43
+ cursorRow = 0;
44
+ /** durable 末行(追加落笔行 = 槽首行;滚动时钉区底) */
45
+ durableEndRow = 0;
46
+ /** 当前槽直写行数(余行清除上界依据) */
47
+ slotLineCount = 0;
48
+ /** 固定区网格(装配画好交入——null = 固定区未装配只归位光标) */
49
+ fixedGrid = null;
50
+ /** 固定区上次呈现网格(行级差分基准;null = 全量重画) */
51
+ prevFixed = null;
52
+ constructor(io, options) {
53
+ this.io = io;
54
+ this.fixedHeight = options.fixedHeight;
55
+ const size = io.size();
56
+ this.columns = size.columns;
57
+ this.rows = size.rows;
58
+ }
59
+ /** 几何观测(装配层 resize 编舞消费) */
60
+ get geometry() {
61
+ return { columns: this.columns, rows: this.rows };
62
+ }
63
+ /** 启动编舞:清屏 + 滚动区确立 + 光标归位(呈现不变式自洽) */
64
+ start() {
65
+ this.io.write(CLEAR_SCREEN);
66
+ this.applyScrollRegion();
67
+ }
68
+ /**
69
+ * 增量呈现(追加块直写 → 槽换装 → 余行清除 → 固定区差分)。
70
+ * 前置:光标在固定区末行行首(start / setFixed / 上次 present 归位)。
71
+ */
72
+ present(blocks) {
73
+ // 末块为 streaming 时即流式槽(const 绑定经 kind 判别收窄)
74
+ const last = blocks.length > 0 ? blocks[blocks.length - 1] : null;
75
+ const slot = last !== null && last.kind === 'streaming' ? last : null;
76
+ const durableCount = slot === null ? blocks.length : blocks.length - 1;
77
+ // 余行清除上界:上次呈现的槽末行(= durable 末 + 槽行数 - 1——本帧前的账)
78
+ const prevBottomRow = Math.min(this.rows - this.fixedHeight - 1, this.durableEndRow + this.slotLineCount - 1);
79
+ // 光标归 durable 末(B/C 共同起点——无新增块时 C 段也从这里起笔)
80
+ this.gotoRow(this.durableEndRow);
81
+ // B. 追加块直写(每行 CR 起笔 + LF 推进,区底触滚交 scrollback)
82
+ if (durableCount > this.writtenBlocks) {
83
+ for (let i = this.writtenBlocks; i < durableCount; i++) {
84
+ this.writeBlockLines(blocks[i]);
85
+ }
86
+ this.writtenBlocks = durableCount;
87
+ this.durableEndRow = this.cursorRow;
88
+ }
89
+ // C. 槽换装(光标已在槽首 = durable 末;partial 是完整快照——逐行整写)
90
+ const slotLines = slot === null ? [] : this.renderSlotLines(slot);
91
+ for (const line of slotLines) {
92
+ this.writeLine(line);
93
+ }
94
+ // D. 余行清除(新槽末到上次槽末之间的 stale 行——EL 擦除禁空格填充)
95
+ const fixedTop = this.rows - this.fixedHeight;
96
+ const clearEnd = Math.min(fixedTop - 1, prevBottomRow);
97
+ for (let row = this.cursorRow; row <= clearEnd; row++) {
98
+ this.io.write((row > this.cursorRow ? cud(1) : '') + CR + EL_TO_EOL);
99
+ }
100
+ // E. 固定区差分重画 + 光标归位(呈现不变式)
101
+ this.redrawFixed();
102
+ this.slotLineCount = slotLines.length;
103
+ }
104
+ /**
105
+ * 瞬时行直写(非聚焦摘要行 / notify 通知行——不进行集不记 writtenBlocks,
106
+ * repaint 不重建)。编舞同追加块:归 durable 末 → 写行 → 余行清除 → 归位。
107
+ * 行内容由调用方(TuiBackend)序列化——本件纯编舞不做着色决策。
108
+ */
109
+ appendTransient(lines) {
110
+ if (lines.length === 0)
111
+ return;
112
+ this.gotoRow(this.durableEndRow);
113
+ for (const line of lines) {
114
+ this.writeLine(line);
115
+ }
116
+ this.durableEndRow = this.cursorRow;
117
+ const fixedTop = this.rows - this.fixedHeight;
118
+ const clearEnd = Math.min(fixedTop - 1, this.durableEndRow + this.slotLineCount - 1);
119
+ for (let row = this.cursorRow; row <= clearEnd; row++) {
120
+ this.io.write((row > this.cursorRow ? cud(1) : '') + CR + EL_TO_EOL);
121
+ }
122
+ this.redrawFixed();
123
+ }
124
+ /** 固定区网格更新(装配直呼——行级差分;几何变化时滚动区重设 + 差分基准失效) */
125
+ setFixed(grid) {
126
+ if (grid.rows !== this.fixedHeight) {
127
+ this.fixedHeight = grid.rows;
128
+ this.applyScrollRegion();
129
+ this.prevFixed = null; // 高度变化——差分基准失效全量重画;durable 末行按区底钳
130
+ this.durableEndRow = Math.min(this.durableEndRow, this.rows - this.fixedHeight - 1);
131
+ this.slotLineCount = 0;
132
+ }
133
+ this.fixedGrid = grid;
134
+ this.redrawFixed();
135
+ }
136
+ /** repaint(焦点切换):清屏 + 行集全量重写(投影即真相——scrollback 旧内容不参与) */
137
+ repaint(blocks) {
138
+ this.writtenBlocks = 0;
139
+ this.slotLineCount = 0;
140
+ this.durableEndRow = 0;
141
+ this.io.write(CLEAR_SCREEN);
142
+ this.applyScrollRegion();
143
+ this.present(blocks);
144
+ }
145
+ /** resize 编舞:几何重取 + 滚动区重设 + 全量重画(弃旧换新——宽字符 reflow 必失真) */
146
+ handleResize(blocks) {
147
+ const size = this.io.size();
148
+ this.columns = size.columns;
149
+ this.rows = size.rows;
150
+ this.repaint(blocks);
151
+ }
152
+ /* ---------------- 内部编舞 ---------------- */
153
+ /** 滚动区确立/重设(DECSTBM 规范行为是光标归 home——随后显式归位呈现不变式位) */
154
+ applyScrollRegion() {
155
+ const bottom = Math.max(1, this.rows - this.fixedHeight);
156
+ this.io.write(setScrollRegion(bottom));
157
+ this.io.write(cup(this.rows - 1, 0));
158
+ this.cursorRow = this.rows - 1;
159
+ }
160
+ /** 写一行(CR 起笔 + LF 推进)并维护 cursorRow;区底 LF 触滚——内容整体上移一格、durableEndRow 同步减一(账不漂移) */
161
+ writeLine(text) {
162
+ this.io.write(CR + text + LF);
163
+ const regionBottom = this.rows - this.fixedHeight - 1;
164
+ if (this.cursorRow < regionBottom)
165
+ this.cursorRow++;
166
+ else if (this.durableEndRow > 0)
167
+ this.durableEndRow--; // 触滚:已写内容上移(B 段随后整账重赋、槽写路保持真值)
168
+ }
169
+ /** 光标归行(present 入口光标在固定区末行——CUU 相对定位即可达全屏任意行) */
170
+ gotoRow(row) {
171
+ const distance = this.cursorRow - row;
172
+ if (distance > 0)
173
+ this.io.write(cuu(distance));
174
+ else if (distance < 0)
175
+ this.io.write(cud(-distance));
176
+ this.cursorRow = row;
177
+ }
178
+ /** 固定区差分重画 + 光标落位(编辑光标外显的物理位) */
179
+ redrawFixed() {
180
+ if (this.fixedGrid !== null) {
181
+ const baseRow = this.rows - this.fixedGrid.rows;
182
+ this.io.write(renderFixedRegionDiff(this.prevFixed, this.fixedGrid, baseRow));
183
+ this.prevFixed = this.fixedGrid;
184
+ // 光标声明位落位(EditorView 编辑位经 setCursor 声明)——绝对 CUP 且
185
+ // 行账同步(gotoRow 相对定位数学依赖 cursorRow 真值);无声明回退
186
+ // 屏底行首(呈现不变式原样)
187
+ const declared = this.fixedGrid.cursor;
188
+ if (declared !== null) {
189
+ const row = Math.min(baseRow + declared.row, this.rows - 1); // 越界声明防御钳屏底
190
+ this.io.write(cup(row, declared.col));
191
+ this.cursorRow = row;
192
+ return;
193
+ }
194
+ }
195
+ this.io.write(cup(this.rows - 1, 0));
196
+ this.cursorRow = this.rows - 1;
197
+ }
198
+ /** 块 → 行序列化直写(序列化单源 renderBlockLines——件 8 回看器复用同一管线,批 10f-4) */
199
+ writeBlockLines(block) {
200
+ for (const line of renderBlockLines(block, this.columns))
201
+ this.writeLine(line);
202
+ }
203
+ /** 流式槽行(纯文本直推——性能:不走网格不走样式;序列化同源 renderBlockLines) */
204
+ renderSlotLines(slot) {
205
+ return renderBlockLines(slot, this.columns);
206
+ }
207
+ }
208
+ //# sourceMappingURL=main-screen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main-screen.js","sourceRoot":"","sources":["../../../../../../../src/channels/tui/backend/main-screen.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * 终端外显件(07 §4.1 呈现面件 7——OSC 标题 + OSC 9;4 进度态)。
3
+ *
4
+ * 语义平移 pi-tui Terminal setTitle/setProgress(自研改裁——字节形锚定
5
+ * 参考源码/pi-monorepo/packages/tui/src/terminal.ts:title = OSC 0;… BEL、
6
+ * 忙态 = `\x1b]9;4;3\x07`、清零 = `\x1b]9;4;0\x07`、keepalive 1s)。
7
+ * - **OSC 写出分治**(07 §4.1 件 7 条款):title 值缓存去重(同值不重写
8
+ * 字节);progress 态**保活周期重发**——OSC 9;4 在部分终端超时衰减,去重
9
+ * 不适用于 progress 序列、须周期重写维持;
10
+ * - **OSC 52 选区复制序列构造**(2026-09-11 鼠标解码批——件 8 选区复制):
11
+ * buildOsc52Copy 纯函数(无状态无缓存——写出与否归装配层注入柄);
12
+ * - 进度态判据(按 sessionId 归账的 agent_start/end 净计数、任一会话 > 0
13
+ * 即忙)在 TuiBackend 侧——本件只承「忙/闲」两态写出与保活自持;
14
+ * - 退出复原两写点:title 复原基线 + 进度清零(restore——TuiBackend 的
15
+ * stop 与硬退复原钩子两消费点)。
16
+ *
17
+ * 可测性:写出走注入 TerminalIO 形参(勿直写 process);保活 timer 走
18
+ * schedule 注入(TuiBackend armTick 同形),停针暴露名册语义(句柄非空才
19
+ * 取消、停后清位——cancelTimer 同律)。schedule 缺席 = 保活缺位(忙态首写
20
+ * 仍在——同步测试语义,与 TuiBackend「无注入调度 = 同步直出」同构)。
21
+ */
22
+ import type { TerminalIO } from '../../engine/index.js';
23
+ /** 保活重发周期(ms——pi-tui TERMINAL_PROGRESS_KEEPALIVE_MS 实证值) */
24
+ export declare const OSC_PROGRESS_KEEPALIVE_MS = 1000;
25
+ /**
26
+ * OSC 52 选区复制序列(07 §4.1 呈现面件 8 细则——BEL 终界):
27
+ * `\x1b]52;c;<base64>\x07`,`c` = 系统剪贴板主位。终端支持不可探测(无标准
28
+ * 应答——kitty/Alacritty/wezterm/foot 支持、iTerm2 默认禁需用户开、tmux 需
29
+ * set-clipboard on、xterm 兼容族受 allowWindowOps 门控)——尽力写出无反馈,
30
+ * 不构成故障面。写出柄归装配层注入(onCopy),本函数只铸字节。
31
+ */
32
+ export declare function buildOsc52Copy(text: string): string;
33
+ /** 调度注入形(与 TuiBackend schedule 注入同形——(fn, ms) → 句柄) */
34
+ export type OscSchedule = (fn: () => void, ms: number) => unknown;
35
+ /** 终端外显件构造选项 */
36
+ export interface OscDisplayOptions {
37
+ /** title 复原基线(退出复原落点——起屏基线形如 `berry-agent <版本>`) */
38
+ readonly baseline: string;
39
+ /** 调度注入(保活周期重发;缺席 = 保活缺位——忙态首写不受影响) */
40
+ readonly schedule?: OscSchedule;
41
+ /** 取消调度注入(与 schedule 配对——停针名册语义的取消出口) */
42
+ readonly cancel?: (handle: unknown) => void;
43
+ }
44
+ /**
45
+ * 终端外显件:OSC title + 进度态两写点的最小自持件。
46
+ * 忙态期间保活自重排(触发即清位再续针——armTick 同形);restore/停针后
47
+ * 句柄位归 null,重复停针是 no-op。
48
+ */
49
+ export declare class OscDisplay {
50
+ /** title 值缓存(null = 未写过——同值不重写判据位) */
51
+ private lastTitle;
52
+ /** 保活在飞句柄(null = 无在飞——名册语义判据位) */
53
+ private keepaliveHandle;
54
+ private readonly io;
55
+ private readonly baseline;
56
+ private readonly schedule;
57
+ private readonly cancel;
58
+ constructor(io: TerminalIO, options: OscDisplayOptions);
59
+ /** 在飞保活句柄现值(null = 无在飞——名册摘除/测试断言位) */
60
+ get activeKeepalive(): unknown;
61
+ /** 标题写出(OSC 0;… BEL——值缓存去重:同值不重写字节) */
62
+ setTitle(title: string): void;
63
+ /**
64
+ * 进度态写出(OSC 9;4):
65
+ * - true = 写忙态序列 + 起 1s 保活周期重发(已在飞不重复起针——重发维持
66
+ * 单链不叠针);同值重复调用仍重写忙态序列(去重不适用于 progress);
67
+ * - false = 写清零序列 + 停保活 timer。
68
+ */
69
+ setProgress(active: boolean): void;
70
+ /**
71
+ * 退出复原两写点齐(07 §4.1 件 7 条款):title 复原基线(经值缓存——
72
+ * 已在基线则零字节)+ 进度清零(无条件写——终态收口,含停保活)。
73
+ */
74
+ restore(): void;
75
+ /** 停保活定时器(名册语义:句柄非空才取消、停后清位——重复停针 no-op) */
76
+ stopKeepalive(): void;
77
+ /** 起保活(schedule 缺席 = 缺位;触发后清位自重排续针——周期重发维持) */
78
+ private armKeepalive;
79
+ }
@@ -0,0 +1,92 @@
1
+ /** 保活重发周期(ms——pi-tui TERMINAL_PROGRESS_KEEPALIVE_MS 实证值) */
2
+ export const OSC_PROGRESS_KEEPALIVE_MS = 1000;
3
+ /** OSC 9;4 忙态序列(indeterminate progress——state 3) */
4
+ const PROGRESS_ACTIVE_SEQUENCE = '\x1b]9;4;3\x07';
5
+ /** OSC 9;4 清零序列(state 0) */
6
+ const PROGRESS_CLEAR_SEQUENCE = '\x1b]9;4;0\x07';
7
+ /**
8
+ * OSC 52 选区复制序列(07 §4.1 呈现面件 8 细则——BEL 终界):
9
+ * `\x1b]52;c;<base64>\x07`,`c` = 系统剪贴板主位。终端支持不可探测(无标准
10
+ * 应答——kitty/Alacritty/wezterm/foot 支持、iTerm2 默认禁需用户开、tmux 需
11
+ * set-clipboard on、xterm 兼容族受 allowWindowOps 门控)——尽力写出无反馈,
12
+ * 不构成故障面。写出柄归装配层注入(onCopy),本函数只铸字节。
13
+ */
14
+ export function buildOsc52Copy(text) {
15
+ return `\x1b]52;c;${Buffer.from(text, 'utf8').toString('base64')}\x07`;
16
+ }
17
+ /**
18
+ * 终端外显件:OSC title + 进度态两写点的最小自持件。
19
+ * 忙态期间保活自重排(触发即清位再续针——armTick 同形);restore/停针后
20
+ * 句柄位归 null,重复停针是 no-op。
21
+ */
22
+ export class OscDisplay {
23
+ /** title 值缓存(null = 未写过——同值不重写判据位) */
24
+ lastTitle = null;
25
+ /** 保活在飞句柄(null = 无在飞——名册语义判据位) */
26
+ keepaliveHandle = null;
27
+ io;
28
+ baseline;
29
+ schedule;
30
+ cancel;
31
+ constructor(io, options) {
32
+ this.io = io;
33
+ this.baseline = options.baseline;
34
+ this.schedule = options.schedule ?? null;
35
+ // 取消缺省兜底 setTimeout 句柄族(与 TuiBackend cancelFn 缺省同形)
36
+ this.cancel = options.cancel ?? ((handle) => clearTimeout(handle));
37
+ }
38
+ /** 在飞保活句柄现值(null = 无在飞——名册摘除/测试断言位) */
39
+ get activeKeepalive() {
40
+ return this.keepaliveHandle;
41
+ }
42
+ /** 标题写出(OSC 0;… BEL——值缓存去重:同值不重写字节) */
43
+ setTitle(title) {
44
+ if (title === this.lastTitle)
45
+ return; // 去重律——同值零字节
46
+ this.lastTitle = title;
47
+ this.io.write(`\x1b]0;${title}\x07`);
48
+ }
49
+ /**
50
+ * 进度态写出(OSC 9;4):
51
+ * - true = 写忙态序列 + 起 1s 保活周期重发(已在飞不重复起针——重发维持
52
+ * 单链不叠针);同值重复调用仍重写忙态序列(去重不适用于 progress);
53
+ * - false = 写清零序列 + 停保活 timer。
54
+ */
55
+ setProgress(active) {
56
+ if (active) {
57
+ this.io.write(PROGRESS_ACTIVE_SEQUENCE);
58
+ this.armKeepalive();
59
+ }
60
+ else {
61
+ this.stopKeepalive();
62
+ this.io.write(PROGRESS_CLEAR_SEQUENCE);
63
+ }
64
+ }
65
+ /**
66
+ * 退出复原两写点齐(07 §4.1 件 7 条款):title 复原基线(经值缓存——
67
+ * 已在基线则零字节)+ 进度清零(无条件写——终态收口,含停保活)。
68
+ */
69
+ restore() {
70
+ this.stopKeepalive();
71
+ this.setTitle(this.baseline);
72
+ this.io.write(PROGRESS_CLEAR_SEQUENCE);
73
+ }
74
+ /** 停保活定时器(名册语义:句柄非空才取消、停后清位——重复停针 no-op) */
75
+ stopKeepalive() {
76
+ if (this.keepaliveHandle === null)
77
+ return;
78
+ this.cancel(this.keepaliveHandle);
79
+ this.keepaliveHandle = null;
80
+ }
81
+ /** 起保活(schedule 缺席 = 缺位;触发后清位自重排续针——周期重发维持) */
82
+ armKeepalive() {
83
+ if (this.schedule === null || this.keepaliveHandle !== null)
84
+ return;
85
+ this.keepaliveHandle = this.schedule(() => {
86
+ this.keepaliveHandle = null;
87
+ this.io.write(PROGRESS_ACTIVE_SEQUENCE); // 周期重发(超时衰减型终端维持)
88
+ this.armKeepalive();
89
+ }, OSC_PROGRESS_KEEPALIVE_MS);
90
+ }
91
+ }
92
+ //# sourceMappingURL=osc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"osc.js","sourceRoot":"","sources":["../../../../../../../src/channels/tui/backend/osc.ts"],"names":[],"mappings":"AAuBA,4DAA4D;AAC5D,MAAM,CAAC,MAAM,yBAAyB,GAAG,IAAI,CAAC;AAE9C,oDAAoD;AACpD,MAAM,wBAAwB,GAAG,gBAAgB,CAAC;AAClD,4BAA4B;AAC5B,MAAM,uBAAuB,GAAG,gBAAgB,CAAC;AAEjD;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,OAAO,aAAa,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC;AACzE,CAAC;AAeD;;;;GAIG;AACH,MAAM,OAAO,UAAU;IACrB,sCAAsC;IAC9B,SAAS,GAAkB,IAAI,CAAC;IACxC,kCAAkC;IAC1B,eAAe,GAAY,IAAI,CAAC;IAEvB,EAAE,CAAa;IACf,QAAQ,CAAS;IACjB,QAAQ,CAAqB;IAC7B,MAAM,CAA4B;IAEnD,YAAY,EAAc,EAAE,OAA0B;QACpD,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;QACjC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAC;QACzC,oDAAoD;QACpD,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,YAAY,CAAC,MAAwB,CAAC,CAAC,CAAC;IACvF,CAAC;IAED,uCAAuC;IACvC,IAAI,eAAe;QACjB,OAAO,IAAI,CAAC,eAAe,CAAC;IAC9B,CAAC;IAED,uCAAuC;IACvC,QAAQ,CAAC,KAAa;QACpB,IAAI,KAAK,KAAK,IAAI,CAAC,SAAS;YAAE,OAAO,CAAC,aAAa;QACnD,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACvB,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,UAAU,KAAK,MAAM,CAAC,CAAC;IACvC,CAAC;IAED;;;;;OAKG;IACH,WAAW,CAAC,MAAe;QACzB,IAAI,MAAM,EAAE,CAAC;YACX,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;YACxC,IAAI,CAAC,YAAY,EAAE,CAAC;QACtB,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,aAAa,EAAE,CAAC;YACrB,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,OAAO;QACL,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC7B,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;IACzC,CAAC;IAED,4CAA4C;IAC5C,aAAa;QACX,IAAI,IAAI,CAAC,eAAe,KAAK,IAAI;YAAE,OAAO;QAC1C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QAClC,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;IAC9B,CAAC;IAED,+CAA+C;IACvC,YAAY;QAClB,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,IAAI,IAAI,CAAC,eAAe,KAAK,IAAI;YAAE,OAAO;QACpE,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE;YACxC,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;YAC5B,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC,CAAC,kBAAkB;YAC3D,IAAI,CAAC,YAAY,EAAE,CAAC;QACtB,CAAC,EAAE,yBAAyB,CAAC,CAAC;IAChC,CAAC;CACF"}
@@ -0,0 +1,98 @@
1
+ import { type AgentMessage } from '../../../contracts/index.js';
2
+ import { type StyledLine } from './ansi-rows.js';
3
+ import { MarkdownDoc } from '../markdown/markdown.js';
4
+ import type { SessionEnvelope } from '../../types.js';
5
+ export type { StyleRun, StyledLine } from './ansi-rows.js';
6
+ /**
7
+ * 主屏滚动帽定值(07 §4.1「屏幕模型双形态」:帽值随主屏实装批实测定值回填、
8
+ * 规范不预写数字。批 10f-3 性能回归锁建锁:四指标 wall-time 面不覆盖块帽
9
+ * 〔内存上限语义〕——v1 维持保守值 500 块,实机校准注记留批 12 host 装配)。
10
+ * 批 10f-4 参数化:本值降级为缺省帽(主屏调用面零变化);回看器全量档经
11
+ * LiveTranscriptOptions.blockCap 传 Number.POSITIVE_INFINITY(全量 durable
12
+ * 正文不被截——perf-lock 全量档回归锁)。
13
+ */
14
+ export declare const TRANSCRIPT_BLOCK_CAP = 500;
15
+ /**
16
+ * 行块(帽单位——blockCount 即帽额度)。streaming 槽是行集末块的瞬时态
17
+ * (定稿摘槽换装);其余为 durable 块(repaint 投影重建的同构物)。
18
+ */
19
+ export type TranscriptBlock = {
20
+ readonly kind: 'user';
21
+ readonly text: string;
22
+ } | {
23
+ readonly kind: 'markdown';
24
+ readonly doc: MarkdownDoc;
25
+ } | {
26
+ readonly kind: 'tool-call';
27
+ readonly name: string;
28
+ readonly brief: string;
29
+ } | {
30
+ readonly kind: 'tool-result';
31
+ readonly brief: string;
32
+ } | {
33
+ readonly kind: 'streaming';
34
+ readonly text: string;
35
+ };
36
+ /** 非聚焦摘要行(瞬时——呈现侧直写后即交 scrollback,不存账) */
37
+ export interface SummaryLine {
38
+ readonly symbol: '⧗' | '✓' | '✖' | '⏹';
39
+ readonly shortId: string;
40
+ readonly label: string;
41
+ }
42
+ /** 会话短 id(呈现层自截——散列映射色板键同源) */
43
+ export declare function shortIdOf(sessionId: string): string;
44
+ /**
45
+ * 块 → 带样式行集(管线单源本体——批 10f-4 件 8 提取)。
46
+ *
47
+ * 主屏 MainScreen 直写(经 renderBlockLines 的 ANSI 序列化形)与件 8 回看器
48
+ * cell 写出(StyledLine 直消费)共用本函数:同输入同行集、零第二渲染器
49
+ * (07 件 8 数据源条款);markdown 块经 CellGrid 渲染(gridRowToStyled 提段)、
50
+ * user 块折行续挂对齐(宽算术单源走 wrapText)、简行块整行 dim、streaming
51
+ * 纯文本零样式、markdown 无内容行保空行(主屏空行直写形字节不变)。
52
+ */
53
+ export declare function renderBlockStyledLines(block: TranscriptBlock, columns: number): StyledLine[];
54
+ /**
55
+ * 块 → 行序列化(渲染管线单源——批 10f-4 提取为可复用函数;主屏直写消费形)。
56
+ * 带样式行本体经 styledLineToAnsi 导出 ANSI 串——与回看器 cell 写出形零第二
57
+ * 渲染器(renderBlockStyledLines 注)。
58
+ */
59
+ export declare function renderBlockLines(block: TranscriptBlock, columns: number): string[];
60
+ /** 行集选项(批 10f-4 帽参数化——主屏缺省帽之外的自定义档) */
61
+ export interface LiveTranscriptOptions {
62
+ /**
63
+ * 块帽(缺省 TRANSCRIPT_BLOCK_CAP = 500 主屏帽——主屏调用面零变化)。
64
+ * 件 8 回看器全量档传 Number.POSITIVE_INFINITY(全量 durable 正文不截)。
65
+ */
66
+ readonly blockCap?: number;
67
+ }
68
+ /**
69
+ * 直播路行集(单聚焦会话一账——非聚焦会话不建账,摘要行直返)。
70
+ * 纯状态件:无 IO、无时钟——applyEvent 同步归约,呈现编舞归 MainScreen。
71
+ */
72
+ export declare class LiveTranscript {
73
+ /** 块帽(构造定着——主屏 500 / 回看器全量 Infinity) */
74
+ private readonly blockCap;
75
+ private blocks;
76
+ /** 流式槽在场位(true = 末块是 streaming——message_start/message_end 配对守卫) */
77
+ private slotOpen;
78
+ constructor(options?: LiveTranscriptOptions);
79
+ /** 行集快照(只读——呈现侧消费) */
80
+ get snapshot(): readonly TranscriptBlock[];
81
+ /** 块计数(帽额度观测面) */
82
+ get blockCount(): number;
83
+ /**
84
+ * 直播路归约:活体信封 → 行集更新 + 瞬时行(非聚焦摘要行直返、聚焦返 null)。
85
+ * 非聚焦会话的 durable 事件全忽略(行集是聚焦会话的账——投影重建走 loadProjection)。
86
+ */
87
+ applyEvent(env: SessionEnvelope, focused: boolean): SummaryLine | null;
88
+ /** 投影重建(repaint 路——清账按投影重拉帽内段;直播/repaint 行集同构) */
89
+ loadProjection(messages: readonly AgentMessage[]): void;
90
+ /** 非聚焦摘要行分档(agent_start/end 之外的事件零产出) */
91
+ private summaryFor;
92
+ /** 聚焦归约:消息事件族分派(唯一渲染源律——tool_execution_* 正文零渲染) */
93
+ private applyFocused;
94
+ /** assistant 定稿展开:文本块非空 → markdown 块;每 toolCall 块 → ⚙ 行块 */
95
+ private appendAssistantFinal;
96
+ /** 帽卸载:超帽从头卸(保留帽内最近段——滚出视口交 scrollback 后内存上限语义;全量档 Infinity 恒不触发) */
97
+ private trimToCap;
98
+ }