berry-agent 0.1.0-alpha.1

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 (401) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +96 -0
  3. package/dist/.api-emit.stamp +1 -0
  4. package/dist/.build-meta.json +6 -0
  5. package/dist/agent/events.js +1 -0
  6. package/dist/agent/index.js +2 -0
  7. package/dist/agent/loop.js +139 -0
  8. package/dist/agent/queue.js +119 -0
  9. package/dist/agent/stream.js +62 -0
  10. package/dist/agent/tools-batch.js +221 -0
  11. package/dist/agent/types.js +8 -0
  12. package/dist/api/berry-agent-llm.d.ts +18 -0
  13. package/dist/api/berry-agent.d.ts +9 -0
  14. package/dist/api/surface.json +1632 -0
  15. package/dist/api/tsconfig.paths.json +12 -0
  16. package/dist/api/typebox-compile.d.ts +2 -0
  17. package/dist/api/typebox-value.d.ts +2 -0
  18. package/dist/api/typebox.d.ts +2 -0
  19. package/dist/browser/cdp.js +256 -0
  20. package/dist/browser/codes.js +31 -0
  21. package/dist/browser/discover.js +107 -0
  22. package/dist/browser/engine.js +169 -0
  23. package/dist/browser/index.js +17 -0
  24. package/dist/browser/install.js +342 -0
  25. package/dist/browser/page.js +321 -0
  26. package/dist/browser/service.js +158 -0
  27. package/dist/browser/tools.js +198 -0
  28. package/dist/browser/types.js +81 -0
  29. package/dist/channels/ask-queue.js +82 -0
  30. package/dist/channels/commands.js +129 -0
  31. package/dist/channels/engine/cell.js +143 -0
  32. package/dist/channels/engine/diff.js +143 -0
  33. package/dist/channels/engine/engine.js +416 -0
  34. package/dist/channels/engine/index.js +8 -0
  35. package/dist/channels/engine/input-keys.js +86 -0
  36. package/dist/channels/engine/input.js +596 -0
  37. package/dist/channels/engine/memory-io.js +71 -0
  38. package/dist/channels/engine/process-io.js +38 -0
  39. package/dist/channels/engine/types.js +17 -0
  40. package/dist/channels/engine/width.js +122 -0
  41. package/dist/channels/index.js +15 -0
  42. package/dist/channels/registry.js +56 -0
  43. package/dist/channels/sdk/admit.js +29 -0
  44. package/dist/channels/sdk/backend.js +102 -0
  45. package/dist/channels/sdk/cursor.js +56 -0
  46. package/dist/channels/sdk/index.js +20 -0
  47. package/dist/channels/sdk/jsonl.js +208 -0
  48. package/dist/channels/sdk/protocol.js +24 -0
  49. package/dist/channels/sdk/schema.js +91 -0
  50. package/dist/channels/sdk/wire-core.js +446 -0
  51. package/dist/channels/service.js +169 -0
  52. package/dist/channels/tui/autocomplete/autocomplete.js +42 -0
  53. package/dist/channels/tui/autocomplete/file-mentions.js +106 -0
  54. package/dist/channels/tui/autocomplete/popup.js +148 -0
  55. package/dist/channels/tui/autocomplete/provider.js +7 -0
  56. package/dist/channels/tui/autocomplete/token.js +68 -0
  57. package/dist/channels/tui/backend/ansi-rows.js +211 -0
  58. package/dist/channels/tui/backend/main-screen.js +207 -0
  59. package/dist/channels/tui/backend/osc.js +91 -0
  60. package/dist/channels/tui/backend/transcript.js +230 -0
  61. package/dist/channels/tui/backend/tui-backend.js +915 -0
  62. package/dist/channels/tui/editor/editor-model.js +543 -0
  63. package/dist/channels/tui/editor/editor-view.js +140 -0
  64. package/dist/channels/tui/editor/editor.js +275 -0
  65. package/dist/channels/tui/editor/undo-stack.js +35 -0
  66. package/dist/channels/tui/editor/visual-lines.js +126 -0
  67. package/dist/channels/tui/editor/word-nav.js +106 -0
  68. package/dist/channels/tui/history/history-viewer.js +403 -0
  69. package/dist/channels/tui/index.js +3 -0
  70. package/dist/channels/tui/layout.js +167 -0
  71. package/dist/channels/tui/markdown/blocks.js +111 -0
  72. package/dist/channels/tui/markdown/inline.js +75 -0
  73. package/dist/channels/tui/markdown/markdown.js +182 -0
  74. package/dist/channels/tui/memory/memory-viewer.js +540 -0
  75. package/dist/channels/tui/overlay/alt-screen.js +105 -0
  76. package/dist/channels/tui/overlay/overlay.js +57 -0
  77. package/dist/channels/tui/overlay/select-confirm.js +156 -0
  78. package/dist/channels/tui/panels/todo-panel.js +54 -0
  79. package/dist/channels/tui/panels/tool-progress-panel.js +93 -0
  80. package/dist/channels/tui/scroll/scroll-view.js +254 -0
  81. package/dist/channels/tui/status/status-line.js +76 -0
  82. package/dist/channels/tui/text.js +38 -0
  83. package/dist/channels/tui/theme.js +41 -0
  84. package/dist/channels/types.js +11 -0
  85. package/dist/channels/ui-core.js +209 -0
  86. package/dist/checkpoint/capture.js +45 -0
  87. package/dist/checkpoint/codes.js +33 -0
  88. package/dist/checkpoint/command.js +82 -0
  89. package/dist/checkpoint/gate.js +48 -0
  90. package/dist/checkpoint/index.js +20 -0
  91. package/dist/checkpoint/restore.js +172 -0
  92. package/dist/checkpoint/store.js +247 -0
  93. package/dist/checkpoint/types.js +4 -0
  94. package/dist/checkpoint/walk.js +146 -0
  95. package/dist/compaction/ccr-tools.js +112 -0
  96. package/dist/compaction/ccr.js +84 -0
  97. package/dist/compaction/codes.js +21 -0
  98. package/dist/compaction/index.js +18 -0
  99. package/dist/compaction/policy.js +200 -0
  100. package/dist/compaction/service.js +422 -0
  101. package/dist/compaction/slots.js +121 -0
  102. package/dist/compaction/types.js +10 -0
  103. package/dist/context/codes.js +40 -0
  104. package/dist/context/events.js +160 -0
  105. package/dist/context/index.js +13 -0
  106. package/dist/context/logger.js +136 -0
  107. package/dist/context/scope.js +182 -0
  108. package/dist/context/workspace.js +104 -0
  109. package/dist/contracts/agent-events.d.ts +73 -0
  110. package/dist/contracts/agent-events.js +16 -0
  111. package/dist/contracts/api.d.ts +249 -0
  112. package/dist/contracts/api.js +299 -0
  113. package/dist/contracts/approval.d.ts +37 -0
  114. package/dist/contracts/approval.js +9 -0
  115. package/dist/contracts/env-ref.d.ts +41 -0
  116. package/dist/contracts/env-ref.js +32 -0
  117. package/dist/contracts/errors.d.ts +56 -0
  118. package/dist/contracts/errors.js +266 -0
  119. package/dist/contracts/events.d.ts +70 -0
  120. package/dist/contracts/events.js +329 -0
  121. package/dist/contracts/index.d.ts +32 -0
  122. package/dist/contracts/index.js +26 -0
  123. package/dist/contracts/llm.d.ts +275 -0
  124. package/dist/contracts/llm.js +12 -0
  125. package/dist/contracts/messages.d.ts +63 -0
  126. package/dist/contracts/messages.js +65 -0
  127. package/dist/contracts/redact.d.ts +46 -0
  128. package/dist/contracts/redact.js +223 -0
  129. package/dist/contracts/tools.d.ts +197 -0
  130. package/dist/contracts/tools.js +33 -0
  131. package/dist/contracts/types.d.ts +302 -0
  132. package/dist/contracts/types.js +50 -0
  133. package/dist/contracts/ui.d.ts +122 -0
  134. package/dist/contracts/ui.js +15 -0
  135. package/dist/conversation/agent-service.js +61 -0
  136. package/dist/conversation/approval-wiring.js +82 -0
  137. package/dist/conversation/backoff.js +38 -0
  138. package/dist/conversation/codes.js +47 -0
  139. package/dist/conversation/control-tools.js +102 -0
  140. package/dist/conversation/control.js +210 -0
  141. package/dist/conversation/driver.js +922 -0
  142. package/dist/conversation/index.js +12 -0
  143. package/dist/conversation/model-visible.js +169 -0
  144. package/dist/conversation/open-tools.js +126 -0
  145. package/dist/conversation/reseed.js +132 -0
  146. package/dist/conversation/sessions.js +215 -0
  147. package/dist/conversation/todo.js +203 -0
  148. package/dist/conversation/types.js +35 -0
  149. package/dist/conversation/wiring.js +204 -0
  150. package/dist/credentials/codes.js +59 -0
  151. package/dist/credentials/commands.js +186 -0
  152. package/dist/credentials/env-ref.js +34 -0
  153. package/dist/credentials/index.js +28 -0
  154. package/dist/credentials/migration.js +18 -0
  155. package/dist/credentials/oauth.js +266 -0
  156. package/dist/credentials/refresh.js +152 -0
  157. package/dist/credentials/secrets.js +118 -0
  158. package/dist/credentials/types.js +30 -0
  159. package/dist/exec/bash.js +279 -0
  160. package/dist/exec/codes.js +37 -0
  161. package/dist/exec/env.js +99 -0
  162. package/dist/exec/environment.js +39 -0
  163. package/dist/exec/git-guard.js +623 -0
  164. package/dist/exec/index.js +24 -0
  165. package/dist/exec/registry.js +120 -0
  166. package/dist/exec/spawn.js +281 -0
  167. package/dist/exec/tail.js +77 -0
  168. package/dist/exec/types.js +5 -0
  169. package/dist/goal/codes.js +33 -0
  170. package/dist/goal/command.js +175 -0
  171. package/dist/goal/fold.js +121 -0
  172. package/dist/goal/gates.js +122 -0
  173. package/dist/goal/index.js +22 -0
  174. package/dist/goal/migration.js +48 -0
  175. package/dist/goal/service.js +501 -0
  176. package/dist/goal/todo-tool.js +174 -0
  177. package/dist/goal/types.js +1 -0
  178. package/dist/goal/update-tool.js +46 -0
  179. package/dist/host/approval-cmd.js +276 -0
  180. package/dist/host/assembly.js +1146 -0
  181. package/dist/host/boot-failures.js +104 -0
  182. package/dist/host/budget-advisory.js +74 -0
  183. package/dist/host/budget-broadcast.js +50 -0
  184. package/dist/host/builtins.js +54 -0
  185. package/dist/host/cli.js +544 -0
  186. package/dist/host/codes.js +120 -0
  187. package/dist/host/config-schema.js +195 -0
  188. package/dist/host/conversation-stack.js +654 -0
  189. package/dist/host/core-plugins.js +1685 -0
  190. package/dist/host/credentials-cmd.js +42 -0
  191. package/dist/host/disclosure.js +30 -0
  192. package/dist/host/dispatch.js +105 -0
  193. package/dist/host/doors-cmd.js +154 -0
  194. package/dist/host/dump-config.js +44 -0
  195. package/dist/host/hook-dispatch-guard.js +27 -0
  196. package/dist/host/import-gate.js +153 -0
  197. package/dist/host/index.js +54 -0
  198. package/dist/host/issue-session.js +241 -0
  199. package/dist/host/loader.js +372 -0
  200. package/dist/host/main.js +161 -0
  201. package/dist/host/manifest.js +381 -0
  202. package/dist/host/mcp-entry.js +53 -0
  203. package/dist/host/plugin-boot.js +952 -0
  204. package/dist/host/plugin-context.js +672 -0
  205. package/dist/host/plugin-install.js +480 -0
  206. package/dist/host/plugin-reload.js +124 -0
  207. package/dist/host/plugin-store.js +462 -0
  208. package/dist/host/plugin-tools.js +359 -0
  209. package/dist/host/plugin-uninstall.js +257 -0
  210. package/dist/host/plugins-cmd.js +302 -0
  211. package/dist/host/plugins-command.js +130 -0
  212. package/dist/host/plugins-config.js +195 -0
  213. package/dist/host/prompt-sections.js +133 -0
  214. package/dist/host/run-entry.js +544 -0
  215. package/dist/host/runtime.js +209 -0
  216. package/dist/host/scheduler-tick.js +294 -0
  217. package/dist/host/serve-daemon.js +501 -0
  218. package/dist/host/serve-entry.js +279 -0
  219. package/dist/host/session-anchor.js +41 -0
  220. package/dist/host/sessions-cmd.js +219 -0
  221. package/dist/host/sessions-face.js +47 -0
  222. package/dist/host/settings-store.js +112 -0
  223. package/dist/host/signals.js +69 -0
  224. package/dist/host/single-instance.js +105 -0
  225. package/dist/host/subagent-factory.js +291 -0
  226. package/dist/host/testkit/harness.js +283 -0
  227. package/dist/host/testkit/index.js +14 -0
  228. package/dist/host/testkit/matrix.js +302 -0
  229. package/dist/host/tool-policy-store.js +177 -0
  230. package/dist/host/triggers.js +212 -0
  231. package/dist/host/tui-entry.js +216 -0
  232. package/dist/host/webui-bridge.js +165 -0
  233. package/dist/issue/codes.js +38 -0
  234. package/dist/issue/filter.js +146 -0
  235. package/dist/issue/github.js +116 -0
  236. package/dist/issue/index.js +17 -0
  237. package/dist/issue/mount.js +70 -0
  238. package/dist/issue/poll.js +58 -0
  239. package/dist/issue/service.js +341 -0
  240. package/dist/issue/tools.js +70 -0
  241. package/dist/issue/types.js +34 -0
  242. package/dist/issue/webhook.js +126 -0
  243. package/dist/llm/codes.js +77 -0
  244. package/dist/llm/complete.js +196 -0
  245. package/dist/llm/events.js +15 -0
  246. package/dist/llm/index.js +24 -0
  247. package/dist/llm/inflight.js +65 -0
  248. package/dist/llm/model-id.js +58 -0
  249. package/dist/llm/provider-face.d.ts +32 -0
  250. package/dist/llm/provider-face.js +34 -0
  251. package/dist/llm/recovery.js +146 -0
  252. package/dist/llm/runtime.js +46 -0
  253. package/dist/llm/stream-fn.js +147 -0
  254. package/dist/lsp/codes.js +31 -0
  255. package/dist/lsp/connection.js +147 -0
  256. package/dist/lsp/frame.js +110 -0
  257. package/dist/lsp/index.js +16 -0
  258. package/dist/lsp/inject.js +58 -0
  259. package/dist/lsp/instance.js +264 -0
  260. package/dist/lsp/service.js +522 -0
  261. package/dist/lsp/tools.js +53 -0
  262. package/dist/lsp/types.js +201 -0
  263. package/dist/mcp/bridge.js +222 -0
  264. package/dist/mcp/codes.js +21 -0
  265. package/dist/mcp/index.js +19 -0
  266. package/dist/mcp/jsonrpc.js +230 -0
  267. package/dist/mcp/service.js +125 -0
  268. package/dist/mcp/tools.js +145 -0
  269. package/dist/mcp/types.js +108 -0
  270. package/dist/memory/cite.js +131 -0
  271. package/dist/memory/codes.js +50 -0
  272. package/dist/memory/command.js +71 -0
  273. package/dist/memory/consolidate.js +219 -0
  274. package/dist/memory/cycle.js +109 -0
  275. package/dist/memory/dao.js +878 -0
  276. package/dist/memory/diff.js +238 -0
  277. package/dist/memory/extract.js +181 -0
  278. package/dist/memory/fts.js +58 -0
  279. package/dist/memory/index.js +42 -0
  280. package/dist/memory/inject.js +354 -0
  281. package/dist/memory/merge.js +178 -0
  282. package/dist/memory/migration.js +132 -0
  283. package/dist/memory/pollution.js +59 -0
  284. package/dist/memory/port.js +385 -0
  285. package/dist/memory/review.js +201 -0
  286. package/dist/memory/scan.js +89 -0
  287. package/dist/memory/tools.js +508 -0
  288. package/dist/memory/types.js +140 -0
  289. package/dist/obs/codes.js +38 -0
  290. package/dist/obs/db.js +115 -0
  291. package/dist/obs/index.js +20 -0
  292. package/dist/obs/rollup.js +61 -0
  293. package/dist/obs/service.js +363 -0
  294. package/dist/obs/session-tools.js +282 -0
  295. package/dist/obs/session-view.js +225 -0
  296. package/dist/obs/tool.js +97 -0
  297. package/dist/obs/types.js +1 -0
  298. package/dist/persist/audit.js +63 -0
  299. package/dist/persist/aux.js +39 -0
  300. package/dist/persist/codes.js +35 -0
  301. package/dist/persist/index.js +30 -0
  302. package/dist/persist/load-history.js +50 -0
  303. package/dist/persist/migrations.js +37 -0
  304. package/dist/persist/paths.js +108 -0
  305. package/dist/persist/persistence.js +229 -0
  306. package/dist/persist/schema.js +99 -0
  307. package/dist/persist/secret-box.js +95 -0
  308. package/dist/persist/store.js +706 -0
  309. package/dist/persist/write-behind.js +238 -0
  310. package/dist/safety/approval.js +171 -0
  311. package/dist/safety/bwrap.js +123 -0
  312. package/dist/safety/codes.js +57 -0
  313. package/dist/safety/danger.js +505 -0
  314. package/dist/safety/gate.js +226 -0
  315. package/dist/safety/index.js +24 -0
  316. package/dist/safety/presets.js +73 -0
  317. package/dist/safety/roots.js +139 -0
  318. package/dist/safety/sandbox.js +214 -0
  319. package/dist/safety/seatbelt.js +88 -0
  320. package/dist/safety/sensitive.js +34 -0
  321. package/dist/safety/tool-policy.js +203 -0
  322. package/dist/safety/types.js +13 -0
  323. package/dist/scheduler/codes.js +54 -0
  324. package/dist/scheduler/cron-backend.js +135 -0
  325. package/dist/scheduler/engine.js +280 -0
  326. package/dist/scheduler/gates.js +60 -0
  327. package/dist/scheduler/index.js +25 -0
  328. package/dist/scheduler/migration.js +22 -0
  329. package/dist/scheduler/runner.js +171 -0
  330. package/dist/scheduler/schedule.js +193 -0
  331. package/dist/scheduler/service.js +283 -0
  332. package/dist/scheduler/tick.js +139 -0
  333. package/dist/scheduler/types.js +1 -0
  334. package/dist/sdk/http.js +865 -0
  335. package/dist/sdk/index.js +22 -0
  336. package/dist/sdk/mcp.js +289 -0
  337. package/dist/sdk/plugin-route-registry.js +126 -0
  338. package/dist/sdk/plugin-routes.js +149 -0
  339. package/dist/sdk/security.js +116 -0
  340. package/dist/sdk/types.js +32 -0
  341. package/dist/session/budget.js +159 -0
  342. package/dist/session/codes.js +40 -0
  343. package/dist/session/derive.js +180 -0
  344. package/dist/session/event-data.js +1 -0
  345. package/dist/session/fork.js +72 -0
  346. package/dist/session/import-gates.js +148 -0
  347. package/dist/session/index.js +18 -0
  348. package/dist/session/recover.js +103 -0
  349. package/dist/session/session.js +279 -0
  350. package/dist/session/snapshot.js +107 -0
  351. package/dist/skills/agents.js +242 -0
  352. package/dist/skills/codes.js +51 -0
  353. package/dist/skills/discovery.js +266 -0
  354. package/dist/skills/frontmatter.js +215 -0
  355. package/dist/skills/index.js +28 -0
  356. package/dist/skills/load.js +118 -0
  357. package/dist/skills/manage.js +201 -0
  358. package/dist/skills/registry.js +138 -0
  359. package/dist/skills/render.js +124 -0
  360. package/dist/skills/sections.js +171 -0
  361. package/dist/skills/types.js +21 -0
  362. package/dist/subagent/codes.js +50 -0
  363. package/dist/subagent/declarative.js +55 -0
  364. package/dist/subagent/index.js +19 -0
  365. package/dist/subagent/notify.js +51 -0
  366. package/dist/subagent/provide.js +7 -0
  367. package/dist/subagent/registry.js +149 -0
  368. package/dist/subagent/service.js +338 -0
  369. package/dist/subagent/surface.js +44 -0
  370. package/dist/subagent/tool.js +153 -0
  371. package/dist/subagent/types.js +25 -0
  372. package/dist/tools/apply-patch.js +164 -0
  373. package/dist/tools/codes.js +109 -0
  374. package/dist/tools/fs.js +501 -0
  375. package/dist/tools/index.js +17 -0
  376. package/dist/tools/observed.js +99 -0
  377. package/dist/tools/pipeline.js +176 -0
  378. package/dist/tools/protected-read.js +54 -0
  379. package/dist/tools/registry.js +250 -0
  380. package/dist/tools/search.js +451 -0
  381. package/dist/tools/worktree.js +327 -0
  382. package/dist/web/codes.js +37 -0
  383. package/dist/web/gate.js +43 -0
  384. package/dist/web/hygiene.js +195 -0
  385. package/dist/web/index.js +16 -0
  386. package/dist/web/service.js +207 -0
  387. package/dist/web/ssrf-guard.js +44 -0
  388. package/dist/web/tool.js +76 -0
  389. package/dist/web/types.js +10 -0
  390. package/dist/webui/assets/index-B-t2O8gh.js +22 -0
  391. package/dist/webui/assets/index-DOlgSZ9Q.css +2 -0
  392. package/dist/webui/index.html +14 -0
  393. package/dist/webui/index.js +14 -0
  394. package/dist/webui/server.js +549 -0
  395. package/dist/webui/types.js +38 -0
  396. package/examples/README.md +26 -0
  397. package/examples/minimal-code-plugin/entry.js +43 -0
  398. package/examples/minimal-code-plugin/package.json +12 -0
  399. package/examples/pure-skill-pack/package.json +14 -0
  400. package/examples/pure-skill-pack/skills/markdown-table/SKILL.md +32 -0
  401. package/package.json +86 -0
@@ -0,0 +1,230 @@
1
+ import { isStandardMessage } from '../../../contracts/index.js';
2
+ import { CellGrid, truncateToWidth, wrapText } from '../../engine/index.js';
3
+ import { gridRowToStyled, styledLineToAnsi } from './ansi-rows.js';
4
+ import { MarkdownDoc } from '../markdown/markdown.js';
5
+ /**
6
+ * 主屏滚动帽定值(07 §4.1「屏幕模型双形态」:帽值随主屏实装批实测定值回填、
7
+ * 规范不预写数字。批 10f-3 性能回归锁建锁:四指标 wall-time 面不覆盖块帽
8
+ * 〔内存上限语义〕——v1 维持保守值 500 块,实机校准注记留批 12 host 装配)。
9
+ * 批 10f-4 参数化:本值降级为缺省帽(主屏调用面零变化);回看器全量档经
10
+ * LiveTranscriptOptions.blockCap 传 Number.POSITIVE_INFINITY(全量 durable
11
+ * 正文不被截——perf-lock 全量档回归锁)。
12
+ */
13
+ export const TRANSCRIPT_BLOCK_CAP = 500;
14
+ /** ⚙ 行 / ↳ 行的参数与结果简述显示宽帽(列) */
15
+ const BRIEF_WIDTH = 40;
16
+ /** 会话短 id(呈现层自截——散列映射色板键同源) */
17
+ export function shortIdOf(sessionId) {
18
+ return sessionId.slice(0, 8);
19
+ }
20
+ /** dim 样式(简行块的整行样式——SGR 2;呈现侧带样式形同值) */
21
+ const DIM_STYLE = Object.freeze({ dim: true });
22
+ /**
23
+ * 块 → 带样式行集(管线单源本体——批 10f-4 件 8 提取)。
24
+ *
25
+ * 主屏 MainScreen 直写(经 renderBlockLines 的 ANSI 序列化形)与件 8 回看器
26
+ * cell 写出(StyledLine 直消费)共用本函数:同输入同行集、零第二渲染器
27
+ * (07 件 8 数据源条款);markdown 块经 CellGrid 渲染(gridRowToStyled 提段)、
28
+ * user 块折行续挂对齐(宽算术单源走 wrapText)、简行块整行 dim、streaming
29
+ * 纯文本零样式、markdown 无内容行保空行(主屏空行直写形字节不变)。
30
+ */
31
+ export function renderBlockStyledLines(block, columns) {
32
+ switch (block.kind) {
33
+ case 'markdown': {
34
+ const grid = new CellGrid(columns, block.doc.measure(columns));
35
+ block.doc.render(grid, { row: 0, col: 0, width: columns, height: grid.rows });
36
+ const lines = [];
37
+ for (let r = 0; r < grid.rows; r++) {
38
+ lines.push(gridRowToStyled(grid, r) ?? { plain: '', runs: [] }); // 无内容行保空行
39
+ }
40
+ return lines;
41
+ }
42
+ case 'user': {
43
+ // '> ' 前缀 + 折行续挂对齐(首行前缀、续行两空格缩进)
44
+ const lines = wrapText(block.text, columns - 2);
45
+ return lines.map((line, i) => ({ plain: (i === 0 ? '> ' : ' ') + line, runs: [] }));
46
+ }
47
+ case 'tool-call':
48
+ return [dimStyledLine(` ⚙ ${block.name}${block.brief}`)];
49
+ case 'tool-result':
50
+ return [dimStyledLine(` ↳ ${block.brief}`)];
51
+ case 'streaming':
52
+ // 流式槽纯文本直推(性能:不走网格不走样式);空文本零行
53
+ return block.text === '' ? [] : wrapText(block.text, columns).map((text) => ({ plain: text, runs: [] }));
54
+ }
55
+ }
56
+ /** 简行块的带样式形(整行 dim——与 ANSI 形 dim() 字节同源) */
57
+ function dimStyledLine(text) {
58
+ return { plain: text, runs: [{ start: 0, end: text.length, style: DIM_STYLE }] };
59
+ }
60
+ /**
61
+ * 块 → 行序列化(渲染管线单源——批 10f-4 提取为可复用函数;主屏直写消费形)。
62
+ * 带样式行本体经 styledLineToAnsi 导出 ANSI 串——与回看器 cell 写出形零第二
63
+ * 渲染器(renderBlockStyledLines 注)。
64
+ */
65
+ export function renderBlockLines(block, columns) {
66
+ return renderBlockStyledLines(block, columns).map(styledLineToAnsi);
67
+ }
68
+ /** 消息文本块拼接(user/assistant/toolResult 通用;自定义角色与无文本块返 '') */
69
+ function textOf(message) {
70
+ // isStandardMessage 守卫先行——CustomMessage role: string 非字面判别位,
71
+ // 相等/开关收窄均排不掉,经守卫归一到标准三角色(自定义角色呈现侧宽容跳过)
72
+ if (!isStandardMessage(message))
73
+ return '';
74
+ if (typeof message.content === 'string')
75
+ return message.content; // user 纯文本形
76
+ return joinTextBlocks(message.content);
77
+ }
78
+ /** 文本块抽取拼接(图文/思考/工具块族里 text 块的串接——无文本块返 '') */
79
+ function joinTextBlocks(blocks) {
80
+ const parts = [];
81
+ for (const block of blocks) {
82
+ if (block.type === 'text' && typeof block.text === 'string')
83
+ parts.push(block.text);
84
+ }
85
+ return parts.join('');
86
+ }
87
+ /** 工具简述:参数键名序列(`path, content` 形——呈现面克制不倒参数值) */
88
+ function argsBrief(args) {
89
+ const keys = Object.keys(args);
90
+ return keys.length > 0 ? `(${keys.join(', ')})` : '';
91
+ }
92
+ /**
93
+ * 直播路行集(单聚焦会话一账——非聚焦会话不建账,摘要行直返)。
94
+ * 纯状态件:无 IO、无时钟——applyEvent 同步归约,呈现编舞归 MainScreen。
95
+ */
96
+ export class LiveTranscript {
97
+ /** 块帽(构造定着——主屏 500 / 回看器全量 Infinity) */
98
+ blockCap;
99
+ blocks = [];
100
+ /** 流式槽在场位(true = 末块是 streaming——message_start/message_end 配对守卫) */
101
+ slotOpen = false;
102
+ constructor(options = {}) {
103
+ this.blockCap = options.blockCap ?? TRANSCRIPT_BLOCK_CAP;
104
+ }
105
+ /** 行集快照(只读——呈现侧消费) */
106
+ get snapshot() {
107
+ return this.blocks;
108
+ }
109
+ /** 块计数(帽额度观测面) */
110
+ get blockCount() {
111
+ return this.blocks.length;
112
+ }
113
+ /**
114
+ * 直播路归约:活体信封 → 行集更新 + 瞬时行(非聚焦摘要行直返、聚焦返 null)。
115
+ * 非聚焦会话的 durable 事件全忽略(行集是聚焦会话的账——投影重建走 loadProjection)。
116
+ */
117
+ applyEvent(env, focused) {
118
+ const { event } = env;
119
+ if (!focused)
120
+ return this.summaryFor(event, env.sessionId);
121
+ this.applyFocused(event);
122
+ return null;
123
+ }
124
+ /** 投影重建(repaint 路——清账按投影重拉帽内段;直播/repaint 行集同构) */
125
+ loadProjection(messages) {
126
+ const rebuilt = [];
127
+ for (const message of messages) {
128
+ switch (message.role) {
129
+ case 'user':
130
+ rebuilt.push({ kind: 'user', text: textOf(message) });
131
+ break;
132
+ case 'assistant':
133
+ this.appendAssistantFinal(rebuilt, message);
134
+ break;
135
+ case 'toolResult':
136
+ rebuilt.push({ kind: 'tool-result', brief: resultBrief(message) });
137
+ break;
138
+ // 自定义角色:content unknown 宽容跳过(不猜形状——件 1 自定义渲染器优先级语义)
139
+ }
140
+ }
141
+ this.blocks = rebuilt;
142
+ this.slotOpen = false; // 投影是 durable 快照——无在飞槽
143
+ this.trimToCap();
144
+ }
145
+ /** 非聚焦摘要行分档(agent_start/end 之外的事件零产出) */
146
+ summaryFor(event, sessionId) {
147
+ const shortId = shortIdOf(sessionId);
148
+ switch (event.type) {
149
+ case 'agent_start':
150
+ return { symbol: '⧗', shortId, label: '后台工作中' };
151
+ case 'agent_end':
152
+ if (event.status === 'completed')
153
+ return { symbol: '✓', shortId, label: '后台完成' };
154
+ if (event.status === 'failed')
155
+ return { symbol: '✖', shortId, label: '后台失败' };
156
+ return { symbol: '⏹', shortId, label: '后台已中止' }; // aborted——失败与中止显式分档
157
+ default:
158
+ return null; // 消息族/turn 族:非聚焦零正文行(摘要行只由 run 生命周期驱动)
159
+ }
160
+ }
161
+ /** 聚焦归约:消息事件族分派(唯一渲染源律——tool_execution_* 正文零渲染) */
162
+ applyFocused(event) {
163
+ switch (event.type) {
164
+ case 'message_start':
165
+ if (event.role !== 'assistant')
166
+ return;
167
+ // 流式单槽守卫:重开先摘旧槽(占位容器不孤儿滞留)
168
+ if (this.slotOpen)
169
+ this.blocks.pop();
170
+ this.blocks.push({ kind: 'streaming', text: '' });
171
+ this.slotOpen = true;
172
+ break;
173
+ case 'message_update':
174
+ if (event.role !== 'assistant' || !this.slotOpen)
175
+ return;
176
+ // partial 是完整快照——直换非追加(性能:纯文本直推)
177
+ this.blocks[this.blocks.length - 1] = { kind: 'streaming', text: textOf(event.partial) };
178
+ break;
179
+ case 'message_end': {
180
+ // 判别位在载荷 message.role(事件自身不带 role 字段——轻载荷事件形)
181
+ const { message } = event;
182
+ if (message.role === 'assistant') {
183
+ if (this.slotOpen) {
184
+ this.blocks.pop();
185
+ this.slotOpen = false;
186
+ }
187
+ this.appendAssistantFinal(this.blocks, message);
188
+ }
189
+ else if (message.role === 'user') {
190
+ this.blocks.push({ kind: 'user', text: textOf(message) });
191
+ }
192
+ else if (message.role === 'toolResult') {
193
+ this.blocks.push({ kind: 'tool-result', brief: resultBrief(message) });
194
+ }
195
+ this.trimToCap();
196
+ break;
197
+ }
198
+ default:
199
+ break; // turn_*/tool_execution_*/agent_* 正文零渲染(状态面消费)
200
+ }
201
+ }
202
+ /** assistant 定稿展开:文本块非空 → markdown 块;每 toolCall 块 → ⚙ 行块 */
203
+ appendAssistantFinal(target, message) {
204
+ // 守卫 + 判别收窄到 AssistantMessage(CustomMessage 判别位是 string——见 textOf 注)
205
+ if (!isStandardMessage(message) || message.role !== 'assistant')
206
+ return;
207
+ const text = textOf(message);
208
+ if (text !== '')
209
+ target.push({ kind: 'markdown', doc: MarkdownDoc.of(text) });
210
+ for (const block of message.content) {
211
+ if (block.type === 'toolCall') {
212
+ target.push({ kind: 'tool-call', name: block.name, brief: argsBrief(block.arguments) });
213
+ }
214
+ }
215
+ }
216
+ /** 帽卸载:超帽从头卸(保留帽内最近段——滚出视口交 scrollback 后内存上限语义;全量档 Infinity 恒不触发) */
217
+ trimToCap() {
218
+ if (this.blocks.length > this.blockCap) {
219
+ this.blocks = this.blocks.slice(this.blocks.length - this.blockCap);
220
+ }
221
+ }
222
+ }
223
+ /** ↳ 工具结果简述:文本块首行按显示宽截断(无文本块返占位) */
224
+ function resultBrief(message) {
225
+ const text = textOf(message);
226
+ if (text === '')
227
+ return '(无文本输出)';
228
+ const firstLine = text.split('\n').find((line) => line.trim() !== '') ?? '';
229
+ return truncateToWidth(firstLine.trim(), BRIEF_WIDTH);
230
+ }