@circuitwall/jarela 2.2.1 → 2.4.0

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 (703) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/app-path-routes-manifest.json +2 -1
  3. package/.next/standalone/.next/build-manifest.json +2 -2
  4. package/.next/standalone/.next/prerender-manifest.json +3 -3
  5. package/.next/standalone/.next/routes-manifest.json +8 -0
  6. package/.next/standalone/.next/server/app/_global-error/page.js +68 -68
  7. package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  8. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  9. package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
  10. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  11. package/.next/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  12. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  13. package/.next/standalone/.next/server/app/_not-found/page.js +76 -76
  14. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  15. package/.next/standalone/.next/server/app/_not-found.html +2 -2
  16. package/.next/standalone/.next/server/app/_not-found.rsc +2 -2
  17. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  18. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  19. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  20. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  21. package/.next/standalone/.next/server/app/api/v1/access/[identity]/route.js +100 -93
  22. package/.next/standalone/.next/server/app/api/v1/access/route.js +176 -169
  23. package/.next/standalone/.next/server/app/api/v1/agents/[id]/compact/route.js +89 -56
  24. package/.next/standalone/.next/server/app/api/v1/agents/[id]/compact/route.js.nft.json +1 -1
  25. package/.next/standalone/.next/server/app/api/v1/agents/[id]/display-filters/route.js +139 -127
  26. package/.next/standalone/.next/server/app/api/v1/agents/[id]/route.js +107 -100
  27. package/.next/standalone/.next/server/app/api/v1/agents/[id]/thread/route.js +765 -753
  28. package/.next/standalone/.next/server/app/api/v1/agents/route.js +72 -65
  29. package/.next/standalone/.next/server/app/api/v1/allowed-sites/[hostname]/route.js +371 -364
  30. package/.next/standalone/.next/server/app/api/v1/allowed-sites/route.js +809 -802
  31. package/.next/standalone/.next/server/app/api/v1/artifacts/lifecycle/route.js +9 -2
  32. package/.next/standalone/.next/server/app/api/v1/attachments/files/route.js +49 -49
  33. package/.next/standalone/.next/server/app/api/v1/attachments/images/route.js +910 -910
  34. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/chats/route.js +583 -16
  35. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/chats/route.js.nft.json +1 -1
  36. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/ignores/[remote_jid]/route.js +41 -30
  37. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/ignores/route.js +48 -37
  38. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/lookup/route.js +697 -130
  39. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/lookup/route.js.nft.json +1 -1
  40. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/pair/route.js +703 -136
  41. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/pair/route.js.nft.json +1 -1
  42. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/route.js +796 -229
  43. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/route.js.nft.json +1 -1
  44. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/routes/[route_id]/route.js +762 -746
  45. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/routes/route.js +1050 -1034
  46. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/status/route.js +673 -106
  47. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/status/route.js.nft.json +1 -1
  48. package/.next/standalone/.next/server/app/api/v1/bridges/kinds/route.js +811 -804
  49. package/.next/standalone/.next/server/app/api/v1/bridges/kinds/route.js.nft.json +1 -1
  50. package/.next/standalone/.next/server/app/api/v1/bridges/route.js +718 -706
  51. package/.next/standalone/.next/server/app/api/v1/bridges/route.js.nft.json +1 -1
  52. package/.next/standalone/.next/server/app/api/v1/builtin-tools/route.js +9 -9
  53. package/.next/standalone/.next/server/app/api/v1/builtin-tools/route.js.nft.json +1 -1
  54. package/.next/standalone/.next/server/app/api/v1/config/route.js +85 -85
  55. package/.next/standalone/.next/server/app/api/v1/credentials/[id]/route.js +709 -709
  56. package/.next/standalone/.next/server/app/api/v1/credentials/[id]/route.js.nft.json +1 -1
  57. package/.next/standalone/.next/server/app/api/v1/credentials/route.js +2 -2
  58. package/.next/standalone/.next/server/app/api/v1/credentials/route.js.nft.json +1 -1
  59. package/.next/standalone/.next/server/app/api/v1/dashboard/currency/route.js +10 -10
  60. package/.next/standalone/.next/server/app/api/v1/dashboard/metrics/route.js +796 -784
  61. package/.next/standalone/.next/server/app/api/v1/dashboard/pricing/route.js +30 -23
  62. package/.next/standalone/.next/server/app/api/v1/dashboard/pricing-task/route.js +86 -86
  63. package/.next/standalone/.next/server/app/api/v1/dashboard/pricing-task/route.js.nft.json +1 -1
  64. package/.next/standalone/.next/server/app/api/v1/delegations/codex/[job_id]/route.js +57 -57
  65. package/.next/standalone/.next/server/app/api/v1/delegations/codex/[job_id]/route.js.nft.json +1 -1
  66. package/.next/standalone/.next/server/app/api/v1/documents/search/route.js +385 -378
  67. package/.next/standalone/.next/server/app/api/v1/documents/settings/route.js +51 -44
  68. package/.next/standalone/.next/server/app/api/v1/documents/sources/[id]/reindex/route.js +65 -65
  69. package/.next/standalone/.next/server/app/api/v1/documents/sources/[id]/reindex/route.js.nft.json +1 -1
  70. package/.next/standalone/.next/server/app/api/v1/documents/sources/[id]/route.js +122 -122
  71. package/.next/standalone/.next/server/app/api/v1/documents/sources/[id]/route.js.nft.json +1 -1
  72. package/.next/standalone/.next/server/app/api/v1/documents/sources/route.js +37 -37
  73. package/.next/standalone/.next/server/app/api/v1/documents/sources/route.js.nft.json +1 -1
  74. package/.next/standalone/.next/server/app/api/v1/env/route.js +9 -9
  75. package/.next/standalone/.next/server/app/api/v1/env-sync/allowlist/route.js +375 -368
  76. package/.next/standalone/.next/server/app/api/v1/env-sync/route.js +51 -44
  77. package/.next/standalone/.next/server/app/api/v1/events/route.js +745 -178
  78. package/.next/standalone/.next/server/app/api/v1/events/route.js.nft.json +1 -1
  79. package/.next/standalone/.next/server/app/api/v1/events/test/route.js +77 -77
  80. package/.next/standalone/.next/server/app/api/v1/extension/agents/route.js +763 -763
  81. package/.next/standalone/.next/server/app/api/v1/extension/agents/route.js.nft.json +1 -1
  82. package/.next/standalone/.next/server/app/api/v1/extension/browser/activate/route.js +51 -44
  83. package/.next/standalone/.next/server/app/api/v1/extension/browser/foreground/route.js +16 -9
  84. package/.next/standalone/.next/server/app/api/v1/extension/browser/history/route.js +72 -65
  85. package/.next/standalone/.next/server/app/api/v1/extension/browser/poll/route.js +41 -34
  86. package/.next/standalone/.next/server/app/api/v1/extension/browser/progress/route.js +211 -204
  87. package/.next/standalone/.next/server/app/api/v1/extension/browser/result/route.js +140 -133
  88. package/.next/standalone/.next/server/app/api/v1/extension/browser/retry/route.js +113 -106
  89. package/.next/standalone/.next/server/app/api/v1/extension/browser/status/route.js +121 -114
  90. package/.next/standalone/.next/server/app/api/v1/extension/browser/tabs/route.js +141 -134
  91. package/.next/standalone/.next/server/app/api/v1/extension/fill/route.js +690 -690
  92. package/.next/standalone/.next/server/app/api/v1/extension/fill/route.js.nft.json +1 -1
  93. package/.next/standalone/.next/server/app/api/v1/extension/refine/route.js +93 -93
  94. package/.next/standalone/.next/server/app/api/v1/extension/refine/route.js.nft.json +1 -1
  95. package/.next/standalone/.next/server/app/api/v1/extension/turn/route.js +9 -9
  96. package/.next/standalone/.next/server/app/api/v1/extension/turn/route.js.nft.json +1 -1
  97. package/.next/standalone/.next/server/app/api/v1/extensions/route.js +185 -185
  98. package/.next/standalone/.next/server/app/api/v1/extensions/route.js.nft.json +1 -1
  99. package/.next/standalone/.next/server/app/api/v1/extensions/tools/[name]/config/route.js +171 -171
  100. package/.next/standalone/.next/server/app/api/v1/extensions/tools/[name]/config/route.js.nft.json +1 -1
  101. package/.next/standalone/.next/server/app/api/v1/extensions/tools/[name]/route.js +396 -396
  102. package/.next/standalone/.next/server/app/api/v1/extensions/tools/[name]/route.js.nft.json +1 -1
  103. package/.next/standalone/.next/server/app/api/v1/extensions/tools/[name]/secrets/route.js +212 -212
  104. package/.next/standalone/.next/server/app/api/v1/extensions/tools/[name]/secrets/route.js.nft.json +1 -1
  105. package/.next/standalone/.next/server/app/api/v1/files/[name]/route.js +235 -235
  106. package/.next/standalone/.next/server/app/api/v1/fs/browse/route.js +26 -26
  107. package/.next/standalone/.next/server/app/api/v1/harnesses/[id]/route.js +228 -221
  108. package/.next/standalone/.next/server/app/api/v1/harnesses/default/route.js +65 -58
  109. package/.next/standalone/.next/server/app/api/v1/harnesses/route.js +79 -72
  110. package/.next/standalone/.next/server/app/api/v1/health/probes/route.js +9 -9
  111. package/.next/standalone/.next/server/app/api/v1/health/probes/route.js.nft.json +1 -1
  112. package/.next/standalone/.next/server/app/api/v1/health/route.js +783 -771
  113. package/.next/standalone/.next/server/app/api/v1/integrations/[name]/route.js +140 -133
  114. package/.next/standalone/.next/server/app/api/v1/integrations/[name]/test/route.js +9 -9
  115. package/.next/standalone/.next/server/app/api/v1/integrations/[name]/test/route.js.nft.json +1 -1
  116. package/.next/standalone/.next/server/app/api/v1/integrations/gmail/oauth/callback/route.js +370 -363
  117. package/.next/standalone/.next/server/app/api/v1/integrations/gmail/oauth/start/route.js +240 -233
  118. package/.next/standalone/.next/server/app/api/v1/integrations/gmail/oauth/status/route.js +689 -682
  119. package/.next/standalone/.next/server/app/api/v1/integrations/outlook/oauth/callback/route.js +886 -879
  120. package/.next/standalone/.next/server/app/api/v1/integrations/outlook/oauth/start/route.js +115 -108
  121. package/.next/standalone/.next/server/app/api/v1/integrations/outlook/oauth/status/route.js +955 -948
  122. package/.next/standalone/.next/server/app/api/v1/integrations/route.js +223 -216
  123. package/.next/standalone/.next/server/app/api/v1/lifecycle/adoption/route.js +876 -847
  124. package/.next/standalone/.next/server/app/api/v1/lifecycle/adoption/route.js.nft.json +1 -1
  125. package/.next/standalone/.next/server/app/api/v1/local-file/route.js +26 -26
  126. package/.next/standalone/.next/server/app/api/v1/logs/route.js +70 -70
  127. package/.next/standalone/.next/server/app/api/v1/maps/embed/route.js +79 -72
  128. package/.next/standalone/.next/server/app/api/v1/mcp-servers/[name]/route.js +991 -979
  129. package/.next/standalone/.next/server/app/api/v1/mcp-servers/registry/route.js +196 -196
  130. package/.next/standalone/.next/server/app/api/v1/mcp-servers/route.js +19 -7
  131. package/.next/standalone/.next/server/app/api/v1/memory/[namespace]/[key]/route.js +539 -532
  132. package/.next/standalone/.next/server/app/api/v1/memory/policy/route.js +86 -79
  133. package/.next/standalone/.next/server/app/api/v1/memory/route.js +58 -51
  134. package/.next/standalone/.next/server/app/api/v1/memory/search/route.js +138 -131
  135. package/.next/standalone/.next/server/app/api/v1/models/[name]/compact-threads/route.js +381 -369
  136. package/.next/standalone/.next/server/app/api/v1/models/[name]/compact-threads/route.js.nft.json +1 -1
  137. package/.next/standalone/.next/server/app/api/v1/models/[name]/route.js +150 -143
  138. package/.next/standalone/.next/server/app/api/v1/models/route.js +634 -627
  139. package/.next/standalone/.next/server/app/api/v1/packages/catalog/route.js +445 -445
  140. package/.next/standalone/.next/server/app/api/v1/packages/defaults/[id]/route.js +120 -120
  141. package/.next/standalone/.next/server/app/api/v1/packages/defaults/[id]/route.js.nft.json +1 -1
  142. package/.next/standalone/.next/server/app/api/v1/packages/install/[id]/route.js +234 -234
  143. package/.next/standalone/.next/server/app/api/v1/packages/install/[id]/route.js.nft.json +1 -1
  144. package/.next/standalone/.next/server/app/api/v1/packages/install/route.js +407 -407
  145. package/.next/standalone/.next/server/app/api/v1/packages/install/route.js.nft.json +1 -1
  146. package/.next/standalone/.next/server/app/api/v1/packages/manifests/[name]/enabled/route.js +37 -37
  147. package/.next/standalone/.next/server/app/api/v1/packages/manifests/[name]/enabled/route.js.nft.json +1 -1
  148. package/.next/standalone/.next/server/app/api/v1/packages/manifests/[name]/route.js +107 -107
  149. package/.next/standalone/.next/server/app/api/v1/packages/manifests/[name]/route.js.nft.json +1 -1
  150. package/.next/standalone/.next/server/app/api/v1/packages/manifests/route.js +228 -228
  151. package/.next/standalone/.next/server/app/api/v1/packages/manifests/route.js.nft.json +1 -1
  152. package/.next/standalone/.next/server/app/api/v1/packages/reload/route.js +9 -9
  153. package/.next/standalone/.next/server/app/api/v1/packages/reload/route.js.nft.json +1 -1
  154. package/.next/standalone/.next/server/app/api/v1/packages/route.js +148 -148
  155. package/.next/standalone/.next/server/app/api/v1/packages/route.js.nft.json +1 -1
  156. package/.next/standalone/.next/server/app/api/v1/page-capture/route.js +787 -787
  157. package/.next/standalone/.next/server/app/api/v1/page-capture/route.js.nft.json +1 -1
  158. package/.next/standalone/.next/server/app/api/v1/pending-actions/[id]/approve/route.js +529 -514
  159. package/.next/standalone/.next/server/app/api/v1/pending-actions/[id]/approve/route.js.nft.json +1 -1
  160. package/.next/standalone/.next/server/app/api/v1/pending-actions/[id]/deny/route.js +181 -181
  161. package/.next/standalone/.next/server/app/api/v1/pending-actions/[id]/deny/route.js.nft.json +1 -1
  162. package/.next/standalone/.next/server/app/api/v1/pending-actions/route.js +258 -258
  163. package/.next/standalone/.next/server/app/api/v1/pending-actions/route.js.nft.json +1 -1
  164. package/.next/standalone/.next/server/app/api/v1/profile/location/route.js +37 -30
  165. package/.next/standalone/.next/server/app/api/v1/profile/route.js +171 -164
  166. package/.next/standalone/.next/server/app/api/v1/providers/[provider]/models/route.js +51 -44
  167. package/.next/standalone/.next/server/app/api/v1/providers/[provider]/probe/route.js +15 -8
  168. package/.next/standalone/.next/server/app/api/v1/providers/github-copilot/auth/route.js +171 -164
  169. package/.next/standalone/.next/server/app/api/v1/providers/route.js +101 -94
  170. package/.next/standalone/.next/server/app/api/v1/proxy-config/route.js +457 -450
  171. package/.next/standalone/.next/server/app/api/v1/redaction/init/route.js +44 -37
  172. package/.next/standalone/.next/server/app/api/v1/redaction/route.js +65 -58
  173. package/.next/standalone/.next/server/app/api/v1/scheduled-tasks/[id]/route.js +617 -605
  174. package/.next/standalone/.next/server/app/api/v1/scheduled-tasks/[id]/run/route.js +44 -44
  175. package/.next/standalone/.next/server/app/api/v1/scheduled-tasks/[id]/run/route.js.nft.json +1 -1
  176. package/.next/standalone/.next/server/app/api/v1/scheduled-tasks/route.js +739 -732
  177. package/.next/standalone/.next/server/app/api/v1/security/idle-timeout/route.js +329 -322
  178. package/.next/standalone/.next/server/app/api/v1/security/pin/route.js +204 -197
  179. package/.next/standalone/.next/server/app/api/v1/security/state/route.js +58 -51
  180. package/.next/standalone/.next/server/app/api/v1/security/unlock/route.js +183 -176
  181. package/.next/standalone/.next/server/app/api/v1/security/verify-pin/route.js +194 -187
  182. package/.next/standalone/.next/server/app/api/v1/setup/test-key/route.js +26 -26
  183. package/.next/standalone/.next/server/app/api/v1/skills/[id]/route.js +776 -769
  184. package/.next/standalone/.next/server/app/api/v1/skills/repos/[id]/route.js +122 -115
  185. package/.next/standalone/.next/server/app/api/v1/skills/repos/route.js +334 -327
  186. package/.next/standalone/.next/server/app/api/v1/skills/route.js +873 -866
  187. package/.next/standalone/.next/server/app/api/v1/system/abort/route.js +838 -808
  188. package/.next/standalone/.next/server/app/api/v1/system/restart/route.js +177 -177
  189. package/.next/standalone/.next/server/app/api/v1/system/restart/route.js.nft.json +1 -1
  190. package/.next/standalone/.next/server/app/api/v1/tailscale/route.js +164 -164
  191. package/.next/standalone/.next/server/app/api/v1/tasks/[agent_id]/route.js +122 -115
  192. package/.next/standalone/.next/server/app/api/v1/tasks/route.js +30 -23
  193. package/.next/standalone/.next/server/app/api/v1/threads/[thread_id]/activity/route.js +1436 -0
  194. package/.next/standalone/.next/server/app/api/v1/threads/[thread_id]/activity/route.js.nft.json +1 -0
  195. package/.next/standalone/.next/server/app/api/v1/threads/[thread_id]/activity/route_client-reference-manifest.js +1 -0
  196. package/.next/standalone/.next/server/app/api/v1/threads/[thread_id]/context-pin/route.js +638 -631
  197. package/.next/standalone/.next/server/app/api/v1/threads/[thread_id]/context-pin/route.js.nft.json +1 -1
  198. package/.next/standalone/.next/server/app/api/v1/threads/[thread_id]/route.js +60 -439
  199. package/.next/standalone/.next/server/app/api/v1/threads/[thread_id]/route.js.nft.json +1 -1
  200. package/.next/standalone/.next/server/app/api/v1/threads/[thread_id]/run/route.js +172 -173
  201. package/.next/standalone/.next/server/app/api/v1/threads/[thread_id]/run/route.js.nft.json +1 -1
  202. package/.next/standalone/.next/server/app/api/v1/threads/route.js +925 -913
  203. package/.next/standalone/.next/server/app/api/v1/tools/route.js +2 -2
  204. package/.next/standalone/.next/server/app/api/v1/tools/route.js.nft.json +1 -1
  205. package/.next/standalone/.next/server/app/api/v1/update/apply/route.js +17 -17
  206. package/.next/standalone/.next/server/app/api/v1/update/apply/route.js.nft.json +1 -1
  207. package/.next/standalone/.next/server/app/api/v1/update/route.js +570 -570
  208. package/.next/standalone/.next/server/app/api/v1/voice/transcribe/route.js +241 -229
  209. package/.next/standalone/.next/server/app/api/v1/voice/tts/route.js +989 -977
  210. package/.next/standalone/.next/server/app/api/v1/watchers/[id]/route.js +40 -28
  211. package/.next/standalone/.next/server/app/api/v1/watchers/[id]/run/route.js +72 -72
  212. package/.next/standalone/.next/server/app/api/v1/watchers/[id]/run/route.js.nft.json +1 -1
  213. package/.next/standalone/.next/server/app/api/v1/watchers/reaction-scripts/route.js +128 -128
  214. package/.next/standalone/.next/server/app/api/v1/watchers/route.js +164 -164
  215. package/.next/standalone/.next/server/app/api/v1/watchers/route.js.nft.json +1 -1
  216. package/.next/standalone/.next/server/app/icon.svg/route.js +62 -62
  217. package/.next/standalone/.next/server/app/manifest.webmanifest/route.js +436 -436
  218. package/.next/standalone/.next/server/app/page.js +1179 -743
  219. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  220. package/.next/standalone/.next/server/app/setup/page.js +99 -91
  221. package/.next/standalone/.next/server/app/setup/page_client-reference-manifest.js +1 -1
  222. package/.next/standalone/.next/server/app-paths-manifest.json +2 -1
  223. package/.next/standalone/.next/server/chunks/{424.js → 1388.js} +441 -1022
  224. package/.next/standalone/.next/server/chunks/1433.js +1 -1
  225. package/.next/standalone/.next/server/chunks/1638.js +1 -2
  226. package/.next/standalone/.next/server/chunks/1738.js +1 -1
  227. package/.next/standalone/.next/server/chunks/2068.js +47 -10
  228. package/.next/standalone/.next/server/chunks/210.js +3 -3
  229. package/.next/standalone/.next/server/chunks/2151.js +31 -1
  230. package/.next/standalone/.next/server/chunks/2207.js +1 -0
  231. package/.next/standalone/.next/server/chunks/2447.js +10 -5
  232. package/.next/standalone/.next/server/chunks/2471.js +45 -45
  233. package/.next/standalone/.next/server/chunks/2504.js +1 -1
  234. package/.next/standalone/.next/server/chunks/2695.js +17 -17
  235. package/.next/standalone/.next/server/chunks/3042.js +24 -16
  236. package/.next/standalone/.next/server/chunks/{4540.js → 309.js} +104 -38
  237. package/.next/standalone/.next/server/chunks/{2350.js → 3272.js} +104 -37
  238. package/.next/standalone/.next/server/chunks/3399.js +526 -526
  239. package/.next/standalone/.next/server/chunks/3524.js +150 -67
  240. package/.next/standalone/.next/server/chunks/3566.js +1 -1
  241. package/.next/standalone/.next/server/chunks/4189.js +946 -0
  242. package/.next/standalone/.next/server/chunks/4433.js +146 -146
  243. package/.next/standalone/.next/server/chunks/4508.js +3 -3
  244. package/.next/standalone/.next/server/chunks/4588.js +1 -0
  245. package/.next/standalone/.next/server/chunks/46.js +78 -28
  246. package/.next/standalone/.next/server/chunks/466.js +12 -0
  247. package/.next/standalone/.next/server/chunks/4868.js +206 -206
  248. package/.next/standalone/.next/server/chunks/4992.js +13 -0
  249. package/.next/standalone/.next/server/chunks/5120.js +963 -0
  250. package/.next/standalone/.next/server/chunks/5701.js +1 -1
  251. package/.next/standalone/.next/server/chunks/5900.js +1 -1
  252. package/.next/standalone/.next/server/chunks/5908.js +63 -42
  253. package/.next/standalone/.next/server/chunks/6142.js +10 -2
  254. package/.next/standalone/.next/server/chunks/6210.js +1 -0
  255. package/.next/standalone/.next/server/chunks/6213.js +1 -1
  256. package/.next/standalone/.next/server/chunks/6649.js +3 -3
  257. package/.next/standalone/.next/server/chunks/6703.js +3 -3
  258. package/.next/standalone/.next/server/chunks/7445.js +1 -0
  259. package/.next/standalone/.next/server/chunks/8067.js +12 -0
  260. package/.next/standalone/.next/server/chunks/8461.js +24 -17
  261. package/.next/standalone/.next/server/chunks/8558.js +1 -1
  262. package/.next/standalone/.next/server/chunks/8724.js +1 -1
  263. package/.next/standalone/.next/server/chunks/8849.js +91 -91
  264. package/.next/standalone/.next/server/chunks/9032.js +4 -3
  265. package/.next/standalone/.next/server/chunks/{2563.js → 9164.js} +33389 -31418
  266. package/.next/standalone/.next/server/chunks/9237.js +396 -396
  267. package/.next/standalone/.next/server/chunks/{9640.js → 9304.js} +1672 -575
  268. package/.next/standalone/.next/server/chunks/9406.js +1 -1
  269. package/.next/standalone/.next/server/chunks/9590.js +68 -18
  270. package/.next/standalone/.next/server/chunks/9824.js +98 -98
  271. package/.next/standalone/.next/server/chunks/9826.js +1 -0
  272. package/.next/standalone/.next/server/middleware-build-manifest.js +2 -2
  273. package/.next/standalone/.next/server/middleware.js +486 -415
  274. package/.next/standalone/.next/server/pages/404.html +2 -2
  275. package/.next/standalone/.next/server/pages/500.html +1 -1
  276. package/.next/standalone/.next/server/preview-props.json +3 -3
  277. package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
  278. package/.next/standalone/.next/static/chunks/{1395-a340fb0a345382a4.js → 1395-e4a99912b8f83044.js} +13 -1
  279. package/.next/standalone/.next/static/chunks/app/_global-error/{page-36cb8b428b38b26a.js → page-6fc5f8e744c81802.js} +1 -1
  280. package/.next/standalone/.next/static/chunks/app/api/v1/access/[identity]/{route-36cb8b428b38b26a.js → route-6fc5f8e744c81802.js} +1 -1
  281. package/.next/standalone/.next/static/chunks/app/api/v1/access/{route-36cb8b428b38b26a.js → route-6fc5f8e744c81802.js} +1 -1
  282. package/.next/standalone/.next/static/chunks/app/api/v1/agents/[id]/compact/{route-36cb8b428b38b26a.js → route-6fc5f8e744c81802.js} +1 -1
  283. package/.next/standalone/.next/static/chunks/app/api/v1/agents/[id]/display-filters/route-6fc5f8e744c81802.js +17 -0
  284. package/.next/standalone/.next/static/chunks/app/api/v1/agents/[id]/route-6fc5f8e744c81802.js +17 -0
  285. package/.next/standalone/.next/static/chunks/app/api/v1/agents/[id]/thread/route-6fc5f8e744c81802.js +17 -0
  286. package/.next/standalone/.next/static/chunks/app/api/v1/agents/route-6fc5f8e744c81802.js +17 -0
  287. package/.next/standalone/.next/static/chunks/app/api/v1/allowed-sites/[hostname]/route-6fc5f8e744c81802.js +17 -0
  288. package/.next/standalone/.next/static/chunks/app/api/v1/allowed-sites/route-6fc5f8e744c81802.js +17 -0
  289. package/.next/standalone/.next/static/chunks/app/api/v1/artifacts/lifecycle/route-6fc5f8e744c81802.js +17 -0
  290. package/.next/standalone/.next/static/chunks/app/api/v1/attachments/files/route-6fc5f8e744c81802.js +17 -0
  291. package/.next/standalone/.next/static/chunks/app/api/v1/attachments/images/route-6fc5f8e744c81802.js +17 -0
  292. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/chats/route-6fc5f8e744c81802.js +17 -0
  293. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/ignores/[remote_jid]/route-6fc5f8e744c81802.js +17 -0
  294. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/ignores/route-6fc5f8e744c81802.js +17 -0
  295. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/lookup/route-6fc5f8e744c81802.js +17 -0
  296. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/pair/route-6fc5f8e744c81802.js +17 -0
  297. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/route-6fc5f8e744c81802.js +17 -0
  298. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/routes/[route_id]/route-6fc5f8e744c81802.js +17 -0
  299. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/routes/route-6fc5f8e744c81802.js +17 -0
  300. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/status/route-6fc5f8e744c81802.js +17 -0
  301. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/kinds/route-6fc5f8e744c81802.js +17 -0
  302. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/route-6fc5f8e744c81802.js +17 -0
  303. package/.next/standalone/.next/static/chunks/app/api/v1/builtin-tools/route-6fc5f8e744c81802.js +17 -0
  304. package/.next/standalone/.next/static/chunks/app/api/v1/config/route-6fc5f8e744c81802.js +17 -0
  305. package/.next/standalone/.next/static/chunks/app/api/v1/credentials/[id]/route-6fc5f8e744c81802.js +17 -0
  306. package/.next/standalone/.next/static/chunks/app/api/v1/credentials/route-6fc5f8e744c81802.js +17 -0
  307. package/.next/standalone/.next/static/chunks/app/api/v1/dashboard/currency/route-6fc5f8e744c81802.js +17 -0
  308. package/.next/standalone/.next/static/chunks/app/api/v1/dashboard/metrics/route-6fc5f8e744c81802.js +17 -0
  309. package/.next/standalone/.next/static/chunks/app/api/v1/dashboard/pricing/route-6fc5f8e744c81802.js +17 -0
  310. package/.next/standalone/.next/static/chunks/app/api/v1/dashboard/pricing-task/route-6fc5f8e744c81802.js +17 -0
  311. package/.next/standalone/.next/static/chunks/app/api/v1/delegations/codex/[job_id]/route-6fc5f8e744c81802.js +17 -0
  312. package/.next/standalone/.next/static/chunks/app/api/v1/documents/search/route-6fc5f8e744c81802.js +17 -0
  313. package/.next/standalone/.next/static/chunks/app/api/v1/documents/settings/route-6fc5f8e744c81802.js +17 -0
  314. package/.next/standalone/.next/static/chunks/app/api/v1/documents/sources/[id]/reindex/route-6fc5f8e744c81802.js +17 -0
  315. package/.next/standalone/.next/static/chunks/app/api/v1/documents/sources/[id]/route-6fc5f8e744c81802.js +17 -0
  316. package/.next/standalone/.next/static/chunks/app/api/v1/documents/sources/route-6fc5f8e744c81802.js +17 -0
  317. package/.next/standalone/.next/static/chunks/app/api/v1/env/route-6fc5f8e744c81802.js +17 -0
  318. package/.next/standalone/.next/static/chunks/app/api/v1/env-sync/allowlist/route-6fc5f8e744c81802.js +17 -0
  319. package/.next/standalone/.next/static/chunks/app/api/v1/env-sync/route-6fc5f8e744c81802.js +17 -0
  320. package/.next/standalone/.next/static/chunks/app/api/v1/events/route-6fc5f8e744c81802.js +17 -0
  321. package/.next/standalone/.next/static/chunks/app/api/v1/events/test/route-6fc5f8e744c81802.js +17 -0
  322. package/.next/standalone/.next/static/chunks/app/api/v1/extension/agents/route-6fc5f8e744c81802.js +17 -0
  323. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/activate/route-6fc5f8e744c81802.js +17 -0
  324. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/foreground/route-6fc5f8e744c81802.js +17 -0
  325. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/history/route-6fc5f8e744c81802.js +17 -0
  326. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/poll/route-6fc5f8e744c81802.js +17 -0
  327. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/progress/route-6fc5f8e744c81802.js +17 -0
  328. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/result/route-6fc5f8e744c81802.js +17 -0
  329. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/retry/route-6fc5f8e744c81802.js +17 -0
  330. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/status/route-6fc5f8e744c81802.js +17 -0
  331. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/tabs/route-6fc5f8e744c81802.js +17 -0
  332. package/.next/standalone/.next/static/chunks/app/api/v1/extension/fill/route-6fc5f8e744c81802.js +17 -0
  333. package/.next/standalone/.next/static/chunks/app/api/v1/extension/refine/route-6fc5f8e744c81802.js +17 -0
  334. package/.next/standalone/.next/static/chunks/app/api/v1/extension/turn/route-6fc5f8e744c81802.js +17 -0
  335. package/.next/standalone/.next/static/chunks/app/api/v1/extensions/route-6fc5f8e744c81802.js +17 -0
  336. package/.next/standalone/.next/static/chunks/app/api/v1/extensions/tools/[name]/config/route-6fc5f8e744c81802.js +17 -0
  337. package/.next/standalone/.next/static/chunks/app/api/v1/extensions/tools/[name]/route-6fc5f8e744c81802.js +17 -0
  338. package/.next/standalone/.next/static/chunks/app/api/v1/extensions/tools/[name]/secrets/route-6fc5f8e744c81802.js +17 -0
  339. package/.next/standalone/.next/static/chunks/app/api/v1/files/[name]/route-6fc5f8e744c81802.js +17 -0
  340. package/.next/standalone/.next/static/chunks/app/api/v1/fs/browse/route-6fc5f8e744c81802.js +17 -0
  341. package/.next/standalone/.next/static/chunks/app/api/v1/harnesses/[id]/route-6fc5f8e744c81802.js +17 -0
  342. package/.next/standalone/.next/static/chunks/app/api/v1/harnesses/default/route-6fc5f8e744c81802.js +17 -0
  343. package/.next/standalone/.next/static/chunks/app/api/v1/harnesses/route-6fc5f8e744c81802.js +17 -0
  344. package/.next/standalone/.next/static/chunks/app/api/v1/health/probes/route-6fc5f8e744c81802.js +17 -0
  345. package/.next/standalone/.next/static/chunks/app/api/v1/health/route-6fc5f8e744c81802.js +17 -0
  346. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/[name]/route-6fc5f8e744c81802.js +17 -0
  347. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/[name]/test/route-6fc5f8e744c81802.js +17 -0
  348. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/gmail/oauth/callback/route-6fc5f8e744c81802.js +17 -0
  349. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/gmail/oauth/start/route-6fc5f8e744c81802.js +17 -0
  350. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/gmail/oauth/status/route-6fc5f8e744c81802.js +17 -0
  351. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/outlook/oauth/callback/route-6fc5f8e744c81802.js +17 -0
  352. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/outlook/oauth/start/route-6fc5f8e744c81802.js +17 -0
  353. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/outlook/oauth/status/route-6fc5f8e744c81802.js +17 -0
  354. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/route-6fc5f8e744c81802.js +17 -0
  355. package/.next/standalone/.next/static/chunks/app/api/v1/lifecycle/adoption/route-6fc5f8e744c81802.js +17 -0
  356. package/.next/standalone/.next/static/chunks/app/api/v1/local-file/route-6fc5f8e744c81802.js +17 -0
  357. package/.next/standalone/.next/static/chunks/app/api/v1/logs/route-6fc5f8e744c81802.js +17 -0
  358. package/.next/standalone/.next/static/chunks/app/api/v1/maps/embed/route-6fc5f8e744c81802.js +17 -0
  359. package/.next/standalone/.next/static/chunks/app/api/v1/mcp-servers/[name]/route-6fc5f8e744c81802.js +17 -0
  360. package/.next/standalone/.next/static/chunks/app/api/v1/mcp-servers/registry/route-6fc5f8e744c81802.js +17 -0
  361. package/.next/standalone/.next/static/chunks/app/api/v1/mcp-servers/route-6fc5f8e744c81802.js +17 -0
  362. package/.next/standalone/.next/static/chunks/app/api/v1/memory/[namespace]/[key]/route-6fc5f8e744c81802.js +17 -0
  363. package/.next/standalone/.next/static/chunks/app/api/v1/memory/policy/route-6fc5f8e744c81802.js +17 -0
  364. package/.next/standalone/.next/static/chunks/app/api/v1/memory/route-6fc5f8e744c81802.js +17 -0
  365. package/.next/standalone/.next/static/chunks/app/api/v1/memory/search/route-6fc5f8e744c81802.js +17 -0
  366. package/.next/standalone/.next/static/chunks/app/api/v1/models/[name]/compact-threads/route-6fc5f8e744c81802.js +17 -0
  367. package/.next/standalone/.next/static/chunks/app/api/v1/models/[name]/route-6fc5f8e744c81802.js +17 -0
  368. package/.next/standalone/.next/static/chunks/app/api/v1/models/route-6fc5f8e744c81802.js +17 -0
  369. package/.next/standalone/.next/static/chunks/app/api/v1/packages/catalog/route-6fc5f8e744c81802.js +17 -0
  370. package/.next/standalone/.next/static/chunks/app/api/v1/packages/defaults/[id]/route-6fc5f8e744c81802.js +17 -0
  371. package/.next/standalone/.next/static/chunks/app/api/v1/packages/install/[id]/route-6fc5f8e744c81802.js +17 -0
  372. package/.next/standalone/.next/static/chunks/app/api/v1/packages/install/route-6fc5f8e744c81802.js +17 -0
  373. package/.next/standalone/.next/static/chunks/app/api/v1/packages/manifests/[name]/enabled/route-6fc5f8e744c81802.js +17 -0
  374. package/.next/standalone/.next/static/chunks/app/api/v1/packages/manifests/[name]/route-6fc5f8e744c81802.js +17 -0
  375. package/.next/standalone/.next/static/chunks/app/api/v1/packages/manifests/route-6fc5f8e744c81802.js +17 -0
  376. package/.next/standalone/.next/static/chunks/app/api/v1/packages/reload/route-6fc5f8e744c81802.js +17 -0
  377. package/.next/standalone/.next/static/chunks/app/api/v1/packages/route-6fc5f8e744c81802.js +17 -0
  378. package/.next/standalone/.next/static/chunks/app/api/v1/page-capture/route-6fc5f8e744c81802.js +17 -0
  379. package/.next/standalone/.next/static/chunks/app/api/v1/pending-actions/[id]/approve/route-6fc5f8e744c81802.js +17 -0
  380. package/.next/standalone/.next/static/chunks/app/api/v1/pending-actions/[id]/deny/route-6fc5f8e744c81802.js +17 -0
  381. package/.next/standalone/.next/static/chunks/app/api/v1/pending-actions/route-6fc5f8e744c81802.js +17 -0
  382. package/.next/standalone/.next/static/chunks/app/api/v1/profile/location/route-6fc5f8e744c81802.js +17 -0
  383. package/.next/standalone/.next/static/chunks/app/api/v1/profile/route-6fc5f8e744c81802.js +17 -0
  384. package/.next/standalone/.next/static/chunks/app/api/v1/providers/[provider]/models/route-6fc5f8e744c81802.js +17 -0
  385. package/.next/standalone/.next/static/chunks/app/api/v1/providers/[provider]/probe/route-6fc5f8e744c81802.js +17 -0
  386. package/.next/standalone/.next/static/chunks/app/api/v1/providers/github-copilot/auth/route-6fc5f8e744c81802.js +17 -0
  387. package/.next/standalone/.next/static/chunks/app/api/v1/providers/route-6fc5f8e744c81802.js +17 -0
  388. package/.next/standalone/.next/static/chunks/app/api/v1/proxy-config/route-6fc5f8e744c81802.js +17 -0
  389. package/.next/standalone/.next/static/chunks/app/api/v1/redaction/init/route-6fc5f8e744c81802.js +17 -0
  390. package/.next/standalone/.next/static/chunks/app/api/v1/redaction/route-6fc5f8e744c81802.js +17 -0
  391. package/.next/standalone/.next/static/chunks/app/api/v1/scheduled-tasks/[id]/route-6fc5f8e744c81802.js +17 -0
  392. package/.next/standalone/.next/static/chunks/app/api/v1/scheduled-tasks/[id]/run/route-6fc5f8e744c81802.js +17 -0
  393. package/.next/standalone/.next/static/chunks/app/api/v1/scheduled-tasks/route-6fc5f8e744c81802.js +17 -0
  394. package/.next/standalone/.next/static/chunks/app/api/v1/security/idle-timeout/route-6fc5f8e744c81802.js +17 -0
  395. package/.next/standalone/.next/static/chunks/app/api/v1/security/pin/route-6fc5f8e744c81802.js +17 -0
  396. package/.next/standalone/.next/static/chunks/app/api/v1/security/state/route-6fc5f8e744c81802.js +17 -0
  397. package/.next/standalone/.next/static/chunks/app/api/v1/security/unlock/route-6fc5f8e744c81802.js +17 -0
  398. package/.next/standalone/.next/static/chunks/app/api/v1/security/verify-pin/route-6fc5f8e744c81802.js +17 -0
  399. package/.next/standalone/.next/static/chunks/app/api/v1/setup/test-key/route-6fc5f8e744c81802.js +17 -0
  400. package/.next/standalone/.next/static/chunks/app/api/v1/skills/[id]/route-6fc5f8e744c81802.js +17 -0
  401. package/.next/standalone/.next/static/chunks/app/api/v1/skills/repos/[id]/route-6fc5f8e744c81802.js +17 -0
  402. package/.next/standalone/.next/static/chunks/app/api/v1/skills/repos/route-6fc5f8e744c81802.js +17 -0
  403. package/.next/standalone/.next/static/chunks/app/api/v1/skills/route-6fc5f8e744c81802.js +17 -0
  404. package/.next/standalone/.next/static/chunks/app/api/v1/system/abort/route-6fc5f8e744c81802.js +17 -0
  405. package/.next/standalone/.next/static/chunks/app/api/v1/system/restart/route-6fc5f8e744c81802.js +17 -0
  406. package/.next/standalone/.next/static/chunks/app/api/v1/tailscale/route-6fc5f8e744c81802.js +17 -0
  407. package/.next/standalone/.next/static/chunks/app/api/v1/tasks/[agent_id]/route-6fc5f8e744c81802.js +17 -0
  408. package/.next/standalone/.next/static/chunks/app/api/v1/tasks/route-6fc5f8e744c81802.js +17 -0
  409. package/.next/standalone/.next/static/chunks/app/api/v1/threads/[thread_id]/activity/route-6fc5f8e744c81802.js +17 -0
  410. package/.next/standalone/.next/static/chunks/app/api/v1/threads/[thread_id]/context-pin/route-6fc5f8e744c81802.js +17 -0
  411. package/.next/standalone/.next/static/chunks/app/api/v1/threads/[thread_id]/route-6fc5f8e744c81802.js +17 -0
  412. package/.next/standalone/.next/static/chunks/app/api/v1/threads/[thread_id]/run/route-6fc5f8e744c81802.js +17 -0
  413. package/.next/standalone/.next/static/chunks/app/api/v1/threads/route-6fc5f8e744c81802.js +17 -0
  414. package/.next/standalone/.next/static/chunks/app/api/v1/tools/route-6fc5f8e744c81802.js +17 -0
  415. package/.next/standalone/.next/static/chunks/app/api/v1/update/apply/route-6fc5f8e744c81802.js +17 -0
  416. package/.next/standalone/.next/static/chunks/app/api/v1/update/route-6fc5f8e744c81802.js +17 -0
  417. package/.next/standalone/.next/static/chunks/app/api/v1/voice/transcribe/route-6fc5f8e744c81802.js +17 -0
  418. package/.next/standalone/.next/static/chunks/app/api/v1/voice/tts/route-6fc5f8e744c81802.js +17 -0
  419. package/.next/standalone/.next/static/chunks/app/api/v1/watchers/[id]/route-6fc5f8e744c81802.js +17 -0
  420. package/.next/standalone/.next/static/chunks/app/api/v1/watchers/[id]/run/route-6fc5f8e744c81802.js +17 -0
  421. package/.next/standalone/.next/static/chunks/app/api/v1/watchers/reaction-scripts/route-6fc5f8e744c81802.js +17 -0
  422. package/.next/standalone/.next/static/chunks/app/api/v1/watchers/route-6fc5f8e744c81802.js +17 -0
  423. package/.next/standalone/.next/static/chunks/app/manifest.webmanifest/route-6fc5f8e744c81802.js +17 -0
  424. package/.next/standalone/.next/static/chunks/app/{page-7017f07f8a7a083c.js → page-04748847c6ff866f.js} +1013 -585
  425. package/.next/standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-6fc5f8e744c81802.js +17 -0
  426. package/.next/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-6fc5f8e744c81802.js +17 -0
  427. package/.next/standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-6fc5f8e744c81802.js +17 -0
  428. package/.next/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-6fc5f8e744c81802.js +17 -0
  429. package/.next/standalone/.next/static/css/{d80058f0b9b41c09.css → 2669e8744cc8c212.css} +2 -2
  430. package/.next/standalone/docs/adoption/changesets.json +358 -0
  431. package/.next/standalone/lib/skills/builtins/memory-organization/SKILL.md +16 -0
  432. package/.next/standalone/package.json +3 -3
  433. package/CHANGELOG.md +44 -0
  434. package/api/client.ts +9 -0
  435. package/api/types.ts +29 -0
  436. package/app/api/v1/lifecycle/adoption/route.ts +14 -2
  437. package/app/api/v1/models/[name]/compact-threads/route.ts +14 -11
  438. package/app/api/v1/threads/[thread_id]/activity/route.ts +19 -0
  439. package/app/api/v1/threads/[thread_id]/context-pin/route.test.ts +1 -0
  440. package/app/api/v1/threads/[thread_id]/context-pin/route.ts +2 -1
  441. package/app/api/v1/threads/[thread_id]/route.ts +5 -1
  442. package/app/api/v1/threads/[thread_id]/run/route.ts +0 -1
  443. package/components/chat/ChatView.tsx +52 -11
  444. package/components/chat/ContextBoundary.test.tsx +68 -1
  445. package/components/chat/ContextBoundary.tsx +92 -13
  446. package/components/chat/MessageBubble.tsx +12 -0
  447. package/components/chat/MessageList.test.tsx +31 -0
  448. package/components/chat/MessageList.tsx +49 -28
  449. package/components/chat/ToolList.test.tsx +92 -16
  450. package/components/chat/ToolList.tsx +59 -4
  451. package/components/chat/chat-helpers.test.tsx +24 -1
  452. package/components/chat/chat-helpers.ts +47 -4
  453. package/components/chat/useThreadActivity.test.tsx +113 -0
  454. package/components/chat/useThreadActivity.ts +94 -0
  455. package/components/chat/useThreadData.ts +16 -16
  456. package/components/chat/workflow-step-retry.ts +25 -0
  457. package/components/integrations/NetworkSection.tsx +2 -2
  458. package/components/ui/BootScreen.tsx +17 -0
  459. package/components/ui/WorkflowChecklist.tsx +71 -33
  460. package/hooks/useSSE.ts +28 -3
  461. package/lib/agents/citation-checker.test.ts +40 -2
  462. package/lib/agents/citation-checker.ts +56 -11
  463. package/lib/agents/compaction-pipeline.test.ts +202 -0
  464. package/lib/agents/compaction-pipeline.ts +483 -0
  465. package/lib/agents/context-boundary.ts +5 -6
  466. package/lib/agents/conversation-summary.ts +37 -21
  467. package/lib/agents/instruction-edits.test.ts +120 -0
  468. package/lib/agents/instruction-edits.ts +65 -42
  469. package/lib/agents/prepare/history-window.test.ts +18 -0
  470. package/lib/agents/prepare/history-window.ts +11 -2
  471. package/lib/agents/prepare/request.ts +4 -2
  472. package/lib/agents/prepare/system-prompt.test.ts +49 -0
  473. package/lib/agents/prepare/system-prompt.ts +16 -5
  474. package/lib/agents/prompt-registry.test.ts +5 -140
  475. package/lib/agents/prompt-registry.ts +45 -1
  476. package/lib/agents/prompt-variants.ts +146 -0
  477. package/lib/agents/proposals.test.ts +76 -0
  478. package/lib/agents/proposals.ts +13 -5
  479. package/lib/agents/run-registry.test.ts +22 -0
  480. package/lib/agents/run-registry.ts +29 -0
  481. package/lib/agents/run-thread.auto-boundary.test.ts +125 -5
  482. package/lib/agents/run-thread.retry.test.ts +67 -1
  483. package/lib/agents/run-thread.ts +110 -10
  484. package/lib/agents/sqlite-checkpoint-saver.test.ts +91 -0
  485. package/lib/agents/thread-activity.test.ts +31 -0
  486. package/lib/agents/thread-activity.ts +27 -0
  487. package/lib/agents/thread-compaction-state.test.ts +82 -0
  488. package/lib/agents/thread-compaction-state.ts +121 -0
  489. package/lib/agents/thread-compaction.test.ts +83 -4
  490. package/lib/agents/thread-compaction.ts +34 -11
  491. package/lib/agents/warm-summary-background.test.ts +219 -5
  492. package/lib/agents/warm-summary-background.ts +346 -143
  493. package/lib/agents/warm-topics.test.ts +191 -0
  494. package/lib/agents/warm-topics.ts +317 -0
  495. package/lib/agents/workflow-step-retry.test.ts +96 -0
  496. package/lib/agents/workflow-step-retry.ts +216 -0
  497. package/lib/api/browser-control.ts +0 -3
  498. package/lib/bridges/dispatcher.ts +1 -0
  499. package/lib/bridges/message-role.test.ts +81 -0
  500. package/lib/bridges/message-role.ts +23 -10
  501. package/lib/bridges/types.ts +6 -0
  502. package/lib/bridges/whatsapp-link.test.ts +32 -0
  503. package/lib/bridges/whatsapp-link.ts +21 -0
  504. package/lib/bridges/whatsapp.inbound.test.ts +239 -0
  505. package/lib/bridges/whatsapp.sender.test.ts +80 -1
  506. package/lib/bridges/whatsapp.ts +76 -38
  507. package/lib/db/migrations.ts +5 -0
  508. package/lib/env/config.ts +2 -0
  509. package/lib/env/schema.ts +12 -0
  510. package/lib/lifecycle/changeset-build.test.ts +93 -0
  511. package/lib/lifecycle/changeset-build.ts +210 -0
  512. package/lib/lifecycle/changesets.test.ts +101 -0
  513. package/lib/lifecycle/changesets.ts +166 -0
  514. package/lib/lifecycle/surface-collect.test.ts +88 -0
  515. package/lib/lifecycle/surface-collect.ts +64 -0
  516. package/lib/lifecycle/surface-snapshot.test.ts +104 -0
  517. package/lib/lifecycle/surface-snapshot.ts +210 -0
  518. package/lib/memory/record.ts +0 -2
  519. package/lib/pricing/snapshot.test.ts +70 -0
  520. package/lib/pricing/snapshot.ts +10 -2
  521. package/lib/providers/external.ts +0 -2
  522. package/lib/proxy/dispatcher.test.ts +119 -1
  523. package/lib/proxy/dispatcher.ts +22 -9
  524. package/lib/skills/builtins/memory-organization/SKILL.md +16 -0
  525. package/lib/stores/agent-configs.ts +10 -5
  526. package/lib/stores/bridges.test.ts +81 -0
  527. package/lib/stores/bridges.ts +9 -8
  528. package/lib/stores/proxy-config.test.ts +120 -0
  529. package/lib/stores/proxy-config.ts +22 -4
  530. package/lib/stores/threads.test.ts +9 -0
  531. package/lib/stores/threads.ts +33 -19
  532. package/lib/stores/version-adoption.test.ts +96 -0
  533. package/lib/stores/version-adoption.ts +239 -26
  534. package/lib/stores/workflow-progress.ts +3 -0
  535. package/lib/tools/communications/calendar.test.ts +43 -2
  536. package/lib/tools/communications/calendar.ts +2 -0
  537. package/lib/tools/communications/gmail.test.ts +51 -1
  538. package/lib/tools/communications/gmail.ts +44 -2
  539. package/lib/tools/communications/ms-todo.ts +0 -7
  540. package/lib/tools/communications/outlook-calendar.ts +2 -0
  541. package/lib/tools/communications/outlook.test.ts +33 -2
  542. package/lib/tools/communications/outlook.ts +2 -0
  543. package/lib/tools/filesystem/edit-match.test.ts +133 -0
  544. package/lib/tools/filesystem/edit-match.ts +7 -2
  545. package/lib/tools/general/memory.ts +1 -1
  546. package/lib/tools/general/workflow-progress.ts +2 -0
  547. package/lib/tools/runtime/catalog.ts +1 -25
  548. package/lib/tools/support/result-refs.test.ts +131 -0
  549. package/lib/tools/support/result-refs.ts +41 -9
  550. package/lib/triggers/registry.ts +0 -4
  551. package/lib/utils/source-link.test.ts +51 -0
  552. package/lib/utils/source-link.ts +45 -0
  553. package/package.json +3 -3
  554. package/scripts/install-to-system.ps1 +39 -11
  555. package/scripts/install-to-system.sh +37 -3
  556. package/.next/standalone/.next/server/chunks/3979.js +0 -581
  557. package/.next/standalone/.next/server/chunks/5936.js +0 -594
  558. package/.next/standalone/.next/static/chunks/app/api/v1/agents/[id]/display-filters/route-36cb8b428b38b26a.js +0 -17
  559. package/.next/standalone/.next/static/chunks/app/api/v1/agents/[id]/route-36cb8b428b38b26a.js +0 -17
  560. package/.next/standalone/.next/static/chunks/app/api/v1/agents/[id]/thread/route-36cb8b428b38b26a.js +0 -17
  561. package/.next/standalone/.next/static/chunks/app/api/v1/agents/route-36cb8b428b38b26a.js +0 -17
  562. package/.next/standalone/.next/static/chunks/app/api/v1/allowed-sites/[hostname]/route-36cb8b428b38b26a.js +0 -17
  563. package/.next/standalone/.next/static/chunks/app/api/v1/allowed-sites/route-36cb8b428b38b26a.js +0 -17
  564. package/.next/standalone/.next/static/chunks/app/api/v1/artifacts/lifecycle/route-36cb8b428b38b26a.js +0 -17
  565. package/.next/standalone/.next/static/chunks/app/api/v1/attachments/files/route-36cb8b428b38b26a.js +0 -17
  566. package/.next/standalone/.next/static/chunks/app/api/v1/attachments/images/route-36cb8b428b38b26a.js +0 -17
  567. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/chats/route-36cb8b428b38b26a.js +0 -17
  568. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/ignores/[remote_jid]/route-36cb8b428b38b26a.js +0 -17
  569. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/ignores/route-36cb8b428b38b26a.js +0 -17
  570. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/lookup/route-36cb8b428b38b26a.js +0 -17
  571. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/pair/route-36cb8b428b38b26a.js +0 -17
  572. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/route-36cb8b428b38b26a.js +0 -17
  573. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/routes/[route_id]/route-36cb8b428b38b26a.js +0 -17
  574. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/routes/route-36cb8b428b38b26a.js +0 -17
  575. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/status/route-36cb8b428b38b26a.js +0 -17
  576. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/kinds/route-36cb8b428b38b26a.js +0 -17
  577. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/route-36cb8b428b38b26a.js +0 -17
  578. package/.next/standalone/.next/static/chunks/app/api/v1/builtin-tools/route-36cb8b428b38b26a.js +0 -17
  579. package/.next/standalone/.next/static/chunks/app/api/v1/config/route-36cb8b428b38b26a.js +0 -17
  580. package/.next/standalone/.next/static/chunks/app/api/v1/credentials/[id]/route-36cb8b428b38b26a.js +0 -17
  581. package/.next/standalone/.next/static/chunks/app/api/v1/credentials/route-36cb8b428b38b26a.js +0 -17
  582. package/.next/standalone/.next/static/chunks/app/api/v1/dashboard/currency/route-36cb8b428b38b26a.js +0 -17
  583. package/.next/standalone/.next/static/chunks/app/api/v1/dashboard/metrics/route-36cb8b428b38b26a.js +0 -17
  584. package/.next/standalone/.next/static/chunks/app/api/v1/dashboard/pricing/route-36cb8b428b38b26a.js +0 -17
  585. package/.next/standalone/.next/static/chunks/app/api/v1/dashboard/pricing-task/route-36cb8b428b38b26a.js +0 -17
  586. package/.next/standalone/.next/static/chunks/app/api/v1/delegations/codex/[job_id]/route-36cb8b428b38b26a.js +0 -17
  587. package/.next/standalone/.next/static/chunks/app/api/v1/documents/search/route-36cb8b428b38b26a.js +0 -17
  588. package/.next/standalone/.next/static/chunks/app/api/v1/documents/settings/route-36cb8b428b38b26a.js +0 -17
  589. package/.next/standalone/.next/static/chunks/app/api/v1/documents/sources/[id]/reindex/route-36cb8b428b38b26a.js +0 -17
  590. package/.next/standalone/.next/static/chunks/app/api/v1/documents/sources/[id]/route-36cb8b428b38b26a.js +0 -17
  591. package/.next/standalone/.next/static/chunks/app/api/v1/documents/sources/route-36cb8b428b38b26a.js +0 -17
  592. package/.next/standalone/.next/static/chunks/app/api/v1/env/route-36cb8b428b38b26a.js +0 -17
  593. package/.next/standalone/.next/static/chunks/app/api/v1/env-sync/allowlist/route-36cb8b428b38b26a.js +0 -17
  594. package/.next/standalone/.next/static/chunks/app/api/v1/env-sync/route-36cb8b428b38b26a.js +0 -17
  595. package/.next/standalone/.next/static/chunks/app/api/v1/events/route-36cb8b428b38b26a.js +0 -17
  596. package/.next/standalone/.next/static/chunks/app/api/v1/events/test/route-36cb8b428b38b26a.js +0 -17
  597. package/.next/standalone/.next/static/chunks/app/api/v1/extension/agents/route-36cb8b428b38b26a.js +0 -17
  598. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/activate/route-36cb8b428b38b26a.js +0 -17
  599. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/foreground/route-36cb8b428b38b26a.js +0 -17
  600. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/history/route-36cb8b428b38b26a.js +0 -17
  601. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/poll/route-36cb8b428b38b26a.js +0 -17
  602. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/progress/route-36cb8b428b38b26a.js +0 -17
  603. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/result/route-36cb8b428b38b26a.js +0 -17
  604. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/retry/route-36cb8b428b38b26a.js +0 -17
  605. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/status/route-36cb8b428b38b26a.js +0 -17
  606. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/tabs/route-36cb8b428b38b26a.js +0 -17
  607. package/.next/standalone/.next/static/chunks/app/api/v1/extension/fill/route-36cb8b428b38b26a.js +0 -17
  608. package/.next/standalone/.next/static/chunks/app/api/v1/extension/refine/route-36cb8b428b38b26a.js +0 -17
  609. package/.next/standalone/.next/static/chunks/app/api/v1/extension/turn/route-36cb8b428b38b26a.js +0 -17
  610. package/.next/standalone/.next/static/chunks/app/api/v1/extensions/route-36cb8b428b38b26a.js +0 -17
  611. package/.next/standalone/.next/static/chunks/app/api/v1/extensions/tools/[name]/config/route-36cb8b428b38b26a.js +0 -17
  612. package/.next/standalone/.next/static/chunks/app/api/v1/extensions/tools/[name]/route-36cb8b428b38b26a.js +0 -17
  613. package/.next/standalone/.next/static/chunks/app/api/v1/extensions/tools/[name]/secrets/route-36cb8b428b38b26a.js +0 -17
  614. package/.next/standalone/.next/static/chunks/app/api/v1/files/[name]/route-36cb8b428b38b26a.js +0 -17
  615. package/.next/standalone/.next/static/chunks/app/api/v1/fs/browse/route-36cb8b428b38b26a.js +0 -17
  616. package/.next/standalone/.next/static/chunks/app/api/v1/harnesses/[id]/route-36cb8b428b38b26a.js +0 -17
  617. package/.next/standalone/.next/static/chunks/app/api/v1/harnesses/default/route-36cb8b428b38b26a.js +0 -17
  618. package/.next/standalone/.next/static/chunks/app/api/v1/harnesses/route-36cb8b428b38b26a.js +0 -17
  619. package/.next/standalone/.next/static/chunks/app/api/v1/health/probes/route-36cb8b428b38b26a.js +0 -17
  620. package/.next/standalone/.next/static/chunks/app/api/v1/health/route-36cb8b428b38b26a.js +0 -17
  621. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/[name]/route-36cb8b428b38b26a.js +0 -17
  622. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/[name]/test/route-36cb8b428b38b26a.js +0 -17
  623. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/gmail/oauth/callback/route-36cb8b428b38b26a.js +0 -17
  624. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/gmail/oauth/start/route-36cb8b428b38b26a.js +0 -17
  625. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/gmail/oauth/status/route-36cb8b428b38b26a.js +0 -17
  626. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/outlook/oauth/callback/route-36cb8b428b38b26a.js +0 -17
  627. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/outlook/oauth/start/route-36cb8b428b38b26a.js +0 -17
  628. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/outlook/oauth/status/route-36cb8b428b38b26a.js +0 -17
  629. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/route-36cb8b428b38b26a.js +0 -17
  630. package/.next/standalone/.next/static/chunks/app/api/v1/lifecycle/adoption/route-36cb8b428b38b26a.js +0 -17
  631. package/.next/standalone/.next/static/chunks/app/api/v1/local-file/route-36cb8b428b38b26a.js +0 -17
  632. package/.next/standalone/.next/static/chunks/app/api/v1/logs/route-36cb8b428b38b26a.js +0 -17
  633. package/.next/standalone/.next/static/chunks/app/api/v1/maps/embed/route-36cb8b428b38b26a.js +0 -17
  634. package/.next/standalone/.next/static/chunks/app/api/v1/mcp-servers/[name]/route-36cb8b428b38b26a.js +0 -17
  635. package/.next/standalone/.next/static/chunks/app/api/v1/mcp-servers/registry/route-36cb8b428b38b26a.js +0 -17
  636. package/.next/standalone/.next/static/chunks/app/api/v1/mcp-servers/route-36cb8b428b38b26a.js +0 -17
  637. package/.next/standalone/.next/static/chunks/app/api/v1/memory/[namespace]/[key]/route-36cb8b428b38b26a.js +0 -17
  638. package/.next/standalone/.next/static/chunks/app/api/v1/memory/policy/route-36cb8b428b38b26a.js +0 -17
  639. package/.next/standalone/.next/static/chunks/app/api/v1/memory/route-36cb8b428b38b26a.js +0 -17
  640. package/.next/standalone/.next/static/chunks/app/api/v1/memory/search/route-36cb8b428b38b26a.js +0 -17
  641. package/.next/standalone/.next/static/chunks/app/api/v1/models/[name]/compact-threads/route-36cb8b428b38b26a.js +0 -17
  642. package/.next/standalone/.next/static/chunks/app/api/v1/models/[name]/route-36cb8b428b38b26a.js +0 -17
  643. package/.next/standalone/.next/static/chunks/app/api/v1/models/route-36cb8b428b38b26a.js +0 -17
  644. package/.next/standalone/.next/static/chunks/app/api/v1/packages/catalog/route-36cb8b428b38b26a.js +0 -17
  645. package/.next/standalone/.next/static/chunks/app/api/v1/packages/defaults/[id]/route-36cb8b428b38b26a.js +0 -17
  646. package/.next/standalone/.next/static/chunks/app/api/v1/packages/install/[id]/route-36cb8b428b38b26a.js +0 -17
  647. package/.next/standalone/.next/static/chunks/app/api/v1/packages/install/route-36cb8b428b38b26a.js +0 -17
  648. package/.next/standalone/.next/static/chunks/app/api/v1/packages/manifests/[name]/enabled/route-36cb8b428b38b26a.js +0 -17
  649. package/.next/standalone/.next/static/chunks/app/api/v1/packages/manifests/[name]/route-36cb8b428b38b26a.js +0 -17
  650. package/.next/standalone/.next/static/chunks/app/api/v1/packages/manifests/route-36cb8b428b38b26a.js +0 -17
  651. package/.next/standalone/.next/static/chunks/app/api/v1/packages/reload/route-36cb8b428b38b26a.js +0 -17
  652. package/.next/standalone/.next/static/chunks/app/api/v1/packages/route-36cb8b428b38b26a.js +0 -17
  653. package/.next/standalone/.next/static/chunks/app/api/v1/page-capture/route-36cb8b428b38b26a.js +0 -17
  654. package/.next/standalone/.next/static/chunks/app/api/v1/pending-actions/[id]/approve/route-36cb8b428b38b26a.js +0 -17
  655. package/.next/standalone/.next/static/chunks/app/api/v1/pending-actions/[id]/deny/route-36cb8b428b38b26a.js +0 -17
  656. package/.next/standalone/.next/static/chunks/app/api/v1/pending-actions/route-36cb8b428b38b26a.js +0 -17
  657. package/.next/standalone/.next/static/chunks/app/api/v1/profile/location/route-36cb8b428b38b26a.js +0 -17
  658. package/.next/standalone/.next/static/chunks/app/api/v1/profile/route-36cb8b428b38b26a.js +0 -17
  659. package/.next/standalone/.next/static/chunks/app/api/v1/providers/[provider]/models/route-36cb8b428b38b26a.js +0 -17
  660. package/.next/standalone/.next/static/chunks/app/api/v1/providers/[provider]/probe/route-36cb8b428b38b26a.js +0 -17
  661. package/.next/standalone/.next/static/chunks/app/api/v1/providers/github-copilot/auth/route-36cb8b428b38b26a.js +0 -17
  662. package/.next/standalone/.next/static/chunks/app/api/v1/providers/route-36cb8b428b38b26a.js +0 -17
  663. package/.next/standalone/.next/static/chunks/app/api/v1/proxy-config/route-36cb8b428b38b26a.js +0 -17
  664. package/.next/standalone/.next/static/chunks/app/api/v1/redaction/init/route-36cb8b428b38b26a.js +0 -17
  665. package/.next/standalone/.next/static/chunks/app/api/v1/redaction/route-36cb8b428b38b26a.js +0 -17
  666. package/.next/standalone/.next/static/chunks/app/api/v1/scheduled-tasks/[id]/route-36cb8b428b38b26a.js +0 -17
  667. package/.next/standalone/.next/static/chunks/app/api/v1/scheduled-tasks/[id]/run/route-36cb8b428b38b26a.js +0 -17
  668. package/.next/standalone/.next/static/chunks/app/api/v1/scheduled-tasks/route-36cb8b428b38b26a.js +0 -17
  669. package/.next/standalone/.next/static/chunks/app/api/v1/security/idle-timeout/route-36cb8b428b38b26a.js +0 -17
  670. package/.next/standalone/.next/static/chunks/app/api/v1/security/pin/route-36cb8b428b38b26a.js +0 -17
  671. package/.next/standalone/.next/static/chunks/app/api/v1/security/state/route-36cb8b428b38b26a.js +0 -17
  672. package/.next/standalone/.next/static/chunks/app/api/v1/security/unlock/route-36cb8b428b38b26a.js +0 -17
  673. package/.next/standalone/.next/static/chunks/app/api/v1/security/verify-pin/route-36cb8b428b38b26a.js +0 -17
  674. package/.next/standalone/.next/static/chunks/app/api/v1/setup/test-key/route-36cb8b428b38b26a.js +0 -17
  675. package/.next/standalone/.next/static/chunks/app/api/v1/skills/[id]/route-36cb8b428b38b26a.js +0 -17
  676. package/.next/standalone/.next/static/chunks/app/api/v1/skills/repos/[id]/route-36cb8b428b38b26a.js +0 -17
  677. package/.next/standalone/.next/static/chunks/app/api/v1/skills/repos/route-36cb8b428b38b26a.js +0 -17
  678. package/.next/standalone/.next/static/chunks/app/api/v1/skills/route-36cb8b428b38b26a.js +0 -17
  679. package/.next/standalone/.next/static/chunks/app/api/v1/system/abort/route-36cb8b428b38b26a.js +0 -17
  680. package/.next/standalone/.next/static/chunks/app/api/v1/system/restart/route-36cb8b428b38b26a.js +0 -17
  681. package/.next/standalone/.next/static/chunks/app/api/v1/tailscale/route-36cb8b428b38b26a.js +0 -17
  682. package/.next/standalone/.next/static/chunks/app/api/v1/tasks/[agent_id]/route-36cb8b428b38b26a.js +0 -17
  683. package/.next/standalone/.next/static/chunks/app/api/v1/tasks/route-36cb8b428b38b26a.js +0 -17
  684. package/.next/standalone/.next/static/chunks/app/api/v1/threads/[thread_id]/context-pin/route-36cb8b428b38b26a.js +0 -17
  685. package/.next/standalone/.next/static/chunks/app/api/v1/threads/[thread_id]/route-36cb8b428b38b26a.js +0 -17
  686. package/.next/standalone/.next/static/chunks/app/api/v1/threads/[thread_id]/run/route-36cb8b428b38b26a.js +0 -17
  687. package/.next/standalone/.next/static/chunks/app/api/v1/threads/route-36cb8b428b38b26a.js +0 -17
  688. package/.next/standalone/.next/static/chunks/app/api/v1/tools/route-36cb8b428b38b26a.js +0 -17
  689. package/.next/standalone/.next/static/chunks/app/api/v1/update/apply/route-36cb8b428b38b26a.js +0 -17
  690. package/.next/standalone/.next/static/chunks/app/api/v1/update/route-36cb8b428b38b26a.js +0 -17
  691. package/.next/standalone/.next/static/chunks/app/api/v1/voice/transcribe/route-36cb8b428b38b26a.js +0 -17
  692. package/.next/standalone/.next/static/chunks/app/api/v1/voice/tts/route-36cb8b428b38b26a.js +0 -17
  693. package/.next/standalone/.next/static/chunks/app/api/v1/watchers/[id]/route-36cb8b428b38b26a.js +0 -17
  694. package/.next/standalone/.next/static/chunks/app/api/v1/watchers/[id]/run/route-36cb8b428b38b26a.js +0 -17
  695. package/.next/standalone/.next/static/chunks/app/api/v1/watchers/reaction-scripts/route-36cb8b428b38b26a.js +0 -17
  696. package/.next/standalone/.next/static/chunks/app/api/v1/watchers/route-36cb8b428b38b26a.js +0 -17
  697. package/.next/standalone/.next/static/chunks/app/manifest.webmanifest/route-36cb8b428b38b26a.js +0 -17
  698. package/.next/standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-36cb8b428b38b26a.js +0 -17
  699. package/.next/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-36cb8b428b38b26a.js +0 -17
  700. package/.next/standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-36cb8b428b38b26a.js +0 -17
  701. package/.next/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-36cb8b428b38b26a.js +0 -17
  702. /package/.next/standalone/.next/static/{NUrC9xax1sp1Q70nlFqS6 → hwujW4hR1b-r3k5WdMxZO}/_buildManifest.js +0 -0
  703. /package/.next/standalone/.next/static/{NUrC9xax1sp1Q70nlFqS6 → hwujW4hR1b-r3k5WdMxZO}/_ssgManifest.js +0 -0
@@ -230,85 +230,6 @@ if ((typeof exports.default === 'function' || typeof exports.default === 'object
230
230
  } //# sourceMappingURL=link.js.map
231
231
 
232
232
 
233
- /***/ }),
234
-
235
- /***/ 3067:
236
- /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
237
-
238
- "use strict";
239
- __webpack_require__.r(__webpack_exports__);
240
- /* harmony export */ __webpack_require__.d(__webpack_exports__, {
241
- /* harmony export */ __next_app__: () => (/* binding */ __next_app__),
242
- /* harmony export */ handler: () => (/* binding */ handler),
243
- /* harmony export */ routeModule: () => (/* binding */ routeModule)
244
- /* harmony export */ });
245
- /* harmony import */ var next_dist_server_app_render_module_loading_instrument_module_getter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(21635);
246
- /* harmony import */ var next_dist_build_templates_app_page_runtime__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(86315);
247
- /* harmony import */ var next_dist_server_app_render_interop_default__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(1020);
248
- /* harmony import */ var next_dist_server_app_render_entry_base__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(61287);
249
- /* harmony import */ var next_dist_server_app_render_entry_base__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(next_dist_server_app_render_entry_base__WEBPACK_IMPORTED_MODULE_3__);
250
- /* harmony reexport (unknown) */ var __WEBPACK_REEXPORT_OBJECT__ = {};
251
- /* harmony reexport (unknown) */ for(const __WEBPACK_IMPORT_KEY__ in next_dist_server_app_render_entry_base__WEBPACK_IMPORTED_MODULE_3__) if(["default","__next_app__","routeModule","handler"].indexOf(__WEBPACK_IMPORT_KEY__) < 0) __WEBPACK_REEXPORT_OBJECT__[__WEBPACK_IMPORT_KEY__] = () => next_dist_server_app_render_entry_base__WEBPACK_IMPORTED_MODULE_3__[__WEBPACK_IMPORT_KEY__]
252
- /* harmony reexport (unknown) */ __webpack_require__.d(__webpack_exports__, __WEBPACK_REEXPORT_OBJECT__);
253
-
254
- const module0 = (0,next_dist_server_app_render_module_loading_instrument_module_getter__WEBPACK_IMPORTED_MODULE_0__/* .instrumentModuleGetter */ .p)(() => Promise.resolve(/* import() eager */).then(__webpack_require__.bind(__webpack_require__, 32056)));
255
- const module1 = (0,next_dist_server_app_render_module_loading_instrument_module_getter__WEBPACK_IMPORTED_MODULE_0__/* .instrumentModuleGetter */ .p)(() => Promise.resolve(/* import() eager */).then(__webpack_require__.t.bind(__webpack_require__, 95547, 23)));
256
- const module2 = (0,next_dist_server_app_render_module_loading_instrument_module_getter__WEBPACK_IMPORTED_MODULE_0__/* .instrumentModuleGetter */ .p)(() => Promise.resolve(/* import() eager */).then(__webpack_require__.t.bind(__webpack_require__, 55091, 23)));
257
- const module3 = (0,next_dist_server_app_render_module_loading_instrument_module_getter__WEBPACK_IMPORTED_MODULE_0__/* .instrumentModuleGetter */ .p)(() => Promise.resolve(/* import() eager */).then(__webpack_require__.t.bind(__webpack_require__, 45270, 23)));
258
- const module4 = (0,next_dist_server_app_render_module_loading_instrument_module_getter__WEBPACK_IMPORTED_MODULE_0__/* .instrumentModuleGetter */ .p)(() => Promise.resolve(/* import() eager */).then(__webpack_require__.t.bind(__webpack_require__, 28193, 23)));
259
- const page5 = (0,next_dist_server_app_render_module_loading_instrument_module_getter__WEBPACK_IMPORTED_MODULE_0__/* .instrumentModuleGetter */ .p)(() => Promise.resolve(/* import() eager */).then(__webpack_require__.bind(__webpack_require__, 99647)));
260
-
261
-
262
- const tree = {
263
- children: [
264
- '',
265
- {
266
- children: ['__PAGE__', {}, {
267
- page: [page5, "/home/runner/work/jarela/jarela/app/page.tsx"],
268
- metadata: {
269
- icon: [(async (props) => (await (0,next_dist_server_app_render_module_loading_instrument_module_getter__WEBPACK_IMPORTED_MODULE_0__/* .instrumentModuleGetter */ .p)(() => Promise.resolve(/* import() eager */).then(__webpack_require__.bind(__webpack_require__, 86364)))()).default(props))],
270
- apple: [],
271
- openGraph: [],
272
- twitter: [],
273
- manifest: "/manifest.webmanifest"
274
- }
275
- }]
276
- },
277
- {
278
- 'layout': [module0, "/home/runner/work/jarela/jarela/app/layout.tsx"],
279
- 'global-error': [module1, "next/dist/client/components/builtin/global-error.js"],
280
- 'not-found': [module2, "next/dist/client/components/builtin/not-found.js"],
281
- 'forbidden': [module3, "next/dist/client/components/builtin/forbidden.js"],
282
- 'unauthorized': [module4, "next/dist/client/components/builtin/unauthorized.js"],
283
- metadata: {
284
- icon: [(async (props) => (await (0,next_dist_server_app_render_module_loading_instrument_module_getter__WEBPACK_IMPORTED_MODULE_0__/* .instrumentModuleGetter */ .p)(() => Promise.resolve(/* import() eager */).then(__webpack_require__.bind(__webpack_require__, 86364)))()).default(props))],
285
- apple: [],
286
- openGraph: [],
287
- twitter: [],
288
- manifest: "/manifest.webmanifest"
289
- }
290
- },
291
- []
292
- ]
293
- }.children;
294
- const __next_app_require__ = __webpack_require__
295
- const __next_app_load_chunk__ = () => Promise.resolve()
296
- const entrypoint = (0,next_dist_build_templates_app_page_runtime__WEBPACK_IMPORTED_MODULE_1__/* .createAppPageEntrypoint */ .H)({
297
- tree,
298
- page: "/page",
299
- pathname: "/",
300
- require: __next_app_require__,
301
- loadChunk: __next_app_load_chunk__,
302
- interopDefault: next_dist_server_app_render_interop_default__WEBPACK_IMPORTED_MODULE_2__/* .interopDefault */ .T
303
- });
304
- const __next_app__ = entrypoint.__next_app__;
305
- const routeModule = entrypoint.routeModule;
306
- const handler = entrypoint.handler;
307
-
308
-
309
- //# sourceMappingURL=app-page.js.map
310
-
311
-
312
233
  /***/ }),
313
234
 
314
235
  /***/ 3295:
@@ -2948,6 +2869,85 @@ module.exports = require("undici");
2948
2869
  "use strict";
2949
2870
  module.exports = require("next/dist/compiled/next-server/app-page.runtime.prod.js");
2950
2871
 
2872
+ /***/ }),
2873
+
2874
+ /***/ 13297:
2875
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2876
+
2877
+ "use strict";
2878
+ __webpack_require__.r(__webpack_exports__);
2879
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
2880
+ /* harmony export */ __next_app__: () => (/* binding */ __next_app__),
2881
+ /* harmony export */ handler: () => (/* binding */ handler),
2882
+ /* harmony export */ routeModule: () => (/* binding */ routeModule)
2883
+ /* harmony export */ });
2884
+ /* harmony import */ var next_dist_server_app_render_module_loading_instrument_module_getter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(21635);
2885
+ /* harmony import */ var next_dist_build_templates_app_page_runtime__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(86315);
2886
+ /* harmony import */ var next_dist_server_app_render_interop_default__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(1020);
2887
+ /* harmony import */ var next_dist_server_app_render_entry_base__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(61287);
2888
+ /* harmony import */ var next_dist_server_app_render_entry_base__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(next_dist_server_app_render_entry_base__WEBPACK_IMPORTED_MODULE_3__);
2889
+ /* harmony reexport (unknown) */ var __WEBPACK_REEXPORT_OBJECT__ = {};
2890
+ /* harmony reexport (unknown) */ for(const __WEBPACK_IMPORT_KEY__ in next_dist_server_app_render_entry_base__WEBPACK_IMPORTED_MODULE_3__) if(["default","__next_app__","routeModule","handler"].indexOf(__WEBPACK_IMPORT_KEY__) < 0) __WEBPACK_REEXPORT_OBJECT__[__WEBPACK_IMPORT_KEY__] = () => next_dist_server_app_render_entry_base__WEBPACK_IMPORTED_MODULE_3__[__WEBPACK_IMPORT_KEY__]
2891
+ /* harmony reexport (unknown) */ __webpack_require__.d(__webpack_exports__, __WEBPACK_REEXPORT_OBJECT__);
2892
+
2893
+ const module0 = (0,next_dist_server_app_render_module_loading_instrument_module_getter__WEBPACK_IMPORTED_MODULE_0__/* .instrumentModuleGetter */ .p)(() => Promise.resolve(/* import() eager */).then(__webpack_require__.bind(__webpack_require__, 32056)));
2894
+ const module1 = (0,next_dist_server_app_render_module_loading_instrument_module_getter__WEBPACK_IMPORTED_MODULE_0__/* .instrumentModuleGetter */ .p)(() => Promise.resolve(/* import() eager */).then(__webpack_require__.t.bind(__webpack_require__, 95547, 23)));
2895
+ const module2 = (0,next_dist_server_app_render_module_loading_instrument_module_getter__WEBPACK_IMPORTED_MODULE_0__/* .instrumentModuleGetter */ .p)(() => Promise.resolve(/* import() eager */).then(__webpack_require__.t.bind(__webpack_require__, 55091, 23)));
2896
+ const module3 = (0,next_dist_server_app_render_module_loading_instrument_module_getter__WEBPACK_IMPORTED_MODULE_0__/* .instrumentModuleGetter */ .p)(() => Promise.resolve(/* import() eager */).then(__webpack_require__.t.bind(__webpack_require__, 45270, 23)));
2897
+ const module4 = (0,next_dist_server_app_render_module_loading_instrument_module_getter__WEBPACK_IMPORTED_MODULE_0__/* .instrumentModuleGetter */ .p)(() => Promise.resolve(/* import() eager */).then(__webpack_require__.t.bind(__webpack_require__, 28193, 23)));
2898
+ const page5 = (0,next_dist_server_app_render_module_loading_instrument_module_getter__WEBPACK_IMPORTED_MODULE_0__/* .instrumentModuleGetter */ .p)(() => Promise.resolve(/* import() eager */).then(__webpack_require__.bind(__webpack_require__, 99647)));
2899
+
2900
+
2901
+ const tree = {
2902
+ children: [
2903
+ '',
2904
+ {
2905
+ children: ['__PAGE__', {}, {
2906
+ page: [page5, "/home/runner/work/jarela/jarela/app/page.tsx"],
2907
+ metadata: {
2908
+ icon: [(async (props) => (await (0,next_dist_server_app_render_module_loading_instrument_module_getter__WEBPACK_IMPORTED_MODULE_0__/* .instrumentModuleGetter */ .p)(() => Promise.resolve(/* import() eager */).then(__webpack_require__.bind(__webpack_require__, 86364)))()).default(props))],
2909
+ apple: [],
2910
+ openGraph: [],
2911
+ twitter: [],
2912
+ manifest: "/manifest.webmanifest"
2913
+ }
2914
+ }]
2915
+ },
2916
+ {
2917
+ 'layout': [module0, "/home/runner/work/jarela/jarela/app/layout.tsx"],
2918
+ 'global-error': [module1, "next/dist/client/components/builtin/global-error.js"],
2919
+ 'not-found': [module2, "next/dist/client/components/builtin/not-found.js"],
2920
+ 'forbidden': [module3, "next/dist/client/components/builtin/forbidden.js"],
2921
+ 'unauthorized': [module4, "next/dist/client/components/builtin/unauthorized.js"],
2922
+ metadata: {
2923
+ icon: [(async (props) => (await (0,next_dist_server_app_render_module_loading_instrument_module_getter__WEBPACK_IMPORTED_MODULE_0__/* .instrumentModuleGetter */ .p)(() => Promise.resolve(/* import() eager */).then(__webpack_require__.bind(__webpack_require__, 86364)))()).default(props))],
2924
+ apple: [],
2925
+ openGraph: [],
2926
+ twitter: [],
2927
+ manifest: "/manifest.webmanifest"
2928
+ }
2929
+ },
2930
+ []
2931
+ ]
2932
+ }.children;
2933
+ const __next_app_require__ = __webpack_require__
2934
+ const __next_app_load_chunk__ = () => Promise.resolve()
2935
+ const entrypoint = (0,next_dist_build_templates_app_page_runtime__WEBPACK_IMPORTED_MODULE_1__/* .createAppPageEntrypoint */ .H)({
2936
+ tree,
2937
+ page: "/page",
2938
+ pathname: "/",
2939
+ require: __next_app_require__,
2940
+ loadChunk: __next_app_load_chunk__,
2941
+ interopDefault: next_dist_server_app_render_interop_default__WEBPACK_IMPORTED_MODULE_2__/* .interopDefault */ .T
2942
+ });
2943
+ const __next_app__ = entrypoint.__next_app__;
2944
+ const routeModule = entrypoint.routeModule;
2945
+ const handler = entrypoint.handler;
2946
+
2947
+
2948
+ //# sourceMappingURL=app-page.js.map
2949
+
2950
+
2951
2951
  /***/ }),
2952
2952
 
2953
2953
  /***/ 14116:
@@ -3042,7 +3042,7 @@ module.exports = require("node:http");
3042
3042
  /***/ 38084:
3043
3043
  /***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {
3044
3044
 
3045
- Promise.resolve(/* import() eager */).then(__webpack_require__.bind(__webpack_require__, 74403));
3045
+ Promise.resolve(/* import() eager */).then(__webpack_require__.bind(__webpack_require__, 60095));
3046
3046
  ;
3047
3047
  Promise.resolve(/* import() eager */).then(__webpack_require__.bind(__webpack_require__, 26751));
3048
3048
 
@@ -3256,57 +3256,7 @@ function() { throw new Error("Attempted to call AppShell() from the server but A
3256
3256
 
3257
3257
  /***/ }),
3258
3258
 
3259
- /***/ 63033:
3260
- /***/ ((module) => {
3261
-
3262
- "use strict";
3263
- module.exports = require("next/dist/server/app-render/work-unit-async-storage.external.js");
3264
-
3265
- /***/ }),
3266
-
3267
- /***/ 71000:
3268
- /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
3269
-
3270
- "use strict";
3271
-
3272
- Object.defineProperty(exports, "__esModule", ({
3273
- value: true
3274
- }));
3275
- Object.defineProperty(exports, "addPathPrefix", ({
3276
- enumerable: true,
3277
- get: function() {
3278
- return addPathPrefix;
3279
- }
3280
- }));
3281
- const _parsepath = __webpack_require__(10571);
3282
- function addPathPrefix(path, prefix) {
3283
- if (!path.startsWith('/') || !prefix) {
3284
- return path;
3285
- }
3286
- const { pathname, query, hash } = (0, _parsepath.parsePath)(path);
3287
- return `${prefix}${pathname}${query}${hash}`;
3288
- } //# sourceMappingURL=add-path-prefix.js.map
3289
-
3290
-
3291
- /***/ }),
3292
-
3293
- /***/ 73024:
3294
- /***/ ((module) => {
3295
-
3296
- "use strict";
3297
- module.exports = require("node:fs");
3298
-
3299
- /***/ }),
3300
-
3301
- /***/ 73136:
3302
- /***/ ((module) => {
3303
-
3304
- "use strict";
3305
- module.exports = require("node:url");
3306
-
3307
- /***/ }),
3308
-
3309
- /***/ 74403:
3259
+ /***/ 60095:
3310
3260
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3311
3261
 
3312
3262
  "use strict";
@@ -4443,6 +4393,26 @@ function useSSE(onDone) {
4443
4393
  // Cleared on every new start()/attach().
4444
4394
  const [authError, setAuthError] = (0,react.useState)(null);
4445
4395
  const abortRef = (0,react.useRef)(null);
4396
+ // Synchronous view of whether start()/attach() owns a live stream, and when
4397
+ // the last one settled. React's `streaming` lags a render behind, so the
4398
+ // activity poller reads this to avoid aborting a stream that just opened
4399
+ // or re-attaching a run whose stream has only just ended.
4400
+ const liveRef = (0,react.useRef)({
4401
+ busy: false,
4402
+ settledAt: 0
4403
+ });
4404
+ const markLive = (0,react.useCallback)(()=>{
4405
+ liveRef.current.busy = true;
4406
+ }, []);
4407
+ const markSettled = (0,react.useCallback)((ctrl)=>{
4408
+ if (ctrl && abortRef.current !== ctrl) return;
4409
+ liveRef.current = {
4410
+ busy: false,
4411
+ settledAt: Date.now()
4412
+ };
4413
+ }, []);
4414
+ const isLive = (0,react.useCallback)(()=>liveRef.current.busy, []);
4415
+ const lastSettledAt = (0,react.useCallback)(()=>liveRef.current.settledAt, []);
4446
4416
  const threadIdRef = (0,react.useRef)(null);
4447
4417
  // ADR-0080 — id of the steering message currently armed for a possible
4448
4418
  // continuation break, or null. Set eagerly (before the steer PATCH
@@ -4604,6 +4574,7 @@ function useSSE(onDone) {
4604
4574
  abortRef.current?.abort();
4605
4575
  const ctrl = new AbortController();
4606
4576
  abortRef.current = ctrl;
4577
+ markLive();
4607
4578
  threadIdRef.current = threadId;
4608
4579
  resetBuffer();
4609
4580
  setStreaming(true);
@@ -4651,10 +4622,13 @@ function useSSE(onDone) {
4651
4622
  // them.
4652
4623
  setStreaming(false);
4653
4624
  closeActivity();
4625
+ markSettled(ctrl);
4654
4626
  }
4655
4627
  }, [
4656
4628
  closeActivity,
4657
4629
  consume,
4630
+ markLive,
4631
+ markSettled,
4658
4632
  openActivity,
4659
4633
  resetBuffer
4660
4634
  ]);
@@ -4679,11 +4653,13 @@ function useSSE(onDone) {
4679
4653
  // start()/attach() — same pattern as the `done` branch in consume().
4680
4654
  closeActivity();
4681
4655
  abortRef.current?.abort();
4656
+ markSettled(null);
4682
4657
  steeredContinuationIdRef.current = null;
4683
4658
  onDone?.();
4684
4659
  }, [
4685
4660
  closeActivity,
4686
4661
  flushPending,
4662
+ markSettled,
4687
4663
  onDone
4688
4664
  ]);
4689
4665
  // Attach to an in-flight run for the given thread (server-side run kept
@@ -4697,6 +4673,7 @@ function useSSE(onDone) {
4697
4673
  abortRef.current?.abort();
4698
4674
  const ctrl = new AbortController();
4699
4675
  abortRef.current = ctrl;
4676
+ markLive();
4700
4677
  threadIdRef.current = threadId;
4701
4678
  resetBuffer();
4702
4679
  setStreaming(true);
@@ -4724,10 +4701,13 @@ function useSSE(onDone) {
4724
4701
  // hangs in the composer and the "Reconnecting…" badge never clears.
4725
4702
  setStreaming(false);
4726
4703
  closeActivity();
4704
+ markSettled(ctrl);
4727
4705
  }
4728
4706
  }, [
4729
4707
  closeActivity,
4730
4708
  consume,
4709
+ markLive,
4710
+ markSettled,
4731
4711
  onDone,
4732
4712
  openActivity,
4733
4713
  resetBuffer
@@ -4772,6 +4752,8 @@ function useSSE(onDone) {
4772
4752
  start,
4773
4753
  stop,
4774
4754
  attach,
4755
+ isLive,
4756
+ lastSettledAt,
4775
4757
  clearStreamingContent,
4776
4758
  clearToolEvents,
4777
4759
  armSteeredContinuation,
@@ -4791,6 +4773,8 @@ function useSSE(onDone) {
4791
4773
  start,
4792
4774
  stop,
4793
4775
  attach,
4776
+ isLive,
4777
+ lastSettledAt,
4794
4778
  clearStreamingContent,
4795
4779
  clearToolEvents,
4796
4780
  armSteeredContinuation,
@@ -5011,6 +4995,8 @@ function readLegacyGlobal() {
5011
4995
  };
5012
4996
  }
5013
4997
 
4998
+ // EXTERNAL MODULE: ./lib/ui/error-report.ts
4999
+ var error_report = __webpack_require__(10778);
5014
5000
  ;// ./node_modules/lucide-react/dist/esm/icons/shield-alert.mjs
5015
5001
  /**
5016
5002
  * @license lucide-react v1.47.0 - ISC
@@ -7110,9 +7096,53 @@ minus_iconData.node;
7110
7096
  const Minus = (0,createLucideIcon/* default */.A)(minus_iconData);
7111
7097
  //# sourceMappingURL=minus.mjs.map
7112
7098
 
7099
+ ;// ./node_modules/lucide-react/dist/esm/icons/rotate-ccw.mjs
7100
+ /**
7101
+ * @license lucide-react v1.47.0 - ISC
7102
+ *
7103
+ * This source code is licensed under the ISC license.
7104
+ * See the LICENSE file in the root directory of this source tree.
7105
+ */
7106
+ const rotate_ccw_iconData = {
7107
+ name: "rotate-ccw",
7108
+ size: 24,
7109
+ node: [
7110
+ [
7111
+ "path",
7112
+ {
7113
+ d: "M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8",
7114
+ key: "1357e3"
7115
+ }
7116
+ ],
7117
+ [
7118
+ "path",
7119
+ {
7120
+ d: "M3 3v5h5",
7121
+ key: "1xhq8a"
7122
+ }
7123
+ ]
7124
+ ]
7125
+ };
7126
+ rotate_ccw_iconData.node;
7127
+ const RotateCcw = (0,createLucideIcon/* default */.A)(rotate_ccw_iconData);
7128
+ //# sourceMappingURL=rotate-ccw.mjs.map
7129
+
7113
7130
  ;// ./components/ui/WorkflowChecklist.tsx
7114
7131
 
7115
7132
 
7133
+ const RETRYABLE_STATUSES = new Set([
7134
+ "done",
7135
+ "needs_attention",
7136
+ "skipped"
7137
+ ]);
7138
+ function isWorkflowItemRetryable(item) {
7139
+ return RETRYABLE_STATUSES.has(item.status);
7140
+ }
7141
+ function statusLabel(status) {
7142
+ if (status === "done") return "verified";
7143
+ if (status === "needs_attention") return "needs attention";
7144
+ return status;
7145
+ }
7116
7146
  function StatusIcon({ status }) {
7117
7147
  if (status === "done") return /*#__PURE__*/ (0,react_jsx_runtime.jsx)(check/* default */.A, {
7118
7148
  className: "h-3 w-3",
@@ -7142,11 +7172,15 @@ function statusClass(status) {
7142
7172
  if (status === "skipped") return "border-border/60 bg-surface text-fg-faint";
7143
7173
  return "border-border/60 bg-surface text-fg-faint";
7144
7174
  }
7145
- function WorkflowChecklist({ eyebrow, title, phaseLabel, summary, items, error, compact = false, children }) {
7175
+ function itemTooltip(item) {
7176
+ const note = item.status === "done" ? item.validation_evidence : item.reason;
7177
+ return note ? `${item.label}\n${statusLabel(item.status)}: ${note}` : item.label;
7178
+ }
7179
+ function WorkflowChecklist({ eyebrow, title, phaseLabel, summary, items, error, compact = false, onRetryItem, canRetryItem, retryDisabled = false, children }) {
7146
7180
  return /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("div", {
7147
7181
  className: compact ? "flex flex-col gap-1.5" : "absolute inset-x-0 top-0 flex flex-col gap-2 transition-opacity duration-300",
7148
7182
  children: [
7149
- /*#__PURE__*/ (0,react_jsx_runtime.jsx)("p", {
7183
+ !compact && /*#__PURE__*/ (0,react_jsx_runtime.jsx)("p", {
7150
7184
  className: "text-[10px] text-fg-faint uppercase tracking-wider text-center",
7151
7185
  children: eyebrow
7152
7186
  }),
@@ -7166,99 +7200,59 @@ function WorkflowChecklist({ eyebrow, title, phaseLabel, summary, items, error,
7166
7200
  })
7167
7201
  ]
7168
7202
  }),
7169
- /*#__PURE__*/ (0,react_jsx_runtime.jsx)("p", {
7203
+ !compact && summary && /*#__PURE__*/ (0,react_jsx_runtime.jsx)("p", {
7170
7204
  className: "mt-1 text-[11px] leading-snug text-fg-muted line-clamp-2",
7171
7205
  children: summary
7172
7206
  }),
7173
- /*#__PURE__*/ (0,react_jsx_runtime.jsx)("div", {
7174
- className: compact ? "mt-1.5 flex max-h-32 flex-col gap-1 overflow-y-auto pr-1" : "mt-2 flex max-h-32 flex-col gap-1 overflow-y-auto pr-1",
7175
- children: items.map((item)=>/*#__PURE__*/ (0,react_jsx_runtime.jsxs)("div", {
7176
- className: compact ? "rounded border border-border/30 bg-surface-2/40 px-1.5 py-1 text-[10px] leading-tight text-fg-muted" : "text-[10px] leading-tight text-fg-muted",
7207
+ /*#__PURE__*/ (0,react_jsx_runtime.jsx)("ul", {
7208
+ className: compact ? "mt-1.5 flex max-h-48 flex-col gap-0.5 overflow-y-auto pr-1" : "mt-2 flex max-h-32 flex-col gap-1 overflow-y-auto pr-1",
7209
+ children: items.map((item)=>{
7210
+ const retryable = !!onRetryItem && isWorkflowItemRetryable(item) && (canRetryItem ? canRetryItem(item) : true);
7211
+ return /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("li", {
7212
+ className: "group flex items-center gap-1.5 text-[10px] leading-tight text-fg-muted",
7177
7213
  children: [
7178
- /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("div", {
7179
- className: "flex items-start gap-1.5",
7180
- children: [
7181
- /*#__PURE__*/ (0,react_jsx_runtime.jsx)("span", {
7182
- "aria-label": item.status,
7183
- className: [
7184
- "mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded border",
7185
- statusClass(item.status)
7186
- ].join(" "),
7187
- children: /*#__PURE__*/ (0,react_jsx_runtime.jsx)(StatusIcon, {
7188
- status: item.status
7189
- })
7190
- }),
7191
- /*#__PURE__*/ (0,react_jsx_runtime.jsx)("span", {
7192
- className: compact ? "min-w-0 flex-1 truncate" : "line-clamp-2",
7193
- title: item.label,
7194
- children: item.label
7195
- })
7196
- ]
7214
+ /*#__PURE__*/ (0,react_jsx_runtime.jsx)("span", {
7215
+ role: "img",
7216
+ "aria-label": statusLabel(item.status),
7217
+ className: [
7218
+ "flex h-4 w-4 shrink-0 items-center justify-center rounded border",
7219
+ statusClass(item.status)
7220
+ ].join(" "),
7221
+ children: /*#__PURE__*/ (0,react_jsx_runtime.jsx)(StatusIcon, {
7222
+ status: item.status
7223
+ })
7224
+ }),
7225
+ /*#__PURE__*/ (0,react_jsx_runtime.jsx)("span", {
7226
+ className: compact ? "min-w-0 flex-1 truncate" : "min-w-0 flex-1 line-clamp-2",
7227
+ title: itemTooltip(item),
7228
+ children: item.label
7197
7229
  }),
7198
- (item.input || item.output || item.validation || item.validation_evidence) && /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("details", {
7199
- className: "mt-1 pl-5",
7230
+ (item.attempts ?? 0) > 1 && /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("span", {
7231
+ className: "shrink-0 text-[9px] tabular-nums text-fg-faint",
7232
+ title: `Attempt ${item.attempts}`,
7200
7233
  children: [
7201
- /*#__PURE__*/ (0,react_jsx_runtime.jsx)("summary", {
7202
- className: "cursor-pointer text-fg-faint",
7203
- children: "Step contract"
7204
- }),
7205
- /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("dl", {
7206
- className: "mt-1 grid grid-cols-[auto_minmax(0,1fr)] gap-x-2 gap-y-1",
7207
- children: [
7208
- item.input && /*#__PURE__*/ (0,react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, {
7209
- children: [
7210
- /*#__PURE__*/ (0,react_jsx_runtime.jsx)("dt", {
7211
- className: "text-fg-faint",
7212
- children: "Input"
7213
- }),
7214
- /*#__PURE__*/ (0,react_jsx_runtime.jsx)("dd", {
7215
- className: "break-words",
7216
- children: item.input
7217
- })
7218
- ]
7219
- }),
7220
- item.output && /*#__PURE__*/ (0,react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, {
7221
- children: [
7222
- /*#__PURE__*/ (0,react_jsx_runtime.jsx)("dt", {
7223
- className: "text-fg-faint",
7224
- children: "Output"
7225
- }),
7226
- /*#__PURE__*/ (0,react_jsx_runtime.jsx)("dd", {
7227
- className: "break-words",
7228
- children: item.output
7229
- })
7230
- ]
7231
- }),
7232
- item.validation && /*#__PURE__*/ (0,react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, {
7233
- children: [
7234
- /*#__PURE__*/ (0,react_jsx_runtime.jsx)("dt", {
7235
- className: "text-fg-faint",
7236
- children: "Validation"
7237
- }),
7238
- /*#__PURE__*/ (0,react_jsx_runtime.jsx)("dd", {
7239
- className: "break-words",
7240
- children: item.validation
7241
- })
7242
- ]
7243
- }),
7244
- item.validation_evidence && /*#__PURE__*/ (0,react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, {
7245
- children: [
7246
- /*#__PURE__*/ (0,react_jsx_runtime.jsx)("dt", {
7247
- className: "text-fg-faint",
7248
- children: "Evidence"
7249
- }),
7250
- /*#__PURE__*/ (0,react_jsx_runtime.jsx)("dd", {
7251
- className: "break-words",
7252
- children: item.validation_evidence
7253
- })
7254
- ]
7255
- })
7256
- ]
7257
- })
7234
+ "attempt ",
7235
+ item.attempts
7258
7236
  ]
7237
+ }),
7238
+ retryable && /*#__PURE__*/ (0,react_jsx_runtime.jsx)("button", {
7239
+ type: "button",
7240
+ onClick: ()=>onRetryItem(item),
7241
+ disabled: retryDisabled,
7242
+ "aria-label": `Retry ${item.label}`,
7243
+ title: `Retry ${item.label}`,
7244
+ className: [
7245
+ "flex h-4 w-4 shrink-0 items-center justify-center rounded text-fg-faint hover:bg-surface-3 hover:text-fg disabled:opacity-40",
7246
+ item.status === "needs_attention" ? "" : "opacity-0 focus:opacity-100 group-hover:opacity-100"
7247
+ ].join(" "),
7248
+ children: /*#__PURE__*/ (0,react_jsx_runtime.jsx)(RotateCcw, {
7249
+ className: "h-3 w-3",
7250
+ "aria-hidden": true
7251
+ })
7259
7252
  })
7260
7253
  ]
7261
- }, item.id))
7254
+ }, item.id);
7255
+ })
7262
7256
  }),
7263
7257
  error && /*#__PURE__*/ (0,react_jsx_runtime.jsx)("p", {
7264
7258
  className: "mt-2 text-[10px] leading-tight text-red-400",
@@ -7271,6 +7265,21 @@ function WorkflowChecklist({ eyebrow, title, phaseLabel, summary, items, error,
7271
7265
  });
7272
7266
  }
7273
7267
 
7268
+ ;// ./components/chat/workflow-step-retry.ts
7269
+
7270
+ /** Sends a retry request for one workflow step; null when the surface cannot send messages. */ const WorkflowStepRetryContext = (0,react.createContext)(null);
7271
+ function useWorkflowStepRetry() {
7272
+ return (0,react.useContext)(WorkflowStepRetryContext);
7273
+ }
7274
+ function workflowStepRetryMessage({ workflowId, itemId, label }) {
7275
+ const progressUpdate = workflowId === "version_adoption" ? `Call \`workflow_progress\` with \`workflow_id: "version_adoption"\`, \`item_id: "${itemId}"\`, and \`status: "checking"\`` : `Call \`workflow_progress\` for workflow \`${workflowId}\` with the complete items snapshot, setting this step to \`checking\``;
7276
+ return [
7277
+ `Retry workflow step "${label}" (item \`${itemId}\`) in workflow \`${workflowId}\`.`,
7278
+ `${progressUpdate}, then redo the step from its stated input and run its validation again.`,
7279
+ "Finally mark it `done` with newly observed `validation_evidence`, or `needs_attention` with the reason. Leave the other steps unchanged."
7280
+ ].join(" ");
7281
+ }
7282
+
7274
7283
  ;// ./node_modules/lucide-react/dist/esm/icons/clock.mjs
7275
7284
  /**
7276
7285
  * @license lucide-react v1.47.0 - ISC
@@ -7512,6 +7521,7 @@ var ProviderLogo = __webpack_require__(17838);
7512
7521
 
7513
7522
 
7514
7523
 
7524
+
7515
7525
  // Distinct lucide glyph per internal tool family so the chat transcript
7516
7526
  // is glanceable — operator can tell a file write from a web fetch from a
7517
7527
  // schedule from a memory read without reading the tool name.
@@ -7949,7 +7959,34 @@ function groupByCallId(events) {
7949
7959
  }
7950
7960
  g.absorbed = true;
7951
7961
  }
7952
- return order.map((id)=>map.get(id)).filter((g)=>!g.absorbed);
7962
+ const groups = order.map((id)=>map.get(id)).filter((g)=>!g.absorbed);
7963
+ annotateWorkflowAttempts(groups);
7964
+ return groups;
7965
+ }
7966
+ // Counts each workflow step's transitions into `checking` across the
7967
+ // message's workflow_progress calls, so auto-retried steps show "attempt N".
7968
+ // Rejected updates (ok:false) changed nothing and are not counted.
7969
+ function annotateWorkflowAttempts(groups) {
7970
+ const lastStatus = new Map();
7971
+ const attempts = new Map();
7972
+ for (const group of groups){
7973
+ if (group.name !== "workflow_progress") continue;
7974
+ if (coerceObject(unwrapLangChainSerializable(group.result))?.ok === false) continue;
7975
+ const view = workflowViewFor(group);
7976
+ if (!view) continue;
7977
+ const counts = {
7978
+ ...attempts.get(view.workflow_id) ?? {}
7979
+ };
7980
+ for (const item of view.items){
7981
+ const key = `${view.workflow_id}:${item.id}`;
7982
+ if (item.status === "checking" && lastStatus.get(key) !== "checking") {
7983
+ counts[item.id] = (counts[item.id] ?? 0) + 1;
7984
+ }
7985
+ lastStatus.set(key, item.status);
7986
+ }
7987
+ attempts.set(view.workflow_id, counts);
7988
+ group.workflowAttempts = counts;
7989
+ }
7953
7990
  }
7954
7991
  function ToolCallCard({ group, startedAt }) {
7955
7992
  const [open, setOpen] = (0,react.useState)(false);
@@ -8062,23 +8099,27 @@ function ToolCallCard({ group, startedAt }) {
8062
8099
  /*#__PURE__*/ (0,react_jsx_runtime.jsx)(WorkflowProgressDetails, {
8063
8100
  group: group
8064
8101
  }),
8065
- hasVisibleArgs(group.args) ? /*#__PURE__*/ (0,react_jsx_runtime.jsx)(DetailSection, {
8066
- label: "arguments",
8067
- value: group.args
8068
- }) : hasArgs ? /*#__PURE__*/ (0,react_jsx_runtime.jsx)(DetailSection, {
8069
- label: "arguments (inferred from result)",
8070
- value: effectiveArgs
8071
- }) : null,
8072
- group.status !== "running" && group.status !== "async" && (isToolResultRefEnvelope(group.result) ? /*#__PURE__*/ (0,react_jsx_runtime.jsx)(ToolResultRefDetails, {
8073
- value: group.result
8074
- }) : /*#__PURE__*/ (0,react_jsx_runtime.jsx)(DetailSection, {
8075
- label: group.status === "error" ? "error" : "result",
8076
- value: group.result,
8077
- tone: group.status === "error" ? "error" : "default"
8078
- })),
8079
- group.status === "async" && /*#__PURE__*/ (0,react_jsx_runtime.jsx)(DetailSection, {
8080
- label: "background handoff",
8081
- value: group.result
8102
+ !hasWorkflowView(group) && /*#__PURE__*/ (0,react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, {
8103
+ children: [
8104
+ hasVisibleArgs(group.args) ? /*#__PURE__*/ (0,react_jsx_runtime.jsx)(DetailSection, {
8105
+ label: "arguments",
8106
+ value: group.args
8107
+ }) : hasArgs ? /*#__PURE__*/ (0,react_jsx_runtime.jsx)(DetailSection, {
8108
+ label: "arguments (inferred from result)",
8109
+ value: effectiveArgs
8110
+ }) : null,
8111
+ group.status !== "running" && group.status !== "async" && (isToolResultRefEnvelope(group.result) ? /*#__PURE__*/ (0,react_jsx_runtime.jsx)(ToolResultRefDetails, {
8112
+ value: group.result
8113
+ }) : /*#__PURE__*/ (0,react_jsx_runtime.jsx)(DetailSection, {
8114
+ label: group.status === "error" ? "error" : "result",
8115
+ value: group.result,
8116
+ tone: group.status === "error" ? "error" : "default"
8117
+ })),
8118
+ group.status === "async" && /*#__PURE__*/ (0,react_jsx_runtime.jsx)(DetailSection, {
8119
+ label: "background handoff",
8120
+ value: group.result
8121
+ })
8122
+ ]
8082
8123
  })
8083
8124
  ]
8084
8125
  })
@@ -8213,18 +8254,47 @@ function ToolResultRefDetails({ value }) {
8213
8254
  ]
8214
8255
  });
8215
8256
  }
8216
- function WorkflowProgressDetails({ group }) {
8257
+ function workflowViewFor(group) {
8217
8258
  if (group.name !== "workflow_progress") return null;
8218
- const workflow = workflowProgressFrom(group.result) ?? workflowProgressPreviewFrom(group.args);
8259
+ const view = workflowProgressFrom(group.result) ?? workflowProgressPreviewFrom(group.args);
8260
+ const result = coerceObject(unwrapLangChainSerializable(group.result));
8261
+ const attempts = group.workflowAttempts;
8262
+ const withAttempts = view && attempts ? {
8263
+ ...view,
8264
+ items: view.items.map((item)=>attempts[item.id] ? {
8265
+ ...item,
8266
+ attempts: attempts[item.id]
8267
+ } : item)
8268
+ } : view;
8269
+ if (withAttempts && result?.ok === false && typeof result.error === "string") {
8270
+ return {
8271
+ ...withAttempts,
8272
+ error: `Update rejected: ${result.error}`
8273
+ };
8274
+ }
8275
+ return withAttempts;
8276
+ }
8277
+ /** Workflow rows show only their work items; raw payloads stay visible when the call failed. */ function hasWorkflowView(group) {
8278
+ return group.status !== "error" && workflowViewFor(group) !== null;
8279
+ }
8280
+ function WorkflowProgressDetails({ group }) {
8281
+ const retryStep = useWorkflowStepRetry();
8282
+ const workflow = workflowViewFor(group);
8219
8283
  if (!workflow) return null;
8284
+ const workflowId = workflow.workflow_id;
8220
8285
  return /*#__PURE__*/ (0,react_jsx_runtime.jsx)(WorkflowChecklist, {
8221
8286
  compact: true,
8222
8287
  eyebrow: "workflow",
8223
- title: workflow.workflow_id.replace(/[_-]/g, " "),
8288
+ title: workflowId.replace(/[_-]/g, " "),
8224
8289
  phaseLabel: workflow.phase ?? "in progress",
8225
8290
  summary: workflow.summary ?? "",
8226
8291
  items: workflow.items,
8227
- error: workflow.error
8292
+ error: workflow.error,
8293
+ onRetryItem: retryStep ? (item)=>retryStep({
8294
+ workflowId,
8295
+ itemId: item.id,
8296
+ label: item.label
8297
+ }) : undefined
8228
8298
  });
8229
8299
  }
8230
8300
  function workflowProgressFrom(payload) {
@@ -37418,37 +37488,6 @@ link_2_iconData.node;
37418
37488
  const Link2 = (0,createLucideIcon/* default */.A)(link_2_iconData);
37419
37489
  //# sourceMappingURL=link-2.mjs.map
37420
37490
 
37421
- ;// ./node_modules/lucide-react/dist/esm/icons/rotate-ccw.mjs
37422
- /**
37423
- * @license lucide-react v1.47.0 - ISC
37424
- *
37425
- * This source code is licensed under the ISC license.
37426
- * See the LICENSE file in the root directory of this source tree.
37427
- */
37428
- const rotate_ccw_iconData = {
37429
- name: "rotate-ccw",
37430
- size: 24,
37431
- node: [
37432
- [
37433
- "path",
37434
- {
37435
- d: "M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8",
37436
- key: "1357e3"
37437
- }
37438
- ],
37439
- [
37440
- "path",
37441
- {
37442
- d: "M3 3v5h5",
37443
- key: "1xhq8a"
37444
- }
37445
- ]
37446
- ]
37447
- };
37448
- rotate_ccw_iconData.node;
37449
- const RotateCcw = (0,createLucideIcon/* default */.A)(rotate_ccw_iconData);
37450
- //# sourceMappingURL=rotate-ccw.mjs.map
37451
-
37452
37491
  ;// ./node_modules/lucide-react/dist/esm/icons/pause.mjs
37453
37492
  /**
37454
37493
  * @license lucide-react v1.47.0 - ISC
@@ -37972,6 +38011,41 @@ function formatRoutingDuration(durationMs) {
37972
38011
  return `${seconds.toFixed(seconds >= 10 ? 0 : 1)}s`;
37973
38012
  }
37974
38013
 
38014
+ ;// ./lib/utils/source-link.ts
38015
+ /**
38016
+ * Source-link fields for tool results, so an agent can link a reply back to
38017
+ * the email, calendar event, or chat it came from without building URLs.
38018
+ *
38019
+ * `cite_as` is a ready-made markdown link the system prompt tells agents to
38020
+ * paste verbatim. Building it in code keeps the label and URL well-formed:
38021
+ * a stray `]` in a subject or `)` in a URL would otherwise break the link.
38022
+ */ const MAX_LABEL_CHARS = 80;
38023
+ /** Returns `url` when it is an absolute https URL, otherwise null. */ function source_link_httpsUrlOrNull(url) {
38024
+ if (!url) return null;
38025
+ try {
38026
+ const parsed = new URL(url);
38027
+ return parsed.protocol === "https:" ? parsed.href : null;
38028
+ } catch {
38029
+ return null;
38030
+ }
38031
+ }
38032
+ function markdownLabel(label, fallback) {
38033
+ const flat = (label ?? "").replace(/\s+/g, " ").trim();
38034
+ const capped = flat.length > MAX_LABEL_CHARS ? `${flat.slice(0, MAX_LABEL_CHARS - 1).trimEnd()}…` : flat;
38035
+ return (capped || fallback).replace(/[\\[\]]/g, (c)=>`\\${c}`);
38036
+ }
38037
+ function markdownDestination(url) {
38038
+ return url.replace(/[()\s<>]/g, (c)=>`%${c.charCodeAt(0).toString(16).toUpperCase().padStart(2, "0")}`);
38039
+ }
38040
+ /**
38041
+ * Pre-built markdown link for `cite_as`, or null when there is no usable URL.
38042
+ * Only https URLs qualify: the chat renderer drops other schemes.
38043
+ */ function citeAs(label, url, fallbackLabel = "source") {
38044
+ const safe = source_link_httpsUrlOrNull(url);
38045
+ if (!safe) return null;
38046
+ return `[${markdownLabel(label, fallbackLabel)}](${markdownDestination(safe)})`;
38047
+ }
38048
+
37975
38049
  ;// ./lib/bridges/message-role.ts
37976
38050
  /**
37977
38051
  * Cross-adapter framing for bridge inbound messages.
@@ -37989,25 +38063,8 @@ function formatRoutingDuration(durationMs) {
37989
38063
  * sees. Adding a new adapter is a matter of mapping its platform-specific
37990
38064
  * "who sent this" signal onto `MessageRole`; the framing code does not need
37991
38065
  * to change.
37992
- */ /**
37993
- * Who sent the message from the agent's perspective.
37994
- *
37995
- * - `user`: the paired account holder themselves — typed on their phone,
37996
- * in their browser, etc. The agent treats these as the user's own
37997
- * reaction/input to the conversation. Useful as an intent signal but
37998
- * NOT a direct command to the agent (the user is talking to the
37999
- * counterpart, not the agent).
38000
- *
38001
- * - `counterpart`: another participant in the chat — 1:1 partner in a DM,
38002
- * or another member in a group chat. The agent treats these as
38003
- * conversation context the user has not yet reacted to. Not a request
38004
- * directed at the agent.
38005
- *
38006
- * - `agent`: the agent's own prior output, surfaced inbound when the
38007
- * adapter cannot suppress its echo (rare). Adapters with reliable
38008
- * echo-filtering (e.g. WhatsApp's `sentIdsSet`) should never emit this
38009
- * value; it exists for adapters where deduplication is best-effort.
38010
- */ /**
38066
+ */
38067
+ /**
38011
38068
  * Build the prompt prefix the agent receives for one bridge-inbound message.
38012
38069
  *
38013
38070
  * Output shape:
@@ -38021,6 +38078,7 @@ function formatRoutingDuration(durationMs) {
38021
38078
  * [message_role:user|counterpart|agent]
38022
38079
  * [sender_id:<id>]
38023
38080
  * [sender_name:<label>]
38081
+ * ([chat_link:<https url>] when the platform has a permalink for the chat)
38024
38082
  * ([group_name:<label>] [participant_id:<id>] [participant_name:<label>] for groups)
38025
38083
  *
38026
38084
  * <raw text>
@@ -38030,23 +38088,29 @@ function formatRoutingDuration(durationMs) {
38030
38088
  * convention. Both are stable across adapters.
38031
38089
  */ function formatBridgePrompt(input) {
38032
38090
  const note = roleNote(input.role, input.is_group, input.silent === true, input.event);
38091
+ // Header values come from the platform (display names, group subjects) and
38092
+ // are sender-controlled: a line break would forge extra headers or end the
38093
+ // header block early, so every value is flattened onto one line.
38094
+ const h = (value)=>String(value ?? "").replace(/[\r\n\u0085\u2028\u2029]+/g, " ");
38033
38095
  const lines = [
38034
- `[bridge:${input.bridge_id}]`,
38035
- `[chat_id:${input.chat_id}]`,
38036
- `[chat_name:${input.chat_name}]`,
38096
+ `[bridge:${h(input.bridge_id)}]`,
38097
+ `[chat_id:${h(input.chat_id)}]`,
38098
+ `[chat_name:${h(input.chat_name)}]`,
38037
38099
  `[chat_type:${input.is_group ? "group" : "dm"}]`,
38038
38100
  `[message_role:${input.role}]`,
38039
- `[sender_id:${input.sender_id}]`,
38040
- `[sender_name:${input.sender_name}]`
38101
+ `[sender_id:${h(input.sender_id)}]`,
38102
+ `[sender_name:${h(input.sender_name)}]`
38041
38103
  ];
38104
+ const chatLink = httpsUrlOrNull(input.chat_link);
38105
+ if (chatLink) lines.push(`[chat_link:${chatLink}]`);
38042
38106
  if (input.event) {
38043
38107
  lines.push(`[event_type:${input.event.type}]`);
38044
- lines.push(`[event_subtype:${input.event.subtype}]`);
38108
+ lines.push(`[event_subtype:${h(input.event.subtype)}]`);
38045
38109
  }
38046
38110
  if (input.is_group) {
38047
- lines.push(`[group_name:${input.chat_name}]`);
38048
- lines.push(`[participant_id:${input.sender_id}]`);
38049
- lines.push(`[participant_name:${input.sender_name}]`);
38111
+ lines.push(`[group_name:${h(input.chat_name)}]`);
38112
+ lines.push(`[participant_id:${h(input.sender_id)}]`);
38113
+ lines.push(`[participant_name:${h(input.sender_name)}]`);
38050
38114
  }
38051
38115
  return `${note}\n\n${lines.join("\n")}\n\n${input.text}`;
38052
38116
  }
@@ -38061,7 +38125,7 @@ function parseBridgePrompt(raw) {
38061
38125
  const lines = src.split("\n");
38062
38126
  let i = 0;
38063
38127
  for(; i < lines.length; i++){
38064
- const line = lines[i];
38128
+ const line = lines[i].replace(/\r$/, "");
38065
38129
  if (line === "") {
38066
38130
  i++;
38067
38131
  break;
@@ -38080,6 +38144,7 @@ function parseBridgePrompt(raw) {
38080
38144
  isGroup: headers.chat_type === "group",
38081
38145
  senderJid: senderId,
38082
38146
  senderName: headers.sender_name || senderId || "Unknown",
38147
+ chatLink: source_link_httpsUrlOrNull(headers.chat_link),
38083
38148
  body: lines.slice(i).join("\n").trimEnd()
38084
38149
  };
38085
38150
  }
@@ -48700,6 +48765,19 @@ function BridgeMessageCard({ ctx, activity }) {
48700
48765
  activityStatus(activity).copy,
48701
48766
  activity.occurrence_count > 1 ? ` · ${activity.occurrence_count} checks` : ""
48702
48767
  ]
48768
+ }) : null,
48769
+ ctx.chatLink ? /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("a", {
48770
+ href: ctx.chatLink,
48771
+ target: "_blank",
48772
+ rel: "noopener noreferrer",
48773
+ className: "inline-flex items-center gap-1 px-1.5 py-0.5 rounded-full bg-white/15 hover:bg-white/25 text-[9.5px] shrink-0",
48774
+ title: `Open this chat (${ctx.chatLink})`,
48775
+ children: [
48776
+ /*#__PURE__*/ (0,react_jsx_runtime.jsx)(external_link/* default */.A, {
48777
+ size: 9
48778
+ }),
48779
+ "open chat"
48780
+ ]
48703
48781
  }) : null
48704
48782
  ]
48705
48783
  });
@@ -50527,7 +50605,7 @@ function StatusDot({ tone = "neutral", size = "xs", pulse, className, style, lab
50527
50605
  }
50528
50606
 
50529
50607
  ;// ./components/chat/ContextBoundary.tsx
50530
- /* __next_internal_client_entry_do_not_use__ WarmSummaryCard,ContextBoundaryDivider auto */
50608
+ /* __next_internal_client_entry_do_not_use__ WarmSummaryCard,ContextBoundaryDivider,topicsFromSummarySections auto */
50531
50609
  // Inline visual artefacts for ADR-0042: the warm-summary card and the
50532
50610
  // context-boundary divider that sits below it. Rendered by MessageList in
50533
50611
  // the message stream — between summarised history (above) and the active
@@ -50539,17 +50617,25 @@ function StatusDot({ tone = "neutral", size = "xs", pulse, className, style, lab
50539
50617
 
50540
50618
 
50541
50619
 
50542
- function WarmSummaryCard({ olderCount, summary, summaryBeforeSeq, hotSinceSeq, computedAt, streaming, topics }) {
50620
+ const CHANNEL_LABELS = {
50621
+ bridge: "Bridge",
50622
+ watcher: "Watchers",
50623
+ scheduled_task: "Scheduled tasks"
50624
+ };
50625
+ function WarmSummaryCard({ olderCount, summary, summaryBeforeSeq, hotSinceSeq, computedAt, streaming, topics, channelSummaries = [] }) {
50543
50626
  const [expanded, setExpanded] = (0,react.useState)(false);
50544
- const fresh = !!summary && hotSinceSeq != null && summaryBeforeSeq === hotSinceSeq;
50627
+ const committed = hotSinceSeq != null && summaryBeforeSeq === hotSinceSeq;
50628
+ const fresh = !!summary && committed;
50545
50629
  const stale = !!summary && !fresh;
50546
50630
  const computing = stale && streaming;
50547
- const summaryTopics = summary && topics && topics.length > 0 ? topics : null;
50631
+ // Summaries stored before topic segmentation still read as topics: their
50632
+ // markdown sections render through the same collapsible rows.
50633
+ const summaryTopics = summary ? topics && topics.length > 0 ? topics : topicsFromSummarySections(summary) : null;
50548
50634
  return /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("div", {
50549
50635
  className: [
50550
50636
  "relative my-4 rounded-2xl border bg-gradient-to-br shadow-sm",
50551
50637
  "from-accent/[0.06] via-surface-2 to-surface-2",
50552
- fresh ? "border-accent/30" : "border-border"
50638
+ fresh || committed ? "border-accent/30" : "border-border"
50553
50639
  ].join(" "),
50554
50640
  children: [
50555
50641
  /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("div", {
@@ -50594,6 +50680,9 @@ function WarmSummaryCard({ olderCount, summary, summaryBeforeSeq, hotSinceSeq, c
50594
50680
  children: /*#__PURE__*/ (0,react_jsx_runtime.jsx)(lib/* Markdown */.oz, {
50595
50681
  children: stripWarmHeader(summary)
50596
50682
  })
50683
+ }) : !summary && committed ? channelSummaries.length === 0 && /*#__PURE__*/ (0,react_jsx_runtime.jsx)("div", {
50684
+ className: "text-xs text-fg-faint italic",
50685
+ children: "No earlier chat messages needed summarising."
50597
50686
  }) : !summary ? /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("div", {
50598
50687
  className: "flex items-center gap-2 text-xs text-fg-faint italic",
50599
50688
  children: [
@@ -50607,6 +50696,9 @@ function WarmSummaryCard({ olderCount, summary, summaryBeforeSeq, hotSinceSeq, c
50607
50696
  })
50608
50697
  ]
50609
50698
  }) : null,
50699
+ channelSummaries.map((channel)=>/*#__PURE__*/ (0,react_jsx_runtime.jsx)(ChannelSummarySection, {
50700
+ channel: channel
50701
+ }, channel.channel)),
50610
50702
  stale && /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("div", {
50611
50703
  className: "mt-2 inline-flex items-center gap-2 text-[11px] text-fg-faint",
50612
50704
  children: [
@@ -50648,6 +50740,32 @@ function WarmSummaryCard({ olderCount, summary, summaryBeforeSeq, hotSinceSeq, c
50648
50740
  ]
50649
50741
  });
50650
50742
  }
50743
+ function ChannelSummarySection({ channel }) {
50744
+ const topics = channel.topics && channel.topics.length > 0 ? channel.topics : topicsFromSummarySections(channel.summary) ?? [
50745
+ {
50746
+ title: "Recap",
50747
+ start_at: "",
50748
+ end_at: "",
50749
+ recap: stripWarmHeader(channel.summary),
50750
+ facts: []
50751
+ }
50752
+ ];
50753
+ return /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("div", {
50754
+ className: "mt-2",
50755
+ children: [
50756
+ /*#__PURE__*/ (0,react_jsx_runtime.jsx)("div", {
50757
+ className: "mb-1 text-[9px] uppercase tracking-wide text-fg-faint",
50758
+ children: CHANNEL_LABELS[channel.channel] ?? channel.channel
50759
+ }),
50760
+ /*#__PURE__*/ (0,react_jsx_runtime.jsx)("div", {
50761
+ className: "flex flex-col gap-1",
50762
+ children: topics.map((topic, i)=>/*#__PURE__*/ (0,react_jsx_runtime.jsx)(TopicSegmentRow, {
50763
+ topic: topic
50764
+ }, `${channel.channel}-${topic.title}-${i}`))
50765
+ })
50766
+ ]
50767
+ });
50768
+ }
50651
50769
  function TopicSegmentRow({ topic }) {
50652
50770
  const [open, setOpen] = (0,react.useState)(false);
50653
50771
  const range = formatTopicRange(topic.start_at, topic.end_at);
@@ -50675,13 +50793,20 @@ function TopicSegmentRow({ topic }) {
50675
50793
  range
50676
50794
  ]
50677
50795
  }),
50796
+ typeof topic.message_count === "number" && topic.message_count > 0 && /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("span", {
50797
+ className: "text-fg-faint shrink-0",
50798
+ children: [
50799
+ "\xb7 ",
50800
+ topic.message_count,
50801
+ " ",
50802
+ topic.message_count === 1 ? "msg" : "msgs"
50803
+ ]
50804
+ }),
50678
50805
  topic.facts.length > 0 && /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("span", {
50679
50806
  className: "ml-auto shrink-0 text-[9px] uppercase tracking-wide text-accent",
50680
50807
  children: [
50681
50808
  topic.facts.length,
50682
- " ",
50683
- topic.facts.length === 1 ? "fact" : "facts",
50684
- " saved"
50809
+ " memorized"
50685
50810
  ]
50686
50811
  })
50687
50812
  ]
@@ -50701,22 +50826,34 @@ function TopicSegmentRow({ topic }) {
50701
50826
  children: topic.recap
50702
50827
  })
50703
50828
  }),
50704
- topic.facts.length > 0 && /*#__PURE__*/ (0,react_jsx_runtime.jsx)("ul", {
50705
- className: "space-y-0.5",
50706
- children: topic.facts.map((fact, i)=>/*#__PURE__*/ (0,react_jsx_runtime.jsxs)("li", {
50707
- className: "text-[11px] text-fg-faint",
50708
- children: [
50709
- /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("span", {
50710
- className: "font-medium text-fg-muted",
50829
+ topic.facts.length > 0 && /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("div", {
50830
+ children: [
50831
+ /*#__PURE__*/ (0,react_jsx_runtime.jsx)("div", {
50832
+ className: "text-[9px] uppercase tracking-wide text-fg-faint",
50833
+ children: "Memorized"
50834
+ }),
50835
+ /*#__PURE__*/ (0,react_jsx_runtime.jsx)("ul", {
50836
+ className: "space-y-0.5",
50837
+ children: topic.facts.map((fact, i)=>/*#__PURE__*/ (0,react_jsx_runtime.jsxs)("li", {
50838
+ className: "text-[11px] text-fg-faint",
50711
50839
  children: [
50712
- fact.subject,
50713
- ":"
50840
+ /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("span", {
50841
+ className: "font-medium text-fg-muted",
50842
+ children: [
50843
+ fact.subject,
50844
+ ":"
50845
+ ]
50846
+ }),
50847
+ " ",
50848
+ fact.content,
50849
+ fact.key && /*#__PURE__*/ (0,react_jsx_runtime.jsx)("code", {
50850
+ className: "ml-1 text-[10px] text-fg-faint",
50851
+ children: fact.key
50852
+ })
50714
50853
  ]
50715
- }),
50716
- " ",
50717
- fact.content
50718
- ]
50719
- }, `${fact.subject}-${i}`))
50854
+ }, `${fact.key ?? fact.subject}-${i}`))
50855
+ })
50856
+ ]
50720
50857
  })
50721
50858
  ]
50722
50859
  })
@@ -50849,7 +50986,38 @@ function ContextBoundary_formatBytes(n) {
50849
50986
  // `buildWarmSummary` prepends a couple of plain-text header lines that read
50850
50987
  // awkwardly inside a card that already has its own header. Strip them.
50851
50988
  function stripWarmHeader(raw) {
50852
- return raw.replace(/^--- Warm context summary ---\n/, "").replace(/^Compressed recap of earlier messages outside the hot window:\n/, "").trimStart();
50989
+ return raw.replace(/\r\n/g, "\n").replace(/^\s*(<!--[\s\S]*?-->\s*)+/, "").replace(/^--- Warm context summary ---\n/, "").replace(/^Compressed recap of [^\n]*:\n/, "").trimStart();
50990
+ }
50991
+ /**
50992
+ * Splits a markdown summary into topic segments at its headings. Returns
50993
+ * null when there are fewer than two sections, so short or unstructured
50994
+ * summaries keep the plain prose rendering.
50995
+ */ function topicsFromSummarySections(raw) {
50996
+ const sections = [];
50997
+ let title = null;
50998
+ let body = [];
50999
+ const flush = ()=>{
51000
+ const recap = body.join("\n").trim();
51001
+ if (title !== null || recap) sections.push({
51002
+ title: title ?? "Overview",
51003
+ start_at: "",
51004
+ end_at: "",
51005
+ recap,
51006
+ facts: []
51007
+ });
51008
+ };
51009
+ for (const line of stripWarmHeader(raw).split("\n")){
51010
+ const heading = /^#{1,3}\s+(.+?)\s*#*\s*$/.exec(line);
51011
+ if (heading) {
51012
+ flush();
51013
+ title = heading[1];
51014
+ body = [];
51015
+ } else {
51016
+ body.push(line);
51017
+ }
51018
+ }
51019
+ flush();
51020
+ return sections.length >= 2 ? sections : null;
50853
51021
  }
50854
51022
  function summaryLong(raw) {
50855
51023
  // Heuristic: more than 6 lines or > 600 chars after the header strip.
@@ -50882,11 +51050,13 @@ function formatRelative(iso) {
50882
51050
 
50883
51051
 
50884
51052
 
51053
+
50885
51054
  const ALL_FILTERS_SHOWN = Object.fromEntries(MESSAGE_FILTER_KEYS.map((k)=>[
50886
51055
  k,
50887
51056
  true
50888
51057
  ]));
50889
- function MessageList({ threadId, messages, steeredSegments, notices, agentConfig, userProfile, streamingContent, thinkingContent, toolEvents, hasMore, loadingMore, onLoadMore, queuedMessages, onRemoveQueued, hotSinceSeq, warmSummary, warmSummaryBeforeSeq, warmSummaryComputedAt, warmSummarySourceMessages, warmSummarySourceChars, warmSummaryTopics, warmSummaryPending = false, compactionPending = false, onSetContextPin, streaming, contextWindowTokens, onRetryMessage, filters = ALL_FILTERS_SHOWN, onToggleFilter: toggle = ()=>{}, onResetFilters: reset = ()=>{} }) {
51058
+ const NO_CHANNEL_SUMMARIES = [];
51059
+ function MessageList({ threadId, messages, steeredSegments, agentConfig, userProfile, streamingContent, thinkingContent, toolEvents, hasMore, loadingMore, onLoadMore, queuedMessages, onRemoveQueued, hotSinceSeq, warmSummary, warmSummaryBeforeSeq, warmSummaryComputedAt, warmSummarySourceMessages, warmSummarySourceChars, warmSummaryTopics, warmChannelSummaries = NO_CHANNEL_SUMMARIES, warmSummaryPending = false, compactionPending = false, onSetContextPin, streaming, contextWindowTokens, onRetryMessage, filters = ALL_FILTERS_SHOWN, onToggleFilter: toggle = ()=>{}, onResetFilters: reset = ()=>{} }) {
50890
51060
  const hostRef = (0,react.useRef)(null);
50891
51061
  const maskRegionRef = (0,react.useRef)(null);
50892
51062
  const scrollRef = (0,react.useRef)(null);
@@ -50911,6 +51081,9 @@ function MessageList({ threadId, messages, steeredSegments, notices, agentConfig
50911
51081
  const [pendingHotSinceSeq, setPendingHotSinceSeq] = (0,react.useState)(null);
50912
51082
  const [topControlsOpen, setTopControlsOpen] = (0,react.useState)(false);
50913
51083
  const [summaryPopoverOpen, setSummaryPopoverOpen] = (0,react.useState)(false);
51084
+ const retryWorkflowStep = (0,react.useMemo)(()=>onRetryMessage ? (request)=>onRetryMessage(workflowStepRetryMessage(request), []) : null, [
51085
+ onRetryMessage
51086
+ ]);
50914
51087
  // Apply category filter. Messages with no `category` (NULL = ordinary
50915
51088
  // chat) are always shown; tagged messages are gated by their toggle.
50916
51089
  // The `tool_use` and `thinking` filters do NOT remove whole messages —
@@ -51280,7 +51453,11 @@ function MessageList({ threadId, messages, steeredSegments, notices, agentConfig
51280
51453
  const nextHotCount = pendingBoundaryIndex < 0 ? null : visibleMessages.length - pendingBoundaryIndex;
51281
51454
  const removesFromRecent = currentHotCount !== null && nextHotCount !== null ? nextHotCount < currentHotCount : false;
51282
51455
  const hasWarmSummary = !!warmSummary;
51456
+ // A committed boundary whose chat range had nothing to summarise (e.g. a
51457
+ // bridge-only agent): the recap, if any, lives in the channel summaries.
51458
+ const summaryCommittedEmpty = !hasWarmSummary && effectiveHotSinceSeq !== null && warmSummaryBeforeSeq === effectiveHotSinceSeq;
51283
51459
  const summaryFresh = hasWarmSummary && effectiveHotSinceSeq !== null && warmSummaryBeforeSeq === effectiveHotSinceSeq;
51460
+ const summaryReady = summaryFresh || summaryCommittedEmpty;
51284
51461
  const summaryUpdating = hasWarmSummary && !summaryFresh && !!streaming;
51285
51462
  const summaryStale = hasWarmSummary && !summaryFresh && !summaryUpdating;
51286
51463
  process.env.__NEXT_PRIVATE_MINIMIZE_MACRO_FALSE && (0,react.useEffect)(()=>{
@@ -51381,10 +51558,29 @@ function MessageList({ threadId, messages, steeredSegments, notices, agentConfig
51381
51558
  }
51382
51559
  boundaryAnchorRef.current = null;
51383
51560
  }, []);
51561
+ // While a programmatic smooth scroll (locate boundary, deep link) animates
51562
+ // away from the bottom, its first frames are still "near bottom". Without
51563
+ // this lock, scroll sync re-arms bottom-follow and the post-render snap
51564
+ // cancels the animation, so the target is never reached.
51565
+ const programmaticScrollUntilRef = (0,react.useRef)(0);
51384
51566
  const syncScrollButton = (0,react.useCallback)((el)=>{
51385
51567
  const isAtBottom = el.scrollHeight - el.scrollTop - el.clientHeight < 100;
51386
- atBottomRef.current = isAtBottom;
51387
- setShowScrollButton(!isAtBottom && hasScrollTarget);
51568
+ const locked = Date.now() < programmaticScrollUntilRef.current;
51569
+ atBottomRef.current = isAtBottom && !locked;
51570
+ setShowScrollButton(!atBottomRef.current && hasScrollTarget);
51571
+ }, [
51572
+ hasScrollTarget
51573
+ ]);
51574
+ const scrollTargetIntoView = (0,react.useCallback)((target)=>{
51575
+ programmaticScrollUntilRef.current = Date.now() + PROGRAMMATIC_SCROLL_LOCK_MS;
51576
+ atBottomRef.current = false;
51577
+ setShowScrollButton(hasScrollTarget);
51578
+ target.scrollIntoView({
51579
+ behavior: "smooth",
51580
+ block: "center"
51581
+ });
51582
+ target.classList.add("jarela-deep-link-flash");
51583
+ window.setTimeout(()=>target.classList.remove("jarela-deep-link-flash"), 1600);
51388
51584
  }, [
51389
51585
  hasScrollTarget
51390
51586
  ]);
@@ -51513,14 +51709,7 @@ function MessageList({ threadId, messages, steeredSegments, notices, agentConfig
51513
51709
  const safe = id.replace(/"/g, '\\"');
51514
51710
  const el = root.querySelector(`[data-message-id="${safe}"]`);
51515
51711
  if (!el) return;
51516
- atBottomRef.current = false;
51517
- setShowScrollButton(hasScrollTarget);
51518
- el.scrollIntoView({
51519
- behavior: "smooth",
51520
- block: "center"
51521
- });
51522
- el.classList.add("jarela-deep-link-flash");
51523
- setTimeout(()=>el.classList.remove("jarela-deep-link-flash"), 1600);
51712
+ scrollTargetIntoView(el);
51524
51713
  // Strip the hash so the next streaming message / list-length change
51525
51714
  // doesn't yank the view back to this anchor. replaceState avoids
51526
51715
  // triggering a hashchange event (which would re-enter this handler).
@@ -51533,7 +51722,7 @@ function MessageList({ threadId, messages, steeredSegments, notices, agentConfig
51533
51722
  return ()=>window.removeEventListener("hashchange", scrollToHashTarget);
51534
51723
  }, [
51535
51724
  messages.length,
51536
- hasScrollTarget
51725
+ scrollTargetIntoView
51537
51726
  ]);
51538
51727
  // Handle orientation changes and resizes to maintain scroll position
51539
51728
  process.env.__NEXT_PRIVATE_MINIMIZE_MACRO_FALSE && (0,react.useEffect)(()=>{
@@ -51564,419 +51753,411 @@ function MessageList({ threadId, messages, steeredSegments, notices, agentConfig
51564
51753
  if (!root) return;
51565
51754
  const boundary = effectiveHotSinceSeq !== null ? document.getElementById(`context-boundary-${effectiveHotSinceSeq}`) : root.querySelector("[data-focus-boundary='1']");
51566
51755
  if (!boundary) return;
51567
- atBottomRef.current = false;
51568
- setShowScrollButton(hasScrollTarget);
51569
- boundary.scrollIntoView({
51570
- behavior: "smooth",
51571
- block: "center"
51572
- });
51756
+ scrollTargetIntoView(boundary);
51573
51757
  }
51574
- return /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("div", {
51575
- ref: hostRef,
51576
- className: "flex-1 flex flex-col min-h-0 relative",
51577
- children: [
51578
- visibleMessages.length > 0 && /*#__PURE__*/ (0,react_jsx_runtime.jsx)("div", {
51579
- className: "shrink-0 px-4 pt-[calc(var(--app-safe-top)+3rem)] pb-1",
51580
- children: /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("div", {
51581
- className: "w-full border-b border-border/45 bg-surface/30 px-2 py-1 backdrop-blur-sm",
51758
+ return /*#__PURE__*/ (0,react_jsx_runtime.jsx)(WorkflowStepRetryContext.Provider, {
51759
+ value: retryWorkflowStep,
51760
+ children: /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("div", {
51761
+ ref: hostRef,
51762
+ className: "flex-1 flex flex-col min-h-0 relative",
51763
+ children: [
51764
+ visibleMessages.length > 0 && /*#__PURE__*/ (0,react_jsx_runtime.jsx)("div", {
51765
+ className: "shrink-0 px-4 pt-[calc(var(--app-safe-top)+3rem)] pb-1",
51766
+ children: /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("div", {
51767
+ className: "w-full border-b border-border/45 bg-surface/30 px-2 py-1 backdrop-blur-sm",
51768
+ children: [
51769
+ /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("button", {
51770
+ type: "button",
51771
+ onClick: ()=>setTopControlsOpen((v)=>!v),
51772
+ "aria-expanded": topControlsOpen,
51773
+ className: "w-full flex items-center gap-2 py-0.5 text-[11px] text-fg-faint hover:text-fg transition-colors",
51774
+ children: [
51775
+ /*#__PURE__*/ (0,react_jsx_runtime.jsx)(CollapseChevron, {
51776
+ open: topControlsOpen,
51777
+ size: 10
51778
+ }),
51779
+ /*#__PURE__*/ (0,react_jsx_runtime.jsx)("span", {
51780
+ className: "font-semibold uppercase tracking-[0.16em]",
51781
+ children: "Filters & focus"
51782
+ }),
51783
+ hiddenCount > 0 && /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("span", {
51784
+ className: "ml-auto text-[10px] text-fg-faint",
51785
+ "aria-live": "polite",
51786
+ children: [
51787
+ hiddenCount,
51788
+ " hidden"
51789
+ ]
51790
+ })
51791
+ ]
51792
+ }),
51793
+ topControlsOpen && /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("div", {
51794
+ className: "mt-1 flex items-center gap-1.5 flex-wrap py-1",
51795
+ children: [
51796
+ availableChips.map((key)=>{
51797
+ const on = filters[key];
51798
+ const Icon = on ? eye/* default */.A : EyeOff;
51799
+ return /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("button", {
51800
+ type: "button",
51801
+ onClick: ()=>toggle(key),
51802
+ className: [
51803
+ "inline-flex items-center gap-1 rounded-none border px-2 py-0.5 text-[10px] leading-4 transition-colors",
51804
+ on ? "border-border/70 bg-surface-2/70 text-fg-muted hover:text-fg" : "border-border/35 bg-transparent text-fg-faint line-through decoration-fg-faint/60 hover:text-fg-muted"
51805
+ ].join(" "),
51806
+ title: // ADR-0044 — for the three channels the model's own
51807
+ // context is scoped by, the chip's meaning is dual:
51808
+ // it doesn't just show/hide rows here, it also
51809
+ // decides whether that channel's history is folded
51810
+ // into the next turn the agent sees.
51811
+ CHANNEL_SCOPED_FILTER_KEYS.has(key) ? on ? `Hide + exclude ${CHIP_LABELS[key]} from the next turn` : `Show + include ${CHIP_LABELS[key]} in the next turn` : on ? `Hide ${CHIP_LABELS[key]} messages` : `Show ${CHIP_LABELS[key]} messages`,
51812
+ "aria-pressed": on,
51813
+ children: [
51814
+ /*#__PURE__*/ (0,react_jsx_runtime.jsx)(Icon, {
51815
+ size: 10
51816
+ }),
51817
+ /*#__PURE__*/ (0,react_jsx_runtime.jsx)("span", {
51818
+ children: CHIP_LABELS[key]
51819
+ })
51820
+ ]
51821
+ }, key);
51822
+ }),
51823
+ onSetContextPin && /*#__PURE__*/ (0,react_jsx_runtime.jsx)("button", {
51824
+ type: "button",
51825
+ onClick: scrollToBoundaryLine,
51826
+ disabled: !hasContextPin,
51827
+ className: "control-tap ml-auto rounded-none border border-border/60 bg-surface-2/70 px-2 py-0.5 text-[10px] leading-4 text-fg-faint transition-colors hover:border-accent/40 hover:text-fg disabled:cursor-not-allowed disabled:opacity-40 disabled:hover:border-border/60 disabled:hover:text-fg-faint",
51828
+ title: hasContextPin ? "Locate the focus boundary in the message list" : "Set a focus boundary first (drag the divider or pin a message) to enable this",
51829
+ children: "Locate boundary line"
51830
+ })
51831
+ ]
51832
+ })
51833
+ ]
51834
+ })
51835
+ }),
51836
+ /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("div", {
51837
+ ref: maskRegionRef,
51838
+ className: "relative flex-1 min-h-0 overflow-hidden",
51582
51839
  children: [
51583
- /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("button", {
51584
- type: "button",
51585
- onClick: ()=>setTopControlsOpen((v)=>!v),
51586
- "aria-expanded": topControlsOpen,
51587
- className: "w-full flex items-center gap-2 py-0.5 text-[11px] text-fg-faint hover:text-fg transition-colors",
51840
+ /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("div", {
51841
+ ref: scrollRef,
51842
+ onScroll: handleScroll,
51843
+ className: "flex-1 h-full overflow-y-auto overflow-x-hidden px-4 py-4 panel-scrollbar",
51844
+ style: {
51845
+ // Scroll-anchor jumps (deep-link to a message) land below the
51846
+ // floating header, not under it.
51847
+ scrollPaddingTop: "calc(3rem + var(--app-safe-top))"
51848
+ },
51588
51849
  children: [
51589
- /*#__PURE__*/ (0,react_jsx_runtime.jsx)(CollapseChevron, {
51590
- open: topControlsOpen,
51591
- size: 10
51592
- }),
51593
- /*#__PURE__*/ (0,react_jsx_runtime.jsx)("span", {
51594
- className: "font-semibold uppercase tracking-[0.16em]",
51595
- children: "Filters & focus"
51850
+ hasMore && /*#__PURE__*/ (0,react_jsx_runtime.jsx)("div", {
51851
+ className: "text-center py-1.5 text-[11px] text-fg-faint select-none",
51852
+ children: loadingMore ? "Loading earlier messages…" : "Scroll up for earlier messages"
51596
51853
  }),
51597
- hiddenCount > 0 && /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("span", {
51598
- className: "ml-auto text-[10px] text-fg-faint",
51599
- "aria-live": "polite",
51854
+ compactionPending && /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("div", {
51855
+ className: "my-2 flex items-center justify-center gap-2 rounded-lg border border-border bg-surface-2/70 px-3 py-1.5 text-[11px] text-fg-faint select-none",
51600
51856
  children: [
51601
- hiddenCount,
51602
- " hidden"
51857
+ /*#__PURE__*/ (0,react_jsx_runtime.jsx)(StatusDot, {
51858
+ tone: "accent",
51859
+ size: "sm",
51860
+ pulse: true
51861
+ }),
51862
+ /*#__PURE__*/ (0,react_jsx_runtime.jsx)("span", {
51863
+ children: "Summarising earlier messages… this turn still sees the full history."
51864
+ })
51603
51865
  ]
51604
- })
51605
- ]
51606
- }),
51607
- topControlsOpen && /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("div", {
51608
- className: "mt-1 flex items-center gap-1.5 flex-wrap py-1",
51609
- children: [
51610
- availableChips.map((key)=>{
51611
- const on = filters[key];
51612
- const Icon = on ? eye/* default */.A : EyeOff;
51613
- return /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("button", {
51614
- type: "button",
51615
- onClick: ()=>toggle(key),
51616
- className: [
51617
- "inline-flex items-center gap-1 rounded-none border px-2 py-0.5 text-[10px] leading-4 transition-colors",
51618
- on ? "border-border/70 bg-surface-2/70 text-fg-muted hover:text-fg" : "border-border/35 bg-transparent text-fg-faint line-through decoration-fg-faint/60 hover:text-fg-muted"
51619
- ].join(" "),
51620
- title: // ADR-0044 — for the three channels the model's own
51621
- // context is scoped by, the chip's meaning is dual:
51622
- // it doesn't just show/hide rows here, it also
51623
- // decides whether that channel's history is folded
51624
- // into the next turn the agent sees.
51625
- CHANNEL_SCOPED_FILTER_KEYS.has(key) ? on ? `Hide + exclude ${CHIP_LABELS[key]} from the next turn` : `Show + include ${CHIP_LABELS[key]} in the next turn` : on ? `Hide ${CHIP_LABELS[key]} messages` : `Show ${CHIP_LABELS[key]} messages`,
51626
- "aria-pressed": on,
51866
+ }),
51867
+ visibleMessages.length === 0 && !streamingContent && /*#__PURE__*/ (0,react_jsx_runtime.jsx)("div", {
51868
+ className: "flex items-center justify-center h-full text-fg-faint text-sm select-none",
51869
+ children: messages.length === 0 ? /*#__PURE__*/ (0,react_jsx_runtime.jsx)("span", {
51870
+ children: "Send a message to begin"
51871
+ }) : /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("div", {
51872
+ className: "flex flex-col items-center gap-2 text-center px-4",
51627
51873
  children: [
51628
- /*#__PURE__*/ (0,react_jsx_runtime.jsx)(Icon, {
51629
- size: 10
51874
+ /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("span", {
51875
+ children: [
51876
+ hiddenCount,
51877
+ " message",
51878
+ hiddenCount === 1 ? " is" : "s are",
51879
+ " hidden by filters"
51880
+ ]
51630
51881
  }),
51631
- /*#__PURE__*/ (0,react_jsx_runtime.jsx)("span", {
51632
- children: CHIP_LABELS[key]
51882
+ /*#__PURE__*/ (0,react_jsx_runtime.jsx)("button", {
51883
+ type: "button",
51884
+ onClick: reset,
51885
+ className: "control-tap text-xs px-2.5 py-1 rounded-md border border-border bg-surface-2 text-fg-muted hover:text-fg hover:bg-surface-3 transition-colors",
51886
+ children: "Show all messages"
51633
51887
  })
51634
51888
  ]
51635
- }, key);
51889
+ })
51636
51890
  }),
51637
- onSetContextPin && /*#__PURE__*/ (0,react_jsx_runtime.jsx)("button", {
51638
- type: "button",
51639
- onClick: scrollToBoundaryLine,
51640
- disabled: !hasContextPin,
51641
- className: "control-tap ml-auto rounded-none border border-border/60 bg-surface-2/70 px-2 py-0.5 text-[10px] leading-4 text-fg-faint transition-colors hover:border-accent/40 hover:text-fg disabled:cursor-not-allowed disabled:opacity-40 disabled:hover:border-border/60 disabled:hover:text-fg-faint",
51642
- title: hasContextPin ? "Locate the focus boundary in the message list" : "Set a focus boundary first (drag the divider or pin a message) to enable this",
51643
- children: "Locate boundary line"
51891
+ (()=>{
51892
+ // ADR-0042. The boundary divider + warm summary card live INSIDE the
51893
+ // message stream so they scroll with content (not above as a fixed
51894
+ // banner). `boundaryIndex` is the index of the first hot message in
51895
+ // the visible list; everything before it is older-than-pin and gets
51896
+ // covered by the warm summary card sitting above the divider.
51897
+ //
51898
+ const hasPin = effectiveHotSinceSeq !== null;
51899
+ const boundaryIndex = hasPin ? boundaryIndexFor(effectiveHotSinceSeq) : -1;
51900
+ const pinAfterAll = hasPin && visibleMessages.length > 0 && boundaryIndex === visibleMessages.length;
51901
+ // The pin is the boundary's source of truth. Summary data can arrive
51902
+ // later (or be unavailable on an older thread), but hiding the line
51903
+ // in that interval makes a valid focus selection look like it vanished.
51904
+ const hasBoundary = hasPin && boundaryIndex >= 0;
51905
+ const olderInVisible = pinAfterAll ? visibleMessages.length : hasBoundary ? boundaryIndex : 0;
51906
+ // "+ N more we don't know about yet" — older pages are likely unloaded.
51907
+ const olderCountLabel = olderInVisible + (hasMore ? 1 : 0);
51908
+ const attachedActivities = new Map();
51909
+ const hiddenActivityIds = new Set();
51910
+ for(let i = 0; i < visibleMessages.length - 1; i++){
51911
+ const activityMessage = visibleMessages[i];
51912
+ const activity = activityMessage.metadata?.automation_activity;
51913
+ if (!activity) continue;
51914
+ const related = visibleMessages[i + 1];
51915
+ const matches = !related.metadata?.automation_activity && (activity.source_kind === "bridge" ? related.role === "user" && related.metadata?.bridge_conversation?.key === activity.source_id : related.role === "assistant" && related.category === activity.source_kind);
51916
+ if (!matches) continue;
51917
+ attachedActivities.set(related.id, activity);
51918
+ hiddenActivityIds.add(activityMessage.id);
51919
+ }
51920
+ const previousVisibleRoles = new Map();
51921
+ let previousVisibleRole = null;
51922
+ for (const message of visibleMessages){
51923
+ previousVisibleRoles.set(message.id, previousVisibleRole);
51924
+ if (!hiddenActivityIds.has(message.id)) previousVisibleRole = message.role;
51925
+ }
51926
+ const renderBoundary = (key)=>/*#__PURE__*/ (0,react_jsx_runtime.jsx)("div", {
51927
+ id: effectiveHotSinceSeq !== null ? `context-boundary-${effectiveHotSinceSeq}` : undefined,
51928
+ "data-focus-boundary": "1",
51929
+ "data-boundary-seq": effectiveHotSinceSeq ?? undefined,
51930
+ children: /*#__PURE__*/ (0,react_jsx_runtime.jsx)(ContextBoundaryDivider, {
51931
+ sourceMessages: warmSummarySourceMessages ?? null,
51932
+ sourceChars: warmSummarySourceChars ?? null,
51933
+ summaryChars: warmSummary ? warmSummary.length : null,
51934
+ lineStats: lineStatsForHotSince(effectiveHotSinceSeq),
51935
+ updating: warmSummaryPending && !summaryFresh,
51936
+ draggable: !!onSetContextPin,
51937
+ hidden: isDraggingFocus,
51938
+ disabled: !!streaming,
51939
+ onClick: handleBoundaryClick,
51940
+ onPointerDown: handleBoundaryPointerDown,
51941
+ onPointerMove: handleBoundaryPointerMove,
51942
+ onPointerUp: handleBoundaryPointerUp,
51943
+ onPointerCancel: handleBoundaryPointerCancel
51944
+ })
51945
+ }, key);
51946
+ const nodes = visibleMessages.flatMap((msg, i)=>{
51947
+ const out = [];
51948
+ if (hasBoundary && !pinAfterAll && i === boundaryIndex) {
51949
+ out.push(renderBoundary(`boundary-${msg.id}`));
51950
+ }
51951
+ if (hiddenActivityIds.has(msg.id)) return out;
51952
+ const previousRole = previousVisibleRoles.get(msg.id);
51953
+ const startsTurn = previousRole == null || previousRole !== msg.role;
51954
+ const steeredSegment = steeredSegments?.find((segment)=>segment.id === msg.id);
51955
+ if (steeredSegment) {
51956
+ out.push(/*#__PURE__*/ (0,react_jsx_runtime.jsx)(StreamingBubble, {
51957
+ content: steeredSegment.content,
51958
+ threadId: threadId ?? null,
51959
+ agentConfig: agentConfig ?? null,
51960
+ showAvatar: i === 0 || visibleMessages[i - 1].role !== "assistant"
51961
+ }, `steered-${steeredSegment.id}`));
51962
+ }
51963
+ out.push(/*#__PURE__*/ (0,react_jsx_runtime.jsx)("div", {
51964
+ id: typeof msg.seq === "number" ? String(msg.seq) : `msg-${msg.id}`,
51965
+ "data-message-id": msg.id,
51966
+ "data-hot-candidate": "1",
51967
+ "data-message-seq": msg.seq,
51968
+ "data-created-at": msg.created_at,
51969
+ className: startsTurn && i > 0 ? "mt-3" : undefined,
51970
+ children: /*#__PURE__*/ (0,react_jsx_runtime.jsx)(MessageBubble, {
51971
+ message: msg,
51972
+ attachedActivity: attachedActivities.get(msg.id),
51973
+ threadId: threadId ?? null,
51974
+ agentConfig: agentConfig,
51975
+ userProfile: userProfile,
51976
+ showAvatar: startsTurn,
51977
+ showToolEvents: filters.tool_use,
51978
+ contextWindowTokens: contextWindowTokens ?? null,
51979
+ isLatest: i === visibleMessages.length - 1 && !streamingContent,
51980
+ onRetry: onRetryMessage
51981
+ })
51982
+ }, msg.id));
51983
+ return out;
51984
+ });
51985
+ if (hasBoundary && pinAfterAll) nodes.push(renderBoundary("boundary-tail"));
51986
+ return nodes;
51987
+ })(),
51988
+ /*#__PURE__*/ (0,react_jsx_runtime.jsx)(LiveTurnActivity, {
51989
+ thinkingContent: thinkingContent,
51990
+ streamingContent: streamingContent,
51991
+ toolEvents: toolEvents,
51992
+ filters: filters,
51993
+ threadId: threadId ?? null,
51994
+ agentConfig: agentConfig ?? null,
51995
+ showStreamingAvatar: messages.length === 0 || messages[messages.length - 1].role !== "assistant",
51996
+ streaming: streaming
51997
+ }),
51998
+ queuedMessages && queuedMessages.length > 0 && /*#__PURE__*/ (0,react_jsx_runtime.jsx)("div", {
51999
+ className: "flex flex-col gap-1 mt-2 mb-1",
52000
+ children: queuedMessages.map((q)=>/*#__PURE__*/ (0,react_jsx_runtime.jsx)(QueuedBubble, {
52001
+ item: q,
52002
+ onRemove: onRemoveQueued
52003
+ }, q.id))
51644
52004
  })
51645
52005
  ]
52006
+ }),
52007
+ /*#__PURE__*/ (0,react_jsx_runtime.jsx)("div", {
52008
+ ref: dragMaskRef,
52009
+ className: "pointer-events-none absolute left-0 right-0 top-0 z-40 opacity-0 transition-opacity duration-75",
52010
+ style: {
52011
+ transform: "translateY(0px)",
52012
+ height: "0px",
52013
+ background: "linear-gradient(to top, rgba(82,82,91,0.24) 0%, rgba(82,82,91,0.2) 22%, rgba(82,82,91,0.14) 48%, rgba(82,82,91,0.08) 72%, rgba(82,82,91,0.03) 88%, rgba(82,82,91,0) 100%)",
52014
+ borderBottom: "0",
52015
+ backdropFilter: "grayscale(0.5) saturate(0.18) contrast(0.98)",
52016
+ WebkitBackdropFilter: "grayscale(0.5) saturate(0.18) contrast(0.98)",
52017
+ maskImage: "linear-gradient(to top, black 0%, rgba(0,0,0,0.88) 72%, rgba(0,0,0,0.32) 90%, transparent 100%)",
52018
+ WebkitMaskImage: "linear-gradient(to top, black 0%, rgba(0,0,0,0.88) 72%, rgba(0,0,0,0.32) 90%, transparent 100%)"
52019
+ }
51646
52020
  })
51647
52021
  ]
51648
- })
51649
- }),
51650
- /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("div", {
51651
- ref: maskRegionRef,
51652
- className: "relative flex-1 min-h-0 overflow-hidden",
51653
- children: [
51654
- /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("div", {
51655
- ref: scrollRef,
51656
- onScroll: handleScroll,
51657
- className: "flex-1 h-full overflow-y-auto overflow-x-hidden px-4 py-4 panel-scrollbar",
52022
+ }),
52023
+ showScrollButton && /*#__PURE__*/ (0,react_jsx_runtime.jsx)("button", {
52024
+ onClick: scrollToBottom,
52025
+ style: {
52026
+ bottom: "calc(1rem + var(--app-safe-bottom))"
52027
+ },
52028
+ className: "absolute right-4 p-2 rounded-full bg-accent/40 hover:bg-accent/80 text-white backdrop-blur-sm shadow-md transition-all animate-in fade-in slide-in-from-bottom-2 duration-200 z-20",
52029
+ title: "Auto-scroll paused — resume at latest message",
52030
+ "aria-label": "Resume auto-scroll to latest message",
52031
+ children: /*#__PURE__*/ (0,react_jsx_runtime.jsx)(ArrowDown, {
52032
+ size: 18
52033
+ })
52034
+ }),
52035
+ isDraggingFocus && /*#__PURE__*/ (0,react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, {
52036
+ children: /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("div", {
52037
+ ref: dragGuideRef,
52038
+ className: "pointer-events-none absolute left-4 right-4 z-50 opacity-0",
51658
52039
  style: {
51659
- // Scroll-anchor jumps (deep-link to a message) land below the
51660
- // floating header, not under it.
51661
- scrollPaddingTop: "calc(3rem + var(--app-safe-top))"
52040
+ transform: "translateY(0px)"
51662
52041
  },
51663
52042
  children: [
51664
- hasMore && /*#__PURE__*/ (0,react_jsx_runtime.jsx)("div", {
51665
- className: "text-center py-1.5 text-[11px] text-fg-faint select-none",
51666
- children: loadingMore ? "Loading earlier messages…" : "Scroll up for earlier messages"
51667
- }),
51668
- compactionPending && /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("div", {
51669
- className: "my-2 flex items-center justify-center gap-2 rounded-lg border border-border bg-surface-2/70 px-3 py-1.5 text-[11px] text-fg-faint select-none",
51670
- children: [
51671
- /*#__PURE__*/ (0,react_jsx_runtime.jsx)(StatusDot, {
51672
- tone: "accent",
51673
- size: "sm",
51674
- pulse: true
51675
- }),
51676
- /*#__PURE__*/ (0,react_jsx_runtime.jsx)("span", {
51677
- children: "Summarising earlier messages… this turn still sees the full history."
51678
- })
51679
- ]
52043
+ /*#__PURE__*/ (0,react_jsx_runtime.jsx)("div", {
52044
+ className: "h-[2px] bg-gradient-to-r from-transparent via-accent to-transparent opacity-95 shadow-[0_0_8px_rgba(59,130,246,0.55)]"
51680
52045
  }),
51681
- visibleMessages.length === 0 && !streamingContent && /*#__PURE__*/ (0,react_jsx_runtime.jsx)("div", {
51682
- className: "flex items-center justify-center h-full text-fg-faint text-sm select-none",
51683
- children: messages.length === 0 ? /*#__PURE__*/ (0,react_jsx_runtime.jsx)("span", {
51684
- children: "Send a message to begin"
51685
- }) : /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("div", {
51686
- className: "flex flex-col items-center gap-2 text-center px-4",
52046
+ /*#__PURE__*/ (0,react_jsx_runtime.jsx)("span", {
52047
+ ref: dragGuideStatsRef,
52048
+ className: "absolute right-1 top-1/2 -translate-y-1/2 text-[10px] text-fg-faint bg-surface/75 px-1.5 rounded border border-border/60",
52049
+ children: lineStatsForHotSince(effectiveHotSinceSeq)
52050
+ })
52051
+ ]
52052
+ })
52053
+ }),
52054
+ summaryPopoverOpen && /*#__PURE__*/ (0,react_jsx_runtime.jsx)(Dialog/* Dialog */.l, {
52055
+ open: true,
52056
+ onClose: ()=>setSummaryPopoverOpen(false),
52057
+ title: "Earlier messages summary",
52058
+ size: "xl",
52059
+ align: "top",
52060
+ padded: false,
52061
+ children: /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("div", {
52062
+ className: "p-4 space-y-3",
52063
+ children: [
52064
+ /*#__PURE__*/ (0,react_jsx_runtime.jsx)("div", {
52065
+ className: "flex items-center gap-2",
52066
+ children: /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("span", {
52067
+ className: [
52068
+ "text-[10px] px-1.5 py-px rounded border inline-flex items-center gap-1",
52069
+ summaryUpdating ? "border-accent/40 bg-accent/10 text-accent" : summaryReady ? "border-emerald-500/30 bg-emerald-500/10 text-emerald-600 dark:text-emerald-400" : summaryStale ? "border-amber-500/30 bg-amber-500/10 text-amber-700 dark:text-amber-400" : "border-border bg-surface-2 text-fg-faint"
52070
+ ].join(" "),
51687
52071
  children: [
51688
- /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("span", {
51689
- children: [
51690
- hiddenCount,
51691
- " message",
51692
- hiddenCount === 1 ? " is" : "s are",
51693
- " hidden by filters"
51694
- ]
52072
+ summaryUpdating && /*#__PURE__*/ (0,react_jsx_runtime.jsx)("span", {
52073
+ className: "h-2 w-2 rounded-full bg-accent animate-pulse",
52074
+ "aria-label": "Summary updating"
51695
52075
  }),
51696
- /*#__PURE__*/ (0,react_jsx_runtime.jsx)("button", {
51697
- type: "button",
51698
- onClick: reset,
51699
- className: "control-tap text-xs px-2.5 py-1 rounded-md border border-border bg-surface-2 text-fg-muted hover:text-fg hover:bg-surface-3 transition-colors",
51700
- children: "Show all messages"
52076
+ /*#__PURE__*/ (0,react_jsx_runtime.jsx)("span", {
52077
+ children: summaryUpdating ? "updating" : summaryReady ? "ready" : summaryStale ? "needs refresh" : "pending"
51701
52078
  })
51702
52079
  ]
51703
52080
  })
51704
52081
  }),
51705
- (()=>{
51706
- // ADR-0042. The boundary divider + warm summary card live INSIDE the
51707
- // message stream so they scroll with content (not above as a fixed
51708
- // banner). `boundaryIndex` is the index of the first hot message in
51709
- // the visible list; everything before it is older-than-pin and gets
51710
- // covered by the warm summary card sitting above the divider.
51711
- //
51712
- const hasPin = effectiveHotSinceSeq !== null;
51713
- const boundaryIndex = hasPin ? boundaryIndexFor(effectiveHotSinceSeq) : -1;
51714
- const pinAfterAll = hasPin && visibleMessages.length > 0 && boundaryIndex === visibleMessages.length;
51715
- // The pin is the boundary's source of truth. Summary data can arrive
51716
- // later (or be unavailable on an older thread), but hiding the line
51717
- // in that interval makes a valid focus selection look like it vanished.
51718
- const hasBoundary = hasPin && boundaryIndex >= 0;
51719
- const olderInVisible = pinAfterAll ? visibleMessages.length : hasBoundary ? boundaryIndex : 0;
51720
- // "+ N more we don't know about yet" — older pages are likely unloaded.
51721
- const olderCountLabel = olderInVisible + (hasMore ? 1 : 0);
51722
- const attachedActivities = new Map();
51723
- const hiddenActivityIds = new Set();
51724
- for(let i = 0; i < visibleMessages.length - 1; i++){
51725
- const activityMessage = visibleMessages[i];
51726
- const activity = activityMessage.metadata?.automation_activity;
51727
- if (!activity) continue;
51728
- const related = visibleMessages[i + 1];
51729
- const matches = !related.metadata?.automation_activity && (activity.source_kind === "bridge" ? related.role === "user" && related.metadata?.bridge_conversation?.key === activity.source_id : related.role === "assistant" && related.category === activity.source_kind);
51730
- if (!matches) continue;
51731
- attachedActivities.set(related.id, activity);
51732
- hiddenActivityIds.add(activityMessage.id);
51733
- }
51734
- const previousVisibleRoles = new Map();
51735
- let previousVisibleRole = null;
51736
- for (const message of visibleMessages){
51737
- previousVisibleRoles.set(message.id, previousVisibleRole);
51738
- if (!hiddenActivityIds.has(message.id)) previousVisibleRole = message.role;
51739
- }
51740
- const renderBoundary = (key)=>/*#__PURE__*/ (0,react_jsx_runtime.jsx)("div", {
51741
- id: effectiveHotSinceSeq !== null ? `context-boundary-${effectiveHotSinceSeq}` : undefined,
51742
- "data-focus-boundary": "1",
51743
- "data-boundary-seq": effectiveHotSinceSeq ?? undefined,
51744
- children: /*#__PURE__*/ (0,react_jsx_runtime.jsx)(ContextBoundaryDivider, {
51745
- sourceMessages: warmSummarySourceMessages ?? null,
51746
- sourceChars: warmSummarySourceChars ?? null,
51747
- summaryChars: warmSummary ? warmSummary.length : null,
51748
- lineStats: lineStatsForHotSince(effectiveHotSinceSeq),
51749
- updating: warmSummaryPending && !summaryFresh,
51750
- draggable: !!onSetContextPin,
51751
- hidden: isDraggingFocus,
51752
- disabled: !!streaming,
51753
- onClick: handleBoundaryClick,
51754
- onPointerDown: handleBoundaryPointerDown,
51755
- onPointerMove: handleBoundaryPointerMove,
51756
- onPointerUp: handleBoundaryPointerUp,
51757
- onPointerCancel: handleBoundaryPointerCancel
51758
- })
51759
- }, key);
51760
- const nodes = visibleMessages.flatMap((msg, i)=>{
51761
- const out = [];
51762
- if (hasBoundary && !pinAfterAll && i === boundaryIndex) {
51763
- out.push(renderBoundary(`boundary-${msg.id}`));
51764
- }
51765
- if (hiddenActivityIds.has(msg.id)) return out;
51766
- const previousRole = previousVisibleRoles.get(msg.id);
51767
- const startsTurn = previousRole == null || previousRole !== msg.role;
51768
- const steeredSegment = steeredSegments?.find((segment)=>segment.id === msg.id);
51769
- if (steeredSegment) {
51770
- out.push(/*#__PURE__*/ (0,react_jsx_runtime.jsx)(StreamingBubble, {
51771
- content: steeredSegment.content,
51772
- threadId: threadId ?? null,
51773
- agentConfig: agentConfig ?? null,
51774
- showAvatar: i === 0 || visibleMessages[i - 1].role !== "assistant"
51775
- }, `steered-${steeredSegment.id}`));
51776
- }
51777
- out.push(/*#__PURE__*/ (0,react_jsx_runtime.jsx)("div", {
51778
- id: typeof msg.seq === "number" ? String(msg.seq) : `msg-${msg.id}`,
51779
- "data-message-id": msg.id,
51780
- "data-hot-candidate": "1",
51781
- "data-message-seq": msg.seq,
51782
- "data-created-at": msg.created_at,
51783
- className: startsTurn && i > 0 ? "mt-3" : undefined,
51784
- children: /*#__PURE__*/ (0,react_jsx_runtime.jsx)(MessageBubble, {
51785
- message: msg,
51786
- attachedActivity: attachedActivities.get(msg.id),
51787
- threadId: threadId ?? null,
51788
- agentConfig: agentConfig,
51789
- userProfile: userProfile,
51790
- showAvatar: startsTurn,
51791
- showToolEvents: filters.tool_use,
51792
- contextWindowTokens: contextWindowTokens ?? null,
51793
- isLatest: i === visibleMessages.length - 1 && !streamingContent,
51794
- onRetry: onRetryMessage
51795
- })
51796
- }, msg.id));
51797
- return out;
51798
- });
51799
- if (hasBoundary && pinAfterAll) nodes.push(renderBoundary("boundary-tail"));
51800
- return nodes;
51801
- })(),
51802
- /*#__PURE__*/ (0,react_jsx_runtime.jsx)(LiveTurnActivity, {
51803
- thinkingContent: thinkingContent,
51804
- streamingContent: streamingContent,
51805
- toolEvents: toolEvents,
51806
- filters: filters,
51807
- threadId: threadId ?? null,
51808
- agentConfig: agentConfig ?? null,
51809
- showStreamingAvatar: messages.length === 0 || messages[messages.length - 1].role !== "assistant",
51810
- streaming: streaming
51811
- }),
51812
- queuedMessages && queuedMessages.length > 0 && /*#__PURE__*/ (0,react_jsx_runtime.jsx)("div", {
51813
- className: "flex flex-col gap-1 mt-2 mb-1",
51814
- children: queuedMessages.map((q)=>/*#__PURE__*/ (0,react_jsx_runtime.jsx)(QueuedBubble, {
51815
- item: q,
51816
- onRemove: onRemoveQueued
51817
- }, q.id))
52082
+ !summaryUpdating && /*#__PURE__*/ (0,react_jsx_runtime.jsx)("p", {
52083
+ className: "text-[11px] text-fg-faint",
52084
+ children: summaryFresh ? "Showing the latest summary for messages above the boundary line." : summaryCommittedEmpty ? warmChannelSummaries.length > 0 ? "No chat messages above the boundary line; automation activity there is summarised below." : "Nothing above the boundary line needed summarising." : summaryStale ? "This summary is from an older focus and will refresh after the next reply." : "No summary yet. It will appear after the next reply."
51818
52085
  }),
51819
- notices?.map((n)=>/*#__PURE__*/ (0,react_jsx_runtime.jsx)("div", {
51820
- className: "flex justify-center my-3",
51821
- children: /*#__PURE__*/ (0,react_jsx_runtime.jsx)("span", {
51822
- className: "text-xs italic text-fg-faint bg-surface-2 px-3 py-1 rounded-full border border-border",
51823
- children: n.text
51824
- })
51825
- }, n.id))
52086
+ /*#__PURE__*/ (0,react_jsx_runtime.jsx)(WarmSummaryCard, {
52087
+ olderCount: countOlderForHotSince(effectiveHotSinceSeq) + (hasMore ? 1 : 0),
52088
+ summary: warmSummary ?? null,
52089
+ summaryBeforeSeq: warmSummaryBeforeSeq ?? null,
52090
+ hotSinceSeq: effectiveHotSinceSeq,
52091
+ computedAt: warmSummaryComputedAt ?? null,
52092
+ streaming: !!streaming,
52093
+ topics: warmSummaryTopics ?? null,
52094
+ channelSummaries: warmChannelSummaries
52095
+ })
51826
52096
  ]
51827
- }),
51828
- /*#__PURE__*/ (0,react_jsx_runtime.jsx)("div", {
51829
- ref: dragMaskRef,
51830
- className: "pointer-events-none absolute left-0 right-0 top-0 z-40 opacity-0 transition-opacity duration-75",
51831
- style: {
51832
- transform: "translateY(0px)",
51833
- height: "0px",
51834
- background: "linear-gradient(to top, rgba(82,82,91,0.24) 0%, rgba(82,82,91,0.2) 22%, rgba(82,82,91,0.14) 48%, rgba(82,82,91,0.08) 72%, rgba(82,82,91,0.03) 88%, rgba(82,82,91,0) 100%)",
51835
- borderBottom: "0",
51836
- backdropFilter: "grayscale(0.5) saturate(0.18) contrast(0.98)",
51837
- WebkitBackdropFilter: "grayscale(0.5) saturate(0.18) contrast(0.98)",
51838
- maskImage: "linear-gradient(to top, black 0%, rgba(0,0,0,0.88) 72%, rgba(0,0,0,0.32) 90%, transparent 100%)",
51839
- WebkitMaskImage: "linear-gradient(to top, black 0%, rgba(0,0,0,0.88) 72%, rgba(0,0,0,0.32) 90%, transparent 100%)"
51840
- }
51841
52097
  })
51842
- ]
51843
- }),
51844
- showScrollButton && /*#__PURE__*/ (0,react_jsx_runtime.jsx)("button", {
51845
- onClick: scrollToBottom,
51846
- style: {
51847
- bottom: "calc(1rem + var(--app-safe-bottom))"
51848
- },
51849
- className: "absolute right-4 p-2 rounded-full bg-accent/40 hover:bg-accent/80 text-white backdrop-blur-sm shadow-md transition-all animate-in fade-in slide-in-from-bottom-2 duration-200 z-20",
51850
- title: "Auto-scroll paused — resume at latest message",
51851
- "aria-label": "Resume auto-scroll to latest message",
51852
- children: /*#__PURE__*/ (0,react_jsx_runtime.jsx)(ArrowDown, {
51853
- size: 18
51854
- })
51855
- }),
51856
- isDraggingFocus && /*#__PURE__*/ (0,react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, {
51857
- children: /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("div", {
51858
- ref: dragGuideRef,
51859
- className: "pointer-events-none absolute left-4 right-4 z-50 opacity-0",
51860
- style: {
51861
- transform: "translateY(0px)"
52098
+ }),
52099
+ /*#__PURE__*/ (0,react_jsx_runtime.jsxs)(Dialog/* Dialog */.l, {
52100
+ open: confirmOpen,
52101
+ onClose: ()=>{
52102
+ setConfirmOpen(false);
52103
+ setPendingHotSinceSeq(null);
51862
52104
  },
52105
+ size: "sm",
52106
+ align: "center",
52107
+ dismissOnBackdrop: false,
51863
52108
  children: [
51864
- /*#__PURE__*/ (0,react_jsx_runtime.jsx)("div", {
51865
- className: "h-[2px] bg-gradient-to-r from-transparent via-accent to-transparent opacity-95 shadow-[0_0_8px_rgba(59,130,246,0.55)]"
52109
+ /*#__PURE__*/ (0,react_jsx_runtime.jsx)("h4", {
52110
+ className: "text-sm font-semibold text-fg",
52111
+ children: "Move conversation focus here?"
51866
52112
  }),
51867
- /*#__PURE__*/ (0,react_jsx_runtime.jsx)("span", {
51868
- ref: dragGuideStatsRef,
51869
- className: "absolute right-1 top-1/2 -translate-y-1/2 text-[10px] text-fg-faint bg-surface/75 px-1.5 rounded border border-border/60",
51870
- children: lineStatsForHotSince(effectiveHotSinceSeq)
51871
- })
51872
- ]
51873
- })
51874
- }),
51875
- summaryPopoverOpen && /*#__PURE__*/ (0,react_jsx_runtime.jsx)(Dialog/* Dialog */.l, {
51876
- open: true,
51877
- onClose: ()=>setSummaryPopoverOpen(false),
51878
- title: "Earlier messages summary",
51879
- size: "xl",
51880
- align: "top",
51881
- padded: false,
51882
- children: /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("div", {
51883
- className: "p-4 space-y-3",
51884
- children: [
51885
- /*#__PURE__*/ (0,react_jsx_runtime.jsx)("div", {
51886
- className: "flex items-center gap-2",
51887
- children: /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("span", {
51888
- className: [
51889
- "text-[10px] px-1.5 py-px rounded border inline-flex items-center gap-1",
51890
- summaryUpdating ? "border-accent/40 bg-accent/10 text-accent" : summaryFresh ? "border-emerald-500/30 bg-emerald-500/10 text-emerald-600 dark:text-emerald-400" : summaryStale ? "border-amber-500/30 bg-amber-500/10 text-amber-700 dark:text-amber-400" : "border-border bg-surface-2 text-fg-faint"
51891
- ].join(" "),
51892
- children: [
51893
- summaryUpdating && /*#__PURE__*/ (0,react_jsx_runtime.jsx)("span", {
51894
- className: "h-2 w-2 rounded-full bg-accent animate-pulse",
51895
- "aria-label": "Summary updating"
51896
- }),
51897
- /*#__PURE__*/ (0,react_jsx_runtime.jsx)("span", {
51898
- children: summaryUpdating ? "updating" : summaryFresh ? "ready" : summaryStale ? "needs refresh" : "pending"
51899
- })
51900
- ]
51901
- })
52113
+ /*#__PURE__*/ (0,react_jsx_runtime.jsx)("p", {
52114
+ className: "text-xs text-fg-muted leading-relaxed",
52115
+ children: "Start a new conversation context from this point. New replies will prioritize recent messages below this line."
51902
52116
  }),
51903
- !summaryUpdating && /*#__PURE__*/ (0,react_jsx_runtime.jsx)("p", {
52117
+ nextHotCount !== null && /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("p", {
51904
52118
  className: "text-[11px] text-fg-faint",
51905
- children: summaryFresh ? "Showing the latest summary for messages above the boundary line." : summaryStale ? "This summary is from an older focus and will refresh after the next reply." : "No summary yet. It will appear after the next reply."
52119
+ children: [
52120
+ "Recent in focus: ",
52121
+ nextHotCount,
52122
+ " loaded message",
52123
+ nextHotCount === 1 ? "" : "s",
52124
+ "; earlier loaded summary: ",
52125
+ Math.max(0, visibleMessages.length - nextHotCount),
52126
+ "."
52127
+ ]
51906
52128
  }),
51907
- /*#__PURE__*/ (0,react_jsx_runtime.jsx)(WarmSummaryCard, {
51908
- olderCount: countOlderForHotSince(effectiveHotSinceSeq) + (hasMore ? 1 : 0),
51909
- summary: warmSummary ?? null,
51910
- summaryBeforeSeq: warmSummaryBeforeSeq ?? null,
51911
- hotSinceSeq: effectiveHotSinceSeq,
51912
- computedAt: warmSummaryComputedAt ?? null,
51913
- streaming: !!streaming,
51914
- topics: warmSummaryTopics ?? null
52129
+ removesFromRecent && /*#__PURE__*/ (0,react_jsx_runtime.jsx)("p", {
52130
+ className: "text-[11px] text-amber-600 dark:text-amber-400",
52131
+ children: "This reduces recent in-focus messages. You can drag upward later to add history back."
52132
+ }),
52133
+ /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("div", {
52134
+ className: "flex justify-end gap-2 pt-1",
52135
+ children: [
52136
+ /*#__PURE__*/ (0,react_jsx_runtime.jsx)("button", {
52137
+ type: "button",
52138
+ onClick: ()=>{
52139
+ setConfirmOpen(false);
52140
+ setPendingHotSinceSeq(null);
52141
+ },
52142
+ className: "px-3 py-1.5 text-xs text-fg-subtle hover:text-fg transition-colors",
52143
+ children: "Cancel"
52144
+ }),
52145
+ /*#__PURE__*/ (0,react_jsx_runtime.jsx)("button", {
52146
+ type: "button",
52147
+ onClick: ()=>{
52148
+ if (pendingHotSinceSeq !== null && onSetContextPin) onSetContextPin(pendingHotSinceSeq);
52149
+ setConfirmOpen(false);
52150
+ setPendingHotSinceSeq(null);
52151
+ },
52152
+ className: "px-3 py-1.5 rounded-md text-xs border border-accent/40 bg-accent text-white hover:opacity-95 transition-opacity",
52153
+ children: "Move focus"
52154
+ })
52155
+ ]
51915
52156
  })
51916
52157
  ]
51917
52158
  })
51918
- }),
51919
- /*#__PURE__*/ (0,react_jsx_runtime.jsxs)(Dialog/* Dialog */.l, {
51920
- open: confirmOpen,
51921
- onClose: ()=>{
51922
- setConfirmOpen(false);
51923
- setPendingHotSinceSeq(null);
51924
- },
51925
- size: "sm",
51926
- align: "center",
51927
- dismissOnBackdrop: false,
51928
- children: [
51929
- /*#__PURE__*/ (0,react_jsx_runtime.jsx)("h4", {
51930
- className: "text-sm font-semibold text-fg",
51931
- children: "Move conversation focus here?"
51932
- }),
51933
- /*#__PURE__*/ (0,react_jsx_runtime.jsx)("p", {
51934
- className: "text-xs text-fg-muted leading-relaxed",
51935
- children: "Start a new conversation context from this point. New replies will prioritize recent messages below this line."
51936
- }),
51937
- nextHotCount !== null && /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("p", {
51938
- className: "text-[11px] text-fg-faint",
51939
- children: [
51940
- "Recent in focus: ",
51941
- nextHotCount,
51942
- " loaded message",
51943
- nextHotCount === 1 ? "" : "s",
51944
- "; earlier loaded summary: ",
51945
- Math.max(0, visibleMessages.length - nextHotCount),
51946
- "."
51947
- ]
51948
- }),
51949
- removesFromRecent && /*#__PURE__*/ (0,react_jsx_runtime.jsx)("p", {
51950
- className: "text-[11px] text-amber-600 dark:text-amber-400",
51951
- children: "This reduces recent in-focus messages. You can drag upward later to add history back."
51952
- }),
51953
- /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("div", {
51954
- className: "flex justify-end gap-2 pt-1",
51955
- children: [
51956
- /*#__PURE__*/ (0,react_jsx_runtime.jsx)("button", {
51957
- type: "button",
51958
- onClick: ()=>{
51959
- setConfirmOpen(false);
51960
- setPendingHotSinceSeq(null);
51961
- },
51962
- className: "px-3 py-1.5 text-xs text-fg-subtle hover:text-fg transition-colors",
51963
- children: "Cancel"
51964
- }),
51965
- /*#__PURE__*/ (0,react_jsx_runtime.jsx)("button", {
51966
- type: "button",
51967
- onClick: ()=>{
51968
- if (pendingHotSinceSeq !== null && onSetContextPin) onSetContextPin(pendingHotSinceSeq);
51969
- setConfirmOpen(false);
51970
- setPendingHotSinceSeq(null);
51971
- },
51972
- className: "px-3 py-1.5 rounded-md text-xs border border-accent/40 bg-accent text-white hover:opacity-95 transition-opacity",
51973
- children: "Move focus"
51974
- })
51975
- ]
51976
- })
51977
- ]
51978
- })
51979
- ]
52159
+ ]
52160
+ })
51980
52161
  });
51981
52162
  }
51982
52163
  // ADR-0044 — the subset of MESSAGE_FILTER_KEYS that also map to a
@@ -51988,6 +52169,7 @@ const CHANNEL_SCOPED_FILTER_KEYS = new Set([
51988
52169
  "watcher",
51989
52170
  "bridge"
51990
52171
  ]);
52172
+ const PROGRAMMATIC_SCROLL_LOCK_MS = 1500;
51991
52173
  const CHIP_LABELS = {
51992
52174
  scheduled_task: "scheduled",
51993
52175
  watcher: "watcher",
@@ -52157,7 +52339,46 @@ function QueuedBubble({ item, onRemove }) {
52157
52339
  }
52158
52340
 
52159
52341
  ;// ./components/chat/chat-helpers.ts
52160
- /* __next_internal_client_entry_do_not_use__ isUnconfirmed,appendUnique,applyThreadMeta,makeQueuedId,parseWarmSummaryTopics auto */ // Append-with-reconcile. Merges server-persisted rows into the local list
52342
+ /* __next_internal_client_entry_do_not_use__ compactionOutcomeToast,isUnconfirmed,appendUnique,applyThreadMeta,makeQueuedId,parseWarmSummaryTopics auto */ // Maps the /compact response to the toast the user sees. The server's reason
52343
+ // decides the text: "nothing to compact" means the thread is empty, anything
52344
+ // else means there were messages but no summary came out of them.
52345
+ function compactionOutcomeToast(result) {
52346
+ if (result.compacted) {
52347
+ const n = result.message_count ?? 0;
52348
+ return {
52349
+ kind: "success",
52350
+ title: "Context compacted",
52351
+ body: n > 0 ? `Summarised ${n} message${n === 1 ? "" : "s"} into warm context.` : "Started a fresh context window."
52352
+ };
52353
+ }
52354
+ if (result.reason === "nothing to compact") {
52355
+ return {
52356
+ kind: "info",
52357
+ title: "Nothing to compact",
52358
+ body: "This conversation has no messages yet."
52359
+ };
52360
+ }
52361
+ if (result.reason === "already compacting") {
52362
+ return {
52363
+ kind: "info",
52364
+ title: "Already compacting",
52365
+ body: "A compaction for this conversation is still running."
52366
+ };
52367
+ }
52368
+ if (result.reason === "timed out") {
52369
+ return {
52370
+ kind: "error",
52371
+ title: "Compaction timed out",
52372
+ body: "The summary took too long and was discarded. Context is unchanged."
52373
+ };
52374
+ }
52375
+ return {
52376
+ kind: "info",
52377
+ title: "Nothing was compacted",
52378
+ body: "There was too little to summarise, or the model returned no usable summary. Context is unchanged."
52379
+ };
52380
+ }
52381
+ // Append-with-reconcile. Merges server-persisted rows into the local list
52161
52382
  // with three rules, applied in order for each incoming message:
52162
52383
  //
52163
52384
  // 1. Already present by server id → update in place (handles the
@@ -52242,10 +52463,12 @@ function applyThreadMeta(meta, payload) {
52242
52463
  meta.setWarmSummarySourceMessages(payload.warm_summary_source_messages ?? null);
52243
52464
  meta.setWarmSummarySourceChars(payload.warm_summary_source_chars ?? null);
52244
52465
  meta.setWarmSummaryTopics?.(payload.warm_summary_topics ?? null);
52466
+ meta.setWarmChannelSummaries?.(payload.warm_channel_summaries ?? []);
52245
52467
  meta.setContextWindowTokens(payload.context_window_tokens ?? null);
52246
52468
  const summaryFresh = hotSinceSeq !== null && summaryBeforeSeq === hotSinceSeq;
52247
52469
  meta.setWarmSummaryPending?.(hotSinceSeq !== null && !summaryFresh);
52248
52470
  meta.setCompactionPending?.(payload.pending_hot_since_seq != null);
52471
+ meta.setManualCompactionPending?.(payload.manual_compaction_pending === true);
52249
52472
  }
52250
52473
  function makeQueuedId(prefix = "q") {
52251
52474
  return `${prefix}-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;
@@ -52261,8 +52484,6 @@ function makeQueuedId(prefix = "q") {
52261
52484
  }
52262
52485
  }
52263
52486
 
52264
- // EXTERNAL MODULE: ./lib/ui/error-report.ts
52265
- var error_report = __webpack_require__(10778);
52266
52487
  ;// ./lib/ui/error-message.ts
52267
52488
  /* __next_internal_client_entry_do_not_use__ friendlyErrorTitle,reportError auto */ // Centralized human-friendly error-title mapping. Used by pushErrorToast
52268
52489
  // callers so the headline a user sees is consistent across the UI:
@@ -52593,7 +52814,6 @@ function useThreadCrossDeviceSync({ threadId, streamingRef, messagesRef, setMess
52593
52814
 
52594
52815
  function useThreadData({ threadId, attach }) {
52595
52816
  const [messages, setMessages] = (0,react.useState)([]);
52596
- const [notices, setNotices] = (0,react.useState)([]);
52597
52817
  const [hasMore, setHasMore] = (0,react.useState)(false);
52598
52818
  const [loadingMore, setLoadingMore] = (0,react.useState)(false);
52599
52819
  const [messagesLoading, setMessagesLoading] = (0,react.useState)(false);
@@ -52607,8 +52827,10 @@ function useThreadData({ threadId, attach }) {
52607
52827
  const [warmSummarySourceMessages, setWarmSummarySourceMessages] = (0,react.useState)(null);
52608
52828
  const [warmSummarySourceChars, setWarmSummarySourceChars] = (0,react.useState)(null);
52609
52829
  const [warmSummaryTopics, setWarmSummaryTopics] = (0,react.useState)(null);
52830
+ const [warmChannelSummaries, setWarmChannelSummaries] = (0,react.useState)([]);
52610
52831
  const [warmSummaryPending, setWarmSummaryPending] = (0,react.useState)(false);
52611
52832
  const [compactionPending, setCompactionPending] = (0,react.useState)(false);
52833
+ const [manualCompactionPending, setManualCompactionPending] = (0,react.useState)(false);
52612
52834
  const [contextWindowTokens, setContextWindowTokens] = (0,react.useState)(null);
52613
52835
  const messagesRef = (0,react.useRef)([]);
52614
52836
  messagesRef.current = messages;
@@ -52625,22 +52847,14 @@ function useThreadData({ threadId, attach }) {
52625
52847
  setContextWindowTokens,
52626
52848
  setWarmSummaryPending,
52627
52849
  setCompactionPending,
52628
- setWarmSummaryTopics
52850
+ setManualCompactionPending,
52851
+ setWarmSummaryTopics,
52852
+ setWarmChannelSummaries
52629
52853
  };
52630
- const addNotice = (0,react.useCallback)((text)=>{
52631
- setNotices((p)=>[
52632
- ...p,
52633
- {
52634
- id: `notice-${Date.now()}`,
52635
- text
52636
- }
52637
- ]);
52638
- }, []);
52639
52854
  process.env.__NEXT_PRIVATE_MINIMIZE_MACRO_FALSE && (0,react.useEffect)(()=>{
52640
52855
  if (!threadId) {
52641
52856
  setMetadataThreadId(null);
52642
52857
  setMessages([]);
52643
- setNotices([]);
52644
52858
  setHasMore(false);
52645
52859
  setMessagesLoading(false);
52646
52860
  setHotSince(null);
@@ -52652,8 +52866,10 @@ function useThreadData({ threadId, attach }) {
52652
52866
  setWarmSummarySourceMessages(null);
52653
52867
  setWarmSummarySourceChars(null);
52654
52868
  setWarmSummaryTopics(null);
52869
+ setWarmChannelSummaries([]);
52655
52870
  setWarmSummaryPending(false);
52656
52871
  setCompactionPending(false);
52872
+ setManualCompactionPending(false);
52657
52873
  setContextWindowTokens(null);
52658
52874
  return;
52659
52875
  }
@@ -52671,8 +52887,10 @@ function useThreadData({ threadId, attach }) {
52671
52887
  setWarmSummarySourceMessages(null);
52672
52888
  setWarmSummarySourceChars(null);
52673
52889
  setWarmSummaryTopics(null);
52890
+ setWarmChannelSummaries([]);
52674
52891
  setWarmSummaryPending(false);
52675
52892
  setCompactionPending(false);
52893
+ setManualCompactionPending(false);
52676
52894
  setContextWindowTokens(null);
52677
52895
  client/* api */.FH.threads.get(threadId).then((d)=>{
52678
52896
  if (cancelled) return;
@@ -52718,6 +52936,7 @@ function useThreadData({ threadId, attach }) {
52718
52936
  setWarmSummarySourceMessages(updated.warm_summary_source_messages);
52719
52937
  setWarmSummarySourceChars(updated.warm_summary_source_chars);
52720
52938
  setWarmSummaryTopics(updated.warm_summary_topics);
52939
+ setWarmChannelSummaries(updated.warm_channel_summaries ?? []);
52721
52940
  setCompactionPending(updated.pending_hot_since_seq != null);
52722
52941
  const summaryFresh = updated.hot_since_seq != null && updated.warm_summary_before_seq === updated.hot_since_seq;
52723
52942
  if (!updated.pending_hot_since_seq && (!updated.hot_since_seq || summaryFresh)) {
@@ -52735,7 +52954,7 @@ function useThreadData({ threadId, attach }) {
52735
52954
  if (!threadId) return;
52736
52955
  const summaryFresh = hotSinceSeq !== null && warmSummaryBeforeSeq === hotSinceSeq;
52737
52956
  const summaryStale = warmSummaryPending && hotSinceSeq !== null && !summaryFresh;
52738
- if (!summaryStale && !compactionPending) {
52957
+ if (!summaryStale && !compactionPending && !manualCompactionPending) {
52739
52958
  if (warmSummaryPending && hotSinceSeq !== null && summaryFresh) setWarmSummaryPending(false);
52740
52959
  return;
52741
52960
  }
@@ -52761,6 +52980,7 @@ function useThreadData({ threadId, attach }) {
52761
52980
  threadId,
52762
52981
  warmSummaryPending,
52763
52982
  compactionPending,
52983
+ manualCompactionPending,
52764
52984
  hotSince,
52765
52985
  hotSinceSeq,
52766
52986
  warmSummaryBefore,
@@ -52798,9 +53018,6 @@ function useThreadData({ threadId, attach }) {
52798
53018
  messages,
52799
53019
  setMessages,
52800
53020
  messagesRef,
52801
- notices,
52802
- setNotices,
52803
- addNotice,
52804
53021
  hasMore,
52805
53022
  setHasMore,
52806
53023
  loadingMore,
@@ -52815,8 +53032,10 @@ function useThreadData({ threadId, attach }) {
52815
53032
  warmSummarySourceMessages,
52816
53033
  warmSummarySourceChars,
52817
53034
  warmSummaryTopics,
53035
+ warmChannelSummaries,
52818
53036
  warmSummaryPending,
52819
53037
  compactionPending,
53038
+ manualCompactionPending,
52820
53039
  contextWindowTokens,
52821
53040
  metaApplier,
52822
53041
  loadOlder,
@@ -52824,6 +53043,96 @@ function useThreadData({ threadId, attach }) {
52824
53043
  };
52825
53044
  }
52826
53045
 
53046
+ ;// ./components/chat/useThreadActivity.ts
53047
+ /* __next_internal_client_entry_do_not_use__ useThreadActivity auto */
53048
+
53049
+
53050
+ const BUSY_POLL_MS = 1500;
53051
+ const IDLE_POLL_MS = 5000;
53052
+ // A run's stream ends a moment before the registry marks it finished; a
53053
+ // snapshot inside this window may still report the run that just ended.
53054
+ const SETTLE_GRACE_MS = 2000;
53055
+ /**
53056
+ * Poll what the thread is doing on the server and keep the chat in step:
53057
+ * re-attach to a turn started elsewhere (scheduler, watcher, bridge, another
53058
+ * device), restore compaction flags after a remount, and refresh the thread
53059
+ * metadata once a compaction finishes.
53060
+ */ function useThreadActivity({ threadId, attach, isLive, lastSettledAt, metaApplier }) {
53061
+ const [activity, setActivity] = (0,react.useState)(null);
53062
+ const deps = (0,react.useRef)({
53063
+ attach,
53064
+ isLive,
53065
+ lastSettledAt,
53066
+ metaApplier
53067
+ });
53068
+ deps.current = {
53069
+ attach,
53070
+ isLive,
53071
+ lastSettledAt,
53072
+ metaApplier
53073
+ };
53074
+ process.env.__NEXT_PRIVATE_MINIMIZE_MACRO_FALSE && (0,react.useEffect)(()=>{
53075
+ setActivity(null);
53076
+ if (!threadId) return;
53077
+ let cancelled = false;
53078
+ let timer = null;
53079
+ let hadCompaction = false;
53080
+ const schedule = (ms)=>{
53081
+ if (!cancelled) timer = window.setTimeout(tick, ms);
53082
+ };
53083
+ async function tick() {
53084
+ if (cancelled || !threadId) return;
53085
+ if (typeof document !== "undefined" && document.hidden) {
53086
+ schedule(IDLE_POLL_MS);
53087
+ return;
53088
+ }
53089
+ let next;
53090
+ try {
53091
+ next = await client/* api */.FH.threads.activity(threadId);
53092
+ } catch {
53093
+ schedule(IDLE_POLL_MS);
53094
+ return;
53095
+ }
53096
+ if (cancelled) return;
53097
+ setActivity(next);
53098
+ const d = deps.current;
53099
+ const serverRunning = next.run !== null || next.queue_depth > 0;
53100
+ const recentlySettled = Date.now() - d.lastSettledAt() < SETTLE_GRACE_MS;
53101
+ if (serverRunning && !d.isLive() && !recentlySettled) {
53102
+ d.attach(threadId).catch(()=>{});
53103
+ }
53104
+ if (next.compaction) {
53105
+ if (next.compaction.kind !== "refresh") d.metaApplier.setCompactionPending?.(true);
53106
+ if (next.compaction.kind === "manual") d.metaApplier.setManualCompactionPending?.(true);
53107
+ hadCompaction = true;
53108
+ } else if (hadCompaction) {
53109
+ hadCompaction = false;
53110
+ // The compaction just finished. Clear the flags from the snapshot
53111
+ // itself so a failed refresh below can't leave the chat locked, then
53112
+ // pull the new boundary and recap.
53113
+ d.metaApplier.setCompactionPending?.(false);
53114
+ d.metaApplier.setManualCompactionPending?.(false);
53115
+ client/* api */.FH.threads.get(threadId, {
53116
+ limit: 1
53117
+ }).then((meta)=>{
53118
+ if (!cancelled) applyThreadMeta(deps.current.metaApplier, meta);
53119
+ }).catch(()=>{});
53120
+ }
53121
+ schedule(next.busy ? BUSY_POLL_MS : IDLE_POLL_MS);
53122
+ }
53123
+ // The thread load attaches to any in-flight run itself; give it a beat
53124
+ // so this poller doesn't race it with a second attach.
53125
+ schedule(BUSY_POLL_MS);
53126
+ return ()=>{
53127
+ cancelled = true;
53128
+ if (timer !== null) window.clearTimeout(timer);
53129
+ };
53130
+ }, [
53131
+ threadId
53132
+ ]);
53133
+ return activity;
53134
+ }
53135
+
52827
53136
  ;// ./components/chat/useUserProfileAndAgent.ts
52828
53137
  /* __next_internal_client_entry_do_not_use__ useUserProfileAndAgent auto */
52829
53138
 
@@ -53023,6 +53332,9 @@ function useChatSubmitHandlers({ agentId, steerRun, attachments, setAttachments,
53023
53332
 
53024
53333
 
53025
53334
 
53335
+
53336
+
53337
+
53026
53338
 
53027
53339
  function ChatView({ threadId, agentId, sessionLoading, sessionError, onMessageSent }) {
53028
53340
  const { state } = (0,AppContext/* useAppContext */.U)();
@@ -53079,6 +53391,19 @@ function ChatView({ threadId, agentId, sessionLoading, sessionError, onMessageSe
53079
53391
  attachRef.current = sse.attach;
53080
53392
  clearStreamingRef.current = sse.clearStreamingContent;
53081
53393
  clearToolEventsRef.current = sse.clearToolEvents;
53394
+ // `compacting` lives in this component, which remounts per agent; the
53395
+ // server flag keeps a /compact started before an agent switch visible.
53396
+ const sessionCompacting = compacting || thread.manualCompactionPending;
53397
+ const activity = useThreadActivity({
53398
+ threadId,
53399
+ attach: stableAttach,
53400
+ isLive: sse.isLive,
53401
+ lastSettledAt: sse.lastSettledAt,
53402
+ metaApplier: thread.metaApplier
53403
+ });
53404
+ // Run phases come through the attached stream; background compaction
53405
+ // outside a run has no stream, so label it from the polled activity.
53406
+ const backgroundCompaction = !sse.streaming && !sessionCompacting ? activity?.compaction?.kind ?? null : null;
53082
53407
  useChatErrorReporting({
53083
53408
  sessionError,
53084
53409
  streamError: sse.error,
@@ -53088,6 +53413,8 @@ function ChatView({ threadId, agentId, sessionLoading, sessionError, onMessageSe
53088
53413
  });
53089
53414
  const streamingRef = (0,react.useRef)(false);
53090
53415
  streamingRef.current = sse.streaming;
53416
+ const currentThreadIdRef = (0,react.useRef)(threadId);
53417
+ currentThreadIdRef.current = threadId;
53091
53418
  // Auto compaction starts server-side during a run; poll so the banner shows live.
53092
53419
  process.env.__NEXT_PRIVATE_MINIMIZE_MACRO_FALSE && (0,react.useEffect)(()=>{
53093
53420
  if (!threadId || !sse.streaming) return;
@@ -53118,10 +53445,13 @@ function ChatView({ threadId, agentId, sessionLoading, sessionError, onMessageSe
53118
53445
  });
53119
53446
  useTrackLoading(!!sessionLoading);
53120
53447
  useTrackLoading(sse.streaming);
53121
- useTrackLoading(compacting);
53448
+ useTrackLoading(sessionCompacting);
53122
53449
  useTrackLoading(thread.loadingMore);
53123
53450
  useTrackLoading(thread.messagesLoading);
53124
53451
  useTrackLoading(agentConfigLoading);
53452
+ useActivityWhile(sessionCompacting, "Compacting session…");
53453
+ useActivityWhile(backgroundCompaction === "auto", "Compacting earlier messages…");
53454
+ useActivityWhile(backgroundCompaction === "refresh", "Updating summary…");
53125
53455
  useActivityWhile(thread.messagesLoading, "Loading chat history…");
53126
53456
  useActivityWhile(agentConfigLoading, "Loading agent…");
53127
53457
  useActivityWhile(profileLoading, "Loading profile…");
@@ -53225,19 +53555,35 @@ function ChatView({ threadId, agentId, sessionLoading, sessionError, onMessageSe
53225
53555
  const queue = useChatQueue({
53226
53556
  threadId,
53227
53557
  streaming: sse.streaming,
53228
- compacting,
53558
+ compacting: sessionCompacting,
53229
53559
  launchRun
53230
53560
  });
53231
53561
  queueApiRef.current = queue;
53232
53562
  drainQueueRef.current = queue.drainQueueRef.current;
53233
53563
  async function handleCompact() {
53234
53564
  if (!agentId) return;
53565
+ const notifyCompaction = (result)=>{
53566
+ const toast = compactionOutcomeToast(result);
53567
+ (0,ui_toasts/* pushToast */.Iz)({
53568
+ ...toast,
53569
+ source: "system",
53570
+ sourceLabel: "Chat",
53571
+ agent_id: agentId,
53572
+ thread_id: threadId,
53573
+ ttl: 5000,
53574
+ dedupeKey: `compact:${agentId}`
53575
+ });
53576
+ };
53235
53577
  setCompacting(true);
53236
53578
  try {
53237
53579
  const result = await client/* api */.FH.agents.compact(agentId, {
53238
53580
  resetContext: true
53239
53581
  });
53240
- if (result.compacted) {
53582
+ // The thread may have changed while compaction ran; never apply its
53583
+ // result to a different thread's view.
53584
+ const compactedThreadId = threadId;
53585
+ const stillCurrent = ()=>compactedThreadId !== null && currentThreadIdRef.current === compactedThreadId;
53586
+ if (result.compacted && compactedThreadId !== null && stillCurrent()) {
53241
53587
  // Server moved the hot/warm pin to just after the last existing
53242
53588
  // message and persisted the warm summary. Mirror that in-place so
53243
53589
  // the warm card shows the fresh summary without wiping the visible
@@ -53249,16 +53595,29 @@ function ChatView({ threadId, agentId, sessionLoading, sessionError, onMessageSe
53249
53595
  thread.metaApplier.setWarmSummary(result.warm_summary ?? null);
53250
53596
  thread.metaApplier.setWarmSummaryBefore(result.warm_summary_before ?? null);
53251
53597
  thread.metaApplier.setWarmSummaryBeforeSeq(result.warm_summary_before_seq ?? null);
53252
- thread.metaApplier.setWarmSummaryBeforeSeq(result.warm_summary_before_seq ?? null);
53253
53598
  thread.metaApplier.setWarmSummaryComputedAt(result.warm_summary_computed_at ?? null);
53254
53599
  thread.metaApplier.setWarmSummarySourceMessages(result.warm_summary_source_messages ?? null);
53255
53600
  thread.metaApplier.setWarmSummarySourceChars(result.warm_summary_source_chars ?? null);
53256
53601
  thread.metaApplier.setWarmSummaryTopics?.(parseWarmSummaryTopics(result.warm_summary_topics));
53257
- } else {
53258
- thread.addNotice("Nothing to compact yet — send some messages first.");
53259
- }
53602
+ // The compact response carries only the chat recap; channel recaps
53603
+ // (bridge, watcher, scheduled task) come with the thread metadata.
53604
+ void client/* api */.FH.threads.get(compactedThreadId, {
53605
+ limit: 1
53606
+ }).then((d)=>{
53607
+ if (stillCurrent()) applyThreadMeta(thread.metaApplier, d);
53608
+ }).catch(()=>{});
53609
+ }
53610
+ notifyCompaction(result);
53260
53611
  } catch (err) {
53261
- thread.addNotice(`Compaction failed: ${String(err)}`);
53612
+ (0,error_report/* pushErrorToast */.uS)({
53613
+ title: "Compaction failed",
53614
+ error: err,
53615
+ context: {
53616
+ panel: "chat",
53617
+ action: "compact",
53618
+ agent_id: agentId
53619
+ }
53620
+ });
53262
53621
  } finally{
53263
53622
  setCompacting(false);
53264
53623
  queue.drainQueueRef.current();
@@ -53284,7 +53643,6 @@ function ChatView({ threadId, agentId, sessionLoading, sessionError, onMessageSe
53284
53643
  threadId: threadId,
53285
53644
  messages: thread.messages,
53286
53645
  steeredSegments: sse.steeredSegments,
53287
- notices: thread.notices,
53288
53646
  agentConfig: agentConfig,
53289
53647
  userProfile: userProfile,
53290
53648
  // streamingContent stays visible past `streaming=false` so the bubble
@@ -53311,8 +53669,9 @@ function ChatView({ threadId, agentId, sessionLoading, sessionError, onMessageSe
53311
53669
  warmSummarySourceMessages: thread.warmSummarySourceMessages,
53312
53670
  warmSummarySourceChars: thread.warmSummarySourceChars,
53313
53671
  warmSummaryTopics: thread.warmSummaryTopics,
53672
+ warmChannelSummaries: thread.warmChannelSummaries,
53314
53673
  warmSummaryPending: thread.warmSummaryPending,
53315
- compactionPending: thread.compactionPending || compacting,
53674
+ compactionPending: thread.compactionPending || sessionCompacting,
53316
53675
  onSetContextPin: thread.setContextPin,
53317
53676
  streaming: sse.streaming,
53318
53677
  contextWindowTokens: thread.contextWindowTokens,
@@ -53340,7 +53699,7 @@ function ChatView({ threadId, agentId, sessionLoading, sessionError, onMessageSe
53340
53699
  onVoiceTranscript: handleVoiceTranscript,
53341
53700
  disabled: !agentId,
53342
53701
  placeholder: composerPlaceholder({
53343
- compacting,
53702
+ compacting: sessionCompacting,
53344
53703
  sessionLoading: !!sessionLoading,
53345
53704
  streaming: sse.streaming
53346
53705
  })
@@ -55202,12 +55561,12 @@ function NetworkSection() {
55202
55561
  /*#__PURE__*/ (0,react_jsx_runtime.jsxs)("label", {
55203
55562
  className: "block text-xs text-fg-subtle",
55204
55563
  children: [
55205
- "No proxy (comma-separated, optional)",
55564
+ "No proxy (comma-separated, optional; localhost is always direct)",
55206
55565
  /*#__PURE__*/ (0,react_jsx_runtime.jsx)("input", {
55207
55566
  type: "text",
55208
55567
  value: noProxy,
55209
55568
  onChange: (e)=>setNoProxy(e.target.value),
55210
- placeholder: "localhost,127.0.0.1,.internal",
55569
+ placeholder: ".internal,corp.example",
55211
55570
  className: "mt-1 w-full px-2 py-1.5 text-sm rounded border border-border bg-surface-3 text-fg font-mono"
55212
55571
  })
55213
55572
  ]
@@ -73625,6 +73984,22 @@ function BootScreen({ agents, agentsLoaded, activeAgentId, onPickAgent, suppress
73625
73984
  setAdoptionBusy(null);
73626
73985
  }
73627
73986
  }
73987
+ async function handleAdoptionItemRetry(itemId) {
73988
+ if (adoptionBusy || adoption?.status === "running") return;
73989
+ setAdoptionBusy("retry");
73990
+ try {
73991
+ const next = await client/* api */.FH.lifecycle.adoption.retryItem(itemId);
73992
+ setAdoption(next);
73993
+ adoptionRunStartedRef.current = null;
73994
+ } catch {
73995
+ setAdoption((prev)=>prev ? {
73996
+ ...prev,
73997
+ error: "Could not retry that step."
73998
+ } : prev);
73999
+ } finally{
74000
+ setAdoptionBusy(null);
74001
+ }
74002
+ }
73628
74003
  // The agent rendered in the centered tile. During `loading` and
73629
74004
  // `pick` it's the default (so the user sees the same artwork as soon
73630
74005
  // as agents resolve). During `opening` it's whatever was picked.
@@ -73767,6 +74142,9 @@ function BootScreen({ agents, agentsLoaded, activeAgentId, onPickAgent, suppress
73767
74142
  summary: adoptionLiveLabel ?? adoption.summary,
73768
74143
  items: adoption.checklist,
73769
74144
  error: adoption.error,
74145
+ onRetryItem: (item)=>void handleAdoptionItemRetry(item.id),
74146
+ canRetryItem: (item)=>item.id !== "fetch-changes",
74147
+ retryDisabled: adoptionBusy !== null || adoption.status === "running",
73770
74148
  children: [
73771
74149
  adoption.status === "done" && /*#__PURE__*/ (0,react_jsx_runtime.jsx)("p", {
73772
74150
  className: "mt-2 rounded-lg border border-border/50 bg-surface px-2 py-1 text-[10px] leading-snug text-fg-muted",
@@ -77394,6 +77772,56 @@ function AppShell() {
77394
77772
  }
77395
77773
 
77396
77774
 
77775
+ /***/ }),
77776
+
77777
+ /***/ 63033:
77778
+ /***/ ((module) => {
77779
+
77780
+ "use strict";
77781
+ module.exports = require("next/dist/server/app-render/work-unit-async-storage.external.js");
77782
+
77783
+ /***/ }),
77784
+
77785
+ /***/ 71000:
77786
+ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
77787
+
77788
+ "use strict";
77789
+
77790
+ Object.defineProperty(exports, "__esModule", ({
77791
+ value: true
77792
+ }));
77793
+ Object.defineProperty(exports, "addPathPrefix", ({
77794
+ enumerable: true,
77795
+ get: function() {
77796
+ return addPathPrefix;
77797
+ }
77798
+ }));
77799
+ const _parsepath = __webpack_require__(10571);
77800
+ function addPathPrefix(path, prefix) {
77801
+ if (!path.startsWith('/') || !prefix) {
77802
+ return path;
77803
+ }
77804
+ const { pathname, query, hash } = (0, _parsepath.parsePath)(path);
77805
+ return `${prefix}${pathname}${query}${hash}`;
77806
+ } //# sourceMappingURL=add-path-prefix.js.map
77807
+
77808
+
77809
+ /***/ }),
77810
+
77811
+ /***/ 73024:
77812
+ /***/ ((module) => {
77813
+
77814
+ "use strict";
77815
+ module.exports = require("node:fs");
77816
+
77817
+ /***/ }),
77818
+
77819
+ /***/ 73136:
77820
+ /***/ ((module) => {
77821
+
77822
+ "use strict";
77823
+ module.exports = require("node:url");
77824
+
77397
77825
  /***/ }),
77398
77826
 
77399
77827
  /***/ 75729:
@@ -77443,6 +77871,14 @@ module.exports = require("node:path");
77443
77871
 
77444
77872
  /***/ }),
77445
77873
 
77874
+ /***/ 77030:
77875
+ /***/ ((module) => {
77876
+
77877
+ "use strict";
77878
+ module.exports = require("node:net");
77879
+
77880
+ /***/ }),
77881
+
77446
77882
  /***/ 77598:
77447
77883
  /***/ ((module) => {
77448
77884
 
@@ -77658,7 +78094,7 @@ function Home() {
77658
78094
  var __webpack_require__ = require("../webpack-runtime.js");
77659
78095
  __webpack_require__.C(exports);
77660
78096
  var __webpack_exec__ = (moduleId) => (__webpack_require__(__webpack_require__.s = moduleId))
77661
- var __webpack_exports__ = __webpack_require__.X(0, [2970,7377,7981,2430,1427,4992,46,2653,466], () => (__webpack_exec__(3067)));
78097
+ var __webpack_exports__ = __webpack_require__.X(0, [2970,7377,7981,2430,1427,4992,46,2653,466], () => (__webpack_exec__(13297)));
77662
78098
  module.exports = __webpack_exports__;
77663
78099
 
77664
78100
  })();