@ashx-j/lunr 0.2.24 → 0.2.26

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 (254) hide show
  1. package/CHANGELOG.md +24 -1
  2. package/dist/builtin-extensions/index.d.ts.map +1 -1
  3. package/dist/builtin-extensions/index.js +1 -0
  4. package/dist/builtin-extensions/index.js.map +1 -1
  5. package/dist/builtin-extensions/lunr-computer-use.d.ts +3 -0
  6. package/dist/builtin-extensions/lunr-computer-use.d.ts.map +1 -0
  7. package/dist/builtin-extensions/lunr-computer-use.js +179 -0
  8. package/dist/builtin-extensions/lunr-computer-use.js.map +1 -0
  9. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.d.ts.map +1 -1
  10. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js +1 -1
  11. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js.map +1 -1
  12. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.d.ts +4 -4
  13. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.d.ts.map +1 -1
  14. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.js +8 -5
  15. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.js.map +1 -1
  16. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.d.ts +1 -0
  17. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.d.ts.map +1 -1
  18. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.js +11 -2
  19. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.js.map +1 -1
  20. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.d.ts.map +1 -1
  21. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.js +3 -3
  22. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.js.map +1 -1
  23. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.d.ts.map +1 -1
  24. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.js +15 -1
  25. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.js.map +1 -1
  26. package/dist/builtin-extensions/pi-subagents/src/runs/shared/chain-outputs.d.ts +1 -0
  27. package/dist/builtin-extensions/pi-subagents/src/runs/shared/chain-outputs.d.ts.map +1 -1
  28. package/dist/builtin-extensions/pi-subagents/src/runs/shared/chain-outputs.js +5 -0
  29. package/dist/builtin-extensions/pi-subagents/src/runs/shared/chain-outputs.js.map +1 -1
  30. package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.d.ts +1 -1
  31. package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.d.ts.map +1 -1
  32. package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.js +2 -0
  33. package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.js.map +1 -1
  34. package/dist/builtin-extensions/pi-subagents/src/tui/communication.d.ts.map +1 -1
  35. package/dist/builtin-extensions/pi-subagents/src/tui/communication.js +1 -1
  36. package/dist/builtin-extensions/pi-subagents/src/tui/communication.js.map +1 -1
  37. package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts +1 -0
  38. package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts.map +1 -1
  39. package/dist/builtin-extensions/pi-subagents/src/tui/render.js +5 -3
  40. package/dist/builtin-extensions/pi-subagents/src/tui/render.js.map +1 -1
  41. package/dist/core/computer-use/adapter.d.ts +28 -0
  42. package/dist/core/computer-use/adapter.d.ts.map +1 -0
  43. package/dist/core/computer-use/adapter.js +133 -0
  44. package/dist/core/computer-use/adapter.js.map +1 -0
  45. package/dist/core/computer-use/image.d.ts +27 -0
  46. package/dist/core/computer-use/image.d.ts.map +1 -0
  47. package/dist/core/computer-use/image.js +72 -0
  48. package/dist/core/computer-use/image.js.map +1 -0
  49. package/dist/core/computer-use/lease.d.ts +18 -0
  50. package/dist/core/computer-use/lease.d.ts.map +1 -0
  51. package/dist/core/computer-use/lease.js +129 -0
  52. package/dist/core/computer-use/lease.js.map +1 -0
  53. package/dist/core/computer-use/macos-runtime.d.ts +14 -0
  54. package/dist/core/computer-use/macos-runtime.d.ts.map +1 -0
  55. package/dist/core/computer-use/macos-runtime.js +148 -0
  56. package/dist/core/computer-use/macos-runtime.js.map +1 -0
  57. package/dist/core/computer-use/policy.d.ts +19 -0
  58. package/dist/core/computer-use/policy.d.ts.map +1 -0
  59. package/dist/core/computer-use/policy.js +67 -0
  60. package/dist/core/computer-use/policy.js.map +1 -0
  61. package/dist/core/computer-use/release.generated.d.ts +31 -0
  62. package/dist/core/computer-use/release.generated.d.ts.map +1 -0
  63. package/dist/core/computer-use/release.generated.js +36 -0
  64. package/dist/core/computer-use/release.generated.js.map +1 -0
  65. package/dist/core/computer-use/runtime.d.ts +13 -0
  66. package/dist/core/computer-use/runtime.d.ts.map +1 -0
  67. package/dist/core/computer-use/runtime.js +158 -0
  68. package/dist/core/computer-use/runtime.js.map +1 -0
  69. package/dist/core/computer-use/schemas.d.ts +100 -0
  70. package/dist/core/computer-use/schemas.d.ts.map +1 -0
  71. package/dist/core/computer-use/schemas.js +79 -0
  72. package/dist/core/computer-use/schemas.js.map +1 -0
  73. package/dist/core/computer-use/windows-desktop.d.ts +3 -0
  74. package/dist/core/computer-use/windows-desktop.d.ts.map +1 -0
  75. package/dist/core/computer-use/windows-desktop.js +48 -0
  76. package/dist/core/computer-use/windows-desktop.js.map +1 -0
  77. package/dist/core/computer-use/workflow.d.ts +38 -0
  78. package/dist/core/computer-use/workflow.d.ts.map +1 -0
  79. package/dist/core/computer-use/workflow.js +560 -0
  80. package/dist/core/computer-use/workflow.js.map +1 -0
  81. package/dist/core/extensions/loader.d.ts.map +1 -1
  82. package/dist/core/extensions/loader.js +4 -0
  83. package/dist/core/extensions/loader.js.map +1 -1
  84. package/dist/core/permissions.d.ts +1 -1
  85. package/dist/core/permissions.d.ts.map +1 -1
  86. package/dist/core/permissions.js +14 -3
  87. package/dist/core/permissions.js.map +1 -1
  88. package/dist/core/plan-mode.d.ts.map +1 -1
  89. package/dist/core/plan-mode.js +9 -0
  90. package/dist/core/plan-mode.js.map +1 -1
  91. package/dist/core/settings-manager.d.ts +6 -0
  92. package/dist/core/settings-manager.d.ts.map +1 -1
  93. package/dist/core/settings-manager.js +19 -0
  94. package/dist/core/settings-manager.js.map +1 -1
  95. package/dist/core/subagent-event-transport.d.ts +3 -0
  96. package/dist/core/subagent-event-transport.d.ts.map +1 -0
  97. package/dist/core/subagent-event-transport.js +61 -0
  98. package/dist/core/subagent-event-transport.js.map +1 -0
  99. package/dist/gateway/adapters/discord.d.ts.map +1 -1
  100. package/dist/gateway/adapters/discord.js +4 -9
  101. package/dist/gateway/adapters/discord.js.map +1 -1
  102. package/dist/gateway/adapters/telegram.d.ts.map +1 -1
  103. package/dist/gateway/adapters/telegram.js +7 -0
  104. package/dist/gateway/adapters/telegram.js.map +1 -1
  105. package/dist/gateway/agent-bridge.d.ts +4 -1
  106. package/dist/gateway/agent-bridge.d.ts.map +1 -1
  107. package/dist/gateway/agent-bridge.js +57 -17
  108. package/dist/gateway/agent-bridge.js.map +1 -1
  109. package/dist/gateway/approval.d.ts.map +1 -1
  110. package/dist/gateway/approval.js +3 -3
  111. package/dist/gateway/approval.js.map +1 -1
  112. package/dist/gateway/authz.d.ts +4 -4
  113. package/dist/gateway/authz.d.ts.map +1 -1
  114. package/dist/gateway/authz.js +8 -12
  115. package/dist/gateway/authz.js.map +1 -1
  116. package/dist/gateway/buttons.d.ts.map +1 -1
  117. package/dist/gateway/buttons.js +29 -19
  118. package/dist/gateway/buttons.js.map +1 -1
  119. package/dist/gateway/commands.d.ts +2 -0
  120. package/dist/gateway/commands.d.ts.map +1 -1
  121. package/dist/gateway/commands.js +35 -18
  122. package/dist/gateway/commands.js.map +1 -1
  123. package/dist/gateway/config.d.ts +1 -0
  124. package/dist/gateway/config.d.ts.map +1 -1
  125. package/dist/gateway/config.js +2 -0
  126. package/dist/gateway/config.js.map +1 -1
  127. package/dist/gateway/cron.d.ts +1 -1
  128. package/dist/gateway/cron.d.ts.map +1 -1
  129. package/dist/gateway/cron.js +22 -8
  130. package/dist/gateway/cron.js.map +1 -1
  131. package/dist/gateway/index.d.ts.map +1 -1
  132. package/dist/gateway/index.js +26 -26
  133. package/dist/gateway/index.js.map +1 -1
  134. package/dist/gateway/mobile-commands.d.ts.map +1 -1
  135. package/dist/gateway/mobile-commands.js +11 -11
  136. package/dist/gateway/mobile-commands.js.map +1 -1
  137. package/dist/gateway/presenter.d.ts +12 -1
  138. package/dist/gateway/presenter.d.ts.map +1 -1
  139. package/dist/gateway/presenter.js +148 -50
  140. package/dist/gateway/presenter.js.map +1 -1
  141. package/dist/gateway/router.d.ts +5 -5
  142. package/dist/gateway/router.d.ts.map +1 -1
  143. package/dist/gateway/router.js +95 -43
  144. package/dist/gateway/router.js.map +1 -1
  145. package/dist/gateway/service.d.ts.map +1 -1
  146. package/dist/gateway/service.js +13 -4
  147. package/dist/gateway/service.js.map +1 -1
  148. package/dist/gateway/setup.d.ts +5 -0
  149. package/dist/gateway/setup.d.ts.map +1 -1
  150. package/dist/gateway/setup.js +101 -43
  151. package/dist/gateway/setup.js.map +1 -1
  152. package/dist/gateway/stream.d.ts +6 -5
  153. package/dist/gateway/stream.d.ts.map +1 -1
  154. package/dist/gateway/stream.js +24 -11
  155. package/dist/gateway/stream.js.map +1 -1
  156. package/dist/modes/interactive/components/settings-selector.d.ts +4 -0
  157. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  158. package/dist/modes/interactive/components/settings-selector.js +20 -0
  159. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  160. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  161. package/dist/modes/interactive/interactive-mode.js +8 -0
  162. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  163. package/dist/modes/print-mode.d.ts.map +1 -1
  164. package/dist/modes/print-mode.js +9 -1
  165. package/dist/modes/print-mode.js.map +1 -1
  166. package/dist/node-runtime/adapter-VFG7WNPX.js +17 -0
  167. package/dist/node-runtime/{agent-session-services-IEF7LQWD.js → agent-session-services-5YXS2PLF.js} +13 -10
  168. package/dist/node-runtime/{builtin-extensions-EBAWTH4M.js → builtin-extensions-I2HIFEMY.js} +3 -2
  169. package/dist/node-runtime/{chunk-K5AGHH57.js → chunk-2CFDTH5B.js} +7 -3
  170. package/dist/node-runtime/{chunk-VWCE2HSZ.js → chunk-2HMIRK7W.js} +4 -4
  171. package/dist/node-runtime/chunk-2IDTZAG5.js +1415 -0
  172. package/dist/node-runtime/{chunk-IGV54Q5V.js → chunk-3MISGG4S.js} +137 -76
  173. package/dist/node-runtime/chunk-4SBQAI4T.js +2185 -0
  174. package/dist/node-runtime/{chunk-WHLRAGUQ.js → chunk-5B5QN3ZQ.js} +16 -16
  175. package/dist/node-runtime/chunk-5B6VKFEV.js +180 -0
  176. package/dist/node-runtime/{chunk-AD6VXAO7.js → chunk-5Q4A37RB.js} +15 -104
  177. package/dist/node-runtime/{chunk-4TLO4PO2.js → chunk-7IQGBKBJ.js} +7 -1401
  178. package/dist/node-runtime/{chunk-R3K2F5GI.js → chunk-B4HP6ZWM.js} +2 -0
  179. package/dist/node-runtime/{chunk-OCVIXVTZ.js → chunk-D5UCKPBQ.js} +12 -1
  180. package/dist/node-runtime/chunk-DVQSHCVP.js +97 -0
  181. package/dist/node-runtime/{chunk-HFVZUPFJ.js → chunk-E75WFZ33.js} +2 -2
  182. package/dist/node-runtime/chunk-FY4A63RK.js +73 -0
  183. package/dist/node-runtime/{chunk-RORY2HMJ.js → chunk-I74LN5JG.js} +16 -1
  184. package/dist/node-runtime/chunk-IKU6Y7DL.js +287 -0
  185. package/dist/node-runtime/{chunk-QM43FEAE.js → chunk-L24TPBS4.js} +6 -5
  186. package/dist/node-runtime/{chunk-DE2JB6J5.js → chunk-LJTIVM7I.js} +7 -7
  187. package/dist/node-runtime/{chunk-DSIKTUPW.js → chunk-LWJXTA6Z.js} +274 -2433
  188. package/dist/node-runtime/{chunk-YVI6L6LU.js → chunk-P7XBVXGT.js} +36 -21
  189. package/dist/node-runtime/{chunk-OVX6X377.js → chunk-PTFBPO3C.js} +1 -1
  190. package/dist/node-runtime/{chunk-F4FLTQKV.js → chunk-RAK2QA2B.js} +186 -1529
  191. package/dist/node-runtime/{chunk-L3LX4SNR.js → chunk-RCR3XAQY.js} +36 -8
  192. package/dist/node-runtime/chunk-RGQAEOM5.js +81 -0
  193. package/dist/node-runtime/{chunk-UWPJL22I.js → chunk-SLVOAQOY.js} +15 -4
  194. package/dist/node-runtime/chunk-SN2KSMPQ.js +1364 -0
  195. package/dist/node-runtime/{chunk-FU6OODRZ.js → chunk-SPVDBUOS.js} +1 -1
  196. package/dist/node-runtime/{chunk-5Q3EHOHI.js → chunk-T4DA4XE7.js} +19 -17
  197. package/dist/node-runtime/chunk-U5F4IC7R.js +53 -0
  198. package/dist/node-runtime/{chunk-UP2XBVH5.js → chunk-UOEDI7RP.js} +1 -1
  199. package/dist/node-runtime/{chunk-Y73WPE6S.js → chunk-UVWCDQYF.js} +79 -44
  200. package/dist/node-runtime/{chunk-ZXSGTGJ6.js → chunk-WIF24I7G.js} +21 -5
  201. package/dist/node-runtime/{chunk-OF7PWMG4.js → chunk-X3PGBLQ7.js} +3 -87
  202. package/dist/node-runtime/chunk-XHIRAZ26.js +108 -0
  203. package/dist/node-runtime/{chunk-YDO2F2IA.js → chunk-YWOJIGFY.js} +1 -1
  204. package/dist/node-runtime/{command-7BG7VVTS.js → command-FSBU2EVZ.js} +5 -5
  205. package/dist/node-runtime/{commands-NZLSOHPE.js → commands-EMBQQVVT.js} +4 -2
  206. package/dist/node-runtime/{commands-QFDKNQTL.js → commands-NAAL7KNT.js} +7 -6
  207. package/dist/node-runtime/{config-RORQUQFG.js → config-D4QUPAHX.js} +1 -1
  208. package/dist/node-runtime/{direct-tool-executor-77GW4F5P.js → direct-tool-executor-4D7UXYU4.js} +7 -4
  209. package/dist/node-runtime/{gateway-TWR3N65G.js → gateway-DQM333YV.js} +140 -85
  210. package/dist/node-runtime/index.js +28 -21
  211. package/dist/node-runtime/{init-HS6NQXSK.js → init-P5AUV77I.js} +4 -2
  212. package/dist/node-runtime/{install-cli-VAP6KBFN.js → install-cli-NN4YAU44.js} +3 -3
  213. package/dist/node-runtime/{interactive-mode-6J5VZ2TT.js → interactive-mode-YOHZVMKX.js} +14 -11
  214. package/dist/node-runtime/{lunr-browser-J5ZZYVGM.js → lunr-browser-IR7TL3J7.js} +3 -3
  215. package/dist/node-runtime/lunr-computer-use-Y23CCDIJ.js +158 -0
  216. package/dist/node-runtime/{lunr-cron-CXOL37AL.js → lunr-cron-USHC4LXH.js} +9 -7
  217. package/dist/node-runtime/main.js +19 -15
  218. package/dist/node-runtime/{mcp-auth-flow-QIXHW6QN.js → mcp-auth-flow-QVLFVLEO.js} +2 -1
  219. package/dist/node-runtime/{mobile-commands-VTBM5DSZ.js → mobile-commands-O5LCHL32.js} +6 -5
  220. package/dist/node-runtime/{package-manager-cli-ZLW5DZXF.js → package-manager-cli-Q7BL6KZO.js} +12 -8
  221. package/dist/node-runtime/{pi-mcp-adapter-5UKBZP44.js → pi-mcp-adapter-3PHF4KZ4.js} +5 -5
  222. package/dist/node-runtime/{pi-subagents-XPCLLKIM.js → pi-subagents-7IBSSGEW.js} +27 -21
  223. package/dist/node-runtime/{print-mode-XSFM26EL.js → print-mode-XQ76CYMT.js} +2 -1
  224. package/dist/node-runtime/{proxy-modes-LGEUYD7R.js → proxy-modes-5FAPSZEZ.js} +7 -4
  225. package/dist/node-runtime/rpc-entry.js +19 -15
  226. package/dist/node-runtime/runtime-EFPPD2UW.js +21 -0
  227. package/dist/node-runtime/{runtime-bridges-QYXUX2TG.js → runtime-bridges-7WVCLI76.js} +6 -5
  228. package/dist/node-runtime/{service-ISSP6VHE.js → service-MDQIPQ26.js} +1 -1
  229. package/dist/node-runtime/{settings-manager-WCQDUVQB.js → settings-manager-DJDM5AHM.js} +5 -4
  230. package/dist/node-runtime/setup-PFBWRNUI.js +215 -0
  231. package/dist/node-runtime/{subagent-executor-OTNISDQU.js → subagent-executor-LPZ4BHWE.js} +32 -14
  232. package/dist/node-runtime/{update-cli-VBR2777K.js → update-cli-HNMOTNGX.js} +5 -4
  233. package/dist/node-runtime/workflow-OHPBEFO4.js +637 -0
  234. package/dist/utils/image-resize-core.d.ts +2 -0
  235. package/dist/utils/image-resize-core.d.ts.map +1 -1
  236. package/dist/utils/image-resize-core.js +10 -0
  237. package/dist/utils/image-resize-core.js.map +1 -1
  238. package/docs/computer-use.md +362 -0
  239. package/docs/features.md +9 -7
  240. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  241. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  242. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  243. package/examples/extensions/gondolin/package-lock.json +2 -2
  244. package/examples/extensions/gondolin/package.json +1 -1
  245. package/examples/extensions/sandbox/package-lock.json +2 -2
  246. package/examples/extensions/sandbox/package.json +1 -1
  247. package/examples/extensions/with-deps/package-lock.json +2 -2
  248. package/examples/extensions/with-deps/package.json +1 -1
  249. package/install-lock/package-lock.json +3841 -0
  250. package/install-lock/package.json +18 -0
  251. package/native/computer-use/LICENSE.md +21 -0
  252. package/npm-shrinkwrap.json +3822 -0
  253. package/package.json +15 -9
  254. package/dist/node-runtime/setup-YRBKH2LD.js +0 -155
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-RMQZU2YU.js";
5
5
  import {
6
6
  atomicJson
7
- } from "./chunk-UWPJL22I.js";
7
+ } from "./chunk-SLVOAQOY.js";
8
8
  import {
9
9
  noOpUIContext
10
10
  } from "./chunk-GJ2RDBRL.js";
@@ -12,12 +12,13 @@ import {
12
12
  NO_HANDLER_REASON,
13
13
  registerApprovalHandler,
14
14
  setPermissionMode
15
- } from "./chunk-ZXSGTGJ6.js";
15
+ } from "./chunk-WIF24I7G.js";
16
16
  import {
17
+ gatewayConfigPath,
17
18
  loadGatewayConfig,
18
19
  platformConfigFor,
19
20
  saveGatewayConfig
20
- } from "./chunk-R3K2F5GI.js";
21
+ } from "./chunk-B4HP6ZWM.js";
21
22
  import {
22
23
  getAgentDir
23
24
  } from "./chunk-FQMM2EZ2.js";
@@ -31,15 +32,12 @@ function globalAllowedUsers() {
31
32
  let raw = process.env.LUNR_GATEWAY_ALLOWED_USERS;
32
33
  return raw ? raw.split(",").map((u) => u.trim()).filter((u) => u.length > 0) : [];
33
34
  }
34
- function isGatewayOwner(source, cfg) {
35
- return source.chatType !== "dm" || source.platform !== "telegram" && source.platform !== "discord" ? !1 : cfg.owners?.[source.platform].includes(source.userId) ?? !1;
35
+ function requireAuthorized(source, cfg = loadGatewayConfig()) {
36
+ if (!isAuthorized(source, cfg))
37
+ throw new Error("Gateway access is not approved for this user or chat.");
36
38
  }
37
- function requireGatewayOwner(source, cfg = loadGatewayConfig()) {
38
- if (!isGatewayOwner(source, cfg))
39
- throw new Error("This command is available only to the configured owner in a private chat. Use lunr gateway setup to configure owner access.");
40
- }
41
- function isAuthorized(source, cfg, pairing) {
42
- if (isGatewayOwner(source, cfg) || envFlagEnabled("LUNR_GATEWAY_ALLOW_ALL_USERS"))
39
+ function isAuthorized(source, cfg, pairing = createPairingStore()) {
40
+ if ((source.platform === "telegram" || source.platform === "discord") && cfg.owners?.[source.platform].includes(source.userId) || envFlagEnabled("LUNR_GATEWAY_ALLOW_ALL_USERS"))
43
41
  return !0;
44
42
  let platformCfg = platformConfigFor(cfg, source.platform);
45
43
  return !!(platformCfg?.allowedChats.includes(source.chatId) || source.roleAuthorized === !0 || source.userId && pairing.isPaired(source.platform, source.userId) || source.userId && (platformCfg?.allowedUsers.includes(source.userId) || globalAllowedUsers().includes(source.userId)));
@@ -229,8 +227,8 @@ async function handleApprovalCallback(event, adapter) {
229
227
  }), !0;
230
228
  clearTimeout(entry.timeout), pending.delete(parsed.id);
231
229
  let response = parsed.action === "reject" || parsed.action === "cancel" ? "reject" : parsed.action, binding = entry.key ? conversationBinding(entry.key) : void 0;
232
- if (binding?.owner && (!isGatewayOwner(entry.source, loadGatewayConfig()) || binding.owner !== event.userId))
233
- return entry.resolve("reject"), await entry.adapter.answerCallback(event.id, "Owner access was removed.").catch(() => {
230
+ if (binding?.owner && binding.owner !== event.userId)
231
+ return entry.resolve("reject"), await entry.adapter.answerCallback(event.id, "This session belongs to a different user.").catch(() => {
234
232
  }), !0;
235
233
  if (binding && !isAuthorized(entry.source, loadGatewayConfig(), createPairingStore()))
236
234
  return entry.resolve("reject"), !0;
@@ -341,12 +339,12 @@ async function handleCallback(cb, deps) {
341
339
  await answerExpired(adapter, cb);
342
340
  return;
343
341
  }
344
- if (picker.validate && !picker.validate()) {
342
+ if (!picker.completed && picker.validate && !picker.validate()) {
345
343
  registry.delete(parsed.id), picker.onCancel?.(), await answerExpired(adapter, cb);
346
344
  return;
347
345
  }
348
346
  if (Date.now() > picker.createdAt + PICKER_TTL_MS) {
349
- picker.onCancel?.(), registry.delete(parsed.id);
347
+ picker.completed || picker.onCancel?.(), registry.delete(parsed.id);
350
348
  try {
351
349
  await picker.adapter.editMessage(picker.chatId, picker.messageId, "\u23F1 Expired \u2014 run the command again.", []);
352
350
  } catch {
@@ -366,6 +364,11 @@ async function handleCallback(cb, deps) {
366
364
  await answerUnauthorized(adapter, cb);
367
365
  return;
368
366
  }
367
+ if (picker.completed !== void 0) {
368
+ await adapter.answerCallback(cb.id, "Already completed.").catch(() => {
369
+ });
370
+ return;
371
+ }
369
372
  if (parsed.action === "cancel") {
370
373
  registry.delete(parsed.id), picker.onCancel?.();
371
374
  try {
@@ -417,33 +420,25 @@ async function handleCallback(cb, deps) {
417
420
  }
418
421
  return;
419
422
  }
420
- registry.delete(parsed.id);
421
- try {
422
- await picker.adapter.editMessage(picker.chatId, picker.messageId, result.text, []);
423
- } catch {
424
- }
423
+ picker.completed = result.text, await confirmPicker(picker, result.text);
425
424
  } catch (err) {
426
- registry.delete(parsed.id);
427
425
  let message = err instanceof Error ? err.message : String(err);
428
- try {
429
- await picker.adapter.editMessage(picker.chatId, picker.messageId, `\u26A0 ${message}`, []);
430
- } catch {
431
- }
426
+ picker.completed = `\u26A0 ${message}`, await confirmPicker(picker, picker.completed);
432
427
  } finally {
433
428
  picker.resolving = !1;
434
429
  }
435
430
  }
431
+ async function confirmPicker(picker, text) {
432
+ if ((await picker.adapter.editMessage(picker.chatId, picker.messageId, text, []).catch(() => ({ success: !1 }))).success)
433
+ return;
434
+ (await picker.adapter.send(picker.chatId, text, { threadId: picker.source.threadId }).catch(() => ({ success: !1 }))).success || console.error(`[gateway] picker confirmation failed on ${picker.adapter.platform}`);
435
+ }
436
436
  function startButtonSweeper() {
437
437
  sweeper || (sweeper = setInterval(() => {
438
438
  let cutoff = Date.now() - PICKER_TTL_MS;
439
439
  for (let [id, entry] of registry)
440
- if (!(entry.createdAt > cutoff)) {
441
- registry.delete(id), entry.onCancel?.();
442
- try {
443
- entry.adapter.editMessage(entry.chatId, entry.messageId, "\u23F1 Expired \u2014 run the command again.", []);
444
- } catch {
445
- }
446
- }
440
+ entry.createdAt > cutoff || (registry.delete(id), !entry.completed && (entry.onCancel?.(), entry.adapter.editMessage(entry.chatId, entry.messageId, "\u23F1 Expired \u2014 run the command again.", []).catch(() => {
441
+ })));
447
442
  }, SWEEP_INTERVAL_MS), sweeper.unref?.());
448
443
  }
449
444
  function stopButtonSweeper() {
@@ -530,13 +525,23 @@ function splitMessage(text, max) {
530
525
  }
531
526
 
532
527
  // packages/coding-agent/dist/gateway/presenter.js
533
- var epochs = /* @__PURE__ */ new Map(), inputs = /* @__PURE__ */ new Map(), dialogs = /* @__PURE__ */ new Map(), adapters = /* @__PURE__ */ new Map(), timer, sending = !1, path2 = () => join3(getAgentDir(), "gateway-outbox.json"), outbox = [];
528
+ var epochs = /* @__PURE__ */ new Map(), inputs = /* @__PURE__ */ new Map(), dialogs = /* @__PURE__ */ new Map(), adapters = /* @__PURE__ */ new Map(), deliveryConfigs = /* @__PURE__ */ new Map(), roleGrants = /* @__PURE__ */ new Map(), timer, activeDeliveries = /* @__PURE__ */ new Map(), MAX_ATTEMPTS = 5, path2 = () => join3(getAgentDir(), "gateway-outbox.json"), outbox = [];
529
+ function sourceWithCurrentRole(key, source) {
530
+ let grant = roleGrants.get(key);
531
+ return {
532
+ ...source,
533
+ roleAuthorized: grant?.userId === source.userId && grant.chatId === source.chatId && grant.threadId === source.threadId
534
+ };
535
+ }
536
+ function rememberGatewayRole(key, source) {
537
+ source.roleAuthorized === !0 ? roleGrants.set(key, { userId: source.userId, chatId: source.chatId, threadId: source.threadId }) : roleGrants.delete(key);
538
+ }
534
539
  function canDeliver(key) {
535
540
  let binding = conversationBinding(key);
536
541
  if (!binding)
537
542
  return !1;
538
543
  let cfg = loadGatewayConfig();
539
- return binding.owner && (binding.owner !== binding.source.userId || !isGatewayOwner(binding.source, cfg)) ? !1 : isAuthorized(binding.source, cfg, createPairingStore());
544
+ return binding.owner && binding.owner !== binding.source.userId ? !1 : isAuthorized(sourceWithCurrentRole(key, binding.source), cfg, createPairingStore());
540
545
  }
541
546
  function gatewayDestination(key) {
542
547
  let binding = conversationBinding(key), adapter = binding && adapters.get(binding.source.platform);
@@ -551,56 +556,106 @@ function withGatewayPresentation(key, run) {
551
556
  function startGatewayPresenter(connected) {
552
557
  if (adapters = connected, existsSync3(path2()))
553
558
  try {
554
- outbox = JSON.parse(readFileSync3(path2(), "utf8"));
559
+ let raw = JSON.parse(readFileSync3(path2(), "utf8"));
560
+ if (!Array.isArray(raw) || !raw.every((item) => item && typeof item.id == "string" && typeof item.key == "string" && typeof item.text == "string"))
561
+ throw new Error("Invalid outbox");
562
+ outbox = raw;
555
563
  } catch {
556
564
  throw new Error("Gateway outbox is invalid. Restore it before starting.");
557
565
  }
566
+ else
567
+ outbox = [];
568
+ for (let item of outbox)
569
+ item.kind === "notice" && epochs.set(item.key, Math.max(epochs.get(item.key) ?? 0, item.epoch ?? 0));
558
570
  timer && clearInterval(timer), timer = setInterval(() => {
559
- flushOutbox();
560
- }, 3e3), timer.unref(), flushOutbox();
571
+ flushOutbox().catch((error) => console.error("[gateway] outbox flush failed:", error));
572
+ }, 3e3), timer.unref(), flushOutbox().catch((error) => console.error("[gateway] outbox flush failed:", error));
561
573
  }
562
574
  function stopGatewayPresenter() {
563
575
  timer && clearInterval(timer), timer = void 0;
564
576
  for (let key of dialogs.keys())
565
577
  invalidateGatewayDialogs(key);
566
- adapters = /* @__PURE__ */ new Map();
578
+ adapters = /* @__PURE__ */ new Map(), deliveryConfigs.clear(), roleGrants.clear();
567
579
  }
568
- async function sendGatewayNotice(key, text) {
580
+ function gatewayEpoch(key) {
581
+ return epochs.get(key) ?? 0;
582
+ }
583
+ async function sendGatewayNotice(key, text, kind = "notice", epoch = gatewayEpoch(key)) {
569
584
  let clean = text.replace(/\x1b\[[0-9;]*[a-zA-Z]/g, "").trim();
570
585
  if (!clean || !canDeliver(key))
571
586
  return;
572
- let { adapter } = gatewayDestination(key);
573
- for (let chunk of splitMessage(clean, adapter.maxMessageLength))
574
- outbox.push({ id: randomUUID(), key, epoch: epochs.get(key) ?? 0, text: chunk });
575
- atomicJson(path2(), outbox), await flushOutbox();
576
- }
577
- async function flushOutbox() {
578
- if (!sending) {
579
- sending = !0;
580
- try {
581
- for (let item of [...outbox]) {
582
- if (!canDeliver(item.key)) {
583
- outbox = outbox.filter((v) => v.id !== item.id), atomicJson(path2(), outbox);
584
- continue;
585
- }
586
- let target;
587
- try {
588
- target = gatewayDestination(item.key);
589
- } catch {
590
- continue;
591
- }
592
- if ((await target.adapter.send(target.source.chatId, item.text, { threadId: target.source.threadId }).catch(() => ({ success: !1 }))).success)
593
- outbox = outbox.filter((v) => v.id !== item.id), atomicJson(path2(), outbox);
594
- else
595
- break;
587
+ let { adapter, source } = gatewayDestination(key);
588
+ await queueGatewayText(key, source, adapter, clean, { kind, epoch });
589
+ }
590
+ async function queueGatewayText(key, source, adapter, text, options) {
591
+ if (!text || options.kind === "notice" && options.epoch !== void 0 && options.epoch !== gatewayEpoch(key))
592
+ return;
593
+ adapters.set(source.platform, adapter), options.cfg && deliveryConfigs.set(key, options.cfg);
594
+ let chunks = options.chunks ?? splitMessage(text, adapter.maxMessageLength), batchId = randomUUID();
595
+ for (let [index, chunk] of chunks.entries())
596
+ outbox.push({
597
+ id: randomUUID(),
598
+ batchId,
599
+ key,
600
+ source: { ...source, roleAuthorized: void 0 },
601
+ epoch: options.epoch ?? gatewayEpoch(key),
602
+ text: chunk,
603
+ kind: options.kind,
604
+ replyTo: index === 0 ? options.replyTo : void 0
605
+ });
606
+ atomicJson(path2(), outbox), activeDeliveries.has(key) && await activeDeliveries.get(key), await flushKey(key);
607
+ }
608
+ function flushOutbox() {
609
+ return Promise.all([...new Set(outbox.map((item) => item.key))].map(flushKey)).then(() => {
610
+ });
611
+ }
612
+ function flushKey(key) {
613
+ let current = activeDeliveries.get(key);
614
+ if (current)
615
+ return current;
616
+ let running = drainKey(key).finally(() => {
617
+ activeDeliveries.delete(key);
618
+ });
619
+ return activeDeliveries.set(key, running), running;
620
+ }
621
+ async function drainKey(key) {
622
+ let failedBatches = new Set(outbox.filter((item) => item.failed && item.batchId).map((item) => item.batchId));
623
+ for (let item of [...outbox].filter((item2) => item2.key === key)) {
624
+ if (item.failed || item.batchId && failedBatches.has(item.batchId))
625
+ continue;
626
+ if (item.kind === "notice" && item.epoch !== (epochs.get(item.key) ?? 0)) {
627
+ outbox = outbox.filter((v) => v.id !== item.id), atomicJson(path2(), outbox);
628
+ continue;
629
+ }
630
+ let binding = conversationBinding(item.key), source = item.source ?? binding?.source;
631
+ if (!source)
632
+ break;
633
+ let cfg = existsSync3(gatewayConfigPath()) ? loadGatewayConfig() : deliveryConfigs.get(item.key) ?? loadGatewayConfig();
634
+ if (binding && (binding.source.platform !== source.platform || binding.source.chatId !== source.chatId || binding.source.userId !== source.userId || binding.source.threadId !== source.threadId) || !isAuthorized(sourceWithCurrentRole(key, source), cfg, createPairingStore()) || binding?.owner && binding.owner !== source.userId) {
635
+ outbox = outbox.filter((v) => v.id !== item.id), atomicJson(path2(), outbox);
636
+ continue;
637
+ }
638
+ let adapter = adapters.get(source.platform);
639
+ if (!adapter || (item.nextAttempt ?? 0) > Date.now())
640
+ break;
641
+ let opts = { threadId: source.threadId, replyTo: item.replyTo }, result = await adapter.send(source.chatId, item.text, opts).catch((error) => ({ success: !1, error: String(error), retryable: !0 }));
642
+ if (result.success)
643
+ outbox = outbox.filter((v) => v.id !== item.id), atomicJson(path2(), outbox);
644
+ else {
645
+ if (item.attempts = (item.attempts ?? 0) + 1, item.failed = result.retryable === !1 || item.attempts >= MAX_ATTEMPTS, item.nextAttempt = Date.now() + Math.min(6e4, 3e3 * 2 ** (item.attempts - 1)), item.failed && item.batchId) {
646
+ failedBatches.add(item.batchId);
647
+ for (let pending2 of outbox)
648
+ pending2.batchId === item.batchId && (pending2.failed = !0);
596
649
  }
597
- } finally {
598
- sending = !1;
650
+ atomicJson(path2(), outbox), console.error(`[gateway] delivery ${item.failed ? "failed permanently" : "retry scheduled"} for ${source.platform}: ${result.error ?? "unknown error"}`);
651
+ break;
599
652
  }
600
653
  }
601
654
  }
602
655
  function invalidateGatewayDialogs(key) {
603
656
  epochs.set(key, (epochs.get(key) ?? 0) + 1);
657
+ let remaining = outbox.filter((item) => item.key !== key || item.kind !== "notice");
658
+ remaining.length !== outbox.length && (outbox = remaining, atomicJson(path2(), outbox));
604
659
  for (let cancel of dialogs.get(key) ?? [])
605
660
  cancel();
606
661
  dialogs.delete(key), inputs.delete(key);
@@ -642,42 +697,45 @@ ${item.value}` })
642
697
  });
643
698
  }
644
699
  function gatewayInput(key, title, placeholder, opts) {
645
- return inputs.has(key) ? Promise.reject(new Error("Answer or cancel the existing question first.")) : dialog(key, opts, async (done) => {
700
+ if (inputs.has(key))
701
+ return Promise.reject(new Error("Answer or cancel the existing question first."));
702
+ let epoch = gatewayEpoch(key);
703
+ return dialog(key, opts, async (done) => {
646
704
  let { source } = gatewayDestination(key);
647
705
  inputs.set(key, { userId: source.userId, resolve: done }), await sendGatewayNotice(key, `${title}${placeholder ? `
648
706
  ${placeholder}` : ""}
649
- Reply with text, or /cancel.`);
707
+ Reply with text, or /cancel.`, "notice", epoch);
650
708
  });
651
709
  }
652
710
  function createGatewayUI(key) {
711
+ let epoch = gatewayEpoch(key);
653
712
  return {
654
713
  ...noOpUIContext,
655
- select: (title, options, opts) => gatewaySelect(key, title, options, opts),
656
- confirm: async (title, message, opts) => await gatewaySelect(key, `${title}
714
+ select: (title, options, opts) => gatewayEpoch(key) === epoch ? gatewaySelect(key, title, options, opts) : Promise.resolve(void 0),
715
+ confirm: async (title, message, opts) => gatewayEpoch(key) === epoch && await gatewaySelect(key, `${title}
657
716
  ${message}`, ["Approve", "Decline"], opts) === "Approve",
658
- input: (title, placeholder, opts) => gatewayInput(key, title, placeholder, opts),
659
- editor: (title, prefill) => gatewayInput(key, title, prefill),
717
+ input: (title, placeholder, opts) => gatewayEpoch(key) === epoch ? gatewayInput(key, title, placeholder, opts) : Promise.resolve(void 0),
718
+ editor: (title, prefill) => gatewayEpoch(key) === epoch ? gatewayInput(key, title, prefill) : Promise.resolve(void 0),
660
719
  notify: (message) => {
661
- sendGatewayNotice(key, message).catch(() => {
720
+ sendGatewayNotice(key, message, "notice", epoch).catch(() => {
662
721
  });
663
722
  },
664
723
  custom: async () => {
665
724
  throw new Error("This command requires the terminal interface. Use the gateway's text commands or button pickers.");
666
725
  },
667
726
  pasteToEditor: (text) => {
668
- sendGatewayNotice(key, text).catch(() => {
727
+ sendGatewayNotice(key, text, "notice", epoch).catch(() => {
669
728
  });
670
729
  },
671
730
  setEditorText: (text) => {
672
- sendGatewayNotice(key, text).catch(() => {
731
+ sendGatewayNotice(key, text, "notice", epoch).catch(() => {
673
732
  });
674
733
  }
675
734
  };
676
735
  }
677
736
 
678
737
  export {
679
- isGatewayOwner,
680
- requireGatewayOwner,
738
+ requireAuthorized,
681
739
  isAuthorized,
682
740
  addAllowedUser,
683
741
  conversationBinding,
@@ -696,10 +754,13 @@ export {
696
754
  startButtonSweeper,
697
755
  stopButtonSweeper,
698
756
  splitMessage,
757
+ rememberGatewayRole,
699
758
  withGatewayPresentation,
700
759
  startGatewayPresenter,
701
760
  stopGatewayPresenter,
761
+ gatewayEpoch,
702
762
  sendGatewayNotice,
763
+ queueGatewayText,
703
764
  invalidateGatewayDialogs,
704
765
  acceptGatewayInput,
705
766
  gatewaySelect,