@circuitwall/jarela 2.3.0 → 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 (208) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/app-path-routes-manifest.json +4 -4
  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/server/app/_global-error/page_client-reference-manifest.js +1 -1
  6. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  7. package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
  8. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  9. package/.next/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  10. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  11. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  12. package/.next/standalone/.next/server/app/_not-found.html +2 -2
  13. package/.next/standalone/.next/server/app/_not-found.rsc +2 -2
  14. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  15. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  16. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  17. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  18. package/.next/standalone/.next/server/app/api/v1/access/[identity]/route.js +7 -0
  19. package/.next/standalone/.next/server/app/api/v1/access/route.js +7 -0
  20. package/.next/standalone/.next/server/app/api/v1/agents/[id]/compact/route.js +7 -0
  21. package/.next/standalone/.next/server/app/api/v1/agents/[id]/display-filters/route.js +17 -5
  22. package/.next/standalone/.next/server/app/api/v1/agents/[id]/route.js +7 -0
  23. package/.next/standalone/.next/server/app/api/v1/agents/[id]/thread/route.js +17 -5
  24. package/.next/standalone/.next/server/app/api/v1/agents/route.js +7 -0
  25. package/.next/standalone/.next/server/app/api/v1/allowed-sites/[hostname]/route.js +7 -0
  26. package/.next/standalone/.next/server/app/api/v1/allowed-sites/route.js +7 -0
  27. package/.next/standalone/.next/server/app/api/v1/artifacts/lifecycle/route.js +7 -0
  28. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/chats/route.js +26 -32
  29. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/chats/route.js.nft.json +1 -1
  30. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/ignores/[remote_jid]/route.js +18 -7
  31. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/ignores/route.js +18 -7
  32. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/lookup/route.js +26 -32
  33. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/lookup/route.js.nft.json +1 -1
  34. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/pair/route.js +27 -33
  35. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/pair/route.js.nft.json +1 -1
  36. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/route.js +26 -32
  37. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/route.js.nft.json +1 -1
  38. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/routes/[route_id]/route.js +28 -12
  39. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/routes/route.js +28 -12
  40. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/status/route.js +26 -32
  41. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/status/route.js.nft.json +1 -1
  42. package/.next/standalone/.next/server/app/api/v1/bridges/kinds/route.js +9 -2
  43. package/.next/standalone/.next/server/app/api/v1/bridges/kinds/route.js.nft.json +1 -1
  44. package/.next/standalone/.next/server/app/api/v1/bridges/route.js +19 -7
  45. package/.next/standalone/.next/server/app/api/v1/bridges/route.js.nft.json +1 -1
  46. package/.next/standalone/.next/server/app/api/v1/dashboard/metrics/route.js +17 -5
  47. package/.next/standalone/.next/server/app/api/v1/dashboard/pricing/route.js +7 -0
  48. package/.next/standalone/.next/server/app/api/v1/documents/search/route.js +7 -0
  49. package/.next/standalone/.next/server/app/api/v1/documents/settings/route.js +7 -0
  50. package/.next/standalone/.next/server/app/api/v1/env-sync/allowlist/route.js +7 -0
  51. package/.next/standalone/.next/server/app/api/v1/env-sync/route.js +7 -0
  52. package/.next/standalone/.next/server/app/api/v1/events/route.js +26 -32
  53. package/.next/standalone/.next/server/app/api/v1/events/route.js.nft.json +1 -1
  54. package/.next/standalone/.next/server/app/api/v1/extension/browser/activate/route.js +7 -0
  55. package/.next/standalone/.next/server/app/api/v1/extension/browser/foreground/route.js +7 -0
  56. package/.next/standalone/.next/server/app/api/v1/extension/browser/history/route.js +7 -0
  57. package/.next/standalone/.next/server/app/api/v1/extension/browser/poll/route.js +7 -0
  58. package/.next/standalone/.next/server/app/api/v1/extension/browser/progress/route.js +7 -0
  59. package/.next/standalone/.next/server/app/api/v1/extension/browser/result/route.js +7 -0
  60. package/.next/standalone/.next/server/app/api/v1/extension/browser/retry/route.js +7 -0
  61. package/.next/standalone/.next/server/app/api/v1/extension/browser/status/route.js +7 -0
  62. package/.next/standalone/.next/server/app/api/v1/extension/browser/tabs/route.js +7 -0
  63. package/.next/standalone/.next/server/app/api/v1/harnesses/[id]/route.js +7 -0
  64. package/.next/standalone/.next/server/app/api/v1/harnesses/default/route.js +7 -0
  65. package/.next/standalone/.next/server/app/api/v1/harnesses/route.js +7 -0
  66. package/.next/standalone/.next/server/app/api/v1/health/route.js +17 -5
  67. package/.next/standalone/.next/server/app/api/v1/integrations/[name]/route.js +7 -0
  68. package/.next/standalone/.next/server/app/api/v1/integrations/gmail/oauth/callback/route.js +7 -0
  69. package/.next/standalone/.next/server/app/api/v1/integrations/gmail/oauth/start/route.js +7 -0
  70. package/.next/standalone/.next/server/app/api/v1/integrations/gmail/oauth/status/route.js +7 -0
  71. package/.next/standalone/.next/server/app/api/v1/integrations/outlook/oauth/callback/route.js +7 -0
  72. package/.next/standalone/.next/server/app/api/v1/integrations/outlook/oauth/start/route.js +7 -0
  73. package/.next/standalone/.next/server/app/api/v1/integrations/outlook/oauth/status/route.js +7 -0
  74. package/.next/standalone/.next/server/app/api/v1/integrations/route.js +7 -0
  75. package/.next/standalone/.next/server/app/api/v1/lifecycle/adoption/route.js +17 -5
  76. package/.next/standalone/.next/server/app/api/v1/maps/embed/route.js +7 -0
  77. package/.next/standalone/.next/server/app/api/v1/mcp-servers/[name]/route.js +17 -5
  78. package/.next/standalone/.next/server/app/api/v1/mcp-servers/route.js +17 -5
  79. package/.next/standalone/.next/server/app/api/v1/memory/[namespace]/[key]/route.js +7 -0
  80. package/.next/standalone/.next/server/app/api/v1/memory/policy/route.js +7 -0
  81. package/.next/standalone/.next/server/app/api/v1/memory/route.js +7 -0
  82. package/.next/standalone/.next/server/app/api/v1/memory/search/route.js +7 -0
  83. package/.next/standalone/.next/server/app/api/v1/models/[name]/compact-threads/route.js +7 -0
  84. package/.next/standalone/.next/server/app/api/v1/models/[name]/route.js +7 -0
  85. package/.next/standalone/.next/server/app/api/v1/models/route.js +7 -0
  86. package/.next/standalone/.next/server/app/api/v1/pending-actions/[id]/approve/route.js +27 -12
  87. package/.next/standalone/.next/server/app/api/v1/profile/location/route.js +7 -0
  88. package/.next/standalone/.next/server/app/api/v1/profile/route.js +7 -0
  89. package/.next/standalone/.next/server/app/api/v1/providers/[provider]/models/route.js +7 -0
  90. package/.next/standalone/.next/server/app/api/v1/providers/[provider]/probe/route.js +7 -0
  91. package/.next/standalone/.next/server/app/api/v1/providers/github-copilot/auth/route.js +7 -0
  92. package/.next/standalone/.next/server/app/api/v1/providers/route.js +7 -0
  93. package/.next/standalone/.next/server/app/api/v1/proxy-config/route.js +7 -0
  94. package/.next/standalone/.next/server/app/api/v1/redaction/init/route.js +7 -0
  95. package/.next/standalone/.next/server/app/api/v1/redaction/route.js +7 -0
  96. package/.next/standalone/.next/server/app/api/v1/scheduled-tasks/[id]/route.js +17 -5
  97. package/.next/standalone/.next/server/app/api/v1/scheduled-tasks/route.js +7 -0
  98. package/.next/standalone/.next/server/app/api/v1/security/idle-timeout/route.js +7 -0
  99. package/.next/standalone/.next/server/app/api/v1/security/pin/route.js +7 -0
  100. package/.next/standalone/.next/server/app/api/v1/security/state/route.js +7 -0
  101. package/.next/standalone/.next/server/app/api/v1/security/unlock/route.js +7 -0
  102. package/.next/standalone/.next/server/app/api/v1/security/verify-pin/route.js +7 -0
  103. package/.next/standalone/.next/server/app/api/v1/skills/[id]/route.js +7 -0
  104. package/.next/standalone/.next/server/app/api/v1/skills/repos/[id]/route.js +7 -0
  105. package/.next/standalone/.next/server/app/api/v1/skills/repos/route.js +7 -0
  106. package/.next/standalone/.next/server/app/api/v1/skills/route.js +7 -0
  107. package/.next/standalone/.next/server/app/api/v1/tasks/[agent_id]/route.js +7 -0
  108. package/.next/standalone/.next/server/app/api/v1/tasks/route.js +7 -0
  109. package/.next/standalone/.next/server/app/api/v1/threads/[thread_id]/activity/route.js +7 -0
  110. package/.next/standalone/.next/server/app/api/v1/threads/[thread_id]/context-pin/route.js +12 -6
  111. package/.next/standalone/.next/server/app/api/v1/threads/[thread_id]/route.js +7 -0
  112. package/.next/standalone/.next/server/app/api/v1/threads/[thread_id]/run/route.js +0 -1
  113. package/.next/standalone/.next/server/app/api/v1/threads/route.js +17 -5
  114. package/.next/standalone/.next/server/app/api/v1/update/apply/route.js.nft.json +1 -1
  115. package/.next/standalone/.next/server/app/api/v1/voice/transcribe/route.js +17 -5
  116. package/.next/standalone/.next/server/app/api/v1/voice/tts/route.js +17 -5
  117. package/.next/standalone/.next/server/app/api/v1/watchers/[id]/route.js +17 -5
  118. package/.next/standalone/.next/server/app/page.js +322 -275
  119. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  120. package/.next/standalone/.next/server/app/setup/page.js +8 -0
  121. package/.next/standalone/.next/server/app/setup/page_client-reference-manifest.js +1 -1
  122. package/.next/standalone/.next/server/app-paths-manifest.json +4 -4
  123. package/.next/standalone/.next/server/chunks/1388.js +106 -36
  124. package/.next/standalone/.next/server/chunks/2068.js +47 -10
  125. package/.next/standalone/.next/server/chunks/210.js +6 -6
  126. package/.next/standalone/.next/server/chunks/2447.js +10 -5
  127. package/.next/standalone/.next/server/chunks/2471.js +17 -17
  128. package/.next/standalone/.next/server/chunks/3042.js +10 -8
  129. package/.next/standalone/.next/server/chunks/{4540.js → 309.js} +104 -38
  130. package/.next/standalone/.next/server/chunks/{2350.js → 3272.js} +104 -37
  131. package/.next/standalone/.next/server/chunks/3399.js +525 -525
  132. package/.next/standalone/.next/server/chunks/3524.js +150 -67
  133. package/.next/standalone/.next/server/chunks/4189.js +1 -1
  134. package/.next/standalone/.next/server/chunks/4508.js +2 -2
  135. package/.next/standalone/.next/server/chunks/46.js +73 -28
  136. package/.next/standalone/.next/server/chunks/5908.js +63 -42
  137. package/.next/standalone/.next/server/chunks/6142.js +10 -2
  138. package/.next/standalone/.next/server/chunks/6649.js +1 -1
  139. package/.next/standalone/.next/server/chunks/8461.js +10 -8
  140. package/.next/standalone/.next/server/chunks/9032.js +5 -5
  141. package/.next/standalone/.next/server/chunks/9164.js +435 -176
  142. package/.next/standalone/.next/server/chunks/9304.js +51 -12
  143. package/.next/standalone/.next/server/chunks/{423.js → 9590.js} +66 -21
  144. package/.next/standalone/.next/server/middleware-build-manifest.js +2 -2
  145. package/.next/standalone/.next/server/middleware.js +71 -18
  146. package/.next/standalone/.next/server/pages/404.html +2 -2
  147. package/.next/standalone/.next/server/pages/500.html +1 -1
  148. package/.next/standalone/.next/server/preview-props.json +3 -3
  149. package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
  150. package/.next/standalone/.next/static/chunks/app/{page-213a623b37226452.js → page-04748847c6ff866f.js} +171 -132
  151. package/.next/standalone/.next/static/css/{312542a5725ba0d5.css → 2669e8744cc8c212.css} +2 -2
  152. package/.next/standalone/docs/adoption/changesets.json +49 -0
  153. package/.next/standalone/package.json +1 -1
  154. package/CHANGELOG.md +19 -0
  155. package/app/api/v1/threads/[thread_id]/run/route.ts +0 -1
  156. package/components/chat/MessageBubble.tsx +12 -0
  157. package/components/integrations/NetworkSection.tsx +2 -2
  158. package/lib/agents/citation-checker.test.ts +40 -2
  159. package/lib/agents/citation-checker.ts +56 -11
  160. package/lib/agents/context-boundary.ts +5 -6
  161. package/lib/agents/instruction-edits.test.ts +120 -0
  162. package/lib/agents/instruction-edits.ts +65 -42
  163. package/lib/agents/prepare/request.ts +0 -2
  164. package/lib/agents/prepare/system-prompt.test.ts +10 -0
  165. package/lib/agents/prepare/system-prompt.ts +8 -2
  166. package/lib/agents/proposals.test.ts +76 -0
  167. package/lib/agents/proposals.ts +13 -5
  168. package/lib/agents/run-thread.auto-boundary.test.ts +125 -5
  169. package/lib/agents/run-thread.ts +24 -9
  170. package/lib/agents/sqlite-checkpoint-saver.test.ts +91 -0
  171. package/lib/agents/warm-summary-background.ts +22 -2
  172. package/lib/agents/warm-topics.test.ts +155 -1
  173. package/lib/agents/warm-topics.ts +27 -7
  174. package/lib/bridges/dispatcher.ts +1 -0
  175. package/lib/bridges/message-role.test.ts +81 -0
  176. package/lib/bridges/message-role.ts +23 -10
  177. package/lib/bridges/types.ts +6 -0
  178. package/lib/bridges/whatsapp-link.test.ts +32 -0
  179. package/lib/bridges/whatsapp-link.ts +21 -0
  180. package/lib/bridges/whatsapp.inbound.test.ts +239 -0
  181. package/lib/bridges/whatsapp.sender.test.ts +80 -1
  182. package/lib/bridges/whatsapp.ts +76 -38
  183. package/lib/pricing/snapshot.test.ts +70 -0
  184. package/lib/pricing/snapshot.ts +10 -2
  185. package/lib/proxy/dispatcher.test.ts +119 -1
  186. package/lib/proxy/dispatcher.ts +22 -9
  187. package/lib/stores/agent-configs.ts +10 -5
  188. package/lib/stores/bridges.test.ts +81 -0
  189. package/lib/stores/bridges.ts +9 -8
  190. package/lib/stores/proxy-config.test.ts +120 -0
  191. package/lib/stores/proxy-config.ts +22 -4
  192. package/lib/stores/threads.ts +12 -8
  193. package/lib/tools/communications/calendar.test.ts +43 -2
  194. package/lib/tools/communications/calendar.ts +2 -0
  195. package/lib/tools/communications/gmail.test.ts +51 -1
  196. package/lib/tools/communications/gmail.ts +44 -2
  197. package/lib/tools/communications/outlook-calendar.ts +2 -0
  198. package/lib/tools/communications/outlook.test.ts +33 -2
  199. package/lib/tools/communications/outlook.ts +2 -0
  200. package/lib/tools/filesystem/edit-match.test.ts +133 -0
  201. package/lib/tools/filesystem/edit-match.ts +7 -2
  202. package/lib/tools/support/result-refs.test.ts +131 -0
  203. package/lib/tools/support/result-refs.ts +41 -9
  204. package/lib/utils/source-link.test.ts +51 -0
  205. package/lib/utils/source-link.ts +45 -0
  206. package/package.json +1 -1
  207. /package/.next/standalone/.next/static/{bMRK5y3ruT7c3WtBfCQOG → hwujW4hR1b-r3k5WdMxZO}/_buildManifest.js +0 -0
  208. /package/.next/standalone/.next/static/{bMRK5y3ruT7c3WtBfCQOG → hwujW4hR1b-r3k5WdMxZO}/_ssgManifest.js +0 -0
@@ -8680,7 +8680,25 @@ async function applyProxyConfigFromDb() {
8680
8680
  // ---------------------------------------------------------------------
8681
8681
  function buildProxyUrl(scheme, host, port, username, password) {
8682
8682
  const auth = username ? `${encodeURIComponent(username)}${password ? `:${encodeURIComponent(password)}` : ""}@` : "";
8683
- return `${scheme}://${auth}${host}:${port}`;
8683
+ const urlHost = host.includes(":") && !host.startsWith("[") ? `[${host}]` : host;
8684
+ return `${scheme}://${auth}${urlHost}:${port}`;
8685
+ }
8686
+ // undici's EnvHttpProxyAgent has no implicit loopback exemption, so without
8687
+ // these a configured proxy would also receive local traffic (Ollama, the
8688
+ // WhatsApp bridge sidecar, the app's own loopback API).
8689
+ const LOOPBACK_NO_PROXY = [
8690
+ "localhost",
8691
+ "127.0.0.1",
8692
+ "::1"
8693
+ ];
8694
+ function mergeNoProxy(noProxy) {
8695
+ const entries = (noProxy ?? "").split(/[,\s]+/).map((entry)=>entry.trim()).filter(Boolean);
8696
+ return [
8697
+ ...new Set([
8698
+ ...entries,
8699
+ ...LOOPBACK_NO_PROXY
8700
+ ])
8701
+ ].join(",");
8684
8702
  }
8685
8703
  function installProxy(url, noProxy, caBundle) {
8686
8704
  // Set process.env so EnvHttpProxyAgent honors NO_PROXY semantics
@@ -8688,27 +8706,31 @@ function installProxy(url, noProxy, caBundle) {
8688
8706
  // We still treat the boot-time env snapshot as authoritative for the
8689
8707
  // "env beats DB" rule — this mutation only happens after we've
8690
8708
  // confirmed the user did NOT set HTTP_PROXY at launch.
8709
+ const merged = mergeNoProxy(noProxy);
8691
8710
  process.env.HTTP_PROXY = url;
8692
8711
  process.env.HTTPS_PROXY = url;
8693
- if (noProxy && noProxy.trim().length > 0) {
8694
- process.env.NO_PROXY = noProxy.trim();
8695
- } else {
8696
- delete process.env.NO_PROXY;
8697
- }
8712
+ process.env.NO_PROXY = merged;
8698
8713
  // ADR-0012: when the user pasted a corporate root CA, inject it on
8699
8714
  // both TLS legs — the proxy hop (proxyTls) for https-scheme proxies
8700
8715
  // signed by the corporate root, and the upstream tunnel (requestTls)
8701
8716
  // for proxies that MITM outbound HTTPS with the same internal CA.
8702
8717
  // Same blob is correct: the corporate trust chain typically signs
8703
8718
  // both ends.
8704
- const opts = caBundle ? {
8705
- requestTls: {
8706
- ca: caBundle
8707
- },
8708
- proxyTls: {
8709
- ca: caBundle
8710
- }
8711
- } : {};
8719
+ // Pass the values explicitly too: undici prefers lowercase http_proxy /
8720
+ // no_proxy from the environment over the uppercase ones set above.
8721
+ const opts = {
8722
+ httpProxy: url,
8723
+ httpsProxy: url,
8724
+ noProxy: merged,
8725
+ ...caBundle ? {
8726
+ requestTls: {
8727
+ ca: caBundle
8728
+ },
8729
+ proxyTls: {
8730
+ ca: caBundle
8731
+ }
8732
+ } : {}
8733
+ };
8712
8734
  (0,external_undici_.setGlobalDispatcher)(new external_undici_.EnvHttpProxyAgent(opts));
8713
8735
  }
8714
8736
  function resetToBaseline() {
@@ -10776,9 +10798,11 @@ function getIntegrationMeta(name) {
10776
10798
  /* harmony export */ qt: () => (/* binding */ saveProxyConfig),
10777
10799
  /* harmony export */ xl: () => (/* binding */ getProxyConfigRaw)
10778
10800
  /* harmony export */ });
10779
- /* harmony import */ var _lib_db__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(46);
10780
- /* harmony import */ var _lib_crypto_envelope__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(10938);
10781
- /* harmony import */ var _lib_stores_integrations__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(78228);
10801
+ /* harmony import */ var node_net__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(77030);
10802
+ /* harmony import */ var node_net__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(node_net__WEBPACK_IMPORTED_MODULE_0__);
10803
+ /* harmony import */ var _lib_db__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(46);
10804
+ /* harmony import */ var _lib_crypto_envelope__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(10938);
10805
+ /* harmony import */ var _lib_stores_integrations__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(78228);
10782
10806
  // Proxy configuration store (ADR-0009, extended ADR-0012).
10783
10807
  //
10784
10808
  // Single-row table proxy_config. Non-secret columns are plaintext for
@@ -10798,6 +10822,7 @@ function getIntegrationMeta(name) {
10798
10822
 
10799
10823
 
10800
10824
 
10825
+
10801
10826
  const DEFAULT_STATUS = {
10802
10827
  mode: "off",
10803
10828
  scheme: "http",
@@ -10818,7 +10843,7 @@ function getProxyConfigStatus() {
10818
10843
  host: row.host,
10819
10844
  port: row.port,
10820
10845
  username: row.username,
10821
- password: row.password ? _lib_stores_integrations__WEBPACK_IMPORTED_MODULE_2__/* .SECRET_MASK */ .Q6 : null,
10846
+ password: row.password ? _lib_stores_integrations__WEBPACK_IMPORTED_MODULE_3__/* .SECRET_MASK */ .Q6 : null,
10822
10847
  no_proxy: row.no_proxy,
10823
10848
  ca_bundle: row.ca_bundle,
10824
10849
  updated_at: row.updated_at
@@ -10836,7 +10861,7 @@ function getProxyConfigRaw() {
10836
10861
  host: row.host,
10837
10862
  port: row.port,
10838
10863
  username: row.username,
10839
- password: row.password ? (0,_lib_crypto_envelope__WEBPACK_IMPORTED_MODULE_1__/* .decryptIfNeeded */ .qU)(row.password) : null,
10864
+ password: row.password ? (0,_lib_crypto_envelope__WEBPACK_IMPORTED_MODULE_2__/* .decryptIfNeeded */ .qU)(row.password) : null,
10840
10865
  no_proxy: row.no_proxy,
10841
10866
  ca_bundle: row.ca_bundle,
10842
10867
  updated_at: row.updated_at
@@ -10848,15 +10873,26 @@ function saveProxyConfig(input) {
10848
10873
  };
10849
10874
  const scheme = input.scheme === "https" ? "https" : "http";
10850
10875
  // Manual mode requires host + port. system / off don't.
10876
+ let host = nullable(input.host);
10851
10877
  if (input.mode === "manual") {
10852
- if (!input.host || !input.host.trim()) return {
10878
+ if (!host) return {
10853
10879
  error: "host is required in manual mode"
10854
10880
  };
10855
- if (input.port == null || !Number.isFinite(input.port) || input.port <= 0 || input.port > 65535) {
10881
+ const normalisedHost = normaliseProxyHost(host);
10882
+ if (!normalisedHost) {
10856
10883
  return {
10857
- error: "port must be between 1 and 65535"
10884
+ error: "host must be a hostname or IP address, without scheme, port, path or credentials"
10858
10885
  };
10859
10886
  }
10887
+ host = normalisedHost;
10888
+ if (input.port == null) return {
10889
+ error: "port must be between 1 and 65535"
10890
+ };
10891
+ }
10892
+ if (input.port != null && (!Number.isInteger(input.port) || input.port <= 0 || input.port > 65535)) {
10893
+ return {
10894
+ error: "port must be between 1 and 65535"
10895
+ };
10860
10896
  }
10861
10897
  // CA bundle: empty/null clears; non-empty must look like PEM.
10862
10898
  let storedCaBundle = null;
@@ -10871,15 +10907,15 @@ function saveProxyConfig(input) {
10871
10907
  // Preserve existing password when the UI echoes back the masked sentinel.
10872
10908
  const existing = readRow();
10873
10909
  let storedPassword = null;
10874
- if (input.password === _lib_stores_integrations__WEBPACK_IMPORTED_MODULE_2__/* .SECRET_MASK */ .Q6) {
10910
+ if (input.password === _lib_stores_integrations__WEBPACK_IMPORTED_MODULE_3__/* .SECRET_MASK */ .Q6) {
10875
10911
  storedPassword = existing?.password ?? null;
10876
10912
  } else if (input.password && input.password.length > 0) {
10877
- storedPassword = (0,_lib_crypto_envelope__WEBPACK_IMPORTED_MODULE_1__/* .encrypt */ .w)(input.password);
10913
+ storedPassword = (0,_lib_crypto_envelope__WEBPACK_IMPORTED_MODULE_2__/* .encrypt */ .w)(input.password);
10878
10914
  } else {
10879
10915
  storedPassword = null;
10880
10916
  }
10881
10917
  const now = new Date().toISOString();
10882
- const db = (0,_lib_db__WEBPACK_IMPORTED_MODULE_0__/* .getDb */ .Lf)();
10918
+ const db = (0,_lib_db__WEBPACK_IMPORTED_MODULE_1__/* .getDb */ .Lf)();
10883
10919
  db.prepare(`INSERT INTO proxy_config (id, mode, scheme, host, port, username, password, no_proxy, ca_bundle, updated_at)
10884
10920
  VALUES (1, ?, ?, ?, ?, ?, ?, ?, ?, ?)
10885
10921
  ON CONFLICT(id) DO UPDATE SET
@@ -10891,16 +10927,16 @@ function saveProxyConfig(input) {
10891
10927
  password = excluded.password,
10892
10928
  no_proxy = excluded.no_proxy,
10893
10929
  ca_bundle = excluded.ca_bundle,
10894
- updated_at = excluded.updated_at`).run(input.mode, scheme, nullable(input.host), input.port ?? null, nullable(input.username), storedPassword, nullable(input.no_proxy), storedCaBundle, now);
10930
+ updated_at = excluded.updated_at`).run(input.mode, scheme, host, input.port ?? null, nullable(input.username), storedPassword, nullable(input.no_proxy), storedCaBundle, now);
10895
10931
  return getProxyConfigStatus();
10896
10932
  }
10897
10933
  function deleteProxyConfig() {
10898
- const db = (0,_lib_db__WEBPACK_IMPORTED_MODULE_0__/* .getDb */ .Lf)();
10934
+ const db = (0,_lib_db__WEBPACK_IMPORTED_MODULE_1__/* .getDb */ .Lf)();
10899
10935
  const r = db.prepare("DELETE FROM proxy_config WHERE id = 1").run();
10900
10936
  return r.changes > 0;
10901
10937
  }
10902
10938
  function readRow() {
10903
- const db = (0,_lib_db__WEBPACK_IMPORTED_MODULE_0__/* .getDb */ .Lf)();
10939
+ const db = (0,_lib_db__WEBPACK_IMPORTED_MODULE_1__/* .getDb */ .Lf)();
10904
10940
  const r = db.prepare("SELECT mode, scheme, host, port, username, password, no_proxy, ca_bundle, updated_at FROM proxy_config WHERE id = 1").get();
10905
10941
  return r ?? null;
10906
10942
  }
@@ -10913,6 +10949,15 @@ function normaliseMode(m) {
10913
10949
  function normaliseScheme(s) {
10914
10950
  return s === "https" ? "https" : "http";
10915
10951
  }
10952
+ // The dispatcher builds `${scheme}://${auth}${host}:${port}`, so a pasted URL
10953
+ // or host:port would produce an unusable proxy URL. IPv6 is stored unbracketed;
10954
+ // the dispatcher adds the brackets.
10955
+ function normaliseProxyHost(host) {
10956
+ const unbracketed = host.startsWith("[") && host.endsWith("]") ? host.slice(1, -1) : host;
10957
+ if (/^[A-Za-z0-9](?:[A-Za-z0-9.-]*[A-Za-z0-9])?$/.test(unbracketed)) return unbracketed;
10958
+ if ((0,node_net__WEBPACK_IMPORTED_MODULE_0__.isIPv6)(unbracketed)) return unbracketed;
10959
+ return null;
10960
+ }
10916
10961
  function nullable(v) {
10917
10962
  if (v == null) return null;
10918
10963
  const trimmed = v.trim();
@@ -202,58 +202,79 @@ function containsText(source, needle, ignoreCase) {
202
202
  if (!ignoreCase) return source.includes(needle);
203
203
  return source.toLowerCase().includes(needle.toLowerCase());
204
204
  }
205
- function dedupeLines(source, opts) {
206
- const lines = source.split(/\r?\n/);
207
- const keyed = lines.map((line)=>{
208
- const normalized = opts.trim ? line.trim() : line;
209
- return opts.ignoreCase ? normalized.toLowerCase() : normalized;
210
- });
211
- const keep = new Set();
212
- const visit = opts.keep === "first" ? [
213
- ...keyed.keys()
214
- ] : [
215
- ...keyed.keys()
205
+ const FENCE_RE = /^\s{0,3}(`{3,}|~{3,})/;
206
+ const HORIZONTAL_RULE_RE = /^\s{0,3}([-*_])(?:\s*\1){2,}\s*$/;
207
+ /**
208
+ * Drop duplicate segments from `parts`, which alternates content (even
209
+ * indexes) and the original separator that follows it (odd indexes).
210
+ * Separators are preserved verbatim, so only removed segments change the
211
+ * text. `keyOf` returns null for a segment that must always be kept.
212
+ */ function dedupeSegments(parts, keyOf, keep) {
213
+ const contentIdx = parts.map((_, i)=>i).filter((i)=>i % 2 === 0);
214
+ const visit = keep === "first" ? contentIdx : [
215
+ ...contentIdx
216
216
  ].reverse();
217
217
  const seen = new Set();
218
+ const dropped = new Set();
218
219
  for (const idx of visit){
219
- const key = keyed[idx];
220
- if (opts.skipBlank && key.length === 0) {
221
- keep.add(idx);
222
- continue;
223
- }
224
- if (seen.has(key)) continue;
225
- seen.add(key);
226
- keep.add(idx);
220
+ const key = keyOf(idx);
221
+ if (key === null) continue;
222
+ if (seen.has(key)) dropped.add(idx);
223
+ else seen.add(key);
224
+ }
225
+ if (dropped.size === 0) return {
226
+ text: parts.join(""),
227
+ removed: 0
228
+ };
229
+ let text = "";
230
+ let emitted = false;
231
+ for (const idx of contentIdx){
232
+ if (dropped.has(idx)) continue;
233
+ if (emitted && idx > 0) text += parts[idx - 1];
234
+ text += parts[idx];
235
+ emitted = true;
227
236
  }
228
- const next = lines.filter((_, idx)=>keep.has(idx));
229
237
  return {
230
- text: next.join("\n"),
231
- removed: lines.length - next.length
238
+ text,
239
+ removed: dropped.size
232
240
  };
233
241
  }
242
+ function dedupeLines(source, opts) {
243
+ const parts = source.split(/(\r?\n)/);
244
+ // Fence markers, fenced code and horizontal rules repeat by design; a
245
+ // closing ``` is always a "duplicate" of the opening one.
246
+ const protectedIdx = new Set();
247
+ let fence = null;
248
+ for(let i = 0; i < parts.length; i += 2){
249
+ const marker = FENCE_RE.exec(parts[i])?.[1];
250
+ if (fence !== null) {
251
+ protectedIdx.add(i);
252
+ if (marker && marker[0] === fence[0] && marker.length >= fence.length && /^\s*[`~]+\s*$/.test(parts[i])) fence = null;
253
+ } else if (marker) {
254
+ protectedIdx.add(i);
255
+ fence = marker;
256
+ } else if (HORIZONTAL_RULE_RE.test(parts[i])) {
257
+ protectedIdx.add(i);
258
+ }
259
+ }
260
+ return dedupeSegments(parts, (i)=>{
261
+ if (protectedIdx.has(i)) return null;
262
+ const normalized = opts.trim ? parts[i].trim() : parts[i];
263
+ if (opts.skipBlank && normalized.length === 0) return null;
264
+ return opts.ignoreCase ? normalized.toLowerCase() : normalized;
265
+ }, opts.keep);
266
+ }
234
267
  function dedupeParagraphs(source, opts) {
235
- const paragraphs = source.split(/\n\s*\n/).map((p)=>p.trim()).filter((p)=>p.length > 0);
236
- const keys = paragraphs.map((p)=>{
237
- const base = opts.trim ? p.trim() : p;
268
+ const tail = /\s*$/.exec(source)?.[0] ?? "";
269
+ const parts = source.slice(0, source.length - tail.length).split(/(\r?\n(?:[ \t]*\r?\n)+)/);
270
+ const out = dedupeSegments(parts, (i)=>{
271
+ if (parts[i].trim().length === 0) return null;
272
+ const base = opts.trim ? parts[i].trim() : parts[i];
238
273
  return opts.ignoreCase ? base.toLowerCase() : base;
239
- });
240
- const keep = new Set();
241
- const visit = opts.keep === "first" ? [
242
- ...keys.keys()
243
- ] : [
244
- ...keys.keys()
245
- ].reverse();
246
- const seen = new Set();
247
- for (const idx of visit){
248
- const key = keys[idx];
249
- if (seen.has(key)) continue;
250
- seen.add(key);
251
- keep.add(idx);
252
- }
253
- const next = paragraphs.filter((_, idx)=>keep.has(idx));
274
+ }, opts.keep);
254
275
  return {
255
- text: next.join("\n\n"),
256
- removed: paragraphs.length - next.length
276
+ text: out.text + tail,
277
+ removed: out.removed
257
278
  };
258
279
  }
259
280
 
@@ -468,6 +468,7 @@ const PRICE_LINE_RE = new RegExp([
468
468
  String.raw`\$\s*\d+(?:\.\d+)?\s*(?:/|per)\s*(?:image|minute|request)`
469
469
  ].join("|"), "gi");
470
470
  const GOOGLE_RESULT_RE = /href="\/url\?q=([^"&]+)[^"]*"/gi;
471
+ const GOOGLE_OWN_HOST_RE = /^(?:www|accounts|support|maps|policies|webcache)?\.?google\.[a-z.]+$/i;
471
472
  function toCanonicalProvider(id) {
472
473
  const lower = id.toLowerCase();
473
474
  if (lower.includes("google") || lower.includes("gemini")) return "google";
@@ -499,7 +500,8 @@ async function refreshPricingSnapshot(opts) {
499
500
  const existing = await readPricingSnapshot();
500
501
  if (!force && existing) {
501
502
  const ageDays = (Date.now() - Date.parse(existing.generated_at)) / (24 * 60 * 60 * 1000);
502
- if (Number.isFinite(ageDays) && ageDays < ttlDays) {
503
+ // A future generated_at (clock skew, copied snapshot) must not pin the cache as fresh.
504
+ if (Number.isFinite(ageDays) && ageDays >= 0 && ageDays < ttlDays) {
503
505
  return {
504
506
  refreshed: false,
505
507
  reason: "fresh",
@@ -636,6 +638,8 @@ function parseGoogleResultLinks(html) {
636
638
  const out = [];
637
639
  const seen = new Set();
638
640
  let m;
641
+ // Shared /g regex: an early break leaves lastIndex mid-string for the next page.
642
+ GOOGLE_RESULT_RE.lastIndex = 0;
639
643
  while((m = GOOGLE_RESULT_RE.exec(html)) !== null){
640
644
  const raw = m[1] ?? "";
641
645
  let url = "";
@@ -645,7 +649,11 @@ function parseGoogleResultLinks(html) {
645
649
  continue;
646
650
  }
647
651
  if (!/^https?:\/\//i.test(url)) continue;
648
- if (/\/google\./i.test(url)) continue;
652
+ try {
653
+ if (GOOGLE_OWN_HOST_RE.test(new URL(url).hostname)) continue;
654
+ } catch {
655
+ continue;
656
+ }
649
657
  if (seen.has(url)) continue;
650
658
  seen.add(url);
651
659
  out.push(url);
@@ -2165,7 +2165,7 @@ var NumericValue = __webpack_require__(3999);
2165
2165
  // EXTERNAL MODULE: ./node_modules/@smithy/core/dist-es/submodules/serde/util-utf8/toUtf8.js
2166
2166
  var toUtf8 = __webpack_require__(63332);
2167
2167
  // EXTERNAL MODULE: ./node_modules/@smithy/core/dist-es/submodules/protocols/SerdeContext.js
2168
- var SerdeContext = __webpack_require__(71966);
2168
+ var SerdeContext = __webpack_require__(49585);
2169
2169
  // EXTERNAL MODULE: ./node_modules/@smithy/core/dist-es/submodules/protocols/serde/determineTimestampFormat.js
2170
2170
  var determineTimestampFormat = __webpack_require__(67055);
2171
2171
  ;// ./node_modules/@smithy/core/dist-es/submodules/protocols/serde/FromStringShapeDeserializer.js
@@ -15,12 +15,12 @@ exports.modules = {
15
15
  /* harmony export */ S0: () => (/* binding */ getRecentMessagesWindow),
16
16
  /* harmony export */ T1: () => (/* binding */ setThreadContextPin),
17
17
  /* harmony export */ TX: () => (/* binding */ getMessagesByAutomationCategory),
18
+ /* harmony export */ Tb: () => (/* binding */ countForegroundThreadMessages),
18
19
  /* harmony export */ VL: () => (/* binding */ getMessages),
19
20
  /* harmony export */ Xi: () => (/* binding */ appendMessageDraft),
20
21
  /* harmony export */ Zb: () => (/* binding */ mergeMessageMetadata),
21
22
  /* harmony export */ e8: () => (/* binding */ updateMessageContent),
22
23
  /* harmony export */ fG: () => (/* binding */ getThread),
23
- /* harmony export */ fW: () => (/* binding */ countThreadMessagesFromSeq),
24
24
  /* harmony export */ k3: () => (/* binding */ getRecentlyUsedToolNames),
25
25
  /* harmony export */ m9: () => (/* binding */ isValidThreadContextCursor),
26
26
  /* harmony export */ mI: () => (/* binding */ touchThread),
@@ -137,8 +137,10 @@ function getThread(thread_id) {
137
137
  function getThreadMessageBySeq(thread_id, seq) {
138
138
  return (0,_lib_db__WEBPACK_IMPORTED_MODULE_1__/* .getDb */ .L)().prepare(MSG_COLS_SQL + " WHERE thread_id=? AND rowid=?").get(thread_id, seq) ?? null;
139
139
  }
140
- function countThreadMessagesFromSeq(thread_id, seq) {
141
- const row = (0,_lib_db__WEBPACK_IMPORTED_MODULE_1__/* .getDb */ .L)().prepare("SELECT COUNT(*) AS n FROM messages WHERE thread_id=? AND rowid>=?").get(thread_id, seq);
140
+ // Rows that size compaction can prune: automation-channel rows are kept
141
+ // (see pruneThreadMessages), so they must not count toward its trigger.
142
+ function countForegroundThreadMessages(thread_id, fromSeq = 0) {
143
+ const row = (0,_lib_db__WEBPACK_IMPORTED_MODULE_1__/* .getDb */ .L)().prepare("SELECT COUNT(*) AS n FROM messages WHERE thread_id=? AND rowid>=? AND " + foregroundCategoryGuardSql()).get(thread_id, fromSeq, ...FOREGROUND_EXCLUDED_CATEGORIES);
142
144
  return row?.n ?? 0;
143
145
  }
144
146
  function isValidThreadContextCursor(thread_id, seq) {
@@ -578,11 +580,11 @@ function setThreadContextPin(thread_id, hot_since, hot_since_seq) {
578
580
  }
579
581
  (0,_lib_db__WEBPACK_IMPORTED_MODULE_1__/* .getDb */ .L)().prepare("UPDATE threads SET hot_since=?, hot_since_seq=? WHERE thread_id=?").run(hot_since, hot_since === null ? null : hot_since_seq, thread_id);
580
582
  }
581
- // Called by moveThreadContextBoundary whenever the user explicitly moves the
582
- // boundary (drag, or manual /compact) — never by the auto-detector's own
583
- // commit path, which calls setThreadContextPin directly. `untilMessageCount`
584
- // is a one-time write; the read side (lib/agents/run-thread.ts) just compares
585
- // against it, no per-turn write needed.
583
+ // Armed by moveThreadContextBoundary whenever the user explicitly moves the
584
+ // boundary (drag, or manual /compact), and by the auto-detector's hot-turn
585
+ // cooldown when a compaction pass ends without a commit (a commit writes the
586
+ // lock in the same transaction). `untilMessageCount` is a one-time write; the
587
+ // read side (lib/agents/run-thread.ts) just compares against it.
586
588
  function setAutoBoundaryLock(thread_id, untilMessageCount) {
587
589
  (0,_lib_db__WEBPACK_IMPORTED_MODULE_1__/* .getDb */ .L)().prepare("UPDATE threads SET auto_boundary_locked_until_msg_count=? WHERE thread_id=?").run(Math.max(0, untilMessageCount), thread_id);
588
590
  }
@@ -120,7 +120,7 @@ async function runShutdown() {
120
120
  }
121
121
  // 2. Stop the scheduler so no firing kicks off mid-drain.
122
122
  try {
123
- const { stopScheduler } = await Promise.all(/* import() */[__webpack_require__.e(8849), __webpack_require__.e(6703), __webpack_require__.e(3399), __webpack_require__.e(423), __webpack_require__.e(8461), __webpack_require__.e(1433), __webpack_require__.e(9164)]).then(__webpack_require__.bind(__webpack_require__, 47285));
123
+ const { stopScheduler } = await Promise.all(/* import() */[__webpack_require__.e(8849), __webpack_require__.e(6703), __webpack_require__.e(3399), __webpack_require__.e(9590), __webpack_require__.e(8461), __webpack_require__.e(1433), __webpack_require__.e(9164)]).then(__webpack_require__.bind(__webpack_require__, 47285));
124
124
  stopScheduler();
125
125
  } catch (err) {
126
126
  console.error("[jarela] stopping scheduler failed:", err);
@@ -130,14 +130,14 @@ async function runShutdown() {
130
130
  // scheduler tick (those are run-loop ownership; this is per-handler
131
131
  // ownership of OS resources).
132
132
  try {
133
- const { stopAllTriggerHandlers } = await Promise.all(/* import() */[__webpack_require__.e(8849), __webpack_require__.e(6703), __webpack_require__.e(3399), __webpack_require__.e(423), __webpack_require__.e(8461), __webpack_require__.e(1433), __webpack_require__.e(9164)]).then(__webpack_require__.bind(__webpack_require__, 64439));
133
+ const { stopAllTriggerHandlers } = await Promise.all(/* import() */[__webpack_require__.e(8849), __webpack_require__.e(6703), __webpack_require__.e(3399), __webpack_require__.e(9590), __webpack_require__.e(8461), __webpack_require__.e(1433), __webpack_require__.e(9164)]).then(__webpack_require__.bind(__webpack_require__, 64439));
134
134
  await stopAllTriggerHandlers();
135
135
  } catch (err) {
136
136
  console.error("[jarela] stopping trigger handlers failed:", err);
137
137
  }
138
138
  // 3. Close bridges (WhatsApp Baileys WS, etc).
139
139
  try {
140
- const { stopAllBridges } = await Promise.all(/* import() */[__webpack_require__.e(8849), __webpack_require__.e(6703), __webpack_require__.e(3399), __webpack_require__.e(423), __webpack_require__.e(8461), __webpack_require__.e(1433), __webpack_require__.e(9164), __webpack_require__.e(2350)]).then(__webpack_require__.bind(__webpack_require__, 32350));
140
+ const { stopAllBridges } = await Promise.all(/* import() */[__webpack_require__.e(8849), __webpack_require__.e(6703), __webpack_require__.e(3399), __webpack_require__.e(9590), __webpack_require__.e(8461), __webpack_require__.e(1433), __webpack_require__.e(9164), __webpack_require__.e(3272)]).then(__webpack_require__.bind(__webpack_require__, 63272));
141
141
  await stopAllBridges();
142
142
  } catch (err) {
143
143
  console.error("[jarela] stopping bridges failed:", err);
@@ -155,7 +155,7 @@ async function runShutdown() {
155
155
  // 4b. Stop the async-tool-results sweeper. Holds a setInterval that
156
156
  // would otherwise keep the event loop alive past closeDb().
157
157
  try {
158
- const { stopAsyncResults } = await Promise.all(/* import() */[__webpack_require__.e(8849), __webpack_require__.e(423), __webpack_require__.e(8461), __webpack_require__.e(1433), __webpack_require__.e(8182)]).then(__webpack_require__.bind(__webpack_require__, 68182));
158
+ const { stopAsyncResults } = await Promise.all(/* import() */[__webpack_require__.e(8849), __webpack_require__.e(9590), __webpack_require__.e(8461), __webpack_require__.e(1433), __webpack_require__.e(8182)]).then(__webpack_require__.bind(__webpack_require__, 68182));
159
159
  stopAsyncResults();
160
160
  } catch (err) {
161
161
  console.error("[jarela] stopping async-results sweeper failed:", err);
@@ -163,7 +163,7 @@ async function runShutdown() {
163
163
  // 5. Close the DB. WAL is checkpointed so the next boot is fast and we
164
164
  // leave no stale -shm/-wal sidecars on disk.
165
165
  try {
166
- const { closeDb } = await Promise.all(/* import() */[__webpack_require__.e(8849), __webpack_require__.e(423)]).then(__webpack_require__.bind(__webpack_require__, 39504));
166
+ const { closeDb } = await Promise.all(/* import() */[__webpack_require__.e(8849), __webpack_require__.e(9590)]).then(__webpack_require__.bind(__webpack_require__, 39504));
167
167
  closeDb();
168
168
  } catch (err) {
169
169
  console.error("[jarela] closing db failed:", err);