@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
@@ -215,7 +215,18 @@ function buildProxyUrl(
215
215
  const auth = username
216
216
  ? `${encodeURIComponent(username)}${password ? `:${encodeURIComponent(password)}` : ""}@`
217
217
  : "";
218
- return `${scheme}://${auth}${host}:${port}`;
218
+ const urlHost = host.includes(":") && !host.startsWith("[") ? `[${host}]` : host;
219
+ return `${scheme}://${auth}${urlHost}:${port}`;
220
+ }
221
+
222
+ // undici's EnvHttpProxyAgent has no implicit loopback exemption, so without
223
+ // these a configured proxy would also receive local traffic (Ollama, the
224
+ // WhatsApp bridge sidecar, the app's own loopback API).
225
+ const LOOPBACK_NO_PROXY = ["localhost", "127.0.0.1", "::1"];
226
+
227
+ function mergeNoProxy(noProxy: string | null): string {
228
+ const entries = (noProxy ?? "").split(/[,\s]+/).map((entry) => entry.trim()).filter(Boolean);
229
+ return [...new Set([...entries, ...LOOPBACK_NO_PROXY])].join(",");
219
230
  }
220
231
 
221
232
  function installProxy(url: string, noProxy: string | null, caBundle: string | null): void {
@@ -224,22 +235,24 @@ function installProxy(url: string, noProxy: string | null, caBundle: string | nu
224
235
  // We still treat the boot-time env snapshot as authoritative for the
225
236
  // "env beats DB" rule — this mutation only happens after we've
226
237
  // confirmed the user did NOT set HTTP_PROXY at launch.
238
+ const merged = mergeNoProxy(noProxy);
227
239
  process.env.HTTP_PROXY = url;
228
240
  process.env.HTTPS_PROXY = url;
229
- if (noProxy && noProxy.trim().length > 0) {
230
- process.env.NO_PROXY = noProxy.trim();
231
- } else {
232
- delete process.env.NO_PROXY;
233
- }
241
+ process.env.NO_PROXY = merged;
234
242
  // ADR-0012: when the user pasted a corporate root CA, inject it on
235
243
  // both TLS legs — the proxy hop (proxyTls) for https-scheme proxies
236
244
  // signed by the corporate root, and the upstream tunnel (requestTls)
237
245
  // for proxies that MITM outbound HTTPS with the same internal CA.
238
246
  // Same blob is correct: the corporate trust chain typically signs
239
247
  // both ends.
240
- const opts = caBundle
241
- ? { requestTls: { ca: caBundle }, proxyTls: { ca: caBundle } }
242
- : {};
248
+ // Pass the values explicitly too: undici prefers lowercase http_proxy /
249
+ // no_proxy from the environment over the uppercase ones set above.
250
+ const opts = {
251
+ httpProxy: url,
252
+ httpsProxy: url,
253
+ noProxy: merged,
254
+ ...(caBundle ? { requestTls: { ca: caBundle }, proxyTls: { ca: caBundle } } : {}),
255
+ };
243
256
  setGlobalDispatcher(new EnvHttpProxyAgent(opts));
244
257
  }
245
258
 
@@ -37,6 +37,22 @@ Every update to an existing key keeps a dated snapshot of the prior record in
37
37
  its `history`, and older free-form or v1 entries are upgraded to the current
38
38
  schema automatically the first time they're read — no manual migration step.
39
39
 
40
+ ## Proactive Saving
41
+
42
+ Memory is shared by every Jarela agent, so save durable information in the
43
+ turn it appears instead of relying on background compaction, which runs later
44
+ and can miss details.
45
+
46
+ 1. **Trigger:** the user states a preference, fact, decision, constraint, or
47
+ correction; or a tool result verifies a durable fact.
48
+ 2. **Check:** search for an existing record on the same subject and reuse its
49
+ key.
50
+ 3. **Write:** call `memory_upsert` before the final reply.
51
+ 4. **Validate:** the result must contain `ok: true` and the key you sent;
52
+ retry once on failure, then tell the user it was not saved.
53
+ 5. **Cite:** end the reply with `Saved to memory: facts/<key>` for each saved
54
+ key.
55
+
40
56
  ## Retrieval And Consolidation
41
57
 
42
58
  1. Let proactive recall supply matching facts on normal user turns. Use
@@ -253,12 +253,17 @@ function upsertAgentConfigTransaction(input: UpsertAgentInput): AgentConfigRow {
253
253
  const db = getDb();
254
254
  const existing = getAgentConfig(input.id);
255
255
  const created_at = existing?.created_at ?? t;
256
- const mbti = input.adaptive_mbti ?? toMbti(existing?.adaptive_mbti) ?? "INTJ";
256
+ const existingMbti = toMbti(existing?.adaptive_mbti);
257
+ const mbti = input.adaptive_mbti ?? existingMbti ?? "INTJ";
257
258
  const preset = MBTI_PRESETS[mbti];
258
- const strength = input.adaptive_persona_strength ?? preset.strength;
259
- const empathy = input.adaptive_empathy ?? preset.empathy;
260
- const expressiveness = input.adaptive_expressiveness ?? preset.expressiveness;
261
- const verbosity = input.adaptive_verbosity ?? preset.verbosity;
259
+ // Omitted sliders keep their tuned values; they only fall back to the
260
+ // preset when the type changes or the agent is new. Otherwise every
261
+ // partial update (approved proposals, tool edits) reset them.
262
+ const keepTuned = existing !== null && existing !== undefined && mbti === existingMbti;
263
+ const strength = input.adaptive_persona_strength ?? (keepTuned ? existing.adaptive_persona_strength : preset.strength);
264
+ const empathy = input.adaptive_empathy ?? (keepTuned ? existing.adaptive_empathy : preset.empathy);
265
+ const expressiveness = input.adaptive_expressiveness ?? (keepTuned ? existing.adaptive_expressiveness : preset.expressiveness);
266
+ const verbosity = input.adaptive_verbosity ?? (keepTuned ? existing.adaptive_verbosity : preset.verbosity);
262
267
  if (input.is_default) db.prepare("UPDATE agent_configs SET is_default=0").run();
263
268
  // harness_id: explicit `undefined` means "keep existing"; explicit `null`
264
269
  // means "use the global default". Empty string is normalised to null too,
@@ -0,0 +1,81 @@
1
+ import { afterAll, beforeEach, describe, expect, it } from "vitest";
2
+ import { mkdtempSync, rmSync } from "node:fs";
3
+ import { tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+
6
+ const tmpRoot = mkdtempSync(join(tmpdir(), "jarela-test-bridges-"));
7
+ process.env.JARELA_DB_DIR = tmpRoot;
8
+
9
+ const store = await import("./bridges");
10
+ const { getDb } = await import("@/lib/db");
11
+
12
+ afterAll(() => {
13
+ try { rmSync(tmpRoot, { recursive: true, force: true }); } catch { /* */ }
14
+ });
15
+
16
+ describe("bridges store", () => {
17
+ beforeEach(() => {
18
+ const db = getDb();
19
+ db.exec("DELETE FROM bridge_routes; DELETE FROM bridge_ignores; DELETE FROM bridges;");
20
+ });
21
+
22
+ it("keeps each chat's watermark monotonic and isolated from other chats", () => {
23
+ const b = store.createBridge({ kind: "whatsapp", name: "WA" });
24
+ store.createRoute({ bridge_id: b.id, remote_jid: "a@s.whatsapp.net", agent_id: "agent-1" });
25
+ store.createRoute({ bridge_id: b.id, remote_jid: "b@s.whatsapp.net", agent_id: "agent-2" });
26
+
27
+ store.bumpRouteLastSeenTs(b.id, "a@s.whatsapp.net", 2_000);
28
+ store.bumpRouteLastSeenTs(b.id, "a@s.whatsapp.net", 1_000);
29
+ store.bumpRouteLastSeenTs(b.id, "a@s.whatsapp.net", Number.NaN);
30
+ store.bumpRouteLastSeenTs(b.id, "a@s.whatsapp.net", -5);
31
+ store.bumpRouteLastSeenTs(b.id, "unrouted@s.whatsapp.net", 9_000);
32
+
33
+ expect(store.getRouteLastSeenTsMap(b.id)).toEqual(new Map([["a@s.whatsapp.net", 2_000]]));
34
+ });
35
+
36
+ it("scopes watermarks to their bridge", () => {
37
+ const one = store.createBridge({ kind: "whatsapp", name: "one" });
38
+ const two = store.createBridge({ kind: "whatsapp", name: "two" });
39
+ store.createRoute({ bridge_id: one.id, remote_jid: "x@s.whatsapp.net", agent_id: "agent-3" });
40
+ store.createRoute({ bridge_id: two.id, remote_jid: "x@s.whatsapp.net", agent_id: "agent-4" });
41
+ store.bumpRouteLastSeenTs(one.id, "x@s.whatsapp.net", 5_000);
42
+ expect(store.getRouteLastSeenTsMap(two.id).size).toBe(0);
43
+ });
44
+
45
+ it("deletes a bridge together with its routes and ignores", () => {
46
+ const b = store.createBridge({ kind: "whatsapp", name: "WA" });
47
+ const route = store.createRoute({ bridge_id: b.id, remote_jid: "*", agent_id: "agent-5" });
48
+ store.addIgnore({ bridge_id: b.id, remote_jid: "spam@s.whatsapp.net" });
49
+
50
+ expect(store.deleteBridge(b.id)).toBe(true);
51
+ expect(store.getRoute(route.id)).toBeNull();
52
+ expect(store.isIgnored(b.id, "spam@s.whatsapp.net")).toBe(false);
53
+ expect(store.deleteBridge(b.id)).toBe(false);
54
+ });
55
+
56
+ it("rejects a duplicate ignore entry and removes only the matching chat", () => {
57
+ const b = store.createBridge({ kind: "whatsapp", name: "WA" });
58
+ store.addIgnore({ bridge_id: b.id, remote_jid: "a@s.whatsapp.net", label: "A" });
59
+ store.addIgnore({ bridge_id: b.id, remote_jid: "b@s.whatsapp.net" });
60
+ expect(() => store.addIgnore({ bridge_id: b.id, remote_jid: "a@s.whatsapp.net" })).toThrow(/UNIQUE/);
61
+
62
+ expect(store.removeIgnore(b.id, "a@s.whatsapp.net")).toBe(true);
63
+ expect(store.removeIgnore(b.id, "a@s.whatsapp.net")).toBe(false);
64
+ expect(store.listIgnores(b.id).map((i) => i.remote_jid)).toEqual(["b@s.whatsapp.net"]);
65
+ });
66
+
67
+ it("applies partial updates without clobbering nullable fields", () => {
68
+ const b = store.createBridge({ kind: "whatsapp", name: "WA" });
69
+ store.updateBridge(b.id, { last_error: "boom", paired_id: "me" });
70
+ const updated = store.updateBridge(b.id, { status: "connected", forward_group_profile_updates: 0 });
71
+ expect(updated).toMatchObject({ last_error: "boom", paired_id: "me", status: "connected", forward_group_profile_updates: 0 });
72
+ expect(store.updateBridge(b.id, { last_error: null })?.last_error).toBeNull();
73
+ expect(store.getBridge(b.id)).toMatchObject({ last_error: null, paired_id: "me", forward_group_participants_updates: 1 });
74
+ expect(store.updateBridge("missing", { name: "x" })).toBeNull();
75
+
76
+ const route = store.createRoute({ bridge_id: b.id, remote_jid: "a@s.whatsapp.net", agent_id: "agent-6", label: "A", silent_mode: true });
77
+ expect(store.updateRoute(route.id, { respond_to: "user" })).toMatchObject({ label: "A", silent_mode: 1, respond_to: "user" });
78
+ expect(store.updateRoute(route.id, { silent_mode: false, label: null })).toMatchObject({ label: null, silent_mode: 0 });
79
+ expect(store.findRoute(b.id, "a@s.whatsapp.net")).toMatchObject({ silent_mode: 0, respond_to: "user", label: null });
80
+ });
81
+ });
@@ -263,14 +263,15 @@ export function bumpRouteLastSeenTs(bridgeId: string, remoteJid: string, ts: num
263
263
  .run(ts, bridgeId, remoteJid, ts);
264
264
  }
265
265
 
266
- // Snapshot the highest watermark across every route on a bridge. The
267
- // adapter uses this on reconnect to short-circuit very-old appends before
268
- // it has loaded individual route rows.
269
- export function getMaxRouteLastSeenTs(bridgeId: string): number {
270
- const row = getDb()
271
- .prepare("SELECT MAX(last_seen_ts) AS m FROM bridge_routes WHERE bridge_id=?")
272
- .get(bridgeId) as { m: number | null } | undefined;
273
- return row?.m ?? 0;
266
+ // Per-chat watermarks for every explicitly routed chat on a bridge, loaded
267
+ // once per upsert batch. Each chat is gated only by its own progress: a
268
+ // bridge-wide maximum would drop chat B's offline backlog as soon as a newer
269
+ // message from chat A had been delivered.
270
+ export function getRouteLastSeenTsMap(bridgeId: string): Map<string, number> {
271
+ const rows = getDb()
272
+ .prepare("SELECT remote_jid, last_seen_ts FROM bridge_routes WHERE bridge_id=? AND last_seen_ts IS NOT NULL")
273
+ .all(bridgeId) as Array<{ remote_jid: string; last_seen_ts: number }>;
274
+ return new Map(rows.map((r) => [r.remote_jid, r.last_seen_ts]));
274
275
  }
275
276
 
276
277
  // ---------------------------------------------------------------------------
@@ -0,0 +1,120 @@
1
+ import { afterAll, beforeEach, describe, expect, it } from "vitest";
2
+ import { mkdtempSync, rmSync } from "node:fs";
3
+ import { tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+
6
+ const tmpRoot = mkdtempSync(join(tmpdir(), "jarela-test-proxy-config-"));
7
+ process.env.JARELA_DB_DIR = tmpRoot;
8
+
9
+ const store = await import("./proxy-config");
10
+ const { getDb } = await import("@/lib/db");
11
+ const { SECRET_MASK } = await import("./integrations");
12
+
13
+ afterAll(() => {
14
+ try { rmSync(tmpRoot, { recursive: true, force: true }); } catch { /* */ }
15
+ });
16
+
17
+ const PEM = "-----BEGIN CERTIFICATE-----\nMIIBfake\n-----END CERTIFICATE-----\n";
18
+
19
+ function storedPasswordColumn(): string | null {
20
+ const row = getDb().prepare("SELECT password FROM proxy_config WHERE id = 1").get() as { password: string | null } | undefined;
21
+ return row?.password ?? null;
22
+ }
23
+
24
+ describe("proxy-config store", () => {
25
+ beforeEach(() => {
26
+ getDb().exec("DELETE FROM proxy_config");
27
+ });
28
+
29
+ it("returns the default off status before anything is saved", () => {
30
+ expect(store.getProxyConfigStatus()).toMatchObject({ mode: "off", scheme: "http", host: null, password: null });
31
+ expect(store.getProxyConfigRaw()).toBeNull();
32
+ expect(store.deleteProxyConfig()).toBe(false);
33
+ });
34
+
35
+ it("encrypts the password at rest, masks it in status and decrypts it for the dispatcher", () => {
36
+ const saved = store.saveProxyConfig({ mode: "manual", host: "proxy.corp", port: 3128, username: "u", password: "p@ss:word" });
37
+ expect(saved).toMatchObject({ mode: "manual", host: "proxy.corp", port: 3128, password: SECRET_MASK });
38
+ expect(storedPasswordColumn()).not.toContain("p@ss:word");
39
+ expect(store.getProxyConfigRaw()?.password).toBe("p@ss:word");
40
+ });
41
+
42
+ it("keeps the existing password when the UI echoes the mask back, without re-encrypting it", () => {
43
+ store.saveProxyConfig({ mode: "manual", host: "proxy.corp", port: 3128, username: "u", password: "secret" });
44
+ const before = storedPasswordColumn();
45
+ store.saveProxyConfig({ mode: "manual", host: "proxy2.corp", port: 8080, username: "u", password: SECRET_MASK });
46
+ expect(storedPasswordColumn()).toBe(before);
47
+ expect(store.getProxyConfigRaw()).toMatchObject({ host: "proxy2.corp", port: 8080, password: "secret" });
48
+ });
49
+
50
+ it("never stores the mask itself as a password when none existed", () => {
51
+ store.saveProxyConfig({ mode: "manual", host: "proxy.corp", port: 3128, password: SECRET_MASK });
52
+ expect(store.getProxyConfigRaw()?.password).toBeNull();
53
+ expect(store.getProxyConfigStatus().password).toBeNull();
54
+ });
55
+
56
+ it("clears the password when an empty string or null is sent", () => {
57
+ store.saveProxyConfig({ mode: "manual", host: "proxy.corp", port: 3128, password: "secret" });
58
+ store.saveProxyConfig({ mode: "manual", host: "proxy.corp", port: 3128, password: "" });
59
+ expect(store.getProxyConfigRaw()?.password).toBeNull();
60
+ store.saveProxyConfig({ mode: "manual", host: "proxy.corp", port: 3128, password: "secret" });
61
+ store.saveProxyConfig({ mode: "manual", host: "proxy.corp", port: 3128, password: null });
62
+ expect(store.getProxyConfigRaw()?.password).toBeNull();
63
+ });
64
+
65
+ it("trims host, username and no_proxy and stores blanks as null", () => {
66
+ store.saveProxyConfig({ mode: "manual", host: " proxy.corp ", port: 3128, username: " ", no_proxy: " " });
67
+ expect(store.getProxyConfigRaw()).toMatchObject({ host: "proxy.corp", username: null, no_proxy: null });
68
+ });
69
+
70
+ it.each([
71
+ ["a URL with a scheme", "http://proxy.corp"],
72
+ ["a host with a port", "proxy.corp:8080"],
73
+ ["a hex-only host with a port", "dead.beef:3128"],
74
+ ["a host with a path", "proxy.corp/pac"],
75
+ ["a host with credentials", "user:pw@proxy.corp"],
76
+ ["a host with spaces", "proxy corp"],
77
+ ])("rejects %s in manual mode instead of building a broken proxy URL", (_label, host) => {
78
+ const result = store.saveProxyConfig({ mode: "manual", host, port: 3128 });
79
+ expect(result).toHaveProperty("error");
80
+ expect((result as { error: string }).error).toMatch(/host/i);
81
+ expect(store.getProxyConfigRaw()).toBeNull();
82
+ });
83
+
84
+ it.each([
85
+ ["fd00::1", "fd00::1"],
86
+ ["[fd00::1]", "fd00::1"],
87
+ ["10.0.0.5", "10.0.0.5"],
88
+ ["proxy-1.corp.example", "proxy-1.corp.example"],
89
+ ])("accepts host %s and stores it as %s", (input, stored) => {
90
+ const result = store.saveProxyConfig({ mode: "manual", host: input, port: 3128 });
91
+ expect(result).not.toHaveProperty("error");
92
+ expect(store.getProxyConfigRaw()?.host).toBe(stored);
93
+ });
94
+
95
+ it.each([0, -1, 65536, 3128.5, Number.NaN, Number.POSITIVE_INFINITY])("rejects port %s", (port) => {
96
+ expect(store.saveProxyConfig({ mode: "manual", host: "proxy.corp", port })).toHaveProperty("error");
97
+ });
98
+
99
+ it("requires host and port only in manual mode", () => {
100
+ expect(store.saveProxyConfig({ mode: "manual", port: 3128 })).toHaveProperty("error");
101
+ expect(store.saveProxyConfig({ mode: "manual", host: "proxy.corp" })).toHaveProperty("error");
102
+ expect(store.saveProxyConfig({ mode: "system" })).toMatchObject({ mode: "system" });
103
+ expect(store.saveProxyConfig({ mode: "off" })).toMatchObject({ mode: "off" });
104
+ });
105
+
106
+ it("rejects an invalid mode and a non-PEM CA bundle, and clears a blank bundle", () => {
107
+ expect(store.saveProxyConfig({ mode: "auto" as never })).toHaveProperty("error");
108
+ expect(store.saveProxyConfig({ mode: "off", ca_bundle: "not a cert" })).toHaveProperty("error");
109
+ store.saveProxyConfig({ mode: "off", ca_bundle: PEM });
110
+ expect(store.getProxyConfigRaw()?.ca_bundle).toBe(PEM);
111
+ store.saveProxyConfig({ mode: "off", ca_bundle: " " });
112
+ expect(store.getProxyConfigRaw()?.ca_bundle).toBeNull();
113
+ });
114
+
115
+ it("normalises an unknown persisted scheme to http", () => {
116
+ store.saveProxyConfig({ mode: "manual", host: "proxy.corp", port: 3128 });
117
+ getDb().prepare("UPDATE proxy_config SET scheme = 'socks5' WHERE id = 1").run();
118
+ expect(store.getProxyConfigRaw()).toMatchObject({ mode: "manual", scheme: "http" });
119
+ });
120
+ });
@@ -15,6 +15,7 @@
15
15
  // existing password" so the UI can echo back the masked form without
16
16
  // blanking the secret.
17
17
 
18
+ import { isIPv6 } from "node:net";
18
19
  import { getDb } from "@/lib/db";
19
20
  import { decryptIfNeeded, encrypt } from "@/lib/crypto/envelope";
20
21
  import { SECRET_MASK } from "@/lib/stores/integrations";
@@ -122,11 +123,18 @@ export function saveProxyConfig(input: ProxyConfigInput): ProxyConfigStatus | {
122
123
  const scheme: ProxyScheme = input.scheme === "https" ? "https" : "http";
123
124
 
124
125
  // Manual mode requires host + port. system / off don't.
126
+ let host = nullable(input.host);
125
127
  if (input.mode === "manual") {
126
- if (!input.host || !input.host.trim()) return { error: "host is required in manual mode" };
127
- if (input.port == null || !Number.isFinite(input.port) || input.port <= 0 || input.port > 65535) {
128
- return { error: "port must be between 1 and 65535" };
128
+ if (!host) return { error: "host is required in manual mode" };
129
+ const normalisedHost = normaliseProxyHost(host);
130
+ if (!normalisedHost) {
131
+ return { error: "host must be a hostname or IP address, without scheme, port, path or credentials" };
129
132
  }
133
+ host = normalisedHost;
134
+ if (input.port == null) return { error: "port must be between 1 and 65535" };
135
+ }
136
+ if (input.port != null && (!Number.isInteger(input.port) || input.port <= 0 || input.port > 65535)) {
137
+ return { error: "port must be between 1 and 65535" };
130
138
  }
131
139
 
132
140
  // CA bundle: empty/null clears; non-empty must look like PEM.
@@ -167,7 +175,7 @@ export function saveProxyConfig(input: ProxyConfigInput): ProxyConfigStatus | {
167
175
  ).run(
168
176
  input.mode,
169
177
  scheme,
170
- nullable(input.host),
178
+ host,
171
179
  input.port ?? null,
172
180
  nullable(input.username),
173
181
  storedPassword,
@@ -207,6 +215,16 @@ function normaliseScheme(s: string | null | undefined): ProxyScheme {
207
215
  return s === "https" ? "https" : "http";
208
216
  }
209
217
 
218
+ // The dispatcher builds `${scheme}://${auth}${host}:${port}`, so a pasted URL
219
+ // or host:port would produce an unusable proxy URL. IPv6 is stored unbracketed;
220
+ // the dispatcher adds the brackets.
221
+ function normaliseProxyHost(host: string): string | null {
222
+ const unbracketed = host.startsWith("[") && host.endsWith("]") ? host.slice(1, -1) : host;
223
+ if (/^[A-Za-z0-9](?:[A-Za-z0-9.-]*[A-Za-z0-9])?$/.test(unbracketed)) return unbracketed;
224
+ if (isIPv6(unbracketed)) return unbracketed;
225
+ return null;
226
+ }
227
+
210
228
  function nullable(v: string | null | undefined): string | null {
211
229
  if (v == null) return null;
212
230
  const trimmed = v.trim();
@@ -692,6 +692,15 @@ describe("thread channel summaries (ADR-0044)", () => {
692
692
  expect(getThreadChannelSummary(t.thread_id, "watcher")?.summary).toBe("watcher recap");
693
693
  expect(getThreadChannelSummary(t.thread_id, "bridge")?.summary).toBe("bridge recap");
694
694
  });
695
+
696
+ it("round-trips stored channel topics and clears them when a later commit omits them", () => {
697
+ const t = createThread("agent-chsum-4");
698
+ const topics = JSON.stringify([{ title: "Nightly backup", start_seq: 1, end_seq: 2, recap: "r", facts: [], message_count: 2 }]);
699
+ commitThreadChannelSummary(t.thread_id, "scheduled_task", { summary: "recap", summaryBefore: null, summaryBeforeSeq: 3, topics });
700
+ expect(getThreadChannelSummary(t.thread_id, "scheduled_task")?.topics).toBe(topics);
701
+ commitThreadChannelSummary(t.thread_id, "scheduled_task", { summary: "fallback", summaryBefore: null, summaryBeforeSeq: 4 });
702
+ expect(getThreadChannelSummary(t.thread_id, "scheduled_task")?.topics).toBeNull();
703
+ });
695
704
  });
696
705
 
697
706
  describe("getRecentlyUsedToolNames", () => {
@@ -157,11 +157,15 @@ export function getThreadMessageBySeq(thread_id: string, seq: number): MessageRo
157
157
  return (getDb().prepare(MSG_COLS_SQL + " WHERE thread_id=? AND rowid=?").get(thread_id, seq) as unknown as MessageRow | undefined) ?? null;
158
158
  }
159
159
 
160
- export function countThreadMessagesFromSeq(thread_id: string, seq: number): number {
161
- const row = getDb().prepare("SELECT COUNT(*) AS n FROM messages WHERE thread_id=? AND rowid>=?").get(thread_id, seq) as { n: number } | undefined;
160
+
161
+ // Rows that size compaction can prune: automation-channel rows are kept
162
+ // (see pruneThreadMessages), so they must not count toward its trigger.
163
+ export function countForegroundThreadMessages(thread_id: string, fromSeq = 0): number {
164
+ const row = getDb()
165
+ .prepare("SELECT COUNT(*) AS n FROM messages WHERE thread_id=? AND rowid>=? AND " + foregroundCategoryGuardSql())
166
+ .get(thread_id, fromSeq, ...FOREGROUND_EXCLUDED_CATEGORIES) as { n: number } | undefined;
162
167
  return row?.n ?? 0;
163
168
  }
164
-
165
169
  export function isValidThreadContextCursor(thread_id: string, seq: number): boolean {
166
170
  if (getThreadMessageBySeq(thread_id, seq)) return true;
167
171
  return getThread(thread_id)?.hot_since_seq === seq;
@@ -671,6 +675,8 @@ export interface ThreadChannelSummaryRow {
671
675
  summary_before: string | null;
672
676
  summary_before_seq: number | null;
673
677
  computed_at: string;
678
+ /** JSON array of SummaryTopicSegment, or null for summaries without topics. */
679
+ topics: string | null;
674
680
  }
675
681
 
676
682
  // ADR-0044 — one cached warm summary per (thread, automation channel),
@@ -682,27 +688,34 @@ export interface ThreadChannelSummaryRow {
682
688
  // hot/warm boundary move, there's no cross-field invariant to protect here.
683
689
  export function getThreadChannelSummary(threadId: string, channel: string): ThreadChannelSummaryRow | null {
684
690
  return (getDb()
685
- .prepare("SELECT thread_id, channel, summary, summary_before, summary_before_seq, computed_at FROM thread_channel_summaries WHERE thread_id=? AND channel=?")
691
+ .prepare("SELECT thread_id, channel, summary, summary_before, summary_before_seq, computed_at, topics FROM thread_channel_summaries WHERE thread_id=? AND channel=?")
686
692
  .get(threadId, channel) as ThreadChannelSummaryRow | undefined) ?? null;
687
693
  }
688
694
 
695
+ export function listThreadChannelSummaries(threadId: string): ThreadChannelSummaryRow[] {
696
+ return getDb()
697
+ .prepare("SELECT thread_id, channel, summary, summary_before, summary_before_seq, computed_at, topics FROM thread_channel_summaries WHERE thread_id=?")
698
+ .all(threadId) as unknown as ThreadChannelSummaryRow[];
699
+ }
700
+
689
701
  export function commitThreadChannelSummary(
690
702
  threadId: string,
691
703
  channel: string,
692
- input: { summary: string; summaryBefore: string | null; summaryBeforeSeq?: number | null },
704
+ input: { summary: string; summaryBefore: string | null; summaryBeforeSeq?: number | null; topics?: string | null },
693
705
  ): void {
694
706
  if (input.summaryBefore !== null && input.summaryBeforeSeq == null) {
695
707
  throw new Error("summaryBeforeSeq is required for a boundary summary");
696
708
  }
697
709
  getDb()
698
710
  .prepare(
699
- `INSERT INTO thread_channel_summaries (thread_id, channel, summary, summary_before, summary_before_seq, computed_at)
700
- VALUES (?, ?, ?, ?, ?, ?)
711
+ `INSERT INTO thread_channel_summaries (thread_id, channel, summary, summary_before, summary_before_seq, computed_at, topics)
712
+ VALUES (?, ?, ?, ?, ?, ?, ?)
701
713
  ON CONFLICT(thread_id, channel) DO UPDATE SET
702
714
  summary=excluded.summary, summary_before=excluded.summary_before,
703
- summary_before_seq=excluded.summary_before_seq, computed_at=excluded.computed_at`,
715
+ summary_before_seq=excluded.summary_before_seq, computed_at=excluded.computed_at,
716
+ topics=excluded.topics`,
704
717
  )
705
- .run(threadId, channel, input.summary, input.summaryBefore, input.summaryBeforeSeq ?? null, now());
718
+ .run(threadId, channel, input.summary, input.summaryBefore, input.summaryBeforeSeq ?? null, now(), input.topics ?? null);
706
719
  }
707
720
 
708
721
  export function touchThread(thread_id: string, firstMsg?: string): void {
@@ -724,11 +737,11 @@ export function setThreadContextPin(thread_id: string, hot_since: string | null,
724
737
  .run(hot_since, hot_since === null ? null : hot_since_seq!, thread_id);
725
738
  }
726
739
 
727
- // Called by moveThreadContextBoundary whenever the user explicitly moves the
728
- // boundary (drag, or manual /compact) — never by the auto-detector's own
729
- // commit path, which calls setThreadContextPin directly. `untilMessageCount`
730
- // is a one-time write; the read side (lib/agents/run-thread.ts) just compares
731
- // against it, no per-turn write needed.
740
+ // Armed by moveThreadContextBoundary whenever the user explicitly moves the
741
+ // boundary (drag, or manual /compact), and by the auto-detector's hot-turn
742
+ // cooldown when a compaction pass ends without a commit (a commit writes the
743
+ // lock in the same transaction). `untilMessageCount` is a one-time write; the
744
+ // read side (lib/agents/run-thread.ts) just compares against it.
732
745
  export function setAutoBoundaryLock(thread_id: string, untilMessageCount: number): void {
733
746
  getDb()
734
747
  .prepare("UPDATE threads SET auto_boundary_locked_until_msg_count=? WHERE thread_id=?")
@@ -746,7 +759,7 @@ export interface ThreadWarmContextCommit {
746
759
  /** Reject the commit if another compactor refreshed the same boundary. */
747
760
  expectedWarmSummary?: string | null;
748
761
  autoBoundaryLockedUntilMessageCount?: number;
749
- channelSummaries?: Array<{ channel: string; summary: string }>;
762
+ channelSummaries?: Array<{ channel: string; summary: string; topics?: string | null }>;
750
763
  }
751
764
 
752
765
  // A warm recap is only valid for the exact boundary it replaced. Commit both
@@ -790,14 +803,15 @@ export function commitThreadWarmContext(
790
803
  thread_id,
791
804
  );
792
805
  const upsertChannel = db.prepare(
793
- `INSERT INTO thread_channel_summaries (thread_id, channel, summary, summary_before, summary_before_seq, computed_at)
794
- VALUES (?, ?, ?, ?, ?, ?)
806
+ `INSERT INTO thread_channel_summaries (thread_id, channel, summary, summary_before, summary_before_seq, computed_at, topics)
807
+ VALUES (?, ?, ?, ?, ?, ?, ?)
795
808
  ON CONFLICT(thread_id, channel) DO UPDATE SET
796
809
  summary=excluded.summary, summary_before=excluded.summary_before,
797
- summary_before_seq=excluded.summary_before_seq, computed_at=excluded.computed_at`,
810
+ summary_before_seq=excluded.summary_before_seq, computed_at=excluded.computed_at,
811
+ topics=excluded.topics`,
798
812
  );
799
813
  for (const channelSummary of input.channelSummaries ?? []) {
800
- upsertChannel.run(thread_id, channelSummary.channel, channelSummary.summary, input.hotSince, hotSinceSeq, now());
814
+ upsertChannel.run(thread_id, channelSummary.channel, channelSummary.summary, input.hotSince, hotSinceSeq, now(), channelSummary.topics ?? null);
801
815
  }
802
816
  db.exec("COMMIT");
803
817
  return getThread(thread_id);
@@ -13,6 +13,7 @@ const {
13
13
  getVersionAdoptionState,
14
14
  recordVersionAdoptionWorkflowProgress,
15
15
  updateVersionAdoptionState,
16
+ VersionAdoptionRequestError,
16
17
  } = await import("@/lib/stores/version-adoption");
17
18
 
18
19
  afterAll(() => {
@@ -132,6 +133,7 @@ describe("version adoption state", () => {
132
133
  expect(running.checklist[0].status).toBe("done");
133
134
  expect(running.checklist[1].id).toBe("build-todo-list");
134
135
  expect(running.checklist[1].status).toBe("checking");
136
+ expect(running.checklist[1].attempts).toBe(1);
135
137
  });
136
138
 
137
139
  it("records item-by-item adoption progress through the workflow helper", () => {
@@ -174,6 +176,100 @@ describe("version adoption state", () => {
174
176
  });
175
177
  });
176
178
 
179
+ it("builds adaptation items and prompt hints from bundled release changesets", () => {
180
+ upsertAgentConfig({
181
+ id: "default-agent",
182
+ name: "Assistant",
183
+ identity: "helper",
184
+ instructions: "Be useful.",
185
+ tools: [],
186
+ is_default: true,
187
+ });
188
+ updateVersionAdoptionState("mark_done", "2.0.5");
189
+
190
+ const pending = getVersionAdoptionState("2.2.1");
191
+ expect(pending.previous_version).toBe("2.0.5");
192
+ expect(pending.checklist[0]).toMatchObject({ id: "fetch-changes", status: "done" });
193
+ expect(pending.checklist[0].validation_evidence).toContain("bundled release changesets for 2.1.0, 2.2.0, 2.2.1");
194
+ expect(pending.stale_prompt_risks).toEqual(expect.arrayContaining([
195
+ "Adapt agent settings to tool changes",
196
+ "Adapt scheduled task and watcher prompts",
197
+ "Adapt agent instructions and skills",
198
+ ]));
199
+
200
+ const running = updateVersionAdoptionState("start", "2.2.1");
201
+ const prompt = running.adoption_prompt ?? "";
202
+ expect(prompt).toContain("read deterministically by the system from the bundled release changesets");
203
+ expect(prompt).toContain("Release changesets — model-facing prompt and tool description/schema changes from 2.0.5 to 2.2.1:");
204
+ expect(prompt).toContain("tool `workflow_progress`");
205
+ expect(prompt).toContain("params added: validation_evidence");
206
+ expect(prompt).toContain("apply an edit only after the user approves it");
207
+ expect(prompt).not.toContain("partial");
208
+
209
+ const adoption = recordVersionAdoptionWorkflowProgress({
210
+ item_id: "build-todo-list",
211
+ status: "done",
212
+ validation_evidence: "Every changed prompt and tool is covered by an adapt item.",
213
+ }, "2.2.1");
214
+ const ids = adoption.state.checklist.map((item) => item.id);
215
+ expect(ids).toEqual(["adapt-settings", "adapt-task-prompts", "adapt-instructions-skills"]);
216
+ for (const item of adoption.state.checklist) {
217
+ expect(item.input.trim()).not.toBe("");
218
+ expect(item.output.trim()).not.toBe("");
219
+ expect(item.validation).toMatch(/re-(read|list)/);
220
+ }
221
+ expect(adoption.state.checklist[0].affected_files).toContain("tool:workflow_progress");
222
+ });
223
+
224
+ it("retries a single adoption step with a focused prompt and keeps other steps", () => {
225
+ upsertAgentConfig({
226
+ id: "default-agent",
227
+ name: "Assistant",
228
+ identity: "helper",
229
+ instructions: "Be useful.",
230
+ tools: [],
231
+ is_default: true,
232
+ });
233
+ updateVersionAdoptionState("mark_done", "2.0.5");
234
+ updateVersionAdoptionState("start", "2.2.1");
235
+ recordVersionAdoptionWorkflowProgress({
236
+ item_id: "build-todo-list",
237
+ status: "done",
238
+ validation_evidence: "Every changed prompt and tool is covered.",
239
+ }, "2.2.1");
240
+ recordVersionAdoptionWorkflowProgress({
241
+ phase: "adoption",
242
+ item_id: "adapt-settings",
243
+ status: "done",
244
+ validation_evidence: "Re-read agent settings; no removed tools referenced.",
245
+ }, "2.2.1");
246
+ recordVersionAdoptionWorkflowProgress({
247
+ phase: "adoption",
248
+ item_id: "adapt-task-prompts",
249
+ status: "needs_attention",
250
+ }, "2.2.1");
251
+
252
+ const retried = updateVersionAdoptionState("retry", "2.2.1", "adapt-settings");
253
+ expect(retried.status).toBe("running");
254
+ expect(retried.phase).toBe("adoption");
255
+ const settings = retried.checklist.find((item) => item.id === "adapt-settings");
256
+ expect(settings?.status).toBe("checking");
257
+ expect(settings?.attempts).toBe(1);
258
+ expect(settings?.validation_evidence).toBeUndefined();
259
+ expect(retried.checklist.find((item) => item.id === "adapt-task-prompts")?.status).toBe("needs_attention");
260
+
261
+ const prompt = retried.adoption_prompt ?? "";
262
+ expect(prompt).toContain("Retry one Jarela version adoption step for upgrade from 2.0.5 to 2.2.1");
263
+ expect(prompt).toContain("Step: adapt-settings");
264
+ expect(prompt).toContain('item_id: "adapt-settings"');
265
+ expect(prompt).toContain('phase: "adoption"');
266
+ expect(prompt).toContain("Release changesets:");
267
+ expect(prompt).not.toContain("Phase 1 — impact radius analysis");
268
+
269
+ expect(() => updateVersionAdoptionState("retry", "2.2.1", "missing-step")).toThrow(VersionAdoptionRequestError);
270
+ expect(() => updateVersionAdoptionState("retry", "2.2.1", "fetch-changes")).toThrow(VersionAdoptionRequestError);
271
+ });
272
+
177
273
  it("blocks adoption until a default agent exists", () => {
178
274
  const state = getVersionAdoptionState("1.29.5");
179
275
  expect(state.status).toBe("blocked_no_default_agent");