@maudecode/talaria-web 0.0.0 → 1.12.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 (275) hide show
  1. package/_release.json +20 -0
  2. package/dist/api/chat-router.d.ts +120 -3
  3. package/dist/api/chat-router.js +11 -8
  4. package/dist/api/chat-router.js.map +1 -1
  5. package/dist/api/router.d.ts +10 -0
  6. package/dist/api/router.js +2 -1
  7. package/dist/api/router.js.map +1 -1
  8. package/dist/api/sessions-router.d.ts +691 -40
  9. package/dist/api/sessions-router.js +2 -2
  10. package/dist/api/sessions-router.js.map +1 -1
  11. package/dist/api/settings-router.d.ts +8 -0
  12. package/dist/api/settings-router.js +13 -5
  13. package/dist/api/settings-router.js.map +1 -1
  14. package/dist/api/sse-routes.js +53 -9
  15. package/dist/api/sse-routes.js.map +1 -1
  16. package/dist/api/tools-router.d.ts +420 -0
  17. package/dist/api/tools-router.js +98 -5
  18. package/dist/api/tools-router.js.map +1 -1
  19. package/dist/app.d.ts +1247 -43
  20. package/dist/auth/oidc.js +2 -0
  21. package/dist/auth/oidc.js.map +1 -1
  22. package/dist/auth/store.d.ts +17 -0
  23. package/dist/auth/store.js +77 -19
  24. package/dist/auth/store.js.map +1 -1
  25. package/dist/bin/talaria-web.js +4 -1
  26. package/dist/bin/talaria-web.js.map +1 -1
  27. package/dist/cli/supervise.js +2 -1
  28. package/dist/cli/supervise.js.map +1 -1
  29. package/dist/fs/atomic.d.ts +8 -1
  30. package/dist/fs/atomic.js +52 -3
  31. package/dist/fs/atomic.js.map +1 -1
  32. package/dist/http/context.d.ts +2 -0
  33. package/dist/http/context.js.map +1 -1
  34. package/dist/redact.d.ts +15 -0
  35. package/dist/redact.js +1393 -9
  36. package/dist/redact.js.map +1 -1
  37. package/dist/release.js +3 -1
  38. package/dist/release.js.map +1 -1
  39. package/dist/runtime.js +28 -11
  40. package/dist/runtime.js.map +1 -1
  41. package/dist/server.d.ts +1 -1
  42. package/dist/server.js +11 -5
  43. package/dist/server.js.map +1 -1
  44. package/dist/sessions/anchor.d.ts +59 -5
  45. package/dist/sessions/anchor.js +373 -32
  46. package/dist/sessions/anchor.js.map +1 -1
  47. package/dist/sessions/file-changes.d.ts +15 -0
  48. package/dist/sessions/file-changes.js +58 -0
  49. package/dist/sessions/file-changes.js.map +1 -0
  50. package/dist/sessions/journal.d.ts +6 -1
  51. package/dist/sessions/journal.js +9 -15
  52. package/dist/sessions/journal.js.map +1 -1
  53. package/dist/sessions/list.d.ts +21 -1
  54. package/dist/sessions/list.js +81 -17
  55. package/dist/sessions/list.js.map +1 -1
  56. package/dist/sessions/merge.d.ts +72 -2
  57. package/dist/sessions/merge.js +326 -13
  58. package/dist/sessions/merge.js.map +1 -1
  59. package/dist/sessions/pending.d.ts +11 -2
  60. package/dist/sessions/pending.js +52 -3
  61. package/dist/sessions/pending.js.map +1 -1
  62. package/dist/sessions/service.d.ts +18 -3
  63. package/dist/sessions/service.js +115 -62
  64. package/dist/sessions/service.js.map +1 -1
  65. package/dist/sessions/session.js +1 -1
  66. package/dist/sessions/session.js.map +1 -1
  67. package/dist/sessions/state-db.d.ts +5 -0
  68. package/dist/sessions/state-db.js +34 -0
  69. package/dist/sessions/state-db.js.map +1 -1
  70. package/dist/sessions/streams.d.ts +4 -1
  71. package/dist/sessions/streams.js +3 -0
  72. package/dist/sessions/streams.js.map +1 -1
  73. package/dist/sessions/tool-display.d.ts +21 -0
  74. package/dist/sessions/tool-display.js +113 -0
  75. package/dist/sessions/tool-display.js.map +1 -0
  76. package/dist/sessions/turn.d.ts +39 -7
  77. package/dist/sessions/turn.js +288 -98
  78. package/dist/sessions/turn.js.map +1 -1
  79. package/dist/sessions/window.d.ts +1 -0
  80. package/dist/sessions/window.js +1 -1
  81. package/dist/sessions/window.js.map +1 -1
  82. package/dist/settings.js +5 -0
  83. package/dist/settings.js.map +1 -1
  84. package/dist/sidecar/client.d.ts +1 -1
  85. package/dist/sidecar/client.js +15 -4
  86. package/dist/sidecar/client.js.map +1 -1
  87. package/dist/sidecar/fake.js +3 -2
  88. package/dist/sidecar/fake.js.map +1 -1
  89. package/dist/spa.d.ts +2 -0
  90. package/dist/spa.js +9 -0
  91. package/dist/spa.js.map +1 -1
  92. package/dist/test/harness.d.ts +2 -0
  93. package/dist/test/harness.js +1 -1
  94. package/dist/test/harness.js.map +1 -1
  95. package/dist/tools/crons.js +55 -43
  96. package/dist/tools/crons.js.map +1 -1
  97. package/dist/tools/terminal.d.ts +6 -0
  98. package/dist/tools/terminal.js +24 -3
  99. package/dist/tools/terminal.js.map +1 -1
  100. package/dist/tools/update-notifications.d.ts +120 -0
  101. package/dist/tools/update-notifications.js +387 -0
  102. package/dist/tools/update-notifications.js.map +1 -0
  103. package/dist/tools/updates.d.ts +97 -13
  104. package/dist/tools/updates.js +638 -124
  105. package/dist/tools/updates.js.map +1 -1
  106. package/package.json +2 -2
  107. package/sidecar/agent_dependency.json +4 -3
  108. package/sidecar/scripts/replay_sidecar.py +17 -0
  109. package/sidecar/talaria_sidecar/__init__.py +1 -1
  110. package/sidecar/talaria_sidecar/home.py +51 -19
  111. package/sidecar/talaria_sidecar/methods/chat.py +113 -4
  112. package/sidecar/talaria_sidecar/methods/config.py +5 -3
  113. package/sidecar/talaria_sidecar/runtime.py +3 -9
  114. package/static/dist/FILES.txt +115 -116
  115. package/static/dist/assets/AppShell-m4w420jl.js +1 -0
  116. package/static/dist/assets/ChatPage-cuqcnisv.js +20 -0
  117. package/static/dist/assets/HubRoute-hqgqtm35.js +2 -0
  118. package/static/dist/assets/{Markdown-bt9bqd6a.js → Markdown-j2hlu30v.js} +7 -7
  119. package/static/dist/assets/RightPanel-oid5q557.js +1 -0
  120. package/static/dist/assets/Select-ot2zr0il.js +1 -0
  121. package/static/dist/assets/SessionListPanel-o3sgjnrq.js +1 -0
  122. package/static/dist/assets/SettingsLayout-b0idn649.js +1 -0
  123. package/static/dist/assets/States-htz1oee5.js +1 -0
  124. package/static/dist/assets/Toaster-h49pk1hy.js +1 -0
  125. package/static/dist/assets/_app-h7eaezs7.js +1 -0
  126. package/static/dist/assets/_app.ext._extensionId-h8oaqzsj.js +1 -0
  127. package/static/dist/assets/_app.index-xinao3xh.js +1 -0
  128. package/static/dist/assets/_app.insights-cxplvhkm.js +1 -0
  129. package/static/dist/assets/_app.kanban-hhli8h0h.js +1 -0
  130. package/static/dist/assets/_app.logs-f6srwjfl.js +1 -0
  131. package/static/dist/assets/_app.memory-lntcea85.js +1 -0
  132. package/static/dist/assets/_app.profiles-lftyp6of.js +1 -0
  133. package/static/dist/assets/{_app.session._sessionId-kevi4qd2.js → _app.session._sessionId-hhpcqih4.js} +1 -1
  134. package/static/dist/assets/_app.settings-rs93zpvw.js +1 -0
  135. package/static/dist/assets/_app.settings._section-nafqsbwm.js +1 -0
  136. package/static/dist/assets/_app.skills-jzoi1ivd.js +1 -0
  137. package/static/dist/assets/_app.tasks-ijphsw56.js +2 -0
  138. package/static/dist/assets/_app.todos-emyh8inv.js +1 -0
  139. package/static/dist/assets/_app.workspaces-fwr1cum8.js +1 -0
  140. package/static/dist/assets/{abnfDiagram-VCTEODGH-hvrr25lb.js → abnfDiagram-VCTEODGH-egykbz8h.js} +1 -1
  141. package/static/dist/assets/architecture-7GRP2DOG-l6y92mbn.js +1 -0
  142. package/static/dist/assets/{architectureDiagram-5GKGNRK7-b3r0z8sq.js → architectureDiagram-5GKGNRK7-b2e0wk3y.js} +1 -1
  143. package/static/dist/assets/{blockDiagram-I7D4REHJ-hd3gw0cj.js → blockDiagram-I7D4REHJ-i3cq67dn.js} +1 -1
  144. package/static/dist/assets/{c4Diagram-7LVT6UL2-jlmbjiji.js → c4Diagram-7LVT6UL2-lg1p1s7a.js} +1 -1
  145. package/static/dist/assets/channel-gq8cwu71.js +1 -0
  146. package/static/dist/assets/{chunk-4HAMMTFA-oydbpsin.js → chunk-4HAMMTFA-i0s1s7zi.js} +1 -1
  147. package/static/dist/assets/{chunk-75Z2AOVW-j633otj1.js → chunk-75Z2AOVW-kwinpapo.js} +1 -1
  148. package/static/dist/assets/{chunk-DU6HZSFF-ods2l027.js → chunk-DU6HZSFF-hb8qrbc3.js} +3 -3
  149. package/static/dist/assets/{chunk-F27PBJKO-ln4n2cwt.js → chunk-F27PBJKO-dy2tqtcs.js} +1 -1
  150. package/static/dist/assets/{chunk-GMAD6QVW-fpz133eh.js → chunk-GMAD6QVW-fqox5yvt.js} +1 -1
  151. package/static/dist/assets/{chunk-GVQU2GXP-abs9ixiy.js → chunk-GVQU2GXP-bo3x6ze4.js} +1 -1
  152. package/static/dist/assets/{chunk-IMKFNOWR-j9vukdy1.js → chunk-IMKFNOWR-nxs6rrcq.js} +1 -1
  153. package/static/dist/assets/{chunk-L3NEJ4N5-cfyw87r3.js → chunk-L3NEJ4N5-f9yeq1fi.js} +1 -1
  154. package/static/dist/assets/{chunk-OSK3NFVY-baja78wr.js → chunk-OSK3NFVY-c7df44qv.js} +1 -1
  155. package/static/dist/assets/{chunk-P2QGCYS3-g66xby8h.js → chunk-P2QGCYS3-eyjzf5o5.js} +1 -1
  156. package/static/dist/assets/{chunk-POPQ4Y6H-osqu864t.js → chunk-POPQ4Y6H-iy3hp9rc.js} +1 -1
  157. package/static/dist/assets/{chunk-PWAF6VOD-egejasv1.js → chunk-PWAF6VOD-co2yoefz.js} +1 -1
  158. package/static/dist/assets/{chunk-SHT3W25Y-l014h8zz.js → chunk-SHT3W25Y-obzqmn9k.js} +1 -1
  159. package/static/dist/assets/{chunk-SVP7TREG-n3z10bp3.js → chunk-SVP7TREG-hqwdo6vt.js} +1 -1
  160. package/static/dist/assets/{chunk-TICWLB2K-bzozkjc0.js → chunk-TICWLB2K-l8t1mdfd.js} +1 -1
  161. package/static/dist/assets/classDiagram-ZZMXUADV-fg9sc5r8.js +1 -0
  162. package/static/dist/assets/classDiagram-v2-VYDZK3BY-fg9sc5r8.js +1 -0
  163. package/static/dist/assets/{copied-cjsttec1.js → copied-hurn8vn4.js} +1 -1
  164. package/static/dist/assets/{cynefin-OW5HDTMX-elpt7h1j.js → cynefin-OW5HDTMX-ngx2ihay.js} +1 -1
  165. package/static/dist/assets/{cynefinDiagram-5FMLGOSQ-5mzl5pi2.js → cynefinDiagram-5FMLGOSQ-fiyooys3.js} +1 -1
  166. package/static/dist/assets/{dagre-GXQ25YYZ-ihwlhmfl.js → dagre-GXQ25YYZ-fctryel6.js} +1 -1
  167. package/static/dist/assets/{diagram-S7CK7UJ4-4z90agaz.js → diagram-S7CK7UJ4-m27jopok.js} +1 -1
  168. package/static/dist/assets/{diagram-UQ7AKVKN-eifw0lg7.js → diagram-UQ7AKVKN-ojgkbmp4.js} +1 -1
  169. package/static/dist/assets/{diagram-VSXAHHWV-ksh3sjqv.js → diagram-VSXAHHWV-gfafpgyj.js} +1 -1
  170. package/static/dist/assets/{diagram-VX7I27RA-ett72f71.js → diagram-VX7I27RA-daobicg4.js} +1 -1
  171. package/static/dist/assets/{diagram-Z3DM3KII-l8scp8nu.js → diagram-Z3DM3KII-mi475zvk.js} +1 -1
  172. package/static/dist/assets/{ebnfDiagram-PWID7BFC-f0pxcmit.js → ebnfDiagram-PWID7BFC-daf4zvsy.js} +1 -1
  173. package/static/dist/assets/endpoints-cyjhnrbn.js +64 -0
  174. package/static/dist/assets/{erDiagram-RLTQ6QDP-f47m5xh0.js → erDiagram-RLTQ6QDP-gxfhxvfp.js} +1 -1
  175. package/static/dist/assets/eventmodeling-NTZA5JFV-manga0bq.js +1 -0
  176. package/static/dist/assets/flowDiagram-HODETNUW-bpt13uny.js +1 -0
  177. package/static/dist/assets/{ganttDiagram-EL5Y4UJY-bmktjdi0.js → ganttDiagram-EL5Y4UJY-k3208e0p.js} +1 -1
  178. package/static/dist/assets/{gitGraph-4MIJSDKK-j2ueg258.js → gitGraph-4MIJSDKK-gjuhj4zk.js} +1 -1
  179. package/static/dist/assets/{gitGraphDiagram-WWUBYQGX-ms6586v9.js → gitGraphDiagram-WWUBYQGX-jglxvux1.js} +1 -1
  180. package/static/dist/assets/{highlighted-body-KPVGNVTW-ev52d2si.js → highlighted-body-KPVGNVTW-gh24xc9c.js} +1 -1
  181. package/static/dist/assets/index-gsg78cb4.css +2 -0
  182. package/static/dist/assets/{index-hywfjw88.js → index-jb47los5.js} +4 -4
  183. package/static/dist/assets/{info-A6RAGUB7-j717vyt7.js → info-A6RAGUB7-huf0xaoq.js} +1 -1
  184. package/static/dist/assets/{infoDiagram-27XIBGKW-dsbpib36.js → infoDiagram-27XIBGKW-jk3n96ix.js} +1 -1
  185. package/static/dist/assets/{ishikawaDiagram-5VMMS53U-n0sz3i2d.js → ishikawaDiagram-5VMMS53U-o95uo5dx.js} +1 -1
  186. package/static/dist/assets/{journeyDiagram-3NMN7TZE-mcxz1mme.js → journeyDiagram-3NMN7TZE-h5ye2l70.js} +1 -1
  187. package/static/dist/assets/{kanban-definition-UXKFOSKX-n6hq2lyc.js → kanban-definition-UXKFOSKX-lgrpk5yi.js} +1 -1
  188. package/static/dist/assets/{lazyRouteComponent-faquioun.js → lazyRouteComponent-owywngyt.js} +1 -1
  189. package/static/dist/assets/{line-h5xq20s4.js → line-cihmc0pn.js} +1 -1
  190. package/static/dist/assets/login-g063apx6.js +1 -0
  191. package/static/dist/assets/mermaid-HWGCJPDP-okd1mnvj.js +1 -0
  192. package/static/dist/assets/{mermaid-parser.core-n9cuu5ue.js → mermaid-parser.core-d1609aga.js} +3 -3
  193. package/static/dist/assets/{mindmap-definition-YA3MSWOX-gta3u7z4.js → mindmap-definition-YA3MSWOX-lbvtir31.js} +1 -1
  194. package/static/dist/assets/onboarding-ngw0x0pr.js +1 -0
  195. package/static/dist/assets/{packet-AYTQ26CC-bpzuq5n6.js → packet-AYTQ26CC-o4cp5z3k.js} +1 -1
  196. package/static/dist/assets/{pegDiagram-XKGWAZYB-juye13e5.js → pegDiagram-XKGWAZYB-e8xqu1qj.js} +1 -1
  197. package/static/dist/assets/{pie-WAS4IAKB-odhb8buq.js → pie-WAS4IAKB-hm9icuov.js} +1 -1
  198. package/static/dist/assets/{pieDiagram-E7YTZNPT-mgb14ksh.js → pieDiagram-E7YTZNPT-hj96x7hn.js} +1 -1
  199. package/static/dist/assets/{quadrantDiagram-AXDQQJYC-cg36naog.js → quadrantDiagram-AXDQQJYC-80utbxhm.js} +1 -1
  200. package/static/dist/assets/{radar-RG4KPBEZ-lgzfpnef.js → radar-RG4KPBEZ-k39b6100.js} +1 -1
  201. package/static/dist/assets/{railroad-74A4TZTK-gmglc3ua.js → railroad-74A4TZTK-ewyqz67j.js} +1 -1
  202. package/static/dist/assets/railroad-abnf-HS5TGJTU-dx2q0evz.js +1 -0
  203. package/static/dist/assets/railroad-ebnf-LZEXJU2U-l8xt49t5.js +1 -0
  204. package/static/dist/assets/railroad-peg-WCYAUIDC-kuxha9yz.js +1 -0
  205. package/static/dist/assets/{railroadDiagram-O6MQD6OU-cmxwjt73.js → railroadDiagram-O6MQD6OU-iwv9dby8.js} +1 -1
  206. package/static/dist/assets/{refresh-cw-mf192q3f.js → refresh-cw-hjzomwlo.js} +1 -1
  207. package/static/dist/assets/{requirementDiagram-BXWQKSXE-ir0s2mek.js → requirementDiagram-BXWQKSXE-cdgh5jha.js} +1 -1
  208. package/static/dist/assets/{sankeyDiagram-P5KCCOFB-jo7jcdq0.js → sankeyDiagram-P5KCCOFB-dbu6p97m.js} +1 -1
  209. package/static/dist/assets/{saved-g777hp1t.js → saved-feqhycco.js} +1 -1
  210. package/static/dist/assets/{search-i2kfogyx.js → search-n3jdc20p.js} +1 -1
  211. package/static/dist/assets/{sequenceDiagram-WJ2MYXX4-n0pf6xk5.js → sequenceDiagram-WJ2MYXX4-b0wchifg.js} +1 -1
  212. package/static/dist/assets/{settings_section_extensions_title-hgvh507l.js → settings_section_extensions_title-mtyviexd.js} +1 -1
  213. package/static/dist/assets/share._token-cwov8uqh.js +2 -0
  214. package/static/dist/assets/sliders-horizontal-i1lseyg0.js +1 -0
  215. package/static/dist/assets/{stateDiagram-D77RDMKH-olbrwyv9.js → stateDiagram-D77RDMKH-mb4b38xh.js} +1 -1
  216. package/static/dist/assets/stateDiagram-v2-MP3YSRHH-cn1fnqrg.js +1 -0
  217. package/static/dist/assets/{swimlanes-42K2YHIH-od14zrw6.js → swimlanes-42K2YHIH-ofrpfwj0.js} +1 -1
  218. package/static/dist/assets/swimlanesDiagram-VR7AAH4N-d652ummv.js +8 -0
  219. package/static/dist/assets/{timeline-definition-24CTP7MA-l0qokmnb.js → timeline-definition-24CTP7MA-hlw0jg6o.js} +1 -1
  220. package/static/dist/assets/todoStore-mfy9lpio.js +1 -0
  221. package/static/dist/assets/{treeView-Q6P3EWNA-hma3ip8m.js → treeView-Q6P3EWNA-d93wr19c.js} +1 -1
  222. package/static/dist/assets/{treemap-WGGIJYW6-bghjng5m.js → treemap-WGGIJYW6-g7ezdedz.js} +1 -1
  223. package/static/dist/assets/{untitled-nfaw0q7m.js → untitled-mqxhd1eh.js} +1 -1
  224. package/static/dist/assets/{useForm-k7fj2zsr.js → useForm-hh33yrwa.js} +1 -1
  225. package/static/dist/assets/useLocale-cr30vl7r.js +1 -0
  226. package/static/dist/assets/{vennDiagram-4TSXK5OY-bo97zf3z.js → vennDiagram-4TSXK5OY-m5vgeba5.js} +1 -1
  227. package/static/dist/assets/{wardley-WFR3VGLG-pbjl6jav.js → wardley-WFR3VGLG-gpao9bxv.js} +1 -1
  228. package/static/dist/assets/{wardleyDiagram-VM6X3IG4-bmy9i09l.js → wardleyDiagram-VM6X3IG4-g2yzwshm.js} +1 -1
  229. package/static/dist/assets/{xychartDiagram-S5SC5T6Z-eercu0mc.js → xychartDiagram-S5SC5T6Z-itakhpic.js} +1 -1
  230. package/static/dist/index.html +1 -1
  231. package/static/dist/sw.js +114 -152
  232. package/static/dist/assets/AppShell-gs0grlbs.js +0 -1
  233. package/static/dist/assets/ChatPage-gi1xlz52.js +0 -18
  234. package/static/dist/assets/HubRoute-qs9vzuh0.js +0 -2
  235. package/static/dist/assets/RightPanel-dn19xu42.js +0 -1
  236. package/static/dist/assets/Select-y7wtf85g.js +0 -1
  237. package/static/dist/assets/SessionListPanel-igwdj9xr.js +0 -1
  238. package/static/dist/assets/SettingsLayout-n6mu0ghg.js +0 -1
  239. package/static/dist/assets/States-oil2issf.js +0 -1
  240. package/static/dist/assets/Toaster-jtn59pjm.js +0 -1
  241. package/static/dist/assets/_app-k4jrkgfa.js +0 -1
  242. package/static/dist/assets/_app.ext._extensionId-mmf1mepm.js +0 -1
  243. package/static/dist/assets/_app.index-mb41nf00.js +0 -1
  244. package/static/dist/assets/_app.insights-mz5cep8m.js +0 -1
  245. package/static/dist/assets/_app.kanban-ocgw506i.js +0 -1
  246. package/static/dist/assets/_app.logs-lstmoju6.js +0 -1
  247. package/static/dist/assets/_app.memory-dishj9ra.js +0 -1
  248. package/static/dist/assets/_app.profiles-dynpvsio.js +0 -1
  249. package/static/dist/assets/_app.settings-c2czm9v4.js +0 -1
  250. package/static/dist/assets/_app.settings._section-exwflld7.js +0 -1
  251. package/static/dist/assets/_app.skills-j5jh2nug.js +0 -1
  252. package/static/dist/assets/_app.tasks-b99d98fo.js +0 -2
  253. package/static/dist/assets/_app.todos-ma8urvn3.js +0 -1
  254. package/static/dist/assets/_app.workspaces-l86cxeod.js +0 -1
  255. package/static/dist/assets/architecture-7GRP2DOG-mqft9w2p.js +0 -1
  256. package/static/dist/assets/channel-ix8cxdld.js +0 -1
  257. package/static/dist/assets/classDiagram-ZZMXUADV-c210y3il.js +0 -1
  258. package/static/dist/assets/classDiagram-v2-VYDZK3BY-c210y3il.js +0 -1
  259. package/static/dist/assets/endpoints-ipnv1hd4.js +0 -64
  260. package/static/dist/assets/eventmodeling-NTZA5JFV-d9b5a0ia.js +0 -1
  261. package/static/dist/assets/flowDiagram-HODETNUW-kfxxsyrk.js +0 -1
  262. package/static/dist/assets/index-bz7g7rhx.css +0 -2
  263. package/static/dist/assets/login-mvjys1ol.js +0 -1
  264. package/static/dist/assets/mermaid-HWGCJPDP-gmnkgf1n.js +0 -1
  265. package/static/dist/assets/onboarding-l6quy6gz.js +0 -1
  266. package/static/dist/assets/railroad-abnf-HS5TGJTU-5mjl5wpv.js +0 -1
  267. package/static/dist/assets/railroad-ebnf-LZEXJU2U-bfram8v8.js +0 -1
  268. package/static/dist/assets/railroad-peg-WCYAUIDC-nwfczn88.js +0 -1
  269. package/static/dist/assets/share._token-il3y6js2.js +0 -2
  270. package/static/dist/assets/sliders-horizontal-kd99ffvl.js +0 -1
  271. package/static/dist/assets/stateDiagram-v2-MP3YSRHH-dnzlmdpu.js +0 -1
  272. package/static/dist/assets/swimlanesDiagram-VR7AAH4N-ck0eqqdp.js +0 -8
  273. package/static/dist/assets/todoStore-la6uyqzj.js +0 -1
  274. package/static/dist/assets/trash-bxz1k9cw.js +0 -1
  275. package/static/dist/assets/useLocale-evhacmv2.js +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -21,14 +21,62 @@ export declare function findAnchorSceneMessage(messages: unknown[], opts: {
21
21
  }): [number, Record<string, unknown>] | [null, null];
22
22
  export declare function anchorSceneMessageTurnDuration(message: unknown): number | null;
23
23
  export declare function anchorSceneRecords(session: Session): Record<string, unknown>;
24
+ export interface SceneTool {
25
+ id: string;
26
+ name: string;
27
+ args: unknown;
28
+ preview: string | null;
29
+ result: unknown;
30
+ done: boolean;
31
+ is_error: boolean;
32
+ duration: number | null;
33
+ cost_usd: number | null;
34
+ }
35
+ export interface SceneSteering {
36
+ steer_id: string;
37
+ consumed: boolean;
38
+ submitted_at: number | null;
39
+ consumed_at: number | null;
40
+ phase_duration?: number | null;
41
+ }
42
+ /** The one scene row shape both clients render: every decoding decision is made here. */
43
+ export interface SceneRow {
44
+ row_id: string;
45
+ order_index: number;
46
+ role: 'prose' | 'reasoning' | 'tool' | 'steering';
47
+ created_at?: number;
48
+ text?: string;
49
+ titles?: string[];
50
+ tool?: SceneTool;
51
+ steering?: SceneSteering;
52
+ }
53
+ /**
54
+ * Stored rows in durable order (numeric `order_index`, else source position), malformed rows dropped, and one explicit
55
+ * shape per role: legacy `thinking` is `reasoning`, a tool is `done` unless still `running`, `failed`/`error` statuses
56
+ * are errors, and steering is consumed only when marked so. A repeated row id keeps its first position, last content.
57
+ */
58
+ export declare function normalizeSceneRows(value: unknown): SceneRow[];
24
59
  /** Tail-only transport preview of a durable scene. */
25
60
  export declare function anchorActivitySceneTransportPreview(scene: Record<string, unknown>, sceneRef?: string): Record<string, unknown>;
26
61
  /**
27
- * Attach each assistant message's scene preview for a window of messages.
28
- * ponytail: the durable scene is served as stored; the Python
29
- * `_complete_hydrated_anchor_scene` tool-body backfill is not reproduced.
62
+ * One completed turn's presentation, built from its rows: ordered reasoning / prose / tool rows (the work that folds
63
+ * under "Worked"), the visible final answer, the outcome, and whether "Worked" opens by default. Every decision a
64
+ * client used to make about a settled turn is made here.
65
+ */
66
+ export declare function buildTurnScene(turn: [Record<string, unknown>, number][], opts?: {
67
+ clipToolResults?: boolean;
68
+ }): Record<string, unknown> | null;
69
+ /** A settled turn's outcome by the scene's rules, so its `done` frame reports what the settled scene then shows. */
70
+ export declare function turnTerminalState(messages: unknown[], turnId: string): string;
71
+ /**
72
+ * Attach every completed turn's scene preview to its last assistant row, over the full `_turn_id`-stamped transcript
73
+ * (before any window, so every window agrees). A stored scene wins and is completed with the turn's outcome fields; a
74
+ * turn without one gets a built scene. The running turn (`activeTurnId`) gets none: the live stream renders it.
30
75
  */
31
- export declare function hydrateAnchorActivityScenes(messages: unknown[], records: Record<string, unknown>, messageOffset?: number): unknown[];
76
+ export declare function hydrateAnchorActivityScenes(messages: unknown[], records: Record<string, unknown>, opts?: {
77
+ activeTurnId?: string | null;
78
+ clipToolResults?: boolean;
79
+ }): unknown[];
32
80
  /** Persist a settled scene onto a session (the POST body semantics). Returns the placement. */
33
81
  export declare function storeAnchorScene(session: Session, body: Record<string, unknown>, now: number): {
34
82
  message_index: number;
@@ -40,4 +88,10 @@ export declare function readAnchorSceneRows(session: Session, query: {
40
88
  messageIndex: number | null;
41
89
  before: number | null;
42
90
  limit: number | null;
43
- }): Record<string, unknown> | null;
91
+ }, transcript?: unknown[]): Record<string, unknown> | null;
92
+ /**
93
+ * Every message leaves the server with a `_turn_id`. A turn stamps its rows with its stream id; rows written before
94
+ * that (older files, state.db/CLI rows) take `legacy:<index of their opening user row>`, or `legacy:start`, computed
95
+ * over the full transcript so a window boundary never changes a key. Returns copies; stored rows are untouched.
96
+ */
97
+ export declare function withTurnIds<T>(messages: T[]): T[];
@@ -6,6 +6,10 @@
6
6
  */
7
7
  import { str } from '../util.js';
8
8
  import { createHash } from 'node:crypto';
9
+ import { agentSteerText, isContextCompressionMarker, isReasoningBlock, messageText, reasoningBlockText, splitThinkingFromContent } from './merge.js';
10
+ import { toolMessageForLimitedPayload } from './window.js';
11
+ import { toolArgs } from './tool-display.js';
12
+ import { turnFileChanges } from './file-changes.js';
9
13
  const isDict = (v) => Boolean(v) && typeof v === 'object' && !Array.isArray(v);
10
14
  export const ANCHOR_SCENE_MAX_BYTES = 18 * 1024 * 1024;
11
15
  export const ANCHOR_SCENE_MAX_ROWS = 20_000;
@@ -184,32 +188,316 @@ export function anchorSceneMessageTurnDuration(message) {
184
188
  export function anchorSceneRecords(session) {
185
189
  return isDict(session.anchor_activity_scenes) ? session.anchor_activity_scenes : {};
186
190
  }
191
+ const finite = (v) => (typeof v === 'number' && Number.isFinite(v) ? v : null);
192
+ /**
193
+ * Stored rows in durable order (numeric `order_index`, else source position), malformed rows dropped, and one explicit
194
+ * shape per role: legacy `thinking` is `reasoning`, a tool is `done` unless still `running`, `failed`/`error` statuses
195
+ * are errors, and steering is consumed only when marked so. A repeated row id keeps its first position, last content.
196
+ */
197
+ export function normalizeSceneRows(value) {
198
+ if (!Array.isArray(value))
199
+ return [];
200
+ const ordered = value.map((raw, index) => {
201
+ const row = isDict(raw) ? raw : {};
202
+ const order = typeof row.order_index === 'number' || (typeof row.order_index === 'string' && /^-?\d+$/.test(row.order_index.trim())) ? Number(row.order_index) : NaN;
203
+ return { row, index, order: Number.isFinite(order) ? order : index };
204
+ }).sort((a, b) => a.order - b.order || a.index - b.index);
205
+ const rows = [];
206
+ const positions = new Map();
207
+ const put = (row) => {
208
+ const at = positions.get(row.row_id);
209
+ const next = { ...row, order_index: 0 };
210
+ if (at === undefined) {
211
+ positions.set(row.row_id, rows.length);
212
+ rows.push(next);
213
+ }
214
+ else
215
+ rows[at] = next;
216
+ };
217
+ for (const { row, index } of ordered) {
218
+ const tool = isDict(row.tool) ? row.tool : {};
219
+ const payload = isDict(row.payload) ? row.payload : {};
220
+ const steering = isDict(row.steering) ? row.steering : {};
221
+ const toolId = str(row.tool_call_id) || str(tool.id);
222
+ const steerId = str(payload.steer_id) || str(steering.steer_id);
223
+ const rowId = row.role === 'tool' && toolId ? `tool:${toolId}` : row.role === 'steering' && steerId ? `steering:${steerId}` : str(row.row_id) || `scene:${String(index)}`;
224
+ const createdAt = finite(row.created_at);
225
+ const base = createdAt === null ? { row_id: rowId } : { row_id: rowId, created_at: createdAt };
226
+ if (row.role === 'prose') {
227
+ const [content, reasoning] = splitThinkingFromContent(str(row.text));
228
+ if (reasoning)
229
+ put({ ...base, row_id: `${rowId}:thinking`, role: 'reasoning', text: reasoning, titles: [] });
230
+ if (content.trim())
231
+ put({ ...base, role: 'prose', text: content });
232
+ }
233
+ else if (row.role === 'reasoning' || row.role === 'thinking') {
234
+ const thinking = isDict(row.thinking) ? row.thinking : {};
235
+ const rawTitles = Array.isArray(thinking.titles) ? thinking.titles : row.titles;
236
+ const titles = Array.isArray(rawTitles) ? rawTitles.filter((t) => typeof t === 'string' && Boolean(t.trim())) : [];
237
+ const text = str(thinking.text) || str(row.text);
238
+ if (text.trim() || titles.length)
239
+ put({ ...base, role: 'reasoning', text, titles });
240
+ }
241
+ else if (row.role === 'steering' && str(row.text).trim()) {
242
+ // Already-normalized rows (built or re-read scenes) keep their fields: normalizing is idempotent.
243
+ const consumed = row.status === 'consumed' || steering.consumed === true;
244
+ put({ ...base, role: 'steering', text: str(row.text), steering: { steer_id: steerId || rowId, consumed, submitted_at: finite(payload.created_at) ?? finite(steering.submitted_at), consumed_at: consumed ? finite(payload.consumed_at) ?? finite(steering.consumed_at) ?? createdAt : null, phase_duration: finite(steering.phase_duration) } });
245
+ }
246
+ else if (row.role === 'tool') {
247
+ const status = str(row.status).toLowerCase();
248
+ put({ ...base, role: 'tool', tool: {
249
+ id: toolId || rowId, name: str(tool.name) || 'tool', args: tool.args ?? null, preview: str(tool.snippet) || str(tool.preview) || null,
250
+ result: tool.result ?? tool.output ?? tool.snippet ?? null,
251
+ done: typeof tool.done === 'boolean' ? tool.done : status !== 'running',
252
+ is_error: tool.is_error === true || tool.error === true || status === 'error' || status === 'failed',
253
+ duration: finite(tool.duration), cost_usd: finite(tool.cost_usd),
254
+ } });
255
+ }
256
+ }
257
+ return rows.map((row, i) => ({ ...row, order_index: i }));
258
+ }
259
+ /** The rows a client shows under "Worked": normalized, without the final answer's own prose row (it renders below). */
260
+ function transportRows(scene) {
261
+ const rows = normalizeSceneRows(scene.activity_rows);
262
+ const finalKey = anchorSceneCleanText(scene.final_answer);
263
+ const at = finalKey ? rows.findLastIndex((row) => row.role === 'prose' && anchorSceneCleanText(row.text) === finalKey) : -1;
264
+ return at === -1 ? rows : rows.filter((_, i) => i !== at).map((row, i) => ({ ...row, order_index: i }));
265
+ }
187
266
  /** Tail-only transport preview of a durable scene. */
188
267
  export function anchorActivitySceneTransportPreview(scene, sceneRef = '') {
189
268
  const preview = {};
190
269
  for (const [k, v] of Object.entries(scene))
191
270
  if (k !== 'activity_rows')
192
271
  preview[k] = structuredClone(v);
193
- const rows = Array.isArray(scene.activity_rows) ? scene.activity_rows : [];
272
+ if ('final_answer' in scene)
273
+ preview.final_answer = str(scene.final_answer);
274
+ if ('turn_duration' in scene)
275
+ preview.turn_duration = finite(Number(scene.turn_duration ?? NaN));
276
+ const rows = transportRows(scene);
194
277
  const total = rows.length;
195
278
  const offset = Math.max(0, total - ANCHOR_SCENE_PREVIEW_ROWS);
196
- preview.activity_rows = structuredClone(rows.slice(offset));
279
+ preview.activity_rows = rows.slice(offset);
197
280
  preview.activity_rows_total = total;
198
281
  preview.activity_rows_offset = offset;
199
282
  preview.activity_rows_complete = offset === 0;
200
283
  preview.activity_rows_omitted = offset;
284
+ // Over every row, not just the preview: a client settling its local steer hints must see a steer paged out of it.
285
+ preview.has_consumed_steering = rows.some((row) => row.role === 'steering' && row.steering?.consumed === true);
201
286
  if (sceneRef)
202
287
  preview.activity_scene_ref = sceneRef;
203
288
  return preview;
204
289
  }
290
+ /** Terminal outcomes whose "Worked" disclosure opens by default, so readable partial work is not hidden. */
291
+ const EXPANDED_OUTCOMES = new Set(['error', 'no_response', 'degraded', 'connection_lost', 'tool_limit_reached', 'compression_exhausted']);
205
292
  /**
206
- * Attach each assistant message's scene preview for a window of messages.
207
- * ponytail: the durable scene is served as stored; the Python
208
- * `_complete_hydrated_anchor_scene` tool-body backfill is not reproduced.
293
+ * Codex (Responses API) narration between tool calls: `phase: 'commentary'` message items. The Agent routes that text
294
+ * into `reasoning` and leaves `content` empty, so the scene reads it here (`analysis` stays hidden).
209
295
  */
210
- export function hydrateAnchorActivityScenes(messages, records, messageOffset = 0) {
211
- if (!messages.length || !Object.keys(records).length)
212
- return messages;
296
+ function codexCommentary(message) {
297
+ if (!Array.isArray(message.codex_message_items))
298
+ return [];
299
+ return message.codex_message_items.flatMap((item) => isDict(item) && item.type === 'message' && str(item.phase).trim().toLowerCase() === 'commentary' && Array.isArray(item.content)
300
+ ? [item.content.map((part) => (isDict(part) && part.type === 'output_text' ? str(part.text) : '')).join('').trim()]
301
+ : []).filter(Boolean);
302
+ }
303
+ /** Anthropic-style tool calls: `tool_use` blocks in the content array, interleaved with the text around them. */
304
+ function hasToolUseBlocks(message) {
305
+ return Array.isArray(message.content) && message.content.some((part) => isDict(part) && part.type === 'tool_use');
306
+ }
307
+ /**
308
+ * The final answer rule: the turn's last assistant row, with visible content, no tool calls, not interim or partial.
309
+ * A Stop row is no answer: its outcome is the status (TAL-364; older rows still carry English copy).
310
+ */
311
+ function finalAnswerOf(last) {
312
+ if ((Array.isArray(last.tool_calls) && last.tool_calls.length > 0) || hasToolUseBlocks(last) || last._interim === true || last._partial === true)
313
+ return '';
314
+ if (last._error === true && (last._terminal_state === 'cancelled' || last.provider_details_label === 'Cancellation details'))
315
+ return '';
316
+ return splitThinkingFromContent(messageText(last.content))[0];
317
+ }
318
+ /** The turn's outcome: an explicit terminal state, else its error row's kind, else whether it answered. */
319
+ function terminalStateOf(last, finalAnswer) {
320
+ const label = str(last.provider_details_label);
321
+ const errorState = last._error === true ? (label === 'Cancellation details' ? 'cancelled' : label === 'Interruption details' ? 'interrupted' : 'error') : '';
322
+ return str(last.terminal_state) || str(last._terminal_state) || (last._max_iteration_summary_fallback === true ? 'tool_limit_reached' : '') || errorState || (finalAnswer.trim() ? 'completed' : 'no_response');
323
+ }
324
+ /**
325
+ * One completed turn's presentation, built from its rows: ordered reasoning / prose / tool rows (the work that folds
326
+ * under "Worked"), the visible final answer, the outcome, and whether "Worked" opens by default. Every decision a
327
+ * client used to make about a settled turn is made here.
328
+ */
329
+ export function buildTurnScene(turn, opts = {}) {
330
+ const assistants = turn.filter(([m]) => m.role === 'assistant');
331
+ const last = assistants.at(-1)?.[0];
332
+ if (!last)
333
+ return null;
334
+ const finalAnswer = finalAnswerOf(last);
335
+ const results = new Map();
336
+ for (const [m] of turn) {
337
+ if (m.role === 'tool')
338
+ results.set(str(m.tool_call_id) || str(m.tool_use_id), m);
339
+ // Anthropic-style results: `tool_result` blocks in a user row's content, each naming its call.
340
+ else if (m.role === 'user' && Array.isArray(m.content)) {
341
+ for (const part of m.content) {
342
+ if (isDict(part) && part.type === 'tool_result' && str(part.tool_use_id)) {
343
+ results.set(str(part.tool_use_id), { role: 'tool', tool_use_id: part.tool_use_id, content: part.content ?? '', is_error: part.is_error === true });
344
+ }
345
+ }
346
+ }
347
+ }
348
+ const rows = [];
349
+ const seenTools = new Set();
350
+ const push = (row) => rows.push({ ...row, order_index: rows.length });
351
+ for (const [m, index] of turn) {
352
+ const steer = isDict(m._steer) ? m._steer : null;
353
+ if (m.role === 'user' && steer) {
354
+ // A persisted steer sits at its causal place; it ends one work phase and starts the next.
355
+ const steerId = str(steer.steer_id) || `i${String(index)}`;
356
+ const createdAt = finite(m.timestamp);
357
+ push({ row_id: `steering:${steerId}`, role: 'steering', text: messageText(m.content), ...(createdAt === null ? {} : { created_at: createdAt }),
358
+ steering: { steer_id: steerId, consumed: true, submitted_at: finite(steer.submitted_at), consumed_at: finite(steer.consumed_at), phase_duration: finite(steer.phase_duration) } });
359
+ continue;
360
+ }
361
+ if (m.role !== 'assistant')
362
+ continue;
363
+ const ref = str(m.message_id ?? m.id) || `i${String(index)}`;
364
+ const createdAt = finite(m.timestamp);
365
+ const at = createdAt === null ? {} : { created_at: createdAt };
366
+ const commentary = codexCommentary(m);
367
+ // Structured content with tool_use or reasoning blocks is walked in order below, so its reasoning keeps its place.
368
+ const walked = hasToolUseBlocks(m) || (Array.isArray(m.content) && m.content.some((part) => isDict(part) && isReasoningBlock(part)));
369
+ let reasoning = [str(m.reasoning_content), typeof m.reasoning === 'string' ? m.reasoning : '', str(m.thinking)].filter(Boolean).join('\n');
370
+ for (const part of commentary)
371
+ reasoning = reasoning.replace(part, '');
372
+ reasoning = reasoning.replace(/\n{3,}/g, '\n\n').trim();
373
+ const titles = Array.isArray(m.reasoning_titles) ? m.reasoning_titles.filter((t) => typeof t === 'string' && Boolean(t.trim())) : [];
374
+ if (reasoning || titles.length)
375
+ push({ row_id: `${ref}:reasoning`, role: 'reasoning', text: reasoning, titles, ...at });
376
+ const [prose, inlineThinking] = splitThinkingFromContent(messageText(m.content));
377
+ if (inlineThinking)
378
+ push({ row_id: `${ref}:thinking`, role: 'reasoning', text: inlineThinking, titles: [], ...at });
379
+ const pushTool = (raw, i) => {
380
+ const call = isDict(raw) ? raw : {};
381
+ const id = str(call.id) || str(call.call_id) || str(call.tool_call_id) || `${ref}-${String(i)}`;
382
+ if (seenTools.has(id))
383
+ return;
384
+ seenTools.add(id);
385
+ const reply = results.get(id);
386
+ // Full results, except in a limited response, which clips them like its raw tool rows (the full detail keeps them).
387
+ const result = reply ? messageText((opts.clipToolResults ? toolMessageForLimitedPayload(reply) : reply).content) : call.result ?? call.output ?? null;
388
+ push({ row_id: `tool:${id}`, role: 'tool', ...at, tool: {
389
+ id, name: str(call.name) || str(isDict(call.function) ? call.function.name : '') || 'tool', args: toolArgs(call),
390
+ preview: str(call.preview) || null, result, done: typeof call.done === 'boolean' ? call.done : true,
391
+ is_error: call.is_error === true || reply?.is_error === true, duration: finite(call.duration), cost_usd: finite(call.cost_usd),
392
+ } });
393
+ };
394
+ if (walked) {
395
+ // Text, reasoning and tool_use blocks stay in the order the model wrote them. The final reply's text is its answer,
396
+ // so there only its reasoning is emitted.
397
+ const answering = m === last && Boolean(finalAnswer.trim());
398
+ let chunk = [];
399
+ const flush = () => {
400
+ if (answering) {
401
+ chunk = [];
402
+ return;
403
+ }
404
+ const text = splitThinkingFromContent(messageText(chunk))[0];
405
+ if (text.trim())
406
+ push({ row_id: rows.some((r) => r.row_id === `${ref}:prose`) ? `${ref}:prose:${String(rows.length)}` : `${ref}:prose`, role: 'prose', text, ...at });
407
+ chunk = [];
408
+ };
409
+ for (const [i, part] of m.content.entries()) {
410
+ if (isDict(part) && isReasoningBlock(part)) {
411
+ flush();
412
+ const text = reasoningBlockText(part).trim();
413
+ if (text)
414
+ push({ row_id: `${ref}:reasoning:${String(i)}`, role: 'reasoning', text, titles: [], ...at });
415
+ continue;
416
+ }
417
+ if (!isDict(part) || part.type !== 'tool_use') {
418
+ chunk.push(part);
419
+ continue;
420
+ }
421
+ flush();
422
+ // The server's projection of this call (withToolCallOutcomes) carries its outcome.
423
+ const projected = (Array.isArray(m.tool_calls) ? m.tool_calls : []).find((call) => isDict(call) && str(call.id) === str(part.id));
424
+ pushTool({ ...(isDict(projected) ? projected : {}), id: part.id, name: part.name, args: part.input ?? null }, i);
425
+ }
426
+ flush();
427
+ // A call only the session-level list recorded follows the model's own blocks.
428
+ for (const [i, call] of (Array.isArray(m.tool_calls) ? m.tool_calls : []).entries())
429
+ pushTool(call, i);
430
+ continue;
431
+ }
432
+ const text = prose.trim() ? prose : commentary.join('\n\n');
433
+ if (m !== last || !finalAnswer.trim()) {
434
+ if (text.trim())
435
+ push({ row_id: `${ref}:prose`, role: 'prose', text, ...at });
436
+ }
437
+ for (const [i, call] of (Array.isArray(m.tool_calls) ? m.tool_calls : []).entries())
438
+ pushTool(call, i);
439
+ }
440
+ const terminalState = terminalStateOf(last, finalAnswer);
441
+ return {
442
+ version: 'activity_scene_v1', activity_rows: rows, final_answer: finalAnswer, terminal_state: terminalState,
443
+ expanded_by_default: EXPANDED_OUTCOMES.has(terminalState) && rows.length > 0, turn_duration: anchorSceneMessageTurnDuration(last),
444
+ file_changes: turnFileChanges(rows),
445
+ ...(typeof last._final_phase_duration === 'number' ? { final_phase_duration: last._final_phase_duration } : {}),
446
+ };
447
+ }
448
+ /** A settled turn's outcome by the scene's rules, so its `done` frame reports what the settled scene then shows. */
449
+ export function turnTerminalState(messages, turnId) {
450
+ return str(buildTurnScene(turnsOf(messages).get(turnId) ?? [])?.terminal_state) || 'no_response';
451
+ }
452
+ /**
453
+ * A stored scene keeps its rows; the final answer it predates comes from its turn by the same rule, except after a
454
+ * consumed steer (the reply then answers the steer, so the last row is not promoted).
455
+ */
456
+ function withStoredFinalAnswer(scene, built) {
457
+ if (!built || str(scene.final_answer).trim())
458
+ return scene;
459
+ // An explicit empty answer, so no client takes the reply that answered the steer for the missing field's fallback.
460
+ if (normalizeSceneRows(scene.activity_rows).some((row) => row.steering?.consumed === true))
461
+ return { ...scene, final_answer: '' };
462
+ return { ...scene, final_answer: built.final_answer };
463
+ }
464
+ /** The outcome fields a stored scene predates, from its turn by the same rules as a built one, and the turn's file changes. */
465
+ function withStoredOutcome(preview, built) {
466
+ // Always the turn's own: a stored scene is client-posted, so its rows never decide what the turn changed.
467
+ const next = { ...preview, file_changes: built?.file_changes ?? [] };
468
+ // Only an explicit outcome carries over from the turn; answered or not follows the scene's own final answer.
469
+ const explicit = str(built?.terminal_state);
470
+ if (!str(next.terminal_state))
471
+ next.terminal_state = explicit && explicit !== 'completed' && explicit !== 'no_response' ? explicit : str(next.final_answer).trim() ? 'completed' : 'no_response';
472
+ if (typeof next.expanded_by_default !== 'boolean')
473
+ next.expanded_by_default = EXPANDED_OUTCOMES.has(str(next.terminal_state)) && Number(next.activity_rows_total) > 0;
474
+ return next;
475
+ }
476
+ /** Rows of the full transcript grouped by `_turn_id` (see withTurnIds), with their absolute indexes. */
477
+ function turnsOf(messages) {
478
+ const turns = new Map();
479
+ messages.forEach((m, index) => {
480
+ if (!isDict(m))
481
+ return;
482
+ const id = str(m._turn_id);
483
+ if (!id)
484
+ return;
485
+ const rows = turns.get(id) ?? [];
486
+ rows.push([m, index]);
487
+ turns.set(id, rows);
488
+ });
489
+ return turns;
490
+ }
491
+ /** The stored record for a message: a unique content ref first, then its absolute index when the content agrees. */
492
+ function storedRecordFor(message, index, lookup) {
493
+ const ref = assistantAnchorSceneMessageRef(message);
494
+ const record = (lookup.refCounts.get(ref) ?? 0) <= 1 ? lookup.byRef.get(ref) : undefined;
495
+ if (record)
496
+ return record;
497
+ const candidate = lookup.byIndex.get(index);
498
+ return candidate && anchorSceneCandidateMatchesScene(message, candidate.scene ?? {}) ? candidate : undefined;
499
+ }
500
+ function sceneLookup(messages, records) {
213
501
  const byRef = new Map();
214
502
  const byIndex = new Map();
215
503
  for (const [key, record] of Object.entries(records)) {
@@ -230,26 +518,43 @@ export function hydrateAnchorActivityScenes(messages, records, messageOffset = 0
230
518
  refCounts.set(r, (refCounts.get(r) ?? 0) + 1);
231
519
  }
232
520
  }
233
- const out = [...messages];
234
- messages.forEach((message, localIdx) => {
235
- if (!isDict(message) || message.role !== 'assistant')
236
- return;
237
- const absoluteIdx = messageOffset + localIdx;
238
- const ref = assistantAnchorSceneMessageRef(message);
239
- let record = (refCounts.get(ref) ?? 0) <= 1 ? byRef.get(ref) : undefined;
240
- if (!record) {
241
- const candidate = byIndex.get(absoluteIdx);
242
- if (candidate && anchorSceneCandidateMatchesScene(message, candidate.scene ?? {}))
243
- record = candidate;
244
- }
245
- if (!record || !isDict(record.scene))
246
- return;
521
+ return { byRef, byIndex, refCounts };
522
+ }
523
+ /**
524
+ * Attach every completed turn's scene preview to its last assistant row, over the full `_turn_id`-stamped transcript
525
+ * (before any window, so every window agrees). A stored scene wins and is completed with the turn's outcome fields; a
526
+ * turn without one gets a built scene. The running turn (`activeTurnId`) gets none: the live stream renders it.
527
+ */
528
+ export function hydrateAnchorActivityScenes(messages, records, opts = {}) {
529
+ if (!messages.length)
530
+ return messages;
531
+ const lookup = sceneLookup(messages, records);
532
+ // Any scene carried inline leaves in the one normalized shape, even off a turn's last row.
533
+ const out = messages.map((m) => (isDict(m) && isDict(m._anchor_activity_scene) ? { ...m, _anchor_activity_scene: anchorActivitySceneTransportPreview(m._anchor_activity_scene, str(m._anchor_activity_scene.activity_scene_ref)) } : m));
534
+ for (const [turnId, turn] of turnsOf(messages)) {
535
+ if (opts.activeTurnId && turnId === opts.activeTurnId)
536
+ continue;
537
+ const lastEntry = turn.filter(([m]) => m.role === 'assistant').at(-1);
538
+ if (!lastEntry)
539
+ continue;
540
+ const [message, index] = lastEntry;
541
+ const built = buildTurnScene(turn, { clipToolResults: opts.clipToolResults === true });
542
+ const record = storedRecordFor(message, index, lookup);
543
+ const inline = message._anchor_activity_scene;
247
544
  const next = { ...message };
248
- next._anchor_activity_scene = anchorActivitySceneTransportPreview(record.scene, str(record.message_ref || ref));
249
- if (record.stream_id)
250
- next._anchor_stream_id = str(record.stream_id);
251
- out[localIdx] = next;
252
- });
545
+ if (record && isDict(record.scene)) {
546
+ next._anchor_activity_scene = withStoredOutcome(anchorActivitySceneTransportPreview(withStoredFinalAnswer(record.scene, built), str(record.message_ref) || assistantAnchorSceneMessageRef(message)), built);
547
+ if (record.stream_id)
548
+ next._anchor_stream_id = str(record.stream_id);
549
+ }
550
+ else if (isDict(inline)) {
551
+ next._anchor_activity_scene = withStoredOutcome(anchorActivitySceneTransportPreview(withStoredFinalAnswer(inline, built), str(inline.activity_scene_ref)), built);
552
+ }
553
+ else if (built) {
554
+ next._anchor_activity_scene = anchorActivitySceneTransportPreview(built, assistantAnchorSceneMessageRef(message));
555
+ }
556
+ out[index] = next;
557
+ }
253
558
  return out;
254
559
  }
255
560
  /** Persist a settled scene onto a session (the POST body semantics). Returns the placement. */
@@ -274,7 +579,7 @@ export function storeAnchorScene(session, body, now) {
274
579
  return { message_index: idx, message_ref: ref };
275
580
  }
276
581
  /** Page through one stored scene's rows (the GET semantics). */
277
- export function readAnchorSceneRows(session, query) {
582
+ export function readAnchorSceneRows(session, query, transcript = []) {
278
583
  const records = anchorSceneRecords(session);
279
584
  let record = null;
280
585
  if (query.messageRef) {
@@ -298,14 +603,50 @@ export function readAnchorSceneRows(session, query) {
298
603
  }
299
604
  }
300
605
  }
301
- const scene = record && isDict(record.scene) ? record.scene : null;
302
- const rows = scene && Array.isArray(scene.activity_rows) ? scene.activity_rows : null;
303
- if (!rows || !record)
606
+ // The turn that ends at the requested message: its built scene, or the one that completes a stored scene.
607
+ const matches = transcript.map((m, i) => [m, i]).filter(([m, i]) => isDict(m) && m.role === 'assistant' && (query.messageRef ? assistantAnchorSceneMessageRef(m) === query.messageRef : i === query.messageIndex));
608
+ const target = matches.length === 1 ? matches[0] : matches.find(([, i]) => i === query.messageIndex);
609
+ const turn = target && isDict(target[0]) ? turnsOf(transcript).get(str(target[0]._turn_id)) : undefined;
610
+ const built = turn ? buildTurnScene(turn) : null;
611
+ const stored = record && isDict(record.scene) ? withStoredFinalAnswer(record.scene, built) : null;
612
+ const scene = stored ?? built;
613
+ const sceneRef = record ? str(record.message_ref || query.messageRef) : query.messageRef;
614
+ if (!scene || !Array.isArray(scene.activity_rows))
304
615
  return null;
616
+ const rows = transportRows(scene);
305
617
  const total = rows.length;
306
618
  const before = Math.max(0, Math.min(total, query.before ?? total));
307
619
  const limit = Math.max(1, Math.min(200, query.limit ?? 80));
308
620
  const start = Math.max(0, before - limit);
309
- return { scene_ref: str(record.message_ref || query.messageRef), rows: structuredClone(rows.slice(start, before)), start, end: before, total, complete: start === 0 };
621
+ return { scene_ref: sceneRef, rows: rows.slice(start, before), start, end: before, total, complete: start === 0 };
622
+ }
623
+ /** A turn opens at a user message the reader sees (text or attachments); hidden prompts and compaction markers do not. */
624
+ function opensTurn(m) {
625
+ if (m.role !== 'user' || isContextCompressionMarker(m) || isDict(m._steer))
626
+ return false;
627
+ return messageText(m.content).trim() !== '' || (Array.isArray(m.attachments) && m.attachments.length > 0);
628
+ }
629
+ /**
630
+ * Every message leaves the server with a `_turn_id`. A turn stamps its rows with its stream id; rows written before
631
+ * that (older files, state.db/CLI rows) take `legacy:<index of their opening user row>`, or `legacy:start`, computed
632
+ * over the full transcript so a window boundary never changes a key. Returns copies; stored rows are untouched.
633
+ */
634
+ export function withTurnIds(messages) {
635
+ let current = 'legacy:start';
636
+ return messages.map((raw, index) => {
637
+ if (!isDict(raw))
638
+ return raw;
639
+ // The Agent's own record of a delivered steer shows as the steer it is, inside its turn, never as a prompt.
640
+ const agentSteer = agentSteerText(raw);
641
+ const m = agentSteer === null ? raw : { ...raw, content: agentSteer, _steer: { steer_id: `agent:${String(index)}` } };
642
+ const own = str(m._turn_id);
643
+ if (own) {
644
+ current = own;
645
+ return m;
646
+ }
647
+ if (opensTurn(m))
648
+ current = `legacy:${String(index)}`;
649
+ return { ...m, _turn_id: current };
650
+ });
310
651
  }
311
652
  //# sourceMappingURL=anchor.js.map