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,94 @@
1
+ /**
2
+ * 工具实时进度面板(07 §4.1 呈现面件 5)——状态行上方的瞬时活动面板。
3
+ *
4
+ * - 行生命周期:`tool_execution_start` 建档(toolCallId→名——**不建行**,
5
+ * 首个 `tool_execution_update` 才建行)/ 后续 update 原位换行 /
6
+ * `tool_execution_end` 即摘行 / `clear()` 清板(agent_start·end·repaint
7
+ * 三时点——瞬时面律:不入正文、不跨 repaint 保存);
8
+ * - 宽容解码(update 载荷契约面 `unknown`——03 §2.3 自由载荷,呈现侧零
9
+ * 契约收紧):string 直显 / AgentToolResult 形〔content 块数组〕取文本块
10
+ * 倒扫末条非空行 / 其余视为文本缺席退化为 ` ▸ 名 …`;
11
+ * - 帽 4 行 + 溢出行「+ N 更多」;
12
+ * - 与件 3 分职互补:状态行示「执行哪个工具」、本件行示「输出到哪了」。
13
+ */
14
+ import { truncateToWidth } from '../../engine/index.js';
15
+ /** 帽内行数(溢出行另计——spec 定形) */
16
+ const MAX_ROWS = 4;
17
+ /**
18
+ * update 载荷宽容解码 → 末行输出文本(null = 文本缺席)。
19
+ * 网格行是单行物理面——string 形内部换行折叠空格(直显语义的物理收口)。
20
+ */
21
+ export function decodeUpdateText(update) {
22
+ if (typeof update === 'string') {
23
+ const collapsed = update.replaceAll('\n', ' ');
24
+ return collapsed.trim() === '' ? null : collapsed;
25
+ }
26
+ // AgentToolResult 形:content 块数组——取文本块的行序列倒扫末条非空行
27
+ if (typeof update === 'object' && update !== null && Array.isArray(update.content)) {
28
+ const lines = [];
29
+ for (const block of update.content) {
30
+ if (typeof block === 'object' &&
31
+ block !== null &&
32
+ block.type === 'text' &&
33
+ typeof block.text === 'string') {
34
+ lines.push(...block.text.split('\n'));
35
+ }
36
+ }
37
+ for (let i = lines.length - 1; i >= 0; i--) {
38
+ const line = lines[i].trim();
39
+ if (line !== '')
40
+ return line;
41
+ }
42
+ }
43
+ return null; // 数字/布尔/无文本块对象——文本缺席
44
+ }
45
+ /** 工具进度面板:正在流 partial 的工具各占一行(清板即零行) */
46
+ export class ToolProgressPanel {
47
+ /** 建档表(toolCallId→名——start 建档反查;end/clear 同摘) */
48
+ names = new Map();
49
+ rows = [];
50
+ /** 建档不建行(工具名供 update 反查——无档退 toolCallId 防御路径) */
51
+ begin(toolCallId, name) {
52
+ this.names.set(toolCallId, name);
53
+ }
54
+ /** update 消费:已有行原位换文本;无行建行(首 update 建行条款) */
55
+ applyUpdate(toolCallId, update) {
56
+ const text = decodeUpdateText(update);
57
+ const existing = this.rows.find((row) => row.toolCallId === toolCallId);
58
+ if (existing !== undefined) {
59
+ existing.text = text;
60
+ return;
61
+ }
62
+ this.rows.push({ toolCallId, name: this.names.get(toolCallId) ?? toolCallId, text });
63
+ }
64
+ /** end 即摘行(建档同摘——迟到 update 无档退 id 名) */
65
+ end(toolCallId) {
66
+ this.rows = this.rows.filter((row) => row.toolCallId !== toolCallId);
67
+ this.names.delete(toolCallId);
68
+ }
69
+ /** 清板(行与建档同清——agent_start·end·repaint 瞬时面律) */
70
+ clear() {
71
+ this.rows = [];
72
+ this.names.clear();
73
+ }
74
+ /** 量高:清板 0;帽内行数 + 溢出行 */
75
+ measure(width) {
76
+ void width; // 行单行制——宽度不敏感(截断吸收)
77
+ if (this.rows.length === 0)
78
+ return 0;
79
+ return Math.min(this.rows.length, MAX_ROWS) + (this.rows.length > MAX_ROWS ? 1 : 0);
80
+ }
81
+ /** 落位:每工具一行 ` ▸ 名 · 末行`(缺席 ` ▸ 名 …`);溢出行收尾 */
82
+ render(buffer, region) {
83
+ const visible = this.rows.slice(0, MAX_ROWS);
84
+ visible.forEach((row, i) => {
85
+ const tail = row.text !== null ? ` · ${row.text}` : ' …';
86
+ buffer.writeText(region.row + i, region.col, truncateToWidth(` ▸ ${row.name}${tail}`, region.width));
87
+ });
88
+ const overflow = this.rows.length - MAX_ROWS;
89
+ if (overflow > 0) {
90
+ buffer.writeText(region.row + MAX_ROWS, region.col, `+ ${overflow} 更多`, { dim: true });
91
+ }
92
+ }
93
+ }
94
+ //# sourceMappingURL=tool-progress-panel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-progress-panel.js","sourceRoot":"","sources":["../../../../../../../src/channels/tui/panels/tool-progress-panel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,eAAe,EAAiD,MAAM,uBAAuB,CAAC;AAEvG,2BAA2B;AAC3B,MAAM,QAAQ,GAAG,CAAC,CAAC;AAEnB;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAe;IAC9C,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAC/C,OAAO,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;IACpD,CAAC;IACD,iDAAiD;IACjD,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAE,MAAgC,CAAC,OAAO,CAAC,EAAE,CAAC;QAC9G,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,KAAK,MAAM,KAAK,IAAK,MAA0C,CAAC,OAAO,EAAE,CAAC;YACxE,IACE,OAAO,KAAK,KAAK,QAAQ;gBACzB,KAAK,KAAK,IAAI;gBACb,KAA4B,CAAC,IAAI,KAAK,MAAM;gBAC7C,OAAQ,KAA4B,CAAC,IAAI,KAAK,QAAQ,EACtD,CAAC;gBACD,KAAK,CAAC,IAAI,CAAC,GAAI,KAA0B,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;YAC9D,CAAC;QACH,CAAC;QACD,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3C,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC,IAAI,EAAE,CAAC;YAC9B,IAAI,IAAI,KAAK,EAAE;gBAAE,OAAO,IAAI,CAAC;QAC/B,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC,CAAC,qBAAqB;AACpC,CAAC;AASD,wCAAwC;AACxC,MAAM,OAAO,iBAAiB;IAC5B,iDAAiD;IAChC,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC3C,IAAI,GAAkB,EAAE,CAAC;IAEjC,iDAAiD;IACjD,KAAK,CAAC,UAAkB,EAAE,IAAY;QACpC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;IACnC,CAAC;IAED,6CAA6C;IAC7C,WAAW,CAAC,UAAkB,EAAE,MAAe;QAC7C,MAAM,IAAI,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC;QACtC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,KAAK,UAAU,CAAC,CAAC;QACxE,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC3B,QAAQ,CAAC,IAAI,GAAG,IAAI,CAAC;YACrB,OAAO;QACT,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;IACvF,CAAC;IAED,wCAAwC;IACxC,GAAG,CAAC,UAAkB;QACpB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,KAAK,UAAU,CAAC,CAAC;QACrE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAChC,CAAC;IAED,+CAA+C;IAC/C,KAAK;QACH,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC;QACf,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;IAED,yBAAyB;IACzB,OAAO,CAAC,KAAa;QACnB,KAAK,KAAK,CAAC,CAAC,oBAAoB;QAChC,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,CAAC,CAAC;QACrC,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACtF,CAAC;IAED,8CAA8C;IAC9C,MAAM,CAAC,MAAkB,EAAE,MAAc;QACvC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;QAC7C,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE;YACzB,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;YACzD,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,EAAE,MAAM,CAAC,GAAG,EAAE,eAAe,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,IAAI,EAAE,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QACvG,CAAC,CAAC,CAAC;QACH,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC;QAC7C,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;YACjB,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,GAAG,QAAQ,EAAE,MAAM,CAAC,GAAG,EAAE,KAAK,QAAQ,KAAK,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;QACzF,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,96 @@
1
+ /**
2
+ * 滚动视口件(07 §4.1 引擎节件 6(组件与呈现装配件)):行集 + 视口窗口化 + 键盘滚动 + 滚动条按需显隐。
3
+ *
4
+ * - 内容溢出视口才显滚动条(承 pi-tui `scrollbar:'auto'` 语义):先按全宽折
5
+ * 视觉行判溢出,溢出则让出一列重折 + 画 thumb(两遍折叠换「按需占列」的
6
+ * 布局自洽——折宽分槽缓存,帧间零重折);
7
+ * - follow 尾随模式(初始 true——回看器开屏显尾):内容更替贴尾;上滚破随;
8
+ * 再滚到底复随(判据:偏移到达 maxOffset);
9
+ * - 键盘滚动 ↑/↓ 单行、PgUp/PgDn 翻页、Home/End 到首尾(press/repeat 动作、
10
+ * release 归上层);滚轮 ±3 视觉行(vim mousescroll ver 缺省档——2026-09-11
11
+ * 鼠标解码批 mu-2 接入,走显式滚动路:破随后即时夹取、复随判据同键盘);
12
+ * - 滚动条渐隐计时随组件批定形(07 挂账)——v1 溢出期间常显。
13
+ */
14
+ import type { CellBuffer, InputEvent, Region, Renderable } from '../../engine/index.js';
15
+ import { type VisualSegment } from '../editor/visual-lines.js';
16
+ /** 滚动视口选项 */
17
+ export interface ScrollViewOptions {
18
+ /** 量高帽(嵌入 Flex 布局时限制分配;缺省全量——副屏 root 直收全屏 region) */
19
+ readonly maxHeight?: number;
20
+ }
21
+ /**
22
+ * 滚动视口:逻辑行集为数据源,字素硬折视觉行(复用 editor 基件折行算术),
23
+ * 自持视口偏移与尾随态。
24
+ */
25
+ export declare class ScrollView implements Renderable {
26
+ private lines;
27
+ /** 折叠缓存(行集引用失效 + 折宽分槽——同一行集多折宽并存零抖动) */
28
+ private cacheLines;
29
+ private cacheMaps;
30
+ /** 视口首行(视觉行下标) */
31
+ private offset;
32
+ /** 尾随模式(true = 内容更替贴尾) */
33
+ private follow;
34
+ /** 折宽与视口高实测(render / measure 回写——显式滚动的即时夹取依据) */
35
+ private lastWidth;
36
+ private viewportHeight;
37
+ /** 量高帽(嵌入 Flex 布局时限制分配;缺省全量——副屏 root 直收全屏 region) */
38
+ private readonly maxHeight;
39
+ /** 滚动通知(装配层接重绘请求) */
40
+ onScroll?: () => void;
41
+ constructor(options?: ScrollViewOptions);
42
+ /** 行集整体替换(回看器快照档——新事件不追加、整档重设) */
43
+ setLines(lines: string[]): void;
44
+ /** 绝对滚动(视觉行下标——越界即时夹取) */
45
+ scrollTo(viewportRow: number): void;
46
+ /** 相对滚动(负向上 / 正向下;0 无动作) */
47
+ scrollBy(delta: number): void;
48
+ /** 滚到顶部(破随) */
49
+ scrollToTop(): void;
50
+ /** 滚到底部(复随) */
51
+ scrollToEnd(): void;
52
+ /**
53
+ * 滚到逻辑行定位处(件 8 回看器搜索跳转消费):定位处所在视觉行对齐视口顶
54
+ * (col 缺省 = 行首);两遍折叠同 render 判溢出(溢出档折宽与呈现一致——
55
+ * 跳转落点不因滚动条让列错行)。显式滚动路——破随(applyOffset 同律)。
56
+ */
57
+ scrollToLine(line: number, col?: number): void;
58
+ /** 视口首行(夹取后的观测值) */
59
+ get scrollOffset(): number;
60
+ /** 尾随态(回看器判断是否在追新) */
61
+ get isFollowing(): boolean;
62
+ /** 量高:视觉行数夹 maxHeight(缺省全量——副屏 root 场景不经本路) */
63
+ measure(width: number): number;
64
+ /** 落位渲染:折行判溢出 → 夹取自愈 → 正文 → 滚动条(溢出才显) */
65
+ render(buffer: CellBuffer, region: Region): void;
66
+ /**
67
+ * 视口切片写出(批 10f-4 件 8 回看器接缝):基类裸文本直写;子类覆写按
68
+ * 带样式行渲染(样式段 + 匹配高亮)——折叠与偏移算术恒归本件,样式呈现
69
+ * 归子类(零第二滚动引擎)。
70
+ */
71
+ protected writeSlice(buffer: CellBuffer, region: Region, displayRow: number, seg: VisualSegment): void;
72
+ /** 输入消费:key = 无修饰滚动键位(press/repeat 相);mouse = 滚轮(其余归上层) */
73
+ handleEvent(event: InputEvent): boolean;
74
+ /** 视口几何观测(子类屏幕坐标反查用——render/measure 实测回写值) */
75
+ protected get viewportGeometry(): {
76
+ width: number;
77
+ height: number;
78
+ };
79
+ /**
80
+ * 视口内显示行 → 视觉段反查(mu-2 子类接缝:屏幕坐标 → 逻辑位的折叠映射
81
+ * 半场——与 render 两遍折叠同判溢出同分槽缓存,零第二映射;界外返 null)。
82
+ */
83
+ protected segmentAt(displayRow: number): VisualSegment | null;
84
+ /** 滚动条列命中判(溢出让列时末列——07 件 8「视口外命中零动作」的判据位) */
85
+ protected hitScrollbar(col: number): boolean;
86
+ /** 折叠缓存取(行集引用 + 折宽双键——分槽并存) */
87
+ private visualMap;
88
+ /** 以已知折宽即时夹取(显式滚动 / 尾随贴尾的收口路——渲染后缓存命中零成本) */
89
+ private clampNow;
90
+ /** 偏移夹取(内容短于视口归零)+ 复随判据(到底即复随;破随只在显式滚动) */
91
+ private clampOffset;
92
+ /** 显式滚动统一路(先破随后即时夹取——夹到底自然复随) */
93
+ private applyOffset;
94
+ /** 滚动条:右列 thumb 段(size 按比例、start 按偏移比例) */
95
+ private drawScrollbar;
96
+ }
@@ -0,0 +1,255 @@
1
+ import { buildVisualLineMap, findVisualLineAt } from '../editor/visual-lines.js';
2
+ /** 滚动条 thumb 样式(dim——存在感弱于正文) */
3
+ const SCROLLBAR_STYLE = Object.freeze({ dim: true });
4
+ /** 滚动条 thumb 字符 */
5
+ const THUMB = '┃';
6
+ /** 未渲染过时的防御缺省(render 后由实测回写) */
7
+ const DEFAULT_WIDTH = 80;
8
+ const DEFAULT_PAGE_SIZE = 10;
9
+ /** 单步滚动键位表(无修饰——ctrl/meta/shift 组合归上层) */
10
+ const SCROLL_ACTIONS = Object.freeze({
11
+ up: 'line-up',
12
+ down: 'line-down',
13
+ pageup: 'page-up',
14
+ pagedown: 'page-down',
15
+ home: 'to-top',
16
+ end: 'to-bottom',
17
+ });
18
+ /** 滚轮单步视觉行数(vim mousescroll ver 缺省档三行——tmux copy-mode 五行不取;07 引擎节件 6 条款码面缺省参数) */
19
+ const WHEEL_LINES = 3;
20
+ /**
21
+ * 滚动视口:逻辑行集为数据源,字素硬折视觉行(复用 editor 基件折行算术),
22
+ * 自持视口偏移与尾随态。
23
+ */
24
+ export class ScrollView {
25
+ lines = [];
26
+ /** 折叠缓存(行集引用失效 + 折宽分槽——同一行集多折宽并存零抖动) */
27
+ cacheLines = null;
28
+ cacheMaps = new Map();
29
+ /** 视口首行(视觉行下标) */
30
+ offset = 0;
31
+ /** 尾随模式(true = 内容更替贴尾) */
32
+ follow = true;
33
+ /** 折宽与视口高实测(render / measure 回写——显式滚动的即时夹取依据) */
34
+ lastWidth = DEFAULT_WIDTH;
35
+ viewportHeight = DEFAULT_PAGE_SIZE;
36
+ /** 量高帽(嵌入 Flex 布局时限制分配;缺省全量——副屏 root 直收全屏 region) */
37
+ maxHeight;
38
+ /** 滚动通知(装配层接重绘请求) */
39
+ onScroll;
40
+ constructor(options = {}) {
41
+ this.maxHeight = options.maxHeight;
42
+ }
43
+ /* ---------------- 数据面 ---------------- */
44
+ /** 行集整体替换(回看器快照档——新事件不追加、整档重设) */
45
+ setLines(lines) {
46
+ this.lines = lines;
47
+ this.cacheLines = null; // 缓存失效(引用比对落空即整缓存弃)
48
+ if (this.follow) {
49
+ this.offset = Number.MAX_SAFE_INTEGER; // 尾随贴尾
50
+ this.clampNow(); // 即时夹到视觉底
51
+ }
52
+ }
53
+ /* ---------------- 滚动控制面 ---------------- */
54
+ /** 绝对滚动(视觉行下标——越界即时夹取) */
55
+ scrollTo(viewportRow) {
56
+ this.applyOffset(viewportRow);
57
+ }
58
+ /** 相对滚动(负向上 / 正向下;0 无动作) */
59
+ scrollBy(delta) {
60
+ if (delta !== 0)
61
+ this.applyOffset(this.offset + delta);
62
+ }
63
+ /** 滚到顶部(破随) */
64
+ scrollToTop() {
65
+ this.applyOffset(0);
66
+ }
67
+ /** 滚到底部(复随) */
68
+ scrollToEnd() {
69
+ this.applyOffset(Number.MAX_SAFE_INTEGER);
70
+ }
71
+ /**
72
+ * 滚到逻辑行定位处(件 8 回看器搜索跳转消费):定位处所在视觉行对齐视口顶
73
+ * (col 缺省 = 行首);两遍折叠同 render 判溢出(溢出档折宽与呈现一致——
74
+ * 跳转落点不因滚动条让列错行)。显式滚动路——破随(applyOffset 同律)。
75
+ */
76
+ scrollToLine(line, col = 0) {
77
+ let map = this.visualMap(this.lastWidth, false);
78
+ if (map.length > this.viewportHeight)
79
+ map = this.visualMap(this.lastWidth, true);
80
+ // 定位处所在视觉行(col 落段判定——与 findVisualLineAt 同规则的本体内联)
81
+ const vi = findVisualLineAt(map, line, col);
82
+ this.applyOffset(vi);
83
+ }
84
+ /** 视口首行(夹取后的观测值) */
85
+ get scrollOffset() {
86
+ return this.offset;
87
+ }
88
+ /** 尾随态(回看器判断是否在追新) */
89
+ get isFollowing() {
90
+ return this.follow;
91
+ }
92
+ /* ---------------- 渲染协商 ---------------- */
93
+ /** 量高:视觉行数夹 maxHeight(缺省全量——副屏 root 场景不经本路) */
94
+ measure(width) {
95
+ this.lastWidth = width;
96
+ const map = this.visualMap(width, false);
97
+ const cap = this.maxHeight ?? map.length;
98
+ if (map.length <= cap)
99
+ return map.length;
100
+ // 溢出预判:滚动条让列重折后行数只多不少——以折后行数夹帽(量高即承诺,不超卖)
101
+ return Math.min(this.visualMap(width, true).length, cap);
102
+ }
103
+ /** 落位渲染:折行判溢出 → 夹取自愈 → 正文 → 滚动条(溢出才显) */
104
+ render(buffer, region) {
105
+ if (region.width <= 1 || region.height <= 0)
106
+ return; // 一列给内容都不够——防御位
107
+ this.lastWidth = region.width;
108
+ this.viewportHeight = region.height;
109
+ // 两遍折叠:全宽判溢出 → 溢出让一列重折(分槽缓存免抖动)
110
+ let map = this.visualMap(region.width, false);
111
+ const reservesBar = map.length > region.height;
112
+ if (reservesBar)
113
+ map = this.visualMap(region.width, true);
114
+ // follow 物化:尾随态贴真尾后再夹取(防御 setLines 时几何缺省值的贴尾失真
115
+ // ——批 10f-4 回看器开屏场景:构造期 clampNow 用缺省页高,首帧真几何才对齐)
116
+ if (this.follow)
117
+ this.offset = Number.MAX_SAFE_INTEGER;
118
+ this.clampOffset(map, region.height);
119
+ // 正文(视口内视觉行——切片写出经 writeSlice 单点,子类覆写带样式)
120
+ const end = Math.min(map.length, this.offset + region.height);
121
+ for (let vi = this.offset; vi < end; vi++) {
122
+ const seg = map[vi];
123
+ this.writeSlice(buffer, region, vi - this.offset, seg);
124
+ }
125
+ // 滚动条(溢出才显——右列 thumb 段按比例)
126
+ if (reservesBar)
127
+ this.drawScrollbar(buffer, region, map.length);
128
+ }
129
+ /**
130
+ * 视口切片写出(批 10f-4 件 8 回看器接缝):基类裸文本直写;子类覆写按
131
+ * 带样式行渲染(样式段 + 匹配高亮)——折叠与偏移算术恒归本件,样式呈现
132
+ * 归子类(零第二滚动引擎)。
133
+ */
134
+ writeSlice(buffer, region, displayRow, seg) {
135
+ const line = this.lines[seg.line] ?? '';
136
+ buffer.writeText(region.row + displayRow, region.col, line.slice(seg.startCol, seg.startCol + seg.length));
137
+ }
138
+ /* ---------------- 输入事件 ---------------- */
139
+ /** 输入消费:key = 无修饰滚动键位(press/repeat 相);mouse = 滚轮(其余归上层) */
140
+ handleEvent(event) {
141
+ if (event.kind === 'mouse') {
142
+ // 滚轮消费路(mu-2):wheel 无 release 相(终端不报——press 一相到达);
143
+ // 修饰位照常滚动——shift/ctrl+轮在终端侧多已截留改道(水平滚/缩放),
144
+ // SGR 报文到达即按垂直滚消费。走 scrollBy 显式滚动路(复随判据同键盘)
145
+ if (event.phase !== 'press')
146
+ return false;
147
+ if (event.button === 'wheel-up') {
148
+ this.scrollBy(-WHEEL_LINES);
149
+ return true;
150
+ }
151
+ if (event.button === 'wheel-down') {
152
+ this.scrollBy(WHEEL_LINES);
153
+ return true;
154
+ }
155
+ return false; // 非滚轮鼠标相归上层(子类选区路)
156
+ }
157
+ if (event.kind !== 'key')
158
+ return false;
159
+ if (event.phase === 'release')
160
+ return false;
161
+ if (event.ctrl || event.alt || event.shift || event.meta)
162
+ return false;
163
+ const action = SCROLL_ACTIONS[event.key];
164
+ if (action === undefined)
165
+ return false;
166
+ switch (action) {
167
+ case 'line-up':
168
+ this.scrollBy(-1);
169
+ break;
170
+ case 'line-down':
171
+ this.scrollBy(1);
172
+ break;
173
+ case 'page-up':
174
+ this.scrollBy(-this.viewportHeight);
175
+ break;
176
+ case 'page-down':
177
+ this.scrollBy(this.viewportHeight);
178
+ break;
179
+ case 'to-top':
180
+ this.scrollToTop();
181
+ break;
182
+ case 'to-bottom':
183
+ this.scrollToEnd();
184
+ break;
185
+ }
186
+ return true;
187
+ }
188
+ /* ---------------- 内部算术 ---------------- */
189
+ /** 视口几何观测(子类屏幕坐标反查用——render/measure 实测回写值) */
190
+ get viewportGeometry() {
191
+ return { width: this.lastWidth, height: this.viewportHeight };
192
+ }
193
+ /**
194
+ * 视口内显示行 → 视觉段反查(mu-2 子类接缝:屏幕坐标 → 逻辑位的折叠映射
195
+ * 半场——与 render 两遍折叠同判溢出同分槽缓存,零第二映射;界外返 null)。
196
+ */
197
+ segmentAt(displayRow) {
198
+ let map = this.visualMap(this.lastWidth, false);
199
+ if (map.length > this.viewportHeight)
200
+ map = this.visualMap(this.lastWidth, true);
201
+ return map[this.offset + displayRow] ?? null;
202
+ }
203
+ /** 滚动条列命中判(溢出让列时末列——07 件 8「视口外命中零动作」的判据位) */
204
+ hitScrollbar(col) {
205
+ const map = this.visualMap(this.lastWidth, false);
206
+ return map.length > this.viewportHeight && col === this.lastWidth - 1;
207
+ }
208
+ /** 折叠缓存取(行集引用 + 折宽双键——分槽并存) */
209
+ visualMap(width, reserveBar) {
210
+ const foldWidth = Math.max(1, width - (reserveBar ? 1 : 0));
211
+ if (this.cacheLines !== this.lines) {
212
+ this.cacheLines = this.lines;
213
+ this.cacheMaps.clear();
214
+ }
215
+ let map = this.cacheMaps.get(foldWidth);
216
+ if (map === undefined) {
217
+ map = buildVisualLineMap(this.lines, foldWidth);
218
+ this.cacheMaps.set(foldWidth, map);
219
+ }
220
+ return map;
221
+ }
222
+ /** 以已知折宽即时夹取(显式滚动 / 尾随贴尾的收口路——渲染后缓存命中零成本) */
223
+ clampNow() {
224
+ const map = this.visualMap(this.lastWidth, false);
225
+ this.clampOffset(map, this.viewportHeight);
226
+ }
227
+ /** 偏移夹取(内容短于视口归零)+ 复随判据(到底即复随;破随只在显式滚动) */
228
+ clampOffset(map, viewportHeight) {
229
+ const maxOffset = Math.max(0, map.length - viewportHeight);
230
+ this.offset = Math.min(Math.max(0, this.offset), maxOffset);
231
+ if (this.offset >= maxOffset)
232
+ this.follow = true;
233
+ }
234
+ /** 显式滚动统一路(先破随后即时夹取——夹到底自然复随) */
235
+ applyOffset(next) {
236
+ this.follow = false;
237
+ this.offset = Math.max(0, next);
238
+ this.clampNow();
239
+ this.onScroll?.();
240
+ }
241
+ /** 滚动条:右列 thumb 段(size 按比例、start 按偏移比例) */
242
+ drawScrollbar(buffer, region, totalLines) {
243
+ const h = region.height;
244
+ const maxOffset = Math.max(0, totalLines - h);
245
+ if (maxOffset === 0)
246
+ return; // 防御位(溢出判据已排除——双保险)
247
+ const thumbSize = Math.max(1, Math.floor((h * h) / totalLines));
248
+ const thumbStart = Math.round((this.offset / maxOffset) * (h - thumbSize));
249
+ const col = region.col + region.width - 1;
250
+ for (let r = 0; r < thumbSize; r++) {
251
+ buffer.setCell(region.row + thumbStart + r, col, THUMB, SCROLLBAR_STYLE);
252
+ }
253
+ }
254
+ }
255
+ //# sourceMappingURL=scroll-view.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scroll-view.js","sourceRoot":"","sources":["../../../../../../../src/channels/tui/scroll/scroll-view.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * 状态行动画件(07 §4.1 呈现面件 3——批 10d-4)。
3
+ *
4
+ * - 转轮帧动画:braille 十帧(accent 着色——引擎节件 3 着色纪律的两个
5
+ * accent 载体之一:对话输入件焦点边框与本件转轮);帧推进 = `tick()`
6
+ * (装配层定时驱动——件内零自驱时钟,测试确定性前提);
7
+ * - 工具名实时显示:`tool_execution_start` 消费点 → ` ⚙ <工具名> …`
8
+ * (状态面消费——正文面零渲染不变);
9
+ * - 启停驱动:agent_start → start()、agent_end → stop();
10
+ * - 与 setStatus last-writer-wins 共存(件 6 usage 行与 ctx.ui.setStatus
11
+ * 同一载体的闲态文案):忙态显转轮段、闲态显文案行;
12
+ * - onChange 通知:状态任何变更(启停/换工具/换文案/推帧)触发——装配层
13
+ * 接重绘请求。
14
+ */
15
+ import type { CellBuffer, Region, Renderable } from '../../engine/index.js';
16
+ /** 状态行动画件(量高恒 1 行——底部固定区状态行) */
17
+ export declare class StatusLine implements Renderable {
18
+ /** 状态变更通知(装配层接重绘请求——start/stop/setTool/setStatus/tick) */
19
+ onChange?: () => void;
20
+ private busy;
21
+ /** 忙态文案(agent_start 附带的活动描述——工具名在场时让位) */
22
+ private busyText;
23
+ /** 闲态文案(setStatus last-writer-wins——忙时写入挂起、闲时呈现) */
24
+ private idleText;
25
+ /** 实时工具名(tool_execution_start 写入;null = 无工具在场) */
26
+ private toolName;
27
+ private frameIndex;
28
+ /** 量高:恒 1(状态行单行制) */
29
+ measure(width: number): number;
30
+ /** 落位:忙态 = 转轮(accent)+ 工具段/活动文案;闲态 = 文案行(空则空行) */
31
+ render(buffer: CellBuffer, region: Region): void;
32
+ /** 进入忙态(agent_start 驱动;text = 可选活动描述) */
33
+ start(text?: string): void;
34
+ /** 退出忙态(agent_end 驱动——工具名一并清) */
35
+ stop(): void;
36
+ /** 忙态观测(装配层布防抖逻辑用) */
37
+ get isBusy(): boolean;
38
+ /** 实时工具名(tool_execution_start → name;null 清——工具退场) */
39
+ setTool(name: string | null): void;
40
+ /** 闲态文案(last-writer-wins——usage 行与自定义状态同载体共存) */
41
+ setStatus(text: string): void;
42
+ /** 推帧(装配层定时驱动——仅忙态有意义;闲态推帧零变化零通知) */
43
+ tick(): void;
44
+ /** 当前转轮帧观测面(测试断言帧推进用) */
45
+ get frame(): string;
46
+ }
@@ -0,0 +1,77 @@
1
+ import { ansiColor } from '../../engine/index.js';
2
+ import { ACCENT_INDEX } from '../theme.js';
3
+ /** 转轮帧序(braille 十帧——accent 呈现形态随组件批定形,本批定形) */
4
+ const SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
5
+ /** 转轮样式(accent 定值——theme 单源) */
6
+ const SPINNER_STYLE = Object.freeze({ fg: ansiColor(ACCENT_INDEX) });
7
+ /** 状态行动画件(量高恒 1 行——底部固定区状态行) */
8
+ export class StatusLine {
9
+ /** 状态变更通知(装配层接重绘请求——start/stop/setTool/setStatus/tick) */
10
+ onChange;
11
+ busy = false;
12
+ /** 忙态文案(agent_start 附带的活动描述——工具名在场时让位) */
13
+ busyText = '';
14
+ /** 闲态文案(setStatus last-writer-wins——忙时写入挂起、闲时呈现) */
15
+ idleText = '';
16
+ /** 实时工具名(tool_execution_start 写入;null = 无工具在场) */
17
+ toolName = null;
18
+ frameIndex = 0;
19
+ /** 量高:恒 1(状态行单行制) */
20
+ measure(width) {
21
+ void width;
22
+ return 1;
23
+ }
24
+ /** 落位:忙态 = 转轮(accent)+ 工具段/活动文案;闲态 = 文案行(空则空行) */
25
+ render(buffer, region) {
26
+ if (this.busy) {
27
+ const frame = SPINNER_FRAMES[this.frameIndex % SPINNER_FRAMES.length];
28
+ buffer.writeText(region.row, region.col, frame, SPINNER_STYLE);
29
+ // 转轮后文案段(rest 自带前导空格——起点 = 转轮格 +1;工具名优先——件 3 语义)
30
+ const rest = this.toolName !== null ? ` ⚙ ${this.toolName} …` : this.busyText !== '' ? ` ${this.busyText}` : '';
31
+ if (rest !== '')
32
+ buffer.writeText(region.row, region.col + 1, rest);
33
+ }
34
+ else if (this.idleText !== '') {
35
+ buffer.writeText(region.row, region.col, this.idleText);
36
+ }
37
+ }
38
+ /** 进入忙态(agent_start 驱动;text = 可选活动描述) */
39
+ start(text = '') {
40
+ this.busy = true;
41
+ this.busyText = text;
42
+ this.toolName = null;
43
+ this.onChange?.();
44
+ }
45
+ /** 退出忙态(agent_end 驱动——工具名一并清) */
46
+ stop() {
47
+ this.busy = false;
48
+ this.toolName = null;
49
+ this.onChange?.();
50
+ }
51
+ /** 忙态观测(装配层布防抖逻辑用) */
52
+ get isBusy() {
53
+ return this.busy;
54
+ }
55
+ /** 实时工具名(tool_execution_start → name;null 清——工具退场) */
56
+ setTool(name) {
57
+ this.toolName = name;
58
+ this.onChange?.();
59
+ }
60
+ /** 闲态文案(last-writer-wins——usage 行与自定义状态同载体共存) */
61
+ setStatus(text) {
62
+ this.idleText = text;
63
+ this.onChange?.();
64
+ }
65
+ /** 推帧(装配层定时驱动——仅忙态有意义;闲态推帧零变化零通知) */
66
+ tick() {
67
+ if (!this.busy)
68
+ return;
69
+ this.frameIndex++;
70
+ this.onChange?.();
71
+ }
72
+ /** 当前转轮帧观测面(测试断言帧推进用) */
73
+ get frame() {
74
+ return SPINNER_FRAMES[this.frameIndex % SPINNER_FRAMES.length];
75
+ }
76
+ }
77
+ //# sourceMappingURL=status-line.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status-line.js","sourceRoot":"","sources":["../../../../../../../src/channels/tui/status/status-line.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * TUI 呈现配色面(07 篇 §4.1 引擎节件 3「着色克制」条款的定值件)。
3
+ *
4
+ * 着色纪律单源(引擎节件 3):accent 只用于焦点指示面(现载体 = 对话输入件
5
+ * 焦点边框、状态行转轮、overlay 占焦族〔select 面板标题 + 补全弹层空态〕
6
+ * ——2026-09-07 实装对账补列),正文不混用(唯一例外 = 非聚焦摘要行的会话区分色
7
+ * ——非 accent 家族的第二着色位,见 sessionColor);accent 无用户配置面——
8
+ * v1 固定内置色板、缺省索引在本件定值(「随组件批定值」的兑现位)。
9
+ */
10
+ import { type AnsiColor } from '../engine/index.js';
11
+ /**
12
+ * accent 缺省色号(v1 定值 = cyan 6)。
13
+ *
14
+ * 选型依据:cyan 是 16 色板经典强调色,与常见终端配色(暗底浅字)对比稳定;
15
+ * 索引 6 属标准 8 色,8 色降级终端(07 §4.1 支持矩阵——bold 亮色映射兜底)
16
+ * 下仍可辨。真彩 / 256 色升级挂账引擎节件 3,届时本值随色板扩展再裁。
17
+ */
18
+ export declare const ACCENT_INDEX: AnsiColor;
19
+ /**
20
+ * 会话区分色:会话短 id 散列映射 16 色板索引(07 引擎节件 3——确定性纯
21
+ * 函数、零配置零存储;berry themeFor「各归各色」的等价承接,主题配置面
22
+ * 不预造)。消费面 = 非聚焦摘要行着色(呈现面件 9),与 accent 家族互斥。
23
+ *
24
+ * 映射域 = 16 色板全域(含索引 0——黑底终端上可读性弱是已知取舍,按规范
25
+ * 字面全域映射;真实痛感出现时随色板升级挂账一并再裁)。
26
+ */
27
+ export declare function sessionColor(sessionShortId: string): AnsiColor;