@ashx-j/lunr 0.2.26 → 0.2.27

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 (639) hide show
  1. package/CHANGELOG.md +16 -1
  2. package/LICENSE +22 -0
  3. package/dist/builtin-extensions/ashxj-thinking.d.ts +1 -1
  4. package/dist/builtin-extensions/ashxj-thinking.d.ts.map +1 -1
  5. package/dist/builtin-extensions/ashxj-thinking.js +1 -1
  6. package/dist/builtin-extensions/ashxj-thinking.js.map +1 -1
  7. package/dist/builtin-extensions/ashxj-tui.d.ts +11 -1
  8. package/dist/builtin-extensions/ashxj-tui.d.ts.map +1 -1
  9. package/dist/builtin-extensions/ashxj-tui.js +6 -10
  10. package/dist/builtin-extensions/ashxj-tui.js.map +1 -1
  11. package/dist/builtin-extensions/lunr-cron.d.ts +4 -5
  12. package/dist/builtin-extensions/lunr-cron.d.ts.map +1 -1
  13. package/dist/builtin-extensions/lunr-cron.js +94 -108
  14. package/dist/builtin-extensions/lunr-cron.js.map +1 -1
  15. package/dist/builtin-extensions/lunr-local-providers/local-servers.d.ts.map +1 -1
  16. package/dist/builtin-extensions/lunr-local-providers/local-servers.js +3 -1
  17. package/dist/builtin-extensions/lunr-local-providers/local-servers.js.map +1 -1
  18. package/dist/builtin-extensions/narumiruna-pi-goal/src/commands.d.ts.map +1 -1
  19. package/dist/builtin-extensions/narumiruna-pi-goal/src/commands.js +2 -2
  20. package/dist/builtin-extensions/narumiruna-pi-goal/src/commands.js.map +1 -1
  21. package/dist/builtin-extensions/narumiruna-pi-goal/src/goal.d.ts.map +1 -1
  22. package/dist/builtin-extensions/narumiruna-pi-goal/src/goal.js +1 -1
  23. package/dist/builtin-extensions/narumiruna-pi-goal/src/goal.js.map +1 -1
  24. package/dist/builtin-extensions/narumiruna-pi-goal/src/runtime.d.ts.map +1 -1
  25. package/dist/builtin-extensions/narumiruna-pi-goal/src/runtime.js +1 -1
  26. package/dist/builtin-extensions/narumiruna-pi-goal/src/runtime.js.map +1 -1
  27. package/dist/builtin-extensions/pi-intercom/index.d.ts.map +1 -1
  28. package/dist/builtin-extensions/pi-intercom/index.js +2 -2
  29. package/dist/builtin-extensions/pi-intercom/index.js.map +1 -1
  30. package/dist/builtin-extensions/pi-lsp-extension/bemol-extension/index.d.ts +1 -1
  31. package/dist/builtin-extensions/pi-lsp-extension/bemol-extension/index.d.ts.map +1 -1
  32. package/dist/builtin-extensions/pi-lsp-extension/bemol-extension/index.js +1 -1
  33. package/dist/builtin-extensions/pi-lsp-extension/bemol-extension/index.js.map +1 -1
  34. package/dist/builtin-extensions/pi-lsp-extension/src/index.d.ts.map +1 -1
  35. package/dist/builtin-extensions/pi-lsp-extension/src/index.js +1 -15
  36. package/dist/builtin-extensions/pi-lsp-extension/src/index.js.map +1 -1
  37. package/dist/builtin-extensions/pi-lsp-extension/src/lsp-client.d.ts +6 -0
  38. package/dist/builtin-extensions/pi-lsp-extension/src/lsp-client.d.ts.map +1 -1
  39. package/dist/builtin-extensions/pi-lsp-extension/src/lsp-client.js +187 -132
  40. package/dist/builtin-extensions/pi-lsp-extension/src/lsp-client.js.map +1 -1
  41. package/dist/builtin-extensions/pi-lsp-extension/src/lsp-manager.d.ts +8 -0
  42. package/dist/builtin-extensions/pi-lsp-extension/src/lsp-manager.d.ts.map +1 -1
  43. package/dist/builtin-extensions/pi-lsp-extension/src/lsp-manager.js +142 -112
  44. package/dist/builtin-extensions/pi-lsp-extension/src/lsp-manager.js.map +1 -1
  45. package/dist/builtin-extensions/pi-lsp-extension/src/tools/code-rewrite.d.ts +12 -1
  46. package/dist/builtin-extensions/pi-lsp-extension/src/tools/code-rewrite.d.ts.map +1 -1
  47. package/dist/builtin-extensions/pi-lsp-extension/src/tools/code-rewrite.js +14 -7
  48. package/dist/builtin-extensions/pi-lsp-extension/src/tools/code-rewrite.js.map +1 -1
  49. package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/rewrite-engine.d.ts +11 -3
  50. package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/rewrite-engine.d.ts.map +1 -1
  51. package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/rewrite-engine.js +67 -41
  52. package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/rewrite-engine.js.map +1 -1
  53. package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/search-engine.d.ts +4 -2
  54. package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/search-engine.d.ts.map +1 -1
  55. package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/search-engine.js +3 -0
  56. package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/search-engine.js.map +1 -1
  57. package/dist/builtin-extensions/pi-mcp-adapter/commands.d.ts +2 -1
  58. package/dist/builtin-extensions/pi-mcp-adapter/commands.d.ts.map +1 -1
  59. package/dist/builtin-extensions/pi-mcp-adapter/commands.js +6 -6
  60. package/dist/builtin-extensions/pi-mcp-adapter/commands.js.map +1 -1
  61. package/dist/builtin-extensions/pi-mcp-adapter/config.d.ts +1 -1
  62. package/dist/builtin-extensions/pi-mcp-adapter/config.d.ts.map +1 -1
  63. package/dist/builtin-extensions/pi-mcp-adapter/config.js +11 -5
  64. package/dist/builtin-extensions/pi-mcp-adapter/config.js.map +1 -1
  65. package/dist/builtin-extensions/pi-mcp-adapter/direct-tool-executor.d.ts.map +1 -1
  66. package/dist/builtin-extensions/pi-mcp-adapter/direct-tool-executor.js +2 -2
  67. package/dist/builtin-extensions/pi-mcp-adapter/direct-tool-executor.js.map +1 -1
  68. package/dist/builtin-extensions/pi-mcp-adapter/host-html-template.d.ts.map +1 -1
  69. package/dist/builtin-extensions/pi-mcp-adapter/host-html-template.js +1 -1
  70. package/dist/builtin-extensions/pi-mcp-adapter/host-html-template.js.map +1 -1
  71. package/dist/builtin-extensions/pi-mcp-adapter/index.d.ts.map +1 -1
  72. package/dist/builtin-extensions/pi-mcp-adapter/index.js +48 -40
  73. package/dist/builtin-extensions/pi-mcp-adapter/index.js.map +1 -1
  74. package/dist/builtin-extensions/pi-mcp-adapter/init.d.ts.map +1 -1
  75. package/dist/builtin-extensions/pi-mcp-adapter/init.js +3 -1
  76. package/dist/builtin-extensions/pi-mcp-adapter/init.js.map +1 -1
  77. package/dist/builtin-extensions/pi-mcp-adapter/mcp-auth-flow.d.ts +12 -40
  78. package/dist/builtin-extensions/pi-mcp-adapter/mcp-auth-flow.d.ts.map +1 -1
  79. package/dist/builtin-extensions/pi-mcp-adapter/mcp-auth-flow.js +166 -235
  80. package/dist/builtin-extensions/pi-mcp-adapter/mcp-auth-flow.js.map +1 -1
  81. package/dist/builtin-extensions/pi-mcp-adapter/mcp-callback-server.d.ts +5 -0
  82. package/dist/builtin-extensions/pi-mcp-adapter/mcp-callback-server.d.ts.map +1 -1
  83. package/dist/builtin-extensions/pi-mcp-adapter/mcp-callback-server.js +43 -13
  84. package/dist/builtin-extensions/pi-mcp-adapter/mcp-callback-server.js.map +1 -1
  85. package/dist/builtin-extensions/pi-mcp-adapter/mcp-oauth-provider.d.ts +14 -3
  86. package/dist/builtin-extensions/pi-mcp-adapter/mcp-oauth-provider.d.ts.map +1 -1
  87. package/dist/builtin-extensions/pi-mcp-adapter/mcp-oauth-provider.js +73 -21
  88. package/dist/builtin-extensions/pi-mcp-adapter/mcp-oauth-provider.js.map +1 -1
  89. package/dist/builtin-extensions/pi-mcp-adapter/proxy-modes.d.ts.map +1 -1
  90. package/dist/builtin-extensions/pi-mcp-adapter/proxy-modes.js +4 -4
  91. package/dist/builtin-extensions/pi-mcp-adapter/proxy-modes.js.map +1 -1
  92. package/dist/builtin-extensions/pi-mcp-adapter/server-manager.d.ts.map +1 -1
  93. package/dist/builtin-extensions/pi-mcp-adapter/server-manager.js +2 -2
  94. package/dist/builtin-extensions/pi-mcp-adapter/server-manager.js.map +1 -1
  95. package/dist/builtin-extensions/pi-mcp-adapter/state.d.ts +2 -0
  96. package/dist/builtin-extensions/pi-mcp-adapter/state.d.ts.map +1 -1
  97. package/dist/builtin-extensions/pi-mcp-adapter/state.js.map +1 -1
  98. package/dist/builtin-extensions/pi-ollama-cloud/index.d.ts +1 -1
  99. package/dist/builtin-extensions/pi-ollama-cloud/index.d.ts.map +1 -1
  100. package/dist/builtin-extensions/pi-ollama-cloud/index.js +1 -1
  101. package/dist/builtin-extensions/pi-ollama-cloud/index.js.map +1 -1
  102. package/dist/builtin-extensions/pi-ollama-cloud/models.d.ts +11 -5
  103. package/dist/builtin-extensions/pi-ollama-cloud/models.d.ts.map +1 -1
  104. package/dist/builtin-extensions/pi-ollama-cloud/models.js +12 -32
  105. package/dist/builtin-extensions/pi-ollama-cloud/models.js.map +1 -1
  106. package/dist/builtin-extensions/pi-prompt-template-model/index.d.ts.map +1 -1
  107. package/dist/builtin-extensions/pi-prompt-template-model/index.js +5 -3
  108. package/dist/builtin-extensions/pi-prompt-template-model/index.js.map +1 -1
  109. package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.d.ts +2 -1
  110. package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.d.ts.map +1 -1
  111. package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.js +21 -12
  112. package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.js.map +1 -1
  113. package/dist/builtin-extensions/pi-prompt-template-model/tool-manager.d.ts.map +1 -1
  114. package/dist/builtin-extensions/pi-prompt-template-model/tool-manager.js +7 -24
  115. package/dist/builtin-extensions/pi-prompt-template-model/tool-manager.js.map +1 -1
  116. package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts.map +1 -1
  117. package/dist/builtin-extensions/pi-subagents/src/extension/index.js +39 -77
  118. package/dist/builtin-extensions/pi-subagents/src/extension/index.js.map +1 -1
  119. package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.d.ts +1 -1
  120. package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.d.ts.map +1 -1
  121. package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.js +15 -31
  122. package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.js.map +1 -1
  123. package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.d.ts.map +1 -1
  124. package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.js +7 -2
  125. package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.js.map +1 -1
  126. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.d.ts.map +1 -1
  127. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.js +10 -2
  128. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.js.map +1 -1
  129. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.d.ts.map +1 -1
  130. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.js +8 -1
  131. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.js.map +1 -1
  132. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.d.ts.map +1 -1
  133. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.js +106 -24
  134. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.js.map +1 -1
  135. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.d.ts.map +1 -1
  136. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js +25 -5
  137. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js.map +1 -1
  138. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.d.ts +1 -1
  139. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.d.ts.map +1 -1
  140. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.js +1 -1
  141. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.js.map +1 -1
  142. package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.d.ts +7 -8
  143. package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.d.ts.map +1 -1
  144. package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.js +60 -32
  145. package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.js.map +1 -1
  146. package/dist/builtin-extensions/pi-subagents/src/shared/utils.d.ts +1 -1
  147. package/dist/builtin-extensions/pi-subagents/src/shared/utils.d.ts.map +1 -1
  148. package/dist/builtin-extensions/pi-subagents/src/shared/utils.js +15 -5
  149. package/dist/builtin-extensions/pi-subagents/src/shared/utils.js.map +1 -1
  150. package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.d.ts.map +1 -1
  151. package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.js +4 -3
  152. package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.js.map +1 -1
  153. package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts +1 -1
  154. package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts.map +1 -1
  155. package/dist/builtin-extensions/pi-subagents/src/tui/render.js +17 -8
  156. package/dist/builtin-extensions/pi-subagents/src/tui/render.js.map +1 -1
  157. package/dist/builtin-extensions/pi-subagents/src/watchdog/review.d.ts.map +1 -1
  158. package/dist/builtin-extensions/pi-subagents/src/watchdog/review.js +3 -3
  159. package/dist/builtin-extensions/pi-subagents/src/watchdog/review.js.map +1 -1
  160. package/dist/builtin-extensions/pi-tps.d.ts.map +1 -1
  161. package/dist/builtin-extensions/pi-tps.js +20 -17
  162. package/dist/builtin-extensions/pi-tps.js.map +1 -1
  163. package/dist/builtin-extensions/pi-web-access/activity.d.ts +1 -0
  164. package/dist/builtin-extensions/pi-web-access/activity.d.ts.map +1 -1
  165. package/dist/builtin-extensions/pi-web-access/activity.js +27 -5
  166. package/dist/builtin-extensions/pi-web-access/activity.js.map +1 -1
  167. package/dist/builtin-extensions/pi-web-access/bounded-body.d.ts +3 -0
  168. package/dist/builtin-extensions/pi-web-access/bounded-body.d.ts.map +1 -0
  169. package/dist/builtin-extensions/pi-web-access/bounded-body.js +43 -0
  170. package/dist/builtin-extensions/pi-web-access/bounded-body.js.map +1 -0
  171. package/dist/builtin-extensions/pi-web-access/content-page.d.ts +24 -0
  172. package/dist/builtin-extensions/pi-web-access/content-page.d.ts.map +1 -0
  173. package/dist/builtin-extensions/pi-web-access/content-page.js +57 -0
  174. package/dist/builtin-extensions/pi-web-access/content-page.js.map +1 -0
  175. package/dist/builtin-extensions/pi-web-access/extract.d.ts.map +1 -1
  176. package/dist/builtin-extensions/pi-web-access/extract.js +7 -2
  177. package/dist/builtin-extensions/pi-web-access/extract.js.map +1 -1
  178. package/dist/builtin-extensions/pi-web-access/github-extract.d.ts +0 -1
  179. package/dist/builtin-extensions/pi-web-access/github-extract.d.ts.map +1 -1
  180. package/dist/builtin-extensions/pi-web-access/github-extract.js +147 -36
  181. package/dist/builtin-extensions/pi-web-access/github-extract.js.map +1 -1
  182. package/dist/builtin-extensions/pi-web-access/index.d.ts.map +1 -1
  183. package/dist/builtin-extensions/pi-web-access/index.js +48 -73
  184. package/dist/builtin-extensions/pi-web-access/index.js.map +1 -1
  185. package/dist/builtin-extensions/pi-web-access/session-cleanup.d.ts +12 -4
  186. package/dist/builtin-extensions/pi-web-access/session-cleanup.d.ts.map +1 -1
  187. package/dist/builtin-extensions/pi-web-access/session-cleanup.js +35 -12
  188. package/dist/builtin-extensions/pi-web-access/session-cleanup.js.map +1 -1
  189. package/dist/builtin-extensions/pi-web-access/storage.d.ts +9 -6
  190. package/dist/builtin-extensions/pi-web-access/storage.d.ts.map +1 -1
  191. package/dist/builtin-extensions/pi-web-access/storage.js +36 -24
  192. package/dist/builtin-extensions/pi-web-access/storage.js.map +1 -1
  193. package/dist/builtin-extensions/simple-pi-memory.d.ts +1 -1
  194. package/dist/builtin-extensions/simple-pi-memory.d.ts.map +1 -1
  195. package/dist/builtin-extensions/simple-pi-memory.js +1 -1
  196. package/dist/builtin-extensions/simple-pi-memory.js.map +1 -1
  197. package/dist/cli/install-cli.d.ts.map +1 -1
  198. package/dist/cli/install-cli.js +38 -30
  199. package/dist/cli/install-cli.js.map +1 -1
  200. package/dist/core/agent-session-runtime.d.ts +13 -0
  201. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  202. package/dist/core/agent-session-runtime.js +75 -11
  203. package/dist/core/agent-session-runtime.js.map +1 -1
  204. package/dist/core/agent-session-services.d.ts +1 -0
  205. package/dist/core/agent-session-services.d.ts.map +1 -1
  206. package/dist/core/agent-session-services.js +1 -0
  207. package/dist/core/agent-session-services.js.map +1 -1
  208. package/dist/core/agent-session.d.ts +40 -6
  209. package/dist/core/agent-session.d.ts.map +1 -1
  210. package/dist/core/agent-session.js +309 -76
  211. package/dist/core/agent-session.js.map +1 -1
  212. package/dist/core/browser/runtime.d.ts +2 -0
  213. package/dist/core/browser/runtime.d.ts.map +1 -1
  214. package/dist/core/browser/runtime.js +80 -45
  215. package/dist/core/browser/runtime.js.map +1 -1
  216. package/dist/core/browser/setup.d.ts.map +1 -1
  217. package/dist/core/browser/setup.js +12 -1
  218. package/dist/core/browser/setup.js.map +1 -1
  219. package/dist/core/computer-use/adapter.d.ts.map +1 -1
  220. package/dist/core/computer-use/adapter.js +7 -2
  221. package/dist/core/computer-use/adapter.js.map +1 -1
  222. package/dist/core/computer-use/image.d.ts.map +1 -1
  223. package/dist/core/computer-use/image.js +17 -5
  224. package/dist/core/computer-use/image.js.map +1 -1
  225. package/dist/core/computer-use/schemas.d.ts.map +1 -1
  226. package/dist/core/computer-use/schemas.js +23 -6
  227. package/dist/core/computer-use/schemas.js.map +1 -1
  228. package/dist/core/computer-use/workflow.d.ts.map +1 -1
  229. package/dist/core/computer-use/workflow.js +459 -119
  230. package/dist/core/computer-use/workflow.js.map +1 -1
  231. package/dist/core/cron/jobs.d.ts +26 -8
  232. package/dist/core/cron/jobs.d.ts.map +1 -1
  233. package/dist/core/cron/jobs.js +357 -232
  234. package/dist/core/cron/jobs.js.map +1 -1
  235. package/dist/core/cron/origin-context.d.ts +1 -0
  236. package/dist/core/cron/origin-context.d.ts.map +1 -1
  237. package/dist/core/cron/origin-context.js.map +1 -1
  238. package/dist/core/cron/scheduler.d.ts +22 -17
  239. package/dist/core/cron/scheduler.d.ts.map +1 -1
  240. package/dist/core/cron/scheduler.js +153 -73
  241. package/dist/core/cron/scheduler.js.map +1 -1
  242. package/dist/core/extensions/index.d.ts +1 -1
  243. package/dist/core/extensions/index.d.ts.map +1 -1
  244. package/dist/core/extensions/index.js.map +1 -1
  245. package/dist/core/extensions/runner.d.ts +1 -0
  246. package/dist/core/extensions/runner.d.ts.map +1 -1
  247. package/dist/core/extensions/runner.js +8 -0
  248. package/dist/core/extensions/runner.js.map +1 -1
  249. package/dist/core/extensions/types.d.ts +8 -0
  250. package/dist/core/extensions/types.d.ts.map +1 -1
  251. package/dist/core/extensions/types.js.map +1 -1
  252. package/dist/core/footer-data-provider.d.ts +4 -0
  253. package/dist/core/footer-data-provider.d.ts.map +1 -1
  254. package/dist/core/footer-data-provider.js +22 -1
  255. package/dist/core/footer-data-provider.js.map +1 -1
  256. package/dist/core/large-subagent-launch.d.ts +1 -1
  257. package/dist/core/large-subagent-launch.d.ts.map +1 -1
  258. package/dist/core/large-subagent-launch.js +7 -7
  259. package/dist/core/large-subagent-launch.js.map +1 -1
  260. package/dist/core/model-registry.d.ts +2 -0
  261. package/dist/core/model-registry.d.ts.map +1 -1
  262. package/dist/core/model-registry.js +5 -0
  263. package/dist/core/model-registry.js.map +1 -1
  264. package/dist/core/model-runtime.d.ts +4 -1
  265. package/dist/core/model-runtime.d.ts.map +1 -1
  266. package/dist/core/model-runtime.js +40 -4
  267. package/dist/core/model-runtime.js.map +1 -1
  268. package/dist/core/package-manager.d.ts.map +1 -1
  269. package/dist/core/package-manager.js.map +1 -1
  270. package/dist/core/permissions.d.ts +3 -3
  271. package/dist/core/permissions.d.ts.map +1 -1
  272. package/dist/core/permissions.js +11 -35
  273. package/dist/core/permissions.js.map +1 -1
  274. package/dist/core/plan-mode.d.ts +5 -13
  275. package/dist/core/plan-mode.d.ts.map +1 -1
  276. package/dist/core/plan-mode.js +126 -116
  277. package/dist/core/plan-mode.js.map +1 -1
  278. package/dist/core/project-trust.d.ts.map +1 -1
  279. package/dist/core/project-trust.js +1 -1
  280. package/dist/core/project-trust.js.map +1 -1
  281. package/dist/core/prompt-resource-bridge.d.ts +12 -0
  282. package/dist/core/prompt-resource-bridge.d.ts.map +1 -0
  283. package/dist/core/prompt-resource-bridge.js +9 -0
  284. package/dist/core/prompt-resource-bridge.js.map +1 -0
  285. package/dist/core/protected-targets.d.ts +6 -0
  286. package/dist/core/protected-targets.d.ts.map +1 -0
  287. package/dist/core/protected-targets.js +45 -0
  288. package/dist/core/protected-targets.js.map +1 -0
  289. package/dist/core/resource-loader.d.ts.map +1 -1
  290. package/dist/core/resource-loader.js +7 -0
  291. package/dist/core/resource-loader.js.map +1 -1
  292. package/dist/core/rollback.d.ts +19 -3
  293. package/dist/core/rollback.d.ts.map +1 -1
  294. package/dist/core/rollback.js +172 -56
  295. package/dist/core/rollback.js.map +1 -1
  296. package/dist/core/runtime-credentials.d.ts +3 -0
  297. package/dist/core/runtime-credentials.d.ts.map +1 -1
  298. package/dist/core/runtime-credentials.js +14 -1
  299. package/dist/core/runtime-credentials.js.map +1 -1
  300. package/dist/core/sdk.d.ts +3 -0
  301. package/dist/core/sdk.d.ts.map +1 -1
  302. package/dist/core/sdk.js +1 -0
  303. package/dist/core/sdk.js.map +1 -1
  304. package/dist/core/session-manager.d.ts +6 -0
  305. package/dist/core/session-manager.d.ts.map +1 -1
  306. package/dist/core/session-manager.js +95 -32
  307. package/dist/core/session-manager.js.map +1 -1
  308. package/dist/core/session-ownership.d.ts.map +1 -1
  309. package/dist/core/session-ownership.js +8 -3
  310. package/dist/core/session-ownership.js.map +1 -1
  311. package/dist/core/session-retention.d.ts.map +1 -1
  312. package/dist/core/session-retention.js +18 -7
  313. package/dist/core/session-retention.js.map +1 -1
  314. package/dist/core/session-startup-settings.d.ts +10 -0
  315. package/dist/core/session-startup-settings.d.ts.map +1 -0
  316. package/dist/core/session-startup-settings.js +70 -0
  317. package/dist/core/session-startup-settings.js.map +1 -0
  318. package/dist/core/subscriptions.d.ts +16 -7
  319. package/dist/core/subscriptions.d.ts.map +1 -1
  320. package/dist/core/subscriptions.js +96 -55
  321. package/dist/core/subscriptions.js.map +1 -1
  322. package/dist/core/trust-manager.d.ts +2 -1
  323. package/dist/core/trust-manager.d.ts.map +1 -1
  324. package/dist/core/trust-manager.js +6 -1
  325. package/dist/core/trust-manager.js.map +1 -1
  326. package/dist/core/update-check.d.ts.map +1 -1
  327. package/dist/core/update-check.js.map +1 -1
  328. package/dist/core/usage-adapters/kimi-coding.d.ts +2 -2
  329. package/dist/core/usage-adapters/kimi-coding.d.ts.map +1 -1
  330. package/dist/core/usage-adapters/kimi-coding.js +2 -2
  331. package/dist/core/usage-adapters/kimi-coding.js.map +1 -1
  332. package/dist/core/usage-adapters/openai-codex.d.ts +3 -2
  333. package/dist/core/usage-adapters/openai-codex.d.ts.map +1 -1
  334. package/dist/core/usage-adapters/openai-codex.js +3 -3
  335. package/dist/core/usage-adapters/openai-codex.js.map +1 -1
  336. package/dist/core/usage-adapters/xai.d.ts +2 -2
  337. package/dist/core/usage-adapters/xai.d.ts.map +1 -1
  338. package/dist/core/usage-adapters/xai.js +3 -3
  339. package/dist/core/usage-adapters/xai.js.map +1 -1
  340. package/dist/core/usage-adapters/zai.d.ts +2 -2
  341. package/dist/core/usage-adapters/zai.d.ts.map +1 -1
  342. package/dist/core/usage-adapters/zai.js +2 -2
  343. package/dist/core/usage-adapters/zai.js.map +1 -1
  344. package/dist/core/usage-service.d.ts +9 -2
  345. package/dist/core/usage-service.d.ts.map +1 -1
  346. package/dist/core/usage-service.js +95 -50
  347. package/dist/core/usage-service.js.map +1 -1
  348. package/dist/gateway/agent-bridge.d.ts +9 -1
  349. package/dist/gateway/agent-bridge.d.ts.map +1 -1
  350. package/dist/gateway/agent-bridge.js +91 -37
  351. package/dist/gateway/agent-bridge.js.map +1 -1
  352. package/dist/gateway/buttons.d.ts +8 -1
  353. package/dist/gateway/buttons.d.ts.map +1 -1
  354. package/dist/gateway/buttons.js +76 -18
  355. package/dist/gateway/buttons.js.map +1 -1
  356. package/dist/gateway/commands.d.ts +1 -0
  357. package/dist/gateway/commands.d.ts.map +1 -1
  358. package/dist/gateway/commands.js +10 -4
  359. package/dist/gateway/commands.js.map +1 -1
  360. package/dist/gateway/cron.d.ts +12 -11
  361. package/dist/gateway/cron.d.ts.map +1 -1
  362. package/dist/gateway/cron.js +65 -56
  363. package/dist/gateway/cron.js.map +1 -1
  364. package/dist/gateway/index.d.ts.map +1 -1
  365. package/dist/gateway/index.js +2 -1
  366. package/dist/gateway/index.js.map +1 -1
  367. package/dist/gateway/mobile-commands.d.ts +1 -0
  368. package/dist/gateway/mobile-commands.d.ts.map +1 -1
  369. package/dist/gateway/mobile-commands.js +56 -14
  370. package/dist/gateway/mobile-commands.js.map +1 -1
  371. package/dist/gateway/presenter.d.ts +12 -2
  372. package/dist/gateway/presenter.d.ts.map +1 -1
  373. package/dist/gateway/presenter.js +73 -38
  374. package/dist/gateway/presenter.js.map +1 -1
  375. package/dist/gateway/router.d.ts +2 -2
  376. package/dist/gateway/router.d.ts.map +1 -1
  377. package/dist/gateway/router.js +17 -2
  378. package/dist/gateway/router.js.map +1 -1
  379. package/dist/gateway/service.d.ts +2 -0
  380. package/dist/gateway/service.d.ts.map +1 -1
  381. package/dist/gateway/service.js +153 -0
  382. package/dist/gateway/service.js.map +1 -1
  383. package/dist/main.d.ts.map +1 -1
  384. package/dist/main.js +86 -33
  385. package/dist/main.js.map +1 -1
  386. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  387. package/dist/modes/interactive/components/assistant-message.js +6 -4
  388. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  389. package/dist/modes/interactive/components/copyable-text.d.ts.map +1 -1
  390. package/dist/modes/interactive/components/copyable-text.js +3 -2
  391. package/dist/modes/interactive/components/copyable-text.js.map +1 -1
  392. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
  393. package/dist/modes/interactive/components/extension-editor.js +1 -1
  394. package/dist/modes/interactive/components/extension-editor.js.map +1 -1
  395. package/dist/modes/interactive/interactive-mode.d.ts +2 -2
  396. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  397. package/dist/modes/interactive/interactive-mode.js +96 -109
  398. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  399. package/dist/modes/interactive/smooth-streaming.d.ts.map +1 -1
  400. package/dist/modes/interactive/smooth-streaming.js.map +1 -1
  401. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  402. package/dist/modes/rpc/rpc-mode.js +2 -1
  403. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  404. package/dist/node-runtime/{adapter-VFG7WNPX.js → adapter-247RTYLS.js} +4 -5
  405. package/dist/node-runtime/agent-session-services-KDMSPQDY.js +53 -0
  406. package/dist/node-runtime/{brave-UWDA3I22.js → brave-2AFFAXNN.js} +1 -1
  407. package/dist/node-runtime/{builtin-extensions-I2HIFEMY.js → builtin-extensions-OX6KELNX.js} +8 -7
  408. package/dist/node-runtime/{chunk-QH6YL7VK.js → chunk-252ZVPPF.js} +3 -3
  409. package/dist/node-runtime/{chunk-PCEW76PM.js → chunk-2OIPYKLZ.js} +6 -6
  410. package/dist/node-runtime/{chunk-XBWPBZBN.js → chunk-2SWW7KMW.js} +1 -1
  411. package/dist/node-runtime/{chunk-UQUCFAJ3.js → chunk-2VIW3IMF.js} +40 -7
  412. package/dist/node-runtime/{chunk-UOEDI7RP.js → chunk-4KNKQGHM.js} +2 -2
  413. package/dist/node-runtime/{chunk-FQMM2EZ2.js → chunk-64XTQNLA.js} +29 -7
  414. package/dist/node-runtime/{chunk-SPVDBUOS.js → chunk-6O3IW3IA.js} +2 -2
  415. package/dist/node-runtime/{chunk-5ZQXRPMC.js → chunk-6ZZHGUSA.js} +2 -2
  416. package/dist/node-runtime/chunk-A2WO6WIN.js +1197 -0
  417. package/dist/node-runtime/{chunk-WIF24I7G.js → chunk-APVM5NEU.js} +149 -144
  418. package/dist/node-runtime/{chunk-RCR3XAQY.js → chunk-AYHH7YSD.js} +177 -144
  419. package/dist/node-runtime/{chunk-LWYIVUGV.js → chunk-B2IBAXNX.js} +48 -31
  420. package/dist/node-runtime/{chunk-M3LZLQW2.js → chunk-BDRGN3L2.js} +1 -0
  421. package/dist/node-runtime/{chunk-GJ2RDBRL.js → chunk-BYC6RKCN.js} +4 -2
  422. package/dist/node-runtime/{chunk-UVWCDQYF.js → chunk-C3P6Q3B2.js} +455 -278
  423. package/dist/node-runtime/{chunk-SN2KSMPQ.js → chunk-DQSCFU7R.js} +13 -7
  424. package/dist/node-runtime/{chunk-4SBQAI4T.js → chunk-EBLAZVSA.js} +2058 -73
  425. package/dist/node-runtime/{chunk-2KIPT4HJ.js → chunk-EPR2F3GU.js} +68 -20
  426. package/dist/node-runtime/{chunk-CSFI6YXL.js → chunk-ES6PBSIE.js} +1 -1
  427. package/dist/node-runtime/{chunk-IF24A3FH.js → chunk-EVM653DD.js} +4 -4
  428. package/dist/node-runtime/{chunk-HTFRRDSF.js → chunk-F2SMQ6ES.js} +3 -2
  429. package/dist/node-runtime/chunk-F2V2F4ZG.js +114 -0
  430. package/dist/node-runtime/{chunk-IKU6Y7DL.js → chunk-FE3WZI7F.js} +9 -6
  431. package/dist/node-runtime/{chunk-GYIXXQAO.js → chunk-FIRA54AC.js} +2 -5
  432. package/dist/node-runtime/{chunk-6VYZ5UFP.js → chunk-FLGEEH27.js} +1 -1
  433. package/dist/node-runtime/{chunk-5EFIU3OM.js → chunk-FTKEZL27.js} +1 -1
  434. package/dist/node-runtime/{chunk-RGQAEOM5.js → chunk-FYIFPFXE.js} +23 -6
  435. package/dist/node-runtime/{chunk-HMBGROQK.js → chunk-GLDXBBL6.js} +3 -3
  436. package/dist/node-runtime/{chunk-KWA4OC2J.js → chunk-H6YBCWKG.js} +1 -1
  437. package/dist/node-runtime/{chunk-2MI5OPMN.js → chunk-HNNHHJAB.js} +68 -50
  438. package/dist/node-runtime/{chunk-I74LN5JG.js → chunk-HUD2RFJW.js} +2 -2
  439. package/dist/node-runtime/{chunk-I54LGHWM.js → chunk-I2H5QMWW.js} +3 -3
  440. package/dist/node-runtime/{chunk-XHIRAZ26.js → chunk-IAZSK7KK.js} +1 -1
  441. package/dist/node-runtime/{chunk-X3PGBLQ7.js → chunk-IHHTWSXN.js} +9 -9
  442. package/dist/node-runtime/{chunk-DAPBPCBP.js → chunk-IPP5BIV5.js} +25 -3
  443. package/dist/node-runtime/{chunk-QFWG2RVL.js → chunk-IXG6F4NT.js} +11 -0
  444. package/dist/node-runtime/{chunk-RDDAZOMU.js → chunk-JL4HYQXK.js} +1 -1
  445. package/dist/node-runtime/{chunk-CDVHZOOK.js → chunk-JQYNHAKX.js} +1 -1
  446. package/dist/node-runtime/{chunk-L24TPBS4.js → chunk-JWEVT363.js} +37 -29
  447. package/dist/node-runtime/{chunk-2HMIRK7W.js → chunk-LHV3V67B.js} +5 -5
  448. package/dist/node-runtime/{chunk-UAEOTO52.js → chunk-MNQXDFPV.js} +6 -2
  449. package/dist/node-runtime/{chunk-T4DA4XE7.js → chunk-MQPKUHRN.js} +162 -82
  450. package/dist/node-runtime/{chunk-MPKSOJBT.js → chunk-NHATCSOI.js} +4 -7
  451. package/dist/node-runtime/{chunk-RMQZU2YU.js → chunk-NNNR3QIY.js} +1 -1
  452. package/dist/node-runtime/{chunk-RWTKOC3B.js → chunk-QBTJG3UM.js} +1 -1
  453. package/dist/node-runtime/{chunk-P7XBVXGT.js → chunk-QNVMKNNN.js} +18 -14
  454. package/dist/node-runtime/{chunk-GS42T6MX.js → chunk-QW3AAHWN.js} +1 -1
  455. package/dist/node-runtime/{chunk-DVQSHCVP.js → chunk-R4WSB2MQ.js} +5 -5
  456. package/dist/node-runtime/{chunk-B4HP6ZWM.js → chunk-RHCGYWO7.js} +1 -1
  457. package/dist/node-runtime/{chunk-2CFDTH5B.js → chunk-RLGY2QIL.js} +45 -59
  458. package/dist/node-runtime/{chunk-KKUTQQV7.js → chunk-RYRGL7P4.js} +1 -1
  459. package/dist/node-runtime/{chunk-5Q4A37RB.js → chunk-TCT6PCUR.js} +32 -11
  460. package/dist/node-runtime/{chunk-D5UCKPBQ.js → chunk-UBWW2PID.js} +1 -1
  461. package/dist/node-runtime/{chunk-E75WFZ33.js → chunk-UNUZICC4.js} +3 -3
  462. package/dist/node-runtime/{chunk-RAK2QA2B.js → chunk-UYRKUKFE.js} +4 -4
  463. package/dist/node-runtime/{chunk-LWJXTA6Z.js → chunk-VSUEAI7O.js} +1377 -45
  464. package/dist/node-runtime/{chunk-NAY6UUQZ.js → chunk-WDIVLMOH.js} +1 -1
  465. package/dist/node-runtime/{chunk-E24EO34J.js → chunk-WPXUR3HE.js} +1 -1
  466. package/dist/node-runtime/{chunk-SLVOAQOY.js → chunk-WXYNALHD.js} +113 -1
  467. package/dist/node-runtime/{chunk-KJ6DWS3K.js → chunk-XEOCUEUJ.js} +121 -60
  468. package/dist/node-runtime/chunk-YD3IZAZ7.js +47 -0
  469. package/dist/node-runtime/chunk-YSB6URMT.js +41 -0
  470. package/dist/node-runtime/{chunk-LJTIVM7I.js → chunk-ZDJUR45D.js} +427 -126
  471. package/dist/node-runtime/{chunk-YWOJIGFY.js → chunk-ZEVFBFNF.js} +95 -142
  472. package/dist/node-runtime/{chunk-5B6VKFEV.js → chunk-ZIQUS5QO.js} +1 -1
  473. package/dist/node-runtime/cli-runtime.js +4 -4
  474. package/dist/node-runtime/{command-FSBU2EVZ.js → command-3HMSY6W2.js} +5 -5
  475. package/dist/node-runtime/{commands-EMBQQVVT.js → commands-D6A6H4TS.js} +11 -18
  476. package/dist/node-runtime/{commands-NAAL7KNT.js → commands-OCSSEEWJ.js} +16 -16
  477. package/dist/node-runtime/{config-QDD5PUE2.js → config-CU7M7BTK.js} +1 -1
  478. package/dist/node-runtime/{config-D4QUPAHX.js → config-DS7XLMEM.js} +2 -2
  479. package/dist/node-runtime/{direct-tool-executor-4D7UXYU4.js → direct-tool-executor-2QJXVQD2.js} +6 -11
  480. package/dist/node-runtime/{exa-LL64QZR2.js → exa-6VBZNPGE.js} +1 -1
  481. package/dist/node-runtime/{export-html-VM4J2MNR.js → export-html-BRWF5AHI.js} +4 -4
  482. package/dist/node-runtime/{extension-input-E7BJZ35H.js → extension-input-VBBMX7YV.js} +5 -5
  483. package/dist/node-runtime/{extension-selector-WU42XDTU.js → extension-selector-T5AOG5XB.js} +5 -5
  484. package/dist/node-runtime/{extract-EQJE7FZZ.js → extract-BFX2N35A.js} +3 -3
  485. package/dist/node-runtime/{gateway-DQM333YV.js → gateway-6623C2U3.js} +51 -42
  486. package/dist/node-runtime/{gemini-search-35OCRFLN.js → gemini-search-C66QHDT6.js} +2 -2
  487. package/dist/node-runtime/{gemini-url-context-UQY3PHHW.js → gemini-url-context-T7DEK73R.js} +3 -3
  488. package/dist/node-runtime/{github-extract-F64RZOEA.js → github-extract-HOGE3D6F.js} +107 -38
  489. package/dist/node-runtime/{goal-NJEE5CTU.js → goal-AIHEDUYA.js} +5 -5
  490. package/dist/node-runtime/index.js +50 -48
  491. package/dist/node-runtime/{init-P5AUV77I.js → init-JBQJIPYI.js} +3 -6
  492. package/dist/node-runtime/{install-cli-NN4YAU44.js → install-cli-INGHIVBY.js} +30 -25
  493. package/dist/node-runtime/interactive-mode-FM5DNUSW.js +74 -0
  494. package/dist/node-runtime/{interactive-view-NGFAMHPW.js → interactive-view-K33PM4OS.js} +8 -8
  495. package/dist/node-runtime/{lsp-manager-3ASUSO4T.js → lsp-manager-S554V5HR.js} +240 -155
  496. package/dist/node-runtime/{lunr-browser-IR7TL3J7.js → lunr-browser-H4FDOR3C.js} +7 -7
  497. package/dist/node-runtime/{lunr-computer-use-Y23CCDIJ.js → lunr-computer-use-VDP2QNRQ.js} +9 -9
  498. package/dist/node-runtime/{lunr-cron-USHC4LXH.js → lunr-cron-LKVA5CZZ.js} +93 -80
  499. package/dist/node-runtime/main.js +42 -41
  500. package/dist/node-runtime/{mobile-commands-O5LCHL32.js → mobile-commands-XT3NQXLD.js} +12 -12
  501. package/dist/node-runtime/{model-runtime-OO5HFLWE.js → model-runtime-MZ2JMDV4.js} +4 -4
  502. package/dist/node-runtime/{openai-search-B3MSNCQA.js → openai-search-K72LJDYN.js} +1 -1
  503. package/dist/node-runtime/{package-manager-cli-Q7BL6KZO.js → package-manager-cli-CYM262SI.js} +20 -20
  504. package/dist/node-runtime/{parallel-AI2MNSCU.js → parallel-X724NCNU.js} +1 -1
  505. package/dist/node-runtime/{perplexity-QVJW3I35.js → perplexity-RDHQHVMK.js} +2 -2
  506. package/dist/node-runtime/{pi-intercom-QM53RLTS.js → pi-intercom-NHHEPBMI.js} +2 -2
  507. package/dist/node-runtime/{pi-mcp-adapter-3PHF4KZ4.js → pi-mcp-adapter-PP3GQJQ2.js} +98 -94
  508. package/dist/node-runtime/{pi-ollama-cloud-2F3Y2QNM.js → pi-ollama-cloud-4MNWIMFN.js} +11 -24
  509. package/dist/node-runtime/{pi-prompt-template-model-QWTCGLJU.js → pi-prompt-template-model-FTGELLS5.js} +32 -36
  510. package/dist/node-runtime/{pi-subagents-7IBSSGEW.js → pi-subagents-LT3CTO4E.js} +98 -106
  511. package/dist/node-runtime/{pi-web-access-WTGMNZ32.js → pi-web-access-Z3LP246C.js} +144 -108
  512. package/dist/node-runtime/{print-mode-XQ76CYMT.js → print-mode-2XHN5SUA.js} +3 -3
  513. package/dist/node-runtime/{process-registry-4FAKZQOL.js → process-registry-Q4QWIU33.js} +3 -3
  514. package/dist/node-runtime/{proxy-modes-5FAPSZEZ.js → proxy-modes-VEGC6QG5.js} +8 -15
  515. package/dist/node-runtime/rpc-entry.js +42 -41
  516. package/dist/node-runtime/{rpc-mode-O3XV4SID.js → rpc-mode-32DHJPEJ.js} +4 -4
  517. package/dist/node-runtime/{runtime-4VA6JKNF.js → runtime-EDUUGAQD.js} +56 -46
  518. package/dist/node-runtime/{runtime-EFPPD2UW.js → runtime-UGXM4NPQ.js} +2 -2
  519. package/dist/node-runtime/{runtime-bridges-7WVCLI76.js → runtime-bridges-DNKMNJCF.js} +7 -7
  520. package/dist/node-runtime/{service-MDQIPQ26.js → service-IHLGFLBT.js} +6 -4
  521. package/dist/node-runtime/{session-handoff-GWARVEWT.js → session-handoff-LNSPDTKY.js} +4 -4
  522. package/dist/node-runtime/{session-manager-JB5J6XBN.js → session-manager-YIFIAVGC.js} +3 -3
  523. package/dist/node-runtime/{session-selector-GIM4DHQ2.js → session-selector-I73U3EIO.js} +7 -7
  524. package/dist/node-runtime/{settings-manager-DJDM5AHM.js → settings-manager-P2TKGYTR.js} +5 -5
  525. package/dist/node-runtime/{setup-JBKOLJ6F.js → setup-H7CCELIL.js} +15 -1
  526. package/dist/node-runtime/{setup-PFBWRNUI.js → setup-OLQ4GXWS.js} +17 -17
  527. package/dist/node-runtime/{src-IVPNZ2BX.js → src-6RV4PXKJ.js} +64 -36
  528. package/dist/node-runtime/{subagent-executor-LPZ4BHWE.js → subagent-executor-Q5F7DBVM.js} +119 -58
  529. package/dist/node-runtime/{tavily-WEZFVFP7.js → tavily-KZBFYQB6.js} +1 -1
  530. package/dist/node-runtime/{theme-UOO5RVFN.js → theme-YLVZKKZD.js} +2 -2
  531. package/dist/node-runtime/{trust-manager-MMISNCYO.js → trust-manager-ZCU76D23.js} +2 -2
  532. package/dist/node-runtime/{update-cli-HNMOTNGX.js → update-cli-F3XXJANQ.js} +6 -6
  533. package/dist/node-runtime/{usage-service-LFB2SWYV.js → usage-service-CPAGBED5.js} +1 -1
  534. package/dist/node-runtime/{video-extract-OOZHR7SU.js → video-extract-UPKYIBW3.js} +3 -3
  535. package/dist/node-runtime/{workflow-OHPBEFO4.js → workflow-ICDI4N3J.js} +208 -78
  536. package/dist/node-runtime/{youtube-extract-FNPAUNHU.js → youtube-extract-77NT7FWH.js} +4 -4
  537. package/dist/utils/clipboard-image.d.ts.map +1 -1
  538. package/dist/utils/clipboard-image.js.map +1 -1
  539. package/dist/utils/exif-orientation.d.ts.map +1 -1
  540. package/dist/utils/exif-orientation.js +25 -10
  541. package/dist/utils/exif-orientation.js.map +1 -1
  542. package/dist/utils/image-resize-core.d.ts.map +1 -1
  543. package/dist/utils/image-resize-core.js +2 -0
  544. package/dist/utils/image-resize-core.js.map +1 -1
  545. package/dist/utils/paths.d.ts +4 -0
  546. package/dist/utils/paths.d.ts.map +1 -1
  547. package/dist/utils/paths.js +33 -2
  548. package/dist/utils/paths.js.map +1 -1
  549. package/dist/utils/sanitize-terminal-text.d.ts +7 -0
  550. package/dist/utils/sanitize-terminal-text.d.ts.map +1 -0
  551. package/dist/utils/sanitize-terminal-text.js +67 -0
  552. package/dist/utils/sanitize-terminal-text.js.map +1 -0
  553. package/docs/browser.md +1 -1
  554. package/docs/custom-provider.md +3 -3
  555. package/docs/extensions.md +8 -4
  556. package/docs/features.md +15 -7
  557. package/docs/keybindings.md +1 -1
  558. package/docs/models.md +5 -5
  559. package/docs/packages.md +1 -1
  560. package/docs/providers.md +2 -2
  561. package/docs/rpc.md +7 -7
  562. package/docs/security.md +10 -5
  563. package/docs/sessions.md +2 -2
  564. package/docs/skills.md +1 -1
  565. package/docs/terminal-setup.md +7 -7
  566. package/docs/themes.md +1 -1
  567. package/docs/usage.md +1 -1
  568. package/examples/extensions/auto-commit-on-exit.ts +1 -1
  569. package/examples/extensions/bash-spawn-hook.ts +1 -1
  570. package/examples/extensions/built-in-tool-renderer.ts +1 -1
  571. package/examples/extensions/claude-rules.ts +1 -1
  572. package/examples/extensions/commands.ts +1 -1
  573. package/examples/extensions/custom-compaction.ts +1 -1
  574. package/examples/extensions/custom-provider-anthropic/index.ts +3 -3
  575. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  576. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  577. package/examples/extensions/custom-provider-gitlab-duo/index.ts +1 -1
  578. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  579. package/examples/extensions/doom-overlay/index.ts +1 -1
  580. package/examples/extensions/git-merge-and-resolve.ts +2 -2
  581. package/examples/extensions/gondolin/index.ts +1 -1
  582. package/examples/extensions/gondolin/package-lock.json +2 -2
  583. package/examples/extensions/gondolin/package.json +1 -1
  584. package/examples/extensions/hidden-thinking-label.ts +1 -1
  585. package/examples/extensions/inline-bash.ts +2 -2
  586. package/examples/extensions/input-transform-streaming.ts +2 -2
  587. package/examples/extensions/input-transform.ts +2 -2
  588. package/examples/extensions/interactive-shell.ts +1 -1
  589. package/examples/extensions/kimi-deferred-tools.ts +1 -1
  590. package/examples/extensions/mac-system-theme.ts +1 -1
  591. package/examples/extensions/minimal-mode.ts +1 -1
  592. package/examples/extensions/modal-editor.ts +1 -1
  593. package/examples/extensions/model-status.ts +1 -1
  594. package/examples/extensions/notify.ts +3 -3
  595. package/examples/extensions/overlay-qa-tests.ts +1 -1
  596. package/examples/extensions/overlay-test.ts +1 -1
  597. package/examples/extensions/pirate.ts +1 -1
  598. package/examples/extensions/preset.ts +3 -3
  599. package/examples/extensions/project-trust.ts +4 -4
  600. package/examples/extensions/prompt-customizer.ts +1 -1
  601. package/examples/extensions/rainbow-editor.ts +1 -1
  602. package/examples/extensions/rpc-demo.ts +1 -1
  603. package/examples/extensions/sandbox/index.ts +7 -7
  604. package/examples/extensions/sandbox/package-lock.json +2 -2
  605. package/examples/extensions/sandbox/package.json +1 -1
  606. package/examples/extensions/shutdown-command.ts +5 -5
  607. package/examples/extensions/ssh.ts +2 -2
  608. package/examples/extensions/subagent/README.md +3 -3
  609. package/examples/extensions/subagent/index.ts +2 -2
  610. package/examples/extensions/titlebar-spinner.ts +1 -1
  611. package/examples/extensions/tool-override.ts +1 -1
  612. package/examples/extensions/tools.ts +1 -1
  613. package/examples/extensions/with-deps/package-lock.json +2 -2
  614. package/examples/extensions/with-deps/package.json +1 -1
  615. package/examples/extensions/working-indicator.ts +1 -1
  616. package/examples/extensions/working-message-test.ts +1 -1
  617. package/examples/sdk/01-minimal.ts +1 -1
  618. package/examples/sdk/03-custom-prompt.ts +1 -1
  619. package/examples/sdk/04-skills.ts +1 -1
  620. package/examples/sdk/06-extensions.ts +2 -2
  621. package/examples/sdk/08-prompt-templates.ts +1 -1
  622. package/install-lock/package-lock.json +24 -24
  623. package/install-lock/package.json +2 -2
  624. package/npm-shrinkwrap.json +60 -24
  625. package/package.json +9 -9
  626. package/dist/modes/interactive/components/exit-card.d.ts +0 -22
  627. package/dist/modes/interactive/components/exit-card.d.ts.map +0 -1
  628. package/dist/modes/interactive/components/exit-card.js +0 -69
  629. package/dist/modes/interactive/components/exit-card.js.map +0 -1
  630. package/dist/node-runtime/agent-session-services-5YXS2PLF.js +0 -51
  631. package/dist/node-runtime/chunk-2IDTZAG5.js +0 -1415
  632. package/dist/node-runtime/chunk-3MISGG4S.js +0 -769
  633. package/dist/node-runtime/chunk-4HXHDDCF.js +0 -16
  634. package/dist/node-runtime/chunk-5B5QN3ZQ.js +0 -356
  635. package/dist/node-runtime/chunk-7IQGBKBJ.js +0 -2033
  636. package/dist/node-runtime/chunk-AUXVGBO4.js +0 -19
  637. package/dist/node-runtime/chunk-PTFBPO3C.js +0 -50
  638. package/dist/node-runtime/interactive-mode-YOHZVMKX.js +0 -74
  639. package/dist/node-runtime/mcp-auth-flow-QVLFVLEO.js +0 -33
@@ -1 +1 @@
1
- {"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/gateway/commands.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * lunR: gateway chat command registry.\n *\n * Every command is a small headless handler over AgentSession. Router.ts keeps\n * platform gating/authorization and delegates to runChatCommand for busy/session\n * guards, error wrapping, and /help generation.\n */\n\nimport type { ThinkingLevel } from \"@ashx-j/lunr-agent\";\nimport type { Model } from \"@ashx-j/lunr-ai/compat\";\nimport { computeContextBreakdown } from \"../core/context-breakdown.ts\";\nimport type { ToolDefinition } from \"../core/extensions/types.ts\";\nimport { findExactModelReferenceMatch } from \"../core/model-resolver.ts\";\nimport type { ModelRuntime } from \"../core/model-runtime.ts\";\nimport { runtimeScope } from \"../core/runtime-scope.ts\";\nimport type { SessionInfo } from \"../core/session-manager.ts\";\nimport { SessionManager } from \"../core/session-manager.ts\";\nimport type { BridgeSession } from \"./agent-bridge.ts\";\nimport { createPicker, type PickerItem } from \"./buttons.ts\";\nimport { defaultGatewayConfig, type GatewayConfig } from \"./config.ts\";\nimport { conversationBinding } from \"./conversations.ts\";\nimport { FORWARDED_COMMANDS, MOBILE_COMMANDS, resolveWithinRoots } from \"./mobile-commands.ts\";\nimport type { BridgeLike } from \"./router.ts\";\nimport type { MessageEvent, PlatformAdapter } from \"./types.ts\";\n\nconst MODEL_CACHE_TTL_MS = 5 * 60 * 1000;\nconst SESSIONS_CACHE_TTL_MS = 5 * 60 * 1000;\nconst MAX_MODEL_LIST_LINES = 15;\nconst PROVIDER_PER_PAGE = 10;\nconst _MODEL_PER_PAGE = 8;\nconst MAX_MODELS_PER_PROVIDER = 50;\nconst MODEL_ID_MAX = 38;\nconst MODEL_CACHE_CAP = 100;\nconst SESSIONS_CACHE_CAP = 100;\n\ninterface ModelCacheEntry {\n\tmodels: Model<any>[];\n\texpires: number;\n}\n\ninterface SessionsCacheEntry {\n\tsessions: SessionInfo[];\n\texpires: number;\n}\n\nconst modelCache = new Map<string, ModelCacheEntry>();\nconst sessionsCache = new Map<string, SessionsCacheEntry>();\n\nfunction evictLRU<K, V>(map: Map<K, V>, cap: number): void {\n\twhile (map.size > cap) {\n\t\tconst first = map.keys().next().value;\n\t\tif (first !== undefined) map.delete(first);\n\t}\n}\n\nfunction getCachedModels(key: string): Model<any>[] | undefined {\n\tconst cached = modelCache.get(key);\n\tif (!cached) return undefined;\n\tif (Date.now() > cached.expires) {\n\t\tmodelCache.delete(key);\n\t\treturn undefined;\n\t}\n\t// LRU refresh.\n\tmodelCache.delete(key);\n\tmodelCache.set(key, cached);\n\treturn cached.models;\n}\n\nfunction setCachedModels(key: string, models: Model<any>[]): void {\n\tmodelCache.set(key, { models, expires: Date.now() + MODEL_CACHE_TTL_MS });\n\tevictLRU(modelCache, MODEL_CACHE_CAP);\n}\n\nfunction getCachedSessions(key: string): SessionInfo[] | undefined {\n\tconst cached = sessionsCache.get(key);\n\tif (!cached) return undefined;\n\tif (Date.now() > cached.expires) {\n\t\tsessionsCache.delete(key);\n\t\treturn undefined;\n\t}\n\tsessionsCache.delete(key);\n\tsessionsCache.set(key, cached);\n\treturn cached.sessions;\n}\n\nfunction setCachedSessions(key: string, sessions: SessionInfo[]): void {\n\tsessionsCache.set(key, { sessions, expires: Date.now() + SESSIONS_CACHE_TTL_MS });\n\tevictLRU(sessionsCache, SESSIONS_CACHE_CAP);\n}\n\nexport interface ChatCommandContext {\n\tevent: MessageEvent;\n\tkey: string;\n\tadapter: PlatformAdapter;\n\tbridge: BridgeLike;\n\tcfg?: GatewayConfig;\n\tsession?: BridgeSession;\n\treply(text: string): Promise<void>;\n\targs: string;\n}\n\nexport interface ChatCommand {\n\tname: string;\n\taliases?: string[];\n\tdescription: string;\n\tbypassBusy: boolean;\n\tneedsSession: boolean;\n\t// biome-ignore lint/suspicious/noConfusingVoidType: handlers may return nothing; runChatCommand treats undefined as consumed.\n\thandler(ctx: ChatCommandContext): Promise<boolean | void>;\n}\n\nfunction oneLine(text: string): string {\n\treturn text.replace(/\\s+/g, \" \").trim().slice(0, 200);\n}\n\nfunction prefixLines(text: string, prefix: string): string {\n\treturn text\n\t\t.split(\"\\n\")\n\t\t.map((line, index) => (index === 0 ? prefix : \" \") + line)\n\t\t.join(\"\\n\");\n}\n\nfunction truncate(text: string, max: number): string {\n\tif (text.length <= max) return text;\n\treturn `${text.slice(0, max - 1)}…`;\n}\n\nfunction formatRelativeTime(date: Date): string {\n\tconst seconds = Math.max(0, Math.floor((Date.now() - date.getTime()) / 1000));\n\tif (seconds < 60) return `${seconds}s ago`;\n\tconst minutes = Math.floor(seconds / 60);\n\tif (minutes < 60) return `${minutes}m ago`;\n\tconst hours = Math.floor(minutes / 60);\n\tif (hours < 24) return `${hours}h ago`;\n\tconst days = Math.floor(hours / 24);\n\treturn `${days}d ago`;\n}\n\nfunction formatModelList(models: Model<any>[], maxLines = MAX_MODEL_LIST_LINES): string[] {\n\tif (models.length === 0) return [\"No models available.\"];\n\tconst byProvider = new Map<string, Model<any>[]>();\n\tfor (const model of models) {\n\t\tconst list = byProvider.get(model.provider) ?? [];\n\t\tlist.push(model);\n\t\tbyProvider.set(model.provider, list);\n\t}\n\tconst providers = [...byProvider.keys()].sort();\n\tconst lines: string[] = [];\n\tlet index = 1;\n\tfor (const provider of providers) {\n\t\tconst list = (byProvider.get(provider) ?? []).sort((a, b) => a.id.localeCompare(b.id));\n\t\tfor (const model of list) {\n\t\t\tlines.push(`${index}) ${provider}/${model.id}`);\n\t\t\tindex++;\n\t\t}\n\t}\n\tif (lines.length <= maxLines) return lines;\n\treturn [\n\t\t`${models.length} models across ${providers.length} providers.`,\n\t\t\"Use /model <provider/id> or /model <query>.\",\n\t\t...providers.map((p) => `- ${p}`),\n\t];\n}\n\nfunction groupModelsByProvider(models: Model<any>[]): Map<string, Model<any>[]> {\n\tconst byProvider = new Map<string, Model<any>[]>();\n\tfor (const model of models) {\n\t\tconst list = byProvider.get(model.provider) ?? [];\n\t\tlist.push(model);\n\t\tbyProvider.set(model.provider, list);\n\t}\n\tfor (const list of byProvider.values()) {\n\t\tlist.sort((a, b) => a.id.localeCompare(b.id));\n\t}\n\treturn byProvider;\n}\n\nfunction truncateModelId(id: string): string {\n\tconst lastSlash = id.lastIndexOf(\"/\");\n\tconst name = lastSlash >= 0 ? id.slice(lastSlash + 1) : id;\n\treturn truncate(name, MODEL_ID_MAX);\n}\n\nasync function refreshAndCacheModels(session: BridgeSession, key: string): Promise<Model<any>[]> {\n\tconst runtime: ModelRuntime = session.modelRuntime;\n\tawait runtime.refresh();\n\tconst models = [...(await runtime.getAvailable())].sort(\n\t\t(a, b) => a.provider.localeCompare(b.provider) || a.id.localeCompare(b.id),\n\t);\n\tsetCachedModels(key, models);\n\treturn models;\n}\n\nasync function setModelAndReply(ctx: ChatCommandContext, model: Model<any>): Promise<void> {\n\tconst session = ctx.session!;\n\ttry {\n\t\tawait session.setModel(model);\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tif (message.includes(\"No API key\")) {\n\t\t\tawait ctx.reply(`No API key for ${model.provider}.`);\n\t\t\treturn;\n\t\t}\n\t\tthrow error;\n\t}\n\tawait ctx.reply(`Model → ${model.provider}/${model.id} (thinking level re-clamped to ${session.thinkingLevel})`);\n}\n\nconst newCommand: ChatCommand = {\n\tname: \"new\",\n\taliases: [\"reset\"],\n\tdescription: \"start a fresh session for this chat\",\n\t// lunr: busy-session /new must bypass the guard (same as /stop).\n\tbypassBusy: true,\n\tneedsSession: false,\n\tasync handler(ctx) {\n\t\tawait ctx.bridge.reset(ctx.key);\n\t\tconst cfg = ctx.cfg ?? defaultGatewayConfig();\n\t\tlet ready = Boolean(conversationBinding(ctx.key)?.cwd);\n\t\tif (!ready && cfg.defaultProject) {\n\t\t\ttry {\n\t\t\t\tresolveWithinRoots(cfg.defaultProject, cfg.projectRoots ?? []);\n\t\t\t\tready = true;\n\t\t\t} catch {}\n\t\t}\n\t\tawait ctx.reply(\n\t\t\tready\n\t\t\t\t? \"Session reset. Send a message to start fresh in the approved project.\"\n\t\t\t\t: \"Session reset. Use /project to choose an approved project before sending a message.\",\n\t\t);\n\t},\n};\n\nconst undoCommand: ChatCommand = {\n\tname: \"undo\",\n\tdescription: \"rewind the session tree before the last user turn\",\n\tbypassBusy: false,\n\tneedsSession: true,\n\tasync handler(ctx) {\n\t\tconst { userText } = await ctx.bridge.undo(ctx.key);\n\t\tconst text = userText ? ` \"${truncate(userText, 60)}\"` : \"\";\n\t\tawait ctx.reply(`Undone — rewound before${text}. /redo to restore.`);\n\t},\n};\n\nconst redoCommand: ChatCommand = {\n\tname: \"redo\",\n\tdescription: \"restore the last undone turn\",\n\tbypassBusy: false,\n\tneedsSession: true,\n\tasync handler(ctx) {\n\t\tawait ctx.bridge.redo(ctx.key);\n\t\tawait ctx.reply(\"Redone.\");\n\t},\n};\n\nconst stopCommand: ChatCommand = {\n\tname: \"stop\",\n\tdescription: \"abort the running turn\",\n\tbypassBusy: true,\n\tneedsSession: false,\n\tasync handler(ctx) {\n\t\tawait ctx.bridge.abort(ctx.key);\n\t\tawait ctx.reply(\"Stopped.\");\n\t},\n};\n\nconst statusCommand: ChatCommand = {\n\tname: \"status\",\n\tdescription: \"session status\",\n\tbypassBusy: true,\n\tneedsSession: false,\n\tasync handler(ctx) {\n\t\tconst status = ctx.bridge.getStatus(ctx.key);\n\t\tconst age = status.createdAt\n\t\t\t? `${Math.max(0, Math.round((Date.now() - Date.parse(status.createdAt)) / 1000))}s`\n\t\t\t: \"no session yet\";\n\t\tawait ctx.reply(\n\t\t\t`${ctx.event.source.platform} · session age ${age} · ${status.busy ? \"busy\" : \"idle\"} · queue ${status.queueDepth}\\nProject: ${conversationBinding(ctx.key)?.cwd ?? \"not selected\"}`,\n\t\t);\n\t},\n};\n\nconst whoamiCommand: ChatCommand = {\n\tname: \"whoami\",\n\tdescription: \"your ids and session key\",\n\tbypassBusy: true,\n\tneedsSession: false,\n\tasync handler(ctx) {\n\t\tconst { userId, chatId } = ctx.event.source;\n\t\tawait ctx.reply(`userId: ${userId}\\nchatId: ${chatId}\\nkey: ${ctx.key}`);\n\t},\n};\n\nconst helpCommand: ChatCommand = {\n\tname: \"help\",\n\tdescription: \"this message\",\n\tbypassBusy: true,\n\tneedsSession: false,\n\tasync handler(ctx) {\n\t\tawait ctx.reply(formatHelpText());\n\t},\n};\n\nconst modelCommand: ChatCommand = {\n\tname: \"model\",\n\tdescription: \"list or switch models\",\n\tbypassBusy: false,\n\tneedsSession: true,\n\tasync handler(ctx) {\n\t\tconst session = ctx.session!;\n\t\tconst arg = ctx.args.trim();\n\t\tif (!arg) {\n\t\t\tconst cached = getCachedModels(ctx.key);\n\t\t\tconst models = cached ?? (await refreshAndCacheModels(session, ctx.key));\n\t\t\tconst byProvider = groupModelsByProvider(models);\n\t\t\tconst current = session.model;\n\t\t\tconst currentRef = current ? `${current.provider}/${current.id}` : \"\";\n\t\t\tconst providers = [...byProvider.keys()].sort();\n\t\t\tconst providerItems: PickerItem[] = providers.map((provider) => ({\n\t\t\t\tlabel: `${current?.provider === provider ? \"✓ \" : \"\"}${provider} (${byProvider.get(provider)?.length ?? 0})`,\n\t\t\t\tvalue: provider,\n\t\t\t}));\n\n\t\t\tconst pickerOpts = {\n\t\t\t\treplyTo: ctx.event.messageId,\n\t\t\t\tthreadId: ctx.event.source.threadId,\n\t\t\t};\n\t\t\tconst result = await createPicker(\n\t\t\t\tctx.adapter,\n\t\t\t\tctx.event.source,\n\t\t\t\t{\n\t\t\t\t\tkind: \"model\",\n\t\t\t\t\tsessionKey: ctx.key,\n\t\t\t\t\tinvokerId: ctx.event.source.userId,\n\t\t\t\t\titems: providerItems,\n\t\t\t\t\tperPage: PROVIDER_PER_PAGE,\n\t\t\t\t\ttitle: \"Pick a model provider\",\n\t\t\t\t\tasync resolve(item) {\n\t\t\t\t\t\tif (item.value === \"__back__\") {\n\t\t\t\t\t\t\treturn { done: false, items: providerItems, title: \"Pick a model provider\" };\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!item.value.includes(\"/\")) {\n\t\t\t\t\t\t\tconst provider = item.value;\n\t\t\t\t\t\t\tconst list = byProvider.get(provider) ?? [];\n\t\t\t\t\t\t\tconst capped = list.slice(0, MAX_MODELS_PER_PROVIDER);\n\t\t\t\t\t\t\tconst note =\n\t\t\t\t\t\t\t\tlist.length > MAX_MODELS_PER_PROVIDER\n\t\t\t\t\t\t\t\t\t? ` — ${list.length - MAX_MODELS_PER_PROVIDER} more available`\n\t\t\t\t\t\t\t\t\t: \"\";\n\t\t\t\t\t\t\tconst modelItems: PickerItem[] = [];\n\t\t\t\t\t\t\tfor (const m of capped) {\n\t\t\t\t\t\t\t\tconst ref = `${provider}/${m.id}`;\n\t\t\t\t\t\t\t\tmodelItems.push({\n\t\t\t\t\t\t\t\t\tlabel: `${currentRef === ref ? \"✓ \" : \"\"}${truncateModelId(m.id)}`,\n\t\t\t\t\t\t\t\t\tvalue: ref,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tmodelItems.unshift({ label: \"◀ Back\", value: \"__back__\" });\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tdone: false,\n\t\t\t\t\t\t\t\titems: modelItems,\n\t\t\t\t\t\t\t\ttitle: `${provider} (${list.length})${note}`,\n\t\t\t\t\t\t\t\tbreadcrumbs: provider,\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst exact = findExactModelReferenceMatch(item.value, models);\n\t\t\t\t\t\tif (!exact) {\n\t\t\t\t\t\t\treturn { done: true, text: \"That model is no longer available.\" };\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tawait session.setModel(exact);\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\t\t\t\t\tif (message.includes(\"No API key\")) {\n\t\t\t\t\t\t\t\treturn { done: true, text: `No API key for ${exact.provider}.` };\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tthrow error;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tdone: true,\n\t\t\t\t\t\t\ttext: `Model → ${exact.provider}/${exact.id} (thinking level re-clamped to ${session.thinkingLevel})`,\n\t\t\t\t\t\t};\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tpickerOpts,\n\t\t\t);\n\t\t\tif (!result.success) {\n\t\t\t\tconst currentText = `${current?.provider ?? \"none\"}/${current?.id ?? \"none\"}`;\n\t\t\t\tconst lines = formatModelList(models);\n\t\t\t\tawait ctx.reply([`Current: ${currentText}`, ...lines, \"Use /model <n> or /model <provider/id>\"].join(\"\\n\"));\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tconst numeric = Number.parseInt(arg, 10);\n\t\tif (!Number.isNaN(numeric) && /^\\d+$/.test(arg)) {\n\t\t\tconst cached = getCachedModels(ctx.key);\n\t\t\tif (!cached || numeric < 1 || numeric > cached.length) {\n\t\t\t\tawait ctx.reply(\"Invalid selection — run /model to see the current list.\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait setModelAndReply(ctx, cached[numeric - 1]);\n\t\t\treturn;\n\t\t}\n\n\t\tconst models = getCachedModels(ctx.key) ?? (await refreshAndCacheModels(session, ctx.key));\n\t\tconst exact = findExactModelReferenceMatch(arg, models);\n\t\tif (exact) {\n\t\t\tawait setModelAndReply(ctx, exact);\n\t\t\treturn;\n\t\t}\n\n\t\tconst query = arg.toLowerCase();\n\t\tconst matches = models.filter(\n\t\t\t(m) =>\n\t\t\t\tm.id.toLowerCase().includes(query) ||\n\t\t\t\t`${m.provider}/${m.id}`.toLowerCase().includes(query) ||\n\t\t\t\t(m.name?.toLowerCase().includes(query) ?? false),\n\t\t);\n\t\tif (matches.length === 0) {\n\t\t\tawait ctx.reply(`No model matches \"${arg}\".`);\n\t\t\treturn;\n\t\t}\n\t\tif (matches.length > 1) {\n\t\t\tawait ctx.reply(formatModelList(matches).join(\"\\n\"));\n\t\t\treturn;\n\t\t}\n\t\tawait setModelAndReply(ctx, matches[0]);\n\t},\n};\n\nconst sessionsCommand: ChatCommand = {\n\tname: \"sessions\",\n\tdescription: \"list or switch sessions\",\n\tbypassBusy: false,\n\tneedsSession: true,\n\tasync handler(ctx) {\n\t\tconst session = ctx.session!;\n\t\tconst arg = ctx.args.trim();\n\t\tconst currentFile = session.sessionManager?.getSessionFile();\n\t\tconst cwd = session.sessionManager?.getCwd() ?? conversationBinding(ctx.key)?.cwd;\n\t\tif (!cwd) throw new Error(\"Select a project before listing sessions.\");\n\n\t\tif (!arg) {\n\t\t\tconst all = await SessionManager.list(cwd);\n\t\t\tall.sort((a, b) => b.modified.getTime() - a.modified.getTime());\n\t\t\tconst sessions = all.slice(0, 10);\n\t\t\tsetCachedSessions(ctx.key, sessions);\n\t\t\tconst items: PickerItem[] = sessions.map((s) => ({\n\t\t\t\tlabel: `${s.path === currentFile ? \"(current) \" : \"\"}${s.name ? truncate(s.name, 30) : truncate(s.firstMessage, 30) || \"(empty)\"}`,\n\t\t\t\tvalue: s.path,\n\t\t\t}));\n\t\t\tconst result = await createPicker(\n\t\t\t\tctx.adapter,\n\t\t\t\tctx.event.source,\n\t\t\t\t{\n\t\t\t\t\tkind: \"sessions\",\n\t\t\t\t\tsessionKey: ctx.key,\n\t\t\t\t\tinvokerId: ctx.event.source.userId,\n\t\t\t\t\titems,\n\t\t\t\t\tperPage: 8,\n\t\t\t\t\ttitle: \"Pick a session\",\n\t\t\t\t\tasync resolve(item) {\n\t\t\t\t\t\tawait ctx.bridge.switchSession(ctx.key, item.value);\n\t\t\t\t\t\tconst switched = await ctx.bridge.getSession(ctx.key);\n\t\t\t\t\t\tconst name = switched?.sessionManager?.getSessionName() ?? \"unnamed\";\n\t\t\t\t\t\tconst count = switched?.sessionManager?.getEntries().length ?? 0;\n\t\t\t\t\t\treturn { done: true, text: `Switched to \"${name}\" (${count} msgs). History continues here.` };\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{ replyTo: ctx.event.messageId, threadId: ctx.event.source.threadId },\n\t\t\t);\n\t\t\tif (!result.success) {\n\t\t\t\tconst lines = sessions.map((s, i) => {\n\t\t\t\t\tconst marker = s.path === currentFile ? \" (current)\" : \"\";\n\t\t\t\t\tconst label = s.name ? truncate(s.name, 40) : truncate(s.firstMessage, 40) || \"(empty)\";\n\t\t\t\t\treturn `${i + 1}) ${label}${marker} · ${formatRelativeTime(s.modified)} · ${s.messageCount} msgs`;\n\t\t\t\t});\n\t\t\t\tawait ctx.reply([`Sessions for ${cwd}`, ...lines, \"Use /sessions <n> or /sessions <id-prefix>\"].join(\"\\n\"));\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tlet path: string | undefined;\n\t\tconst numeric = Number.parseInt(arg, 10);\n\t\tconst cached = getCachedSessions(ctx.key);\n\t\tif (!Number.isNaN(numeric) && /^\\d+$/.test(arg)) {\n\t\t\tif (!cached || numeric < 1 || numeric > cached.length) {\n\t\t\t\tawait ctx.reply(\"Invalid selection — run /sessions to see the current list.\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tpath = cached[numeric - 1].path;\n\t\t} else {\n\t\t\tconst pool = cached ?? (await SessionManager.list(cwd));\n\t\t\tconst matches = pool.filter((s) => s.id.startsWith(arg) || s.path.startsWith(arg));\n\t\t\tif (matches.length === 0) {\n\t\t\t\tawait ctx.reply(`No session matches \"${arg}\".`);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (matches.length > 1) {\n\t\t\t\tawait ctx.reply(`Multiple sessions match \"${arg}\" — use a longer prefix.`);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tpath = matches[0].path;\n\t\t}\n\n\t\tif (!path) {\n\t\t\tawait ctx.reply(\"No session selected.\");\n\t\t\treturn;\n\t\t}\n\n\t\tawait ctx.bridge.switchSession(ctx.key, path);\n\t\tconst switched = await ctx.bridge.getSession(ctx.key);\n\t\tconst name = switched?.sessionManager?.getSessionName() ?? \"unnamed\";\n\t\tconst count = switched?.sessionManager?.getEntries().length ?? 0;\n\t\tawait ctx.reply(`Switched to \"${name}\" (${count} msgs). History continues here.`);\n\t},\n};\n\nconst titleCommand: ChatCommand = {\n\tname: \"title\",\n\taliases: [\"name\"],\n\tdescription: \"name the current session\",\n\tbypassBusy: true,\n\tneedsSession: true,\n\tasync handler(ctx) {\n\t\tconst session = ctx.session!;\n\t\tconst name = ctx.args.trim();\n\t\tif (!name) {\n\t\t\tconst current = session.sessionManager?.getSessionName();\n\t\t\tawait ctx.reply(current ? `Session title: ${current}` : \"(unnamed)\");\n\t\t\treturn;\n\t\t}\n\t\tsession.setSessionName(name);\n\t\tconst readBack = session.sessionManager?.getSessionName() ?? name;\n\t\tawait ctx.reply(`Session titled \"${readBack}\".`);\n\t},\n};\n\nconst contextCommand: ChatCommand = {\n\tname: \"context\",\n\tdescription: \"estimated context window breakdown\",\n\tbypassBusy: true,\n\tneedsSession: true,\n\tasync handler(ctx) {\n\t\tconst session = ctx.session!;\n\t\tconst model = session.model;\n\t\tif (!model) {\n\t\t\tawait ctx.reply(\"No model selected.\");\n\t\t\treturn;\n\t\t}\n\t\tconst contextWindow = model.contextWindow ?? 0;\n\t\tif (contextWindow <= 0) {\n\t\t\tawait ctx.reply(\"Context window unknown for this model.\");\n\t\t\treturn;\n\t\t}\n\n\t\tconst tools: ToolDefinition[] = session\n\t\t\t.getActiveToolNames()\n\t\t\t.map((name) => session.getToolDefinition(name))\n\t\t\t.filter((d): d is ToolDefinition => d !== undefined);\n\n\t\tconst breakdown = computeContextBreakdown({\n\t\t\tsystemPrompt: session.systemPrompt,\n\t\t\ttools,\n\t\t\tmessages: session.messages,\n\t\t\tcontextWindow,\n\t\t});\n\n\t\tconst usage = session.getContextUsage();\n\t\tconst tokens = usage?.tokens ?? breakdown.total;\n\t\tconst percent = usage?.percent ?? (contextWindow > 0 ? (tokens / contextWindow) * 100 : 0);\n\n\t\tconst messageTokens =\n\t\t\tbreakdown.user +\n\t\t\tbreakdown.assistantText +\n\t\t\tbreakdown.thinking +\n\t\t\tbreakdown.toolCalls +\n\t\t\tbreakdown.toolResults +\n\t\t\tbreakdown.summaries;\n\n\t\tconst stats = session.getSessionStats();\n\t\tawait ctx.reply(\n\t\t\t[\n\t\t\t\t`Context: ${tokens.toLocaleString(\"en-US\")} / ${contextWindow.toLocaleString(\"en-US\")} tokens (${Math.round(percent)}%)`,\n\t\t\t\t` system ${breakdown.systemPrompt.toLocaleString(\"en-US\")} · tools ${breakdown.toolDefinitions.toLocaleString(\"en-US\")} · messages ${messageTokens.toLocaleString(\"en-US\")}`,\n\t\t\t\t`Session: ${stats.totalMessages} messages · ${stats.userMessages} turns · model ${model.provider}/${model.id}`,\n\t\t\t].join(\"\\n\"),\n\t\t);\n\t},\n};\n\nconst compactCommand: ChatCommand = {\n\tname: \"compact\",\n\tdescription: \"summarize and compress session context\",\n\tbypassBusy: true,\n\tneedsSession: true,\n\tasync handler(ctx) {\n\t\tconst session = ctx.session!;\n\t\tconst instructions = ctx.args.trim() || undefined;\n\t\ttry {\n\t\t\tconst result = await session.compact(instructions);\n\t\t\tconst before = result.tokensBefore.toLocaleString(\"en-US\");\n\t\t\tconst after =\n\t\t\t\tresult.estimatedTokensAfter !== undefined\n\t\t\t\t\t? `~${result.estimatedTokensAfter.toLocaleString(\"en-US\")}`\n\t\t\t\t\t: \"~?\";\n\t\t\tawait ctx.reply(`Compacted: ${before} → ${after} tokens.`);\n\t\t} catch (error) {\n\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\tif (\n\t\t\t\tmessage.includes(\"Nothing to compact\") ||\n\t\t\t\tmessage.includes(\"Already compacted\") ||\n\t\t\t\tmessage.includes(\"No model selected\")\n\t\t\t) {\n\t\t\t\tawait ctx.reply(message);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t},\n};\n\nconst thinkingCommand: ChatCommand = {\n\tname: \"thinking\",\n\taliases: [\"effort\", \"reasoning\"],\n\tdescription: \"get or set the thinking level\",\n\tbypassBusy: false,\n\tneedsSession: true,\n\tasync handler(ctx) {\n\t\tconst session = ctx.session!;\n\t\tconst levels = session.getAvailableThinkingLevels();\n\t\tif (!session.supportsThinking()) {\n\t\t\tawait ctx.reply(\n\t\t\t\t`Model ${session.model?.provider ?? \"none\"}/${session.model?.id ?? \"none\"} doesn't support thinking.`,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\tconst arg = ctx.args.trim().toLowerCase() as ThinkingLevel;\n\t\tif (!arg) {\n\t\t\tconst current = session.thinkingLevel;\n\t\t\tconst items: PickerItem[] = levels.map((level) => ({\n\t\t\t\tlabel: `${level === current ? \"✓ \" : \"\"}${level}`,\n\t\t\t\tvalue: level,\n\t\t\t}));\n\t\t\tconst result = await createPicker(\n\t\t\t\tctx.adapter,\n\t\t\t\tctx.event.source,\n\t\t\t\t{\n\t\t\t\t\tkind: \"thinking\",\n\t\t\t\t\tsessionKey: ctx.key,\n\t\t\t\t\tinvokerId: ctx.event.source.userId,\n\t\t\t\t\titems,\n\t\t\t\t\tperPage: levels.length,\n\t\t\t\t\ttitle: \"Pick a thinking level\",\n\t\t\t\t\tasync resolve(item) {\n\t\t\t\t\t\tconst level = item.value as ThinkingLevel;\n\t\t\t\t\t\tsession.setThinkingLevel(level);\n\t\t\t\t\t\treturn { done: true, text: `Thinking → ${level}` };\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{ replyTo: ctx.event.messageId, threadId: ctx.event.source.threadId },\n\t\t\t);\n\t\t\tif (!result.success) {\n\t\t\t\tawait ctx.reply(`Level: ${current} — available: ${levels.join(\", \")}`);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (!levels.includes(arg)) {\n\t\t\tawait ctx.reply(`Invalid level. Available: ${levels.join(\", \")}`);\n\t\t\treturn;\n\t\t}\n\t\tsession.setThinkingLevel(arg);\n\t\tawait ctx.reply(`Thinking → ${arg}`);\n\t},\n};\n\nexport const CHAT_COMMANDS: ChatCommand[] = [\n\tnewCommand,\n\tundoCommand,\n\tredoCommand,\n\tstopCommand,\n\tstatusCommand,\n\twhoamiCommand,\n\thelpCommand,\n\tmodelCommand,\n\tsessionsCommand,\n\ttitleCommand,\n\tcontextCommand,\n\tcompactCommand,\n\tthinkingCommand,\n];\n\n/** Platform menu specs (e.g. Telegram setMyCommands): canonical names only, aliases skipped. */\nexport function botCommandSpecs(): { name: string; description: string }[] {\n\treturn [\n\t\t...new Map(\n\t\t\t[\n\t\t\t\t{ name: \"start\", description: \"Check gateway readiness\" },\n\t\t\t\t...CHAT_COMMANDS,\n\t\t\t\t...MOBILE_COMMANDS,\n\t\t\t\t...FORWARDED_COMMANDS,\n\t\t\t].map((c) => [c.name, { name: c.name, description: c.description }]),\n\t\t).values(),\n\t];\n}\n\nexport function formatHelpText(): string {\n\tconst lines = [\"lunR gateway commands:\", \"/start — check gateway readiness\"];\n\tfor (const cmd of CHAT_COMMANDS) {\n\t\tconst names = [cmd.name, ...(cmd.aliases ?? [])].map((a) => `/${a}`).join(\" | \");\n\t\tlines.push(`${names} — ${cmd.description}`);\n\t}\n\tfor (const cmd of botCommandSpecs()) {\n\t\tif (!CHAT_COMMANDS.some((c) => c.name === cmd.name)) lines.push(`/${cmd.name} · ${cmd.description}`);\n\t}\n\tlines.push(\"\");\n\tlines.push(\"Tap to pick: /model, /thinking, /sessions (run without args to see buttons).\");\n\treturn lines.join(\"\\n\");\n}\n\n/**\n * Run a chat command with busy/session guards and error → \"⚠ one-line\".\n * Returns true when the event was consumed by the command, false when the\n * router should continue when a command mutates the event and wants a normal turn.\n */\nexport async function runChatCommand(cmd: ChatCommand, ctx: ChatCommandContext): Promise<boolean> {\n\tif (!cmd.bypassBusy && ctx.bridge.getStatus(ctx.key).busy) {\n\t\tawait ctx.reply(\"⏳ busy — /stop first or wait\");\n\t\treturn true;\n\t}\n\tif (cmd.needsSession) {\n\t\tconst session = await ctx.bridge.getSession(ctx.key, cmd.name === \"model\");\n\t\tif (!session) {\n\t\t\tawait ctx.reply(\"No session yet. Select an approved project with /project first.\");\n\t\t\treturn true;\n\t\t}\n\t\tctx.session = session;\n\t}\n\ttry {\n\t\tconst settingsManager = ctx.session?.settingsManager;\n\t\tconst consumed = settingsManager\n\t\t\t? await runtimeScope.run(\n\t\t\t\t\t{ settingsManager, modelRuntime: ctx.session?.modelRuntime, thinking: () => ctx.session!.thinkingLevel },\n\t\t\t\t\t() => cmd.handler(ctx),\n\t\t\t\t)\n\t\t\t: await cmd.handler(ctx);\n\t\treturn consumed ?? true;\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tawait ctx.adapter.send(ctx.event.source.chatId, `⚠ ${oneLine(message)}`, {\n\t\t\treplyTo: ctx.event.messageId,\n\t\t\tthreadId: ctx.event.source.threadId,\n\t\t});\n\t\treturn true;\n\t}\n}\n\n/** Reply helper used by the router to build the ChatCommandContext. */\nexport async function sendCommandReply(adapter: PlatformAdapter, event: MessageEvent, text: string): Promise<void> {\n\tawait adapter.send(event.source.chatId, prefixLines(text, \"\"), {\n\t\treplyTo: event.messageId,\n\t\tthreadId: event.source.threadId,\n\t});\n}\n"]}
1
+ {"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/gateway/commands.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * lunR: gateway chat command registry.\n *\n * Every command is a small headless handler over AgentSession. Router.ts keeps\n * platform gating/authorization and delegates to runChatCommand for busy/session\n * guards, error wrapping, and /help generation.\n */\n\nimport type { ThinkingLevel } from \"@ashx-j/lunr-agent\";\nimport type { Model } from \"@ashx-j/lunr-ai/compat\";\nimport { computeContextBreakdown } from \"../core/context-breakdown.ts\";\nimport type { ToolDefinition } from \"../core/extensions/types.ts\";\nimport { findExactModelReferenceMatch } from \"../core/model-resolver.ts\";\nimport type { ModelRuntime } from \"../core/model-runtime.ts\";\nimport { runtimeScope } from \"../core/runtime-scope.ts\";\nimport type { SessionInfo } from \"../core/session-manager.ts\";\nimport { SessionManager } from \"../core/session-manager.ts\";\nimport type { BridgeSession } from \"./agent-bridge.ts\";\nimport { createPicker, gatewayPickerGeneration, type PickerItem } from \"./buttons.ts\";\nimport { defaultGatewayConfig, type GatewayConfig } from \"./config.ts\";\nimport { conversationBinding } from \"./conversations.ts\";\nimport { FORWARDED_COMMANDS, MOBILE_COMMANDS, resolveWithinRoots } from \"./mobile-commands.ts\";\nimport type { BridgeLike } from \"./router.ts\";\nimport type { MessageEvent, PlatformAdapter } from \"./types.ts\";\n\nconst MODEL_CACHE_TTL_MS = 5 * 60 * 1000;\nconst SESSIONS_CACHE_TTL_MS = 5 * 60 * 1000;\nconst MAX_MODEL_LIST_LINES = 15;\nconst PROVIDER_PER_PAGE = 10;\nconst _MODEL_PER_PAGE = 8;\nconst MAX_MODELS_PER_PROVIDER = 50;\nconst MODEL_ID_MAX = 38;\nconst MODEL_CACHE_CAP = 100;\nconst SESSIONS_CACHE_CAP = 100;\n\ninterface ModelCacheEntry {\n\tmodels: Model<any>[];\n\texpires: number;\n}\n\ninterface SessionsCacheEntry {\n\tsessions: SessionInfo[];\n\texpires: number;\n}\n\nconst modelCache = new Map<string, ModelCacheEntry>();\nconst sessionsCache = new Map<string, SessionsCacheEntry>();\n\nfunction evictLRU<K, V>(map: Map<K, V>, cap: number): void {\n\twhile (map.size > cap) {\n\t\tconst first = map.keys().next().value;\n\t\tif (first !== undefined) map.delete(first);\n\t}\n}\n\nfunction getCachedModels(key: string): Model<any>[] | undefined {\n\tconst cached = modelCache.get(key);\n\tif (!cached) return undefined;\n\tif (Date.now() > cached.expires) {\n\t\tmodelCache.delete(key);\n\t\treturn undefined;\n\t}\n\t// LRU refresh.\n\tmodelCache.delete(key);\n\tmodelCache.set(key, cached);\n\treturn cached.models;\n}\n\nfunction setCachedModels(key: string, models: Model<any>[]): void {\n\tmodelCache.set(key, { models, expires: Date.now() + MODEL_CACHE_TTL_MS });\n\tevictLRU(modelCache, MODEL_CACHE_CAP);\n}\n\nfunction getCachedSessions(key: string): SessionInfo[] | undefined {\n\tconst cached = sessionsCache.get(key);\n\tif (!cached) return undefined;\n\tif (Date.now() > cached.expires) {\n\t\tsessionsCache.delete(key);\n\t\treturn undefined;\n\t}\n\tsessionsCache.delete(key);\n\tsessionsCache.set(key, cached);\n\treturn cached.sessions;\n}\n\nfunction setCachedSessions(key: string, sessions: SessionInfo[]): void {\n\tsessionsCache.set(key, { sessions, expires: Date.now() + SESSIONS_CACHE_TTL_MS });\n\tevictLRU(sessionsCache, SESSIONS_CACHE_CAP);\n}\n\nexport interface ChatCommandContext {\n\tevent: MessageEvent;\n\tkey: string;\n\tadapter: PlatformAdapter;\n\tbridge: BridgeLike;\n\tcfg?: GatewayConfig;\n\tsession?: BridgeSession;\n\tpickerGeneration?: number;\n\treply(text: string): Promise<void>;\n\targs: string;\n}\n\nexport interface ChatCommand {\n\tname: string;\n\taliases?: string[];\n\tdescription: string;\n\tbypassBusy: boolean;\n\tneedsSession: boolean;\n\t// biome-ignore lint/suspicious/noConfusingVoidType: handlers may return nothing; runChatCommand treats undefined as consumed.\n\thandler(ctx: ChatCommandContext): Promise<boolean | void>;\n}\n\nfunction oneLine(text: string): string {\n\treturn text.replace(/\\s+/g, \" \").trim().slice(0, 200);\n}\n\nfunction prefixLines(text: string, prefix: string): string {\n\treturn text\n\t\t.split(\"\\n\")\n\t\t.map((line, index) => (index === 0 ? prefix : \" \") + line)\n\t\t.join(\"\\n\");\n}\n\nfunction truncate(text: string, max: number): string {\n\tif (text.length <= max) return text;\n\treturn `${text.slice(0, max - 1)}…`;\n}\n\nfunction formatRelativeTime(date: Date): string {\n\tconst seconds = Math.max(0, Math.floor((Date.now() - date.getTime()) / 1000));\n\tif (seconds < 60) return `${seconds}s ago`;\n\tconst minutes = Math.floor(seconds / 60);\n\tif (minutes < 60) return `${minutes}m ago`;\n\tconst hours = Math.floor(minutes / 60);\n\tif (hours < 24) return `${hours}h ago`;\n\tconst days = Math.floor(hours / 24);\n\treturn `${days}d ago`;\n}\n\nfunction formatModelList(models: Model<any>[], maxLines = MAX_MODEL_LIST_LINES): string[] {\n\tif (models.length === 0) return [\"No models available.\"];\n\tconst byProvider = new Map<string, Model<any>[]>();\n\tfor (const model of models) {\n\t\tconst list = byProvider.get(model.provider) ?? [];\n\t\tlist.push(model);\n\t\tbyProvider.set(model.provider, list);\n\t}\n\tconst providers = [...byProvider.keys()].sort();\n\tconst lines: string[] = [];\n\tlet index = 1;\n\tfor (const provider of providers) {\n\t\tconst list = (byProvider.get(provider) ?? []).sort((a, b) => a.id.localeCompare(b.id));\n\t\tfor (const model of list) {\n\t\t\tlines.push(`${index}) ${provider}/${model.id}`);\n\t\t\tindex++;\n\t\t}\n\t}\n\tif (lines.length <= maxLines) return lines;\n\treturn [\n\t\t`${models.length} models across ${providers.length} providers.`,\n\t\t\"Use /model <provider/id> or /model <query>.\",\n\t\t...providers.map((p) => `- ${p}`),\n\t];\n}\n\nfunction groupModelsByProvider(models: Model<any>[]): Map<string, Model<any>[]> {\n\tconst byProvider = new Map<string, Model<any>[]>();\n\tfor (const model of models) {\n\t\tconst list = byProvider.get(model.provider) ?? [];\n\t\tlist.push(model);\n\t\tbyProvider.set(model.provider, list);\n\t}\n\tfor (const list of byProvider.values()) {\n\t\tlist.sort((a, b) => a.id.localeCompare(b.id));\n\t}\n\treturn byProvider;\n}\n\nfunction truncateModelId(id: string): string {\n\tconst lastSlash = id.lastIndexOf(\"/\");\n\tconst name = lastSlash >= 0 ? id.slice(lastSlash + 1) : id;\n\treturn truncate(name, MODEL_ID_MAX);\n}\n\nasync function refreshAndCacheModels(session: BridgeSession, key: string): Promise<Model<any>[]> {\n\tconst runtime: ModelRuntime = session.modelRuntime;\n\tawait runtime.refresh();\n\tconst models = [...(await runtime.getAvailable())].sort(\n\t\t(a, b) => a.provider.localeCompare(b.provider) || a.id.localeCompare(b.id),\n\t);\n\tsetCachedModels(key, models);\n\treturn models;\n}\n\nasync function setModelAndReply(ctx: ChatCommandContext, model: Model<any>): Promise<void> {\n\tconst session = ctx.session!;\n\ttry {\n\t\tawait session.setModel(model);\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tif (message.includes(\"No API key\")) {\n\t\t\tawait ctx.reply(`No API key for ${model.provider}.`);\n\t\t\treturn;\n\t\t}\n\t\tthrow error;\n\t}\n\tawait ctx.reply(`Model → ${model.provider}/${model.id} (thinking level re-clamped to ${session.thinkingLevel})`);\n}\n\nconst newCommand: ChatCommand = {\n\tname: \"new\",\n\taliases: [\"reset\"],\n\tdescription: \"start a fresh session for this chat\",\n\t// lunr: busy-session /new must bypass the guard (same as /stop).\n\tbypassBusy: true,\n\tneedsSession: false,\n\tasync handler(ctx) {\n\t\tawait ctx.bridge.reset(ctx.key);\n\t\tconst cfg = ctx.cfg ?? defaultGatewayConfig();\n\t\tlet ready = Boolean(conversationBinding(ctx.key)?.cwd);\n\t\tif (!ready && cfg.defaultProject) {\n\t\t\ttry {\n\t\t\t\tresolveWithinRoots(cfg.defaultProject, cfg.projectRoots ?? []);\n\t\t\t\tready = true;\n\t\t\t} catch {}\n\t\t}\n\t\tawait ctx.reply(\n\t\t\tready\n\t\t\t\t? \"Session reset. Send a message to start fresh in the approved project.\"\n\t\t\t\t: \"Session reset. Use /project to choose an approved project before sending a message.\",\n\t\t);\n\t},\n};\n\nconst undoCommand: ChatCommand = {\n\tname: \"undo\",\n\tdescription: \"rewind the session tree before the last user turn\",\n\tbypassBusy: false,\n\tneedsSession: true,\n\tasync handler(ctx) {\n\t\tconst { userText } = await ctx.bridge.undo(ctx.key);\n\t\tconst text = userText ? ` \"${truncate(userText, 60)}\"` : \"\";\n\t\tawait ctx.reply(`Undone — rewound before${text}. /redo to restore.`);\n\t},\n};\n\nconst redoCommand: ChatCommand = {\n\tname: \"redo\",\n\tdescription: \"restore the last undone turn\",\n\tbypassBusy: false,\n\tneedsSession: true,\n\tasync handler(ctx) {\n\t\tawait ctx.bridge.redo(ctx.key);\n\t\tawait ctx.reply(\"Redone.\");\n\t},\n};\n\nconst stopCommand: ChatCommand = {\n\tname: \"stop\",\n\tdescription: \"abort the running turn\",\n\tbypassBusy: true,\n\tneedsSession: false,\n\tasync handler(ctx) {\n\t\tawait ctx.bridge.abort(ctx.key);\n\t\tawait ctx.reply(\"Stopped.\");\n\t},\n};\n\nconst statusCommand: ChatCommand = {\n\tname: \"status\",\n\tdescription: \"session status\",\n\tbypassBusy: true,\n\tneedsSession: false,\n\tasync handler(ctx) {\n\t\tconst status = ctx.bridge.getStatus(ctx.key);\n\t\tconst age = status.createdAt\n\t\t\t? `${Math.max(0, Math.round((Date.now() - Date.parse(status.createdAt)) / 1000))}s`\n\t\t\t: \"no session yet\";\n\t\tawait ctx.reply(\n\t\t\t`${ctx.event.source.platform} · session age ${age} · ${status.busy ? \"busy\" : \"idle\"} · queue ${status.queueDepth}\\nProject: ${conversationBinding(ctx.key)?.cwd ?? \"not selected\"}`,\n\t\t);\n\t},\n};\n\nconst whoamiCommand: ChatCommand = {\n\tname: \"whoami\",\n\tdescription: \"your ids and session key\",\n\tbypassBusy: true,\n\tneedsSession: false,\n\tasync handler(ctx) {\n\t\tconst { userId, chatId } = ctx.event.source;\n\t\tawait ctx.reply(`userId: ${userId}\\nchatId: ${chatId}\\nkey: ${ctx.key}`);\n\t},\n};\n\nconst helpCommand: ChatCommand = {\n\tname: \"help\",\n\tdescription: \"this message\",\n\tbypassBusy: true,\n\tneedsSession: false,\n\tasync handler(ctx) {\n\t\tawait ctx.reply(formatHelpText());\n\t},\n};\n\nconst modelCommand: ChatCommand = {\n\tname: \"model\",\n\tdescription: \"list or switch models\",\n\tbypassBusy: false,\n\tneedsSession: true,\n\tasync handler(ctx) {\n\t\tconst session = ctx.session!;\n\t\tconst arg = ctx.args.trim();\n\t\tif (!arg) {\n\t\t\tconst cached = getCachedModels(ctx.key);\n\t\t\tconst models = cached ?? (await refreshAndCacheModels(session, ctx.key));\n\t\t\tconst byProvider = groupModelsByProvider(models);\n\t\t\tconst current = session.model;\n\t\t\tconst currentRef = current ? `${current.provider}/${current.id}` : \"\";\n\t\t\tconst providers = [...byProvider.keys()].sort();\n\t\t\tconst providerItems: PickerItem[] = providers.map((provider) => ({\n\t\t\t\tlabel: `${current?.provider === provider ? \"✓ \" : \"\"}${provider} (${byProvider.get(provider)?.length ?? 0})`,\n\t\t\t\tvalue: provider,\n\t\t\t}));\n\n\t\t\tconst pickerOpts = {\n\t\t\t\treplyTo: ctx.event.messageId,\n\t\t\t\tthreadId: ctx.event.source.threadId,\n\t\t\t};\n\t\t\tconst result = await createPicker(\n\t\t\t\tctx.adapter,\n\t\t\t\tctx.event.source,\n\t\t\t\t{\n\t\t\t\t\tkind: \"model\",\n\t\t\t\t\tsessionKey: ctx.key,\n\t\t\t\t\tgeneration: ctx.pickerGeneration,\n\t\t\t\t\tinvokerId: ctx.event.source.userId,\n\t\t\t\t\titems: providerItems,\n\t\t\t\t\tperPage: PROVIDER_PER_PAGE,\n\t\t\t\t\ttitle: \"Pick a model provider\",\n\t\t\t\t\tasync resolve(item) {\n\t\t\t\t\t\tif (item.value === \"__back__\") {\n\t\t\t\t\t\t\treturn { done: false, items: providerItems, title: \"Pick a model provider\" };\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!item.value.includes(\"/\")) {\n\t\t\t\t\t\t\tconst provider = item.value;\n\t\t\t\t\t\t\tconst list = byProvider.get(provider) ?? [];\n\t\t\t\t\t\t\tconst capped = list.slice(0, MAX_MODELS_PER_PROVIDER);\n\t\t\t\t\t\t\tconst note =\n\t\t\t\t\t\t\t\tlist.length > MAX_MODELS_PER_PROVIDER\n\t\t\t\t\t\t\t\t\t? ` — ${list.length - MAX_MODELS_PER_PROVIDER} more available`\n\t\t\t\t\t\t\t\t\t: \"\";\n\t\t\t\t\t\t\tconst modelItems: PickerItem[] = [];\n\t\t\t\t\t\t\tfor (const m of capped) {\n\t\t\t\t\t\t\t\tconst ref = `${provider}/${m.id}`;\n\t\t\t\t\t\t\t\tmodelItems.push({\n\t\t\t\t\t\t\t\t\tlabel: `${currentRef === ref ? \"✓ \" : \"\"}${truncateModelId(m.id)}`,\n\t\t\t\t\t\t\t\t\tvalue: ref,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tmodelItems.unshift({ label: \"◀ Back\", value: \"__back__\" });\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tdone: false,\n\t\t\t\t\t\t\t\titems: modelItems,\n\t\t\t\t\t\t\t\ttitle: `${provider} (${list.length})${note}`,\n\t\t\t\t\t\t\t\tbreadcrumbs: provider,\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst exact = findExactModelReferenceMatch(item.value, models);\n\t\t\t\t\t\tif (!exact) {\n\t\t\t\t\t\t\treturn { done: true, text: \"That model is no longer available.\" };\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tawait session.setModel(exact);\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\t\t\t\t\tif (message.includes(\"No API key\")) {\n\t\t\t\t\t\t\t\treturn { done: true, text: `No API key for ${exact.provider}.` };\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tthrow error;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tdone: true,\n\t\t\t\t\t\t\ttext: `Model → ${exact.provider}/${exact.id} (thinking level re-clamped to ${session.thinkingLevel})`,\n\t\t\t\t\t\t};\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tpickerOpts,\n\t\t\t);\n\t\t\tif (!result.success && ctx.pickerGeneration === gatewayPickerGeneration(ctx.key)) {\n\t\t\t\tconst currentText = `${current?.provider ?? \"none\"}/${current?.id ?? \"none\"}`;\n\t\t\t\tconst lines = formatModelList(models);\n\t\t\t\tawait ctx.reply([`Current: ${currentText}`, ...lines, \"Use /model <n> or /model <provider/id>\"].join(\"\\n\"));\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tconst numeric = Number.parseInt(arg, 10);\n\t\tif (!Number.isNaN(numeric) && /^\\d+$/.test(arg)) {\n\t\t\tconst cached = getCachedModels(ctx.key);\n\t\t\tif (!cached || numeric < 1 || numeric > cached.length) {\n\t\t\t\tawait ctx.reply(\"Invalid selection — run /model to see the current list.\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait setModelAndReply(ctx, cached[numeric - 1]);\n\t\t\treturn;\n\t\t}\n\n\t\tconst models = getCachedModels(ctx.key) ?? (await refreshAndCacheModels(session, ctx.key));\n\t\tconst exact = findExactModelReferenceMatch(arg, models);\n\t\tif (exact) {\n\t\t\tawait setModelAndReply(ctx, exact);\n\t\t\treturn;\n\t\t}\n\n\t\tconst query = arg.toLowerCase();\n\t\tconst matches = models.filter(\n\t\t\t(m) =>\n\t\t\t\tm.id.toLowerCase().includes(query) ||\n\t\t\t\t`${m.provider}/${m.id}`.toLowerCase().includes(query) ||\n\t\t\t\t(m.name?.toLowerCase().includes(query) ?? false),\n\t\t);\n\t\tif (matches.length === 0) {\n\t\t\tawait ctx.reply(`No model matches \"${arg}\".`);\n\t\t\treturn;\n\t\t}\n\t\tif (matches.length > 1) {\n\t\t\tawait ctx.reply(formatModelList(matches).join(\"\\n\"));\n\t\t\treturn;\n\t\t}\n\t\tawait setModelAndReply(ctx, matches[0]);\n\t},\n};\n\nconst sessionsCommand: ChatCommand = {\n\tname: \"sessions\",\n\tdescription: \"list or switch sessions\",\n\tbypassBusy: false,\n\tneedsSession: true,\n\tasync handler(ctx) {\n\t\tconst session = ctx.session!;\n\t\tconst arg = ctx.args.trim();\n\t\tconst currentFile = session.sessionManager?.getSessionFile();\n\t\tconst cwd = session.sessionManager?.getCwd() ?? conversationBinding(ctx.key)?.cwd;\n\t\tif (!cwd) throw new Error(\"Select a project before listing sessions.\");\n\n\t\tif (!arg) {\n\t\t\tconst all = await SessionManager.list(cwd);\n\t\t\tall.sort((a, b) => b.modified.getTime() - a.modified.getTime());\n\t\t\tconst sessions = all.slice(0, 10);\n\t\t\tsetCachedSessions(ctx.key, sessions);\n\t\t\tconst items: PickerItem[] = sessions.map((s) => ({\n\t\t\t\tlabel: `${s.path === currentFile ? \"(current) \" : \"\"}${s.name ? truncate(s.name, 30) : truncate(s.firstMessage, 30) || \"(empty)\"}`,\n\t\t\t\tvalue: s.path,\n\t\t\t}));\n\t\t\tconst result = await createPicker(\n\t\t\t\tctx.adapter,\n\t\t\t\tctx.event.source,\n\t\t\t\t{\n\t\t\t\t\tkind: \"sessions\",\n\t\t\t\t\tsessionKey: ctx.key,\n\t\t\t\t\tgeneration: ctx.pickerGeneration,\n\t\t\t\t\tinvokerId: ctx.event.source.userId,\n\t\t\t\t\titems,\n\t\t\t\t\tperPage: 8,\n\t\t\t\t\ttitle: \"Pick a session\",\n\t\t\t\t\tasync resolve(item) {\n\t\t\t\t\t\tawait ctx.bridge.switchSession(ctx.key, item.value);\n\t\t\t\t\t\tconst switched = await ctx.bridge.getSession(ctx.key);\n\t\t\t\t\t\tconst name = switched?.sessionManager?.getSessionName() ?? \"unnamed\";\n\t\t\t\t\t\tconst count = switched?.sessionManager?.getEntries().length ?? 0;\n\t\t\t\t\t\treturn { done: true, text: `Switched to \"${name}\" (${count} msgs). History continues here.` };\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{ replyTo: ctx.event.messageId, threadId: ctx.event.source.threadId },\n\t\t\t);\n\t\t\tif (!result.success && ctx.pickerGeneration === gatewayPickerGeneration(ctx.key)) {\n\t\t\t\tconst lines = sessions.map((s, i) => {\n\t\t\t\t\tconst marker = s.path === currentFile ? \" (current)\" : \"\";\n\t\t\t\t\tconst label = s.name ? truncate(s.name, 40) : truncate(s.firstMessage, 40) || \"(empty)\";\n\t\t\t\t\treturn `${i + 1}) ${label}${marker} · ${formatRelativeTime(s.modified)} · ${s.messageCount} msgs`;\n\t\t\t\t});\n\t\t\t\tawait ctx.reply([`Sessions for ${cwd}`, ...lines, \"Use /sessions <n> or /sessions <id-prefix>\"].join(\"\\n\"));\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tlet path: string | undefined;\n\t\tconst numeric = Number.parseInt(arg, 10);\n\t\tconst cached = getCachedSessions(ctx.key);\n\t\tif (!Number.isNaN(numeric) && /^\\d+$/.test(arg)) {\n\t\t\tif (!cached || numeric < 1 || numeric > cached.length) {\n\t\t\t\tawait ctx.reply(\"Invalid selection — run /sessions to see the current list.\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tpath = cached[numeric - 1].path;\n\t\t} else {\n\t\t\tconst pool = cached ?? (await SessionManager.list(cwd));\n\t\t\tconst matches = pool.filter((s) => s.id.startsWith(arg) || s.path.startsWith(arg));\n\t\t\tif (matches.length === 0) {\n\t\t\t\tawait ctx.reply(`No session matches \"${arg}\".`);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (matches.length > 1) {\n\t\t\t\tawait ctx.reply(`Multiple sessions match \"${arg}\" — use a longer prefix.`);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tpath = matches[0].path;\n\t\t}\n\n\t\tif (!path) {\n\t\t\tawait ctx.reply(\"No session selected.\");\n\t\t\treturn;\n\t\t}\n\n\t\tawait ctx.bridge.switchSession(ctx.key, path);\n\t\tconst switched = await ctx.bridge.getSession(ctx.key);\n\t\tconst name = switched?.sessionManager?.getSessionName() ?? \"unnamed\";\n\t\tconst count = switched?.sessionManager?.getEntries().length ?? 0;\n\t\tawait ctx.reply(`Switched to \"${name}\" (${count} msgs). History continues here.`);\n\t},\n};\n\nconst titleCommand: ChatCommand = {\n\tname: \"title\",\n\taliases: [\"name\"],\n\tdescription: \"name the current session\",\n\tbypassBusy: true,\n\tneedsSession: true,\n\tasync handler(ctx) {\n\t\tconst session = ctx.session!;\n\t\tconst name = ctx.args.trim();\n\t\tif (!name) {\n\t\t\tconst current = session.sessionManager?.getSessionName();\n\t\t\tawait ctx.reply(current ? `Session title: ${current}` : \"(unnamed)\");\n\t\t\treturn;\n\t\t}\n\t\tsession.setSessionName(name);\n\t\tconst readBack = session.sessionManager?.getSessionName() ?? name;\n\t\tawait ctx.reply(`Session titled \"${readBack}\".`);\n\t},\n};\n\nconst contextCommand: ChatCommand = {\n\tname: \"context\",\n\tdescription: \"estimated context window breakdown\",\n\tbypassBusy: true,\n\tneedsSession: true,\n\tasync handler(ctx) {\n\t\tconst session = ctx.session!;\n\t\tconst model = session.model;\n\t\tif (!model) {\n\t\t\tawait ctx.reply(\"No model selected.\");\n\t\t\treturn;\n\t\t}\n\t\tconst contextWindow = model.contextWindow ?? 0;\n\t\tif (contextWindow <= 0) {\n\t\t\tawait ctx.reply(\"Context window unknown for this model.\");\n\t\t\treturn;\n\t\t}\n\n\t\tconst tools: ToolDefinition[] = session\n\t\t\t.getActiveToolNames()\n\t\t\t.map((name) => session.getToolDefinition(name))\n\t\t\t.filter((d): d is ToolDefinition => d !== undefined);\n\n\t\tconst breakdown = computeContextBreakdown({\n\t\t\tsystemPrompt: session.systemPrompt,\n\t\t\ttools,\n\t\t\tmessages: session.messages,\n\t\t\tcontextWindow,\n\t\t});\n\n\t\tconst usage = session.getContextUsage();\n\t\tconst tokens = usage?.tokens ?? breakdown.total;\n\t\tconst percent = usage?.percent ?? (contextWindow > 0 ? (tokens / contextWindow) * 100 : 0);\n\n\t\tconst messageTokens =\n\t\t\tbreakdown.user +\n\t\t\tbreakdown.assistantText +\n\t\t\tbreakdown.thinking +\n\t\t\tbreakdown.toolCalls +\n\t\t\tbreakdown.toolResults +\n\t\t\tbreakdown.summaries;\n\n\t\tconst stats = session.getSessionStats();\n\t\tawait ctx.reply(\n\t\t\t[\n\t\t\t\t`Context: ${tokens.toLocaleString(\"en-US\")} / ${contextWindow.toLocaleString(\"en-US\")} tokens (${Math.round(percent)}%)`,\n\t\t\t\t` system ${breakdown.systemPrompt.toLocaleString(\"en-US\")} · tools ${breakdown.toolDefinitions.toLocaleString(\"en-US\")} · messages ${messageTokens.toLocaleString(\"en-US\")}`,\n\t\t\t\t`Session: ${stats.totalMessages} messages · ${stats.userMessages} turns · model ${model.provider}/${model.id}`,\n\t\t\t].join(\"\\n\"),\n\t\t);\n\t},\n};\n\nconst compactCommand: ChatCommand = {\n\tname: \"compact\",\n\tdescription: \"summarize and compress session context\",\n\tbypassBusy: true,\n\tneedsSession: true,\n\tasync handler(ctx) {\n\t\tconst session = ctx.session!;\n\t\tconst instructions = ctx.args.trim() || undefined;\n\t\ttry {\n\t\t\tconst result = await session.compact(instructions);\n\t\t\tconst before = result.tokensBefore.toLocaleString(\"en-US\");\n\t\t\tconst after =\n\t\t\t\tresult.estimatedTokensAfter !== undefined\n\t\t\t\t\t? `~${result.estimatedTokensAfter.toLocaleString(\"en-US\")}`\n\t\t\t\t\t: \"~?\";\n\t\t\tawait ctx.reply(`Compacted: ${before} → ${after} tokens.`);\n\t\t} catch (error) {\n\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\tif (\n\t\t\t\tmessage.includes(\"Nothing to compact\") ||\n\t\t\t\tmessage.includes(\"Already compacted\") ||\n\t\t\t\tmessage.includes(\"No model selected\")\n\t\t\t) {\n\t\t\t\tawait ctx.reply(message);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t},\n};\n\nconst thinkingCommand: ChatCommand = {\n\tname: \"thinking\",\n\taliases: [\"effort\", \"reasoning\"],\n\tdescription: \"get or set the thinking level\",\n\tbypassBusy: false,\n\tneedsSession: true,\n\tasync handler(ctx) {\n\t\tconst session = ctx.session!;\n\t\tconst levels = session.getAvailableThinkingLevels();\n\t\tif (!session.supportsThinking()) {\n\t\t\tawait ctx.reply(\n\t\t\t\t`Model ${session.model?.provider ?? \"none\"}/${session.model?.id ?? \"none\"} doesn't support thinking.`,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\tconst arg = ctx.args.trim().toLowerCase() as ThinkingLevel;\n\t\tif (!arg) {\n\t\t\tconst current = session.thinkingLevel;\n\t\t\tconst items: PickerItem[] = levels.map((level) => ({\n\t\t\t\tlabel: `${level === current ? \"✓ \" : \"\"}${level}`,\n\t\t\t\tvalue: level,\n\t\t\t}));\n\t\t\tconst result = await createPicker(\n\t\t\t\tctx.adapter,\n\t\t\t\tctx.event.source,\n\t\t\t\t{\n\t\t\t\t\tkind: \"thinking\",\n\t\t\t\t\tsessionKey: ctx.key,\n\t\t\t\t\tgeneration: ctx.pickerGeneration,\n\t\t\t\t\tinvokerId: ctx.event.source.userId,\n\t\t\t\t\titems,\n\t\t\t\t\tperPage: levels.length,\n\t\t\t\t\ttitle: \"Pick a thinking level\",\n\t\t\t\t\tasync resolve(item) {\n\t\t\t\t\t\tconst level = item.value as ThinkingLevel;\n\t\t\t\t\t\tsession.setThinkingLevel(level);\n\t\t\t\t\t\treturn { done: true, text: `Thinking → ${level}` };\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{ replyTo: ctx.event.messageId, threadId: ctx.event.source.threadId },\n\t\t\t);\n\t\t\tif (!result.success && ctx.pickerGeneration === gatewayPickerGeneration(ctx.key)) {\n\t\t\t\tawait ctx.reply(`Level: ${current} — available: ${levels.join(\", \")}`);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (!levels.includes(arg)) {\n\t\t\tawait ctx.reply(`Invalid level. Available: ${levels.join(\", \")}`);\n\t\t\treturn;\n\t\t}\n\t\tsession.setThinkingLevel(arg);\n\t\tawait ctx.reply(`Thinking → ${arg}`);\n\t},\n};\n\nexport const CHAT_COMMANDS: ChatCommand[] = [\n\tnewCommand,\n\tundoCommand,\n\tredoCommand,\n\tstopCommand,\n\tstatusCommand,\n\twhoamiCommand,\n\thelpCommand,\n\tmodelCommand,\n\tsessionsCommand,\n\ttitleCommand,\n\tcontextCommand,\n\tcompactCommand,\n\tthinkingCommand,\n];\n\n/** Platform menu specs (e.g. Telegram setMyCommands): canonical names only, aliases skipped. */\nexport function botCommandSpecs(): { name: string; description: string }[] {\n\treturn [\n\t\t...new Map(\n\t\t\t[\n\t\t\t\t{ name: \"start\", description: \"Check gateway readiness\" },\n\t\t\t\t...CHAT_COMMANDS,\n\t\t\t\t...MOBILE_COMMANDS,\n\t\t\t\t...FORWARDED_COMMANDS,\n\t\t\t].map((c) => [c.name, { name: c.name, description: c.description }]),\n\t\t).values(),\n\t];\n}\n\nexport function formatHelpText(): string {\n\tconst lines = [\"lunR gateway commands:\", \"/start — check gateway readiness\"];\n\tfor (const cmd of CHAT_COMMANDS) {\n\t\tconst names = [cmd.name, ...(cmd.aliases ?? [])].map((a) => `/${a}`).join(\" | \");\n\t\tlines.push(`${names} — ${cmd.description}`);\n\t}\n\tfor (const cmd of botCommandSpecs()) {\n\t\tif (!CHAT_COMMANDS.some((c) => c.name === cmd.name)) lines.push(`/${cmd.name} · ${cmd.description}`);\n\t}\n\tlines.push(\"\");\n\tlines.push(\"Tap to pick: /model, /thinking, /sessions (run without args to see buttons).\");\n\treturn lines.join(\"\\n\");\n}\n\n/**\n * Run a chat command with busy/session guards and error → \"⚠ one-line\".\n * Returns true when the event was consumed by the command, false when the\n * router should continue when a command mutates the event and wants a normal turn.\n */\nexport async function runChatCommand(cmd: ChatCommand, ctx: ChatCommandContext): Promise<boolean> {\n\tctx.pickerGeneration ??= gatewayPickerGeneration(ctx.key);\n\tif (!cmd.bypassBusy && ctx.bridge.getStatus(ctx.key).busy) {\n\t\tawait ctx.reply(\"⏳ busy — /stop first or wait\");\n\t\treturn true;\n\t}\n\tif (cmd.needsSession) {\n\t\tconst session = await ctx.bridge.getSession(ctx.key, cmd.name === \"model\");\n\t\tif (!session) {\n\t\t\tawait ctx.reply(\"No session yet. Select an approved project with /project first.\");\n\t\t\treturn true;\n\t\t}\n\t\tctx.session = session;\n\t}\n\tif (ctx.pickerGeneration !== gatewayPickerGeneration(ctx.key)) return true;\n\ttry {\n\t\tconst settingsManager = ctx.session?.settingsManager;\n\t\tconst consumed = settingsManager\n\t\t\t? await runtimeScope.run(\n\t\t\t\t\t{ settingsManager, modelRuntime: ctx.session?.modelRuntime, thinking: () => ctx.session!.thinkingLevel },\n\t\t\t\t\t() => cmd.handler(ctx),\n\t\t\t\t)\n\t\t\t: await cmd.handler(ctx);\n\t\treturn consumed ?? true;\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tawait ctx.adapter.send(ctx.event.source.chatId, `⚠ ${oneLine(message)}`, {\n\t\t\treplyTo: ctx.event.messageId,\n\t\t\tthreadId: ctx.event.source.threadId,\n\t\t});\n\t\treturn true;\n\t}\n}\n\n/** Reply helper used by the router to build the ChatCommandContext. */\nexport async function sendCommandReply(adapter: PlatformAdapter, event: MessageEvent, text: string): Promise<void> {\n\tawait adapter.send(event.source.chatId, prefixLines(text, \"\"), {\n\t\treplyTo: event.messageId,\n\t\tthreadId: event.source.threadId,\n\t});\n}\n"]}
@@ -13,19 +13,17 @@
13
13
  * - deliverResult: replaces the `@lunr/cron-delivery` bridge on globalThis
14
14
  * with a platform deliverer. Targets come from job.deliver
15
15
  * (comma-separated): "local" (no-op — the output file is already written),
16
- * "origin" (the chat that created the job, homeChannel fallback), a bare
16
+ * "origin" (the identified, currently authorized requester chat), a bare
17
17
  * platform name (that platform's homeChannel), or
18
18
  * "<platform>:<chatId>[:<threadId>]" (explicit). Content is wrapped as
19
19
  * "Cron: <name>" and split to the adapter's maxMessageLength.
20
20
  *
21
- * The bridge is re-installed after every cron session creation because loading
22
- * the builtin extensions (lunr-cron) re-registers its local-notify bridge per
23
- * session; delivery re-reads the bridge on every call, matching lunr-cron.
21
+ * The compatibility delivery bridge exposes the platform deliverer. The scheduler
22
+ * retains its own callback so another session cannot redirect its output.
24
23
  *
25
- * Fallback models (2026-08-02): settings.json `cronFallbackModels`
26
- * ("provider/modelId" entries) are tried IN ORDER when a fire fails — timeout
27
- * or any error. Each attempt gets a fresh headless session and
28
- * jobTimeoutMs/candidates of the budget; a successful fallback run prefixes
24
+ * Fallback models: settings.json `cronFallbackModels`
25
+ * ("provider/modelId" entries) are tried in order only when session setup fails before prompt dispatch.
26
+ * An admitted failure may have external effects and is never replayed automatically; a successful fallback run prefixes
29
27
  * "[fell back to provider/modelId]" to the output. TUI fires are unaffected
30
28
  * (they use the live session's model).
31
29
  */
@@ -49,6 +47,9 @@ export interface GatewayCronOptions {
49
47
  sessionFactory?: CronSessionFactory;
50
48
  /** Test seam: fallback models. When omitted, read fresh from settings.json `cronFallbackModels` on every fire. */
51
49
  fallbackModels?: CronModelRef[];
50
+ /** Config seam; production always reloads current grants. */
51
+ getConfig?: () => GatewayConfig;
52
+ jobTimeoutMs?: number;
52
53
  }
53
54
  /** True when a resolved chat may receive cron output for this job. */
54
55
  export declare function isAllowedDeliverChat(cfg: GatewayConfig, platform: string, chatId: string, origin?: CronJobOrigin | null): boolean;
@@ -59,13 +60,13 @@ export declare function wrapCronContent(job: CronJob, content: string): string;
59
60
  * The platform deliverer installed at the `@lunr/cron-delivery` bridge.
60
61
  * Every target is attempted; the first error is returned (null on success).
61
62
  */
62
- export declare function createPlatformDeliverer(adapters: Map<string, PlatformAdapter>, cfg: GatewayConfig): DeliveryBridge;
63
+ export declare function createPlatformDeliverer(adapters: Map<string, PlatformAdapter>, config: GatewayConfig | (() => GatewayConfig)): DeliveryBridge;
63
64
  /**
64
65
  * Start the cron scheduler inside the gateway daemon. Starts even with zero
65
- * stored jobs — jobs can be created later from chats. stop() halts the loop.
66
+ * stored jobs — jobs can be created later from chats. stop() cancels admitted work, awaits session cleanup and releases the lease last.
66
67
  */
67
68
  export declare function startGatewayCron(options: GatewayCronOptions): {
68
- stop(): void;
69
+ stop(): Promise<void>;
69
70
  intervalMs: number;
70
71
  };
71
72
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"cron.d.ts","sourceRoot":"","sources":["../../src/gateway/cron.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAIH,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAInE,OAAO,EAAE,KAAK,aAAa,EAAyB,MAAM,mBAAmB,CAAC;AAC9E,OAAO,EAAE,KAAK,aAAa,EAAqB,MAAM,aAAa,CAAC;AAEpE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAIlD,KAAK,cAAc,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;AAEhF,qEAAqE;AACrE,MAAM,WAAW,YAAY;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,kBAAkB,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,aAAa,CAAC,EAAE,YAAY,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC;AAExG,MAAM,WAAW,kBAAkB;IAClC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACvC,GAAG,EAAE,aAAa,CAAC;IACnB,kCAAkC;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iFAAiF;IACjF,cAAc,CAAC,EAAE,kBAAkB,CAAC;IACpC,kHAAkH;IAClH,cAAc,CAAC,EAAE,YAAY,EAAE,CAAC;CAChC;AA2ID,sEAAsE;AACtE,wBAAgB,oBAAoB,CACnC,GAAG,EAAE,aAAa,EAClB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,aAAa,GAAG,IAAI,GAC3B,OAAO,CAMT;AAED,wBAAgB,sBAAsB,CACrC,GAAG,EAAE,aAAa,GAChB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,IAAI,KAAK,MAAM,GAAG,SAAS,CAuBxE;AAED,sDAAsD;AACtD,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAErE;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,EAAE,GAAG,EAAE,aAAa,GAAG,cAAc,CAyClH;AA8CD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,kBAAkB,GAAG;IAAE,IAAI,IAAI,IAAI,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CA0DlG","sourcesContent":["/**\n * lunR: gateway cron runner + delivery (Phase 4 of the cron/gateway roadmap).\n *\n * startGatewayCron() runs the core/cron scheduler inside the `lunr gateway`\n * daemon:\n *\n * - runJob: each fire gets a FRESH headless agent session (createAgentSession\n * with SessionManager.inMemory — cron runs never write session files and\n * never touch the per-chat gateway sessions; the files under\n * <agentDir>/cron/output/ are the audit trail). The shared fire-guard\n * (core/cron/fire-guard) brackets the turn so the `cron` tool refuses to\n * run inside it (jobs cannot schedule jobs).\n * - deliverResult: replaces the `@lunr/cron-delivery` bridge on globalThis\n * with a platform deliverer. Targets come from job.deliver\n * (comma-separated): \"local\" (no-op — the output file is already written),\n * \"origin\" (the chat that created the job, homeChannel fallback), a bare\n * platform name (that platform's homeChannel), or\n * \"<platform>:<chatId>[:<threadId>]\" (explicit). Content is wrapped as\n * \"Cron: <name>\" and split to the adapter's maxMessageLength.\n *\n * The bridge is re-installed after every cron session creation because loading\n * the builtin extensions (lunr-cron) re-registers its local-notify bridge per\n * session; delivery re-reads the bridge on every call, matching lunr-cron.\n *\n * Fallback models (2026-08-02): settings.json `cronFallbackModels`\n * (\"provider/modelId\" entries) are tried IN ORDER when a fire fails — timeout\n * or any error. Each attempt gets a fresh headless session and\n * jobTimeoutMs/candidates of the budget; a successful fallback run prefixes\n * \"[fell back to provider/modelId]\" to the output. TUI fires are unaffected\n * (they use the live session's model).\n */\n\nimport type { Model } from \"@ashx-j/lunr-ai\";\nimport { beginCronFire, endCronFire } from \"../core/cron/fire-guard.ts\";\nimport type { CronJob, CronJobOrigin } from \"../core/cron/jobs.ts\";\nimport { setCronDeliverValidator } from \"../core/cron/jobs.ts\";\nimport { startScheduler } from \"../core/cron/scheduler.ts\";\nimport { createPermissionContext, deletePermissionContext } from \"../core/permissions.ts\";\nimport { type BridgeSession, shutdownBridgeSession } from \"./agent-bridge.ts\";\nimport { type GatewayConfig, platformConfigFor } from \"./config.ts\";\nimport { splitMessage } from \"./text.ts\";\nimport type { PlatformAdapter } from \"./types.ts\";\n\nconst DELIVERY_BRIDGE_SYMBOL = Symbol.for(\"@lunr/cron-delivery\");\n\ntype DeliveryBridge = (job: CronJob, content: string) => Promise<string | null>;\n\n/** Test seam / default: one fresh headless session per cron fire. */\nexport interface CronModelRef {\n\tprovider: string;\n\tmodelId: string;\n}\n\nexport type CronSessionFactory = (job: CronJob, modelOverride?: CronModelRef) => Promise<BridgeSession>;\n\nexport interface GatewayCronOptions {\n\tadapters: Map<string, PlatformAdapter>;\n\tcfg: GatewayConfig;\n\t/** Tick interval; default 60s. */\n\tintervalMs?: number;\n\t/** Session factory for cron fires; defaults to a real headless agent session. */\n\tsessionFactory?: CronSessionFactory;\n\t/** Test seam: fallback models. When omitted, read fresh from settings.json `cronFallbackModels` on every fire. */\n\tfallbackModels?: CronModelRef[];\n}\n\nconst KNOWN_PLATFORMS = [\"telegram\", \"discord\"] as const;\n\n/** Default factory: fresh in-memory headless session, mirroring agent-bridge's wiring. */\nasync function defaultCronSessionFactory(job: CronJob, modelOverride?: CronModelRef): Promise<BridgeSession> {\n\tconst [\n\t\t{ loadAllBuiltinExtensions },\n\t\t{ getAgentDir },\n\t\t{ registerCustomizeBridge },\n\t\t{ registerMemoryCapBridge },\n\t\t{ registerModelTierBridge },\n\t\t{ createAgentSessionFromServices, createAgentSessionServices },\n\t\t{ SessionManager },\n\t\t{ SettingsManager },\n\t\t{ bindRuntimeBridges },\n\t] = await Promise.all([\n\t\timport(\"../builtin-extensions/index.ts\"),\n\t\timport(\"../config.ts\"),\n\t\timport(\"../core/customize.ts\"),\n\t\timport(\"../core/memory-cap.ts\"),\n\t\timport(\"../core/model-tiers.ts\"),\n\t\timport(\"../core/agent-session-services.ts\"),\n\t\timport(\"../core/session-manager.ts\"),\n\t\timport(\"../core/settings-manager.ts\"),\n\t\timport(\"../core/runtime-bridges.ts\"),\n\t]);\n\tconst cwd = job.workdir ?? process.cwd();\n\tconst agentDir = getAgentDir();\n\tconst settingsManager = SettingsManager.create(cwd, agentDir, { projectTrusted: false });\n\tregisterModelTierBridge(settingsManager);\n\tregisterMemoryCapBridge(settingsManager);\n\tregisterCustomizeBridge(settingsManager);\n\n\t// In-memory on purpose: cron runs must not persist session files or pollute\n\t// the per-chat gateway sessions — <agentDir>/cron/output/ is the audit trail.\n\tconst sessionManager = SessionManager.inMemory(cwd);\n\n\t// Services-first (mirrors main.ts): extension-registered providers (e.g.\n\t// ollama-cloud) must land in the shared ModelRuntime BEFORE session\n\t// creation — otherwise findInitialModel can't resolve the user's default\n\t// model and silently falls back to an arbitrary catalog provider.\n\tconst services = await createAgentSessionServices({\n\t\tcwd,\n\t\tagentDir,\n\t\tsettingsManager,\n\t\tresourceLoaderOptions: { extensionFactories: await loadAllBuiltinExtensions() },\n\t});\n\t// Fallback-model attempts pin the session model explicitly; an unresolvable\n\t// or unauthenticated override fails the attempt so the next fallback runs.\n\tlet model: Model<any> | undefined;\n\tif (modelOverride) {\n\t\tconst resolved = services.modelRuntime.getModel(modelOverride.provider, modelOverride.modelId);\n\t\tif (!resolved) throw new Error(`model not found: ${modelOverride.provider}/${modelOverride.modelId}`);\n\t\tif (!services.modelRuntime.hasConfiguredAuth(resolved.provider)) {\n\t\t\tthrow new Error(`no configured auth for provider: ${modelOverride.provider}`);\n\t\t}\n\t\tmodel = resolved;\n\t}\n\tconst { session } = await createAgentSessionFromServices({ services, sessionManager, model });\n\tconst permissionId = sessionManager.getSessionId();\n\tcreatePermissionContext(permissionId, settingsManager.getDefaultPermissionMode(), false);\n\tconst dispose = session.dispose.bind(session);\n\tsession.dispose = () => {\n\t\tdeletePermissionContext(permissionId);\n\t\tdispose();\n\t};\n\ttry {\n\t\tbindRuntimeBridges({ session, services });\n\t\tawait session.bindExtensions({\n\t\t\tmode: \"print\",\n\t\t\tonError: (err) => console.error(`[gateway cron] extension error (${err.extensionPath}): ${err.error}`),\n\t\t});\n\t\treturn session;\n\t} catch (error) {\n\t\tawait shutdownBridgeSession(session, \"quit\");\n\t\tthrow error;\n\t}\n}\n\n/** Final assistant text, print-mode style; throws on error/aborted stop. */\nfunction extractFinalText(session: BridgeSession): string {\n\tconst messages = session.state.messages;\n\tconst last = messages[messages.length - 1];\n\tif (last?.role !== \"assistant\") return \"\";\n\tconst assistant = last as {\n\t\tstopReason?: string;\n\t\terrorMessage?: string;\n\t\tcontent?: Array<{ type: string; text?: string }>;\n\t};\n\tif (assistant.stopReason === \"error\" || assistant.stopReason === \"aborted\") {\n\t\tthrow new Error(assistant.errorMessage || `Request ${assistant.stopReason}`);\n\t}\n\tlet text = \"\";\n\tfor (const content of assistant.content ?? []) {\n\t\tif (content.type === \"text\") text += content.text ?? \"\";\n\t}\n\treturn text;\n}\n\ninterface ResolvedTarget {\n\tplatform: string;\n\tchatId: string;\n\tthreadId?: string;\n}\n\nconst EXPLICIT_TARGET_RE = /^([a-z0-9_-]+):([^:]+)(?::([^:]+))?$/i;\n\n/** Resolve one deliver target to a concrete destination. Returns an error string on failure. */\nfunction resolveTarget(target: string, job: CronJob, cfg: GatewayConfig): ResolvedTarget | string {\n\tif (target === \"origin\") {\n\t\tconst origin = job.origin;\n\t\tif (origin?.platform && origin.chatId) {\n\t\t\treturn { platform: origin.platform, chatId: origin.chatId, threadId: origin.threadId };\n\t\t}\n\t\t// Missing/incomplete origin → fall back to a homeChannel: the origin's\n\t\t// platform when known, otherwise the first platform that has one.\n\t\tconst platforms = origin?.platform ? [origin.platform] : KNOWN_PLATFORMS;\n\t\tfor (const platform of platforms) {\n\t\t\tconst home = platformConfigFor(cfg, platform)?.homeChannel;\n\t\t\tif (home) return { platform, chatId: home };\n\t\t}\n\t\treturn `deliver target \"origin\": job has no origin and no homeChannel is configured`;\n\t}\n\n\tconst explicit = EXPLICIT_TARGET_RE.exec(target);\n\tconst platform = explicit ? explicit[1].toLowerCase() : target.toLowerCase();\n\tif (platformConfigFor(cfg, platform) === undefined) {\n\t\treturn `unknown platform \"${explicit ? explicit[1] : target}\"`;\n\t}\n\tif (explicit) {\n\t\treturn { platform, chatId: explicit[2], threadId: explicit[3] };\n\t}\n\t// Bare platform name → its homeChannel.\n\tconst home = platformConfigFor(cfg, platform)?.homeChannel;\n\tif (!home) return `no homeChannel configured for ${platform}`;\n\treturn { platform, chatId: home };\n}\n\n/** True when a resolved chat may receive cron output for this job. */\nexport function isAllowedDeliverChat(\n\tcfg: GatewayConfig,\n\tplatform: string,\n\tchatId: string,\n\torigin?: CronJobOrigin | null,\n): boolean {\n\tconst platformCfg = platformConfigFor(cfg, platform);\n\tif (!platformCfg) return false;\n\tif (platformCfg.homeChannel && platformCfg.homeChannel === chatId) return true;\n\tif (platformCfg.allowedChats?.includes(chatId)) return true;\n\treturn origin?.platform === platform && origin.chatId === chatId;\n}\n\nexport function createDeliverValidator(\n\tcfg: GatewayConfig,\n): (deliver: string, origin?: CronJobOrigin | null) => string | undefined {\n\treturn (deliver, origin) => {\n\t\tconst targets = deliver\n\t\t\t.split(\",\")\n\t\t\t.map((t) => t.trim())\n\t\t\t.filter(Boolean);\n\t\tfor (const target of targets) {\n\t\t\tif (target === \"local\") continue;\n\t\t\tif (target === \"origin\") continue; // delivery time resolves/fails with a sensible error\n\t\t\tconst explicit = EXPLICIT_TARGET_RE.exec(target);\n\t\t\tconst platform = explicit ? explicit[1].toLowerCase() : target.toLowerCase();\n\t\t\tconst platformCfg = platformConfigFor(cfg, platform);\n\t\t\tif (!platformCfg) return `unknown platform \"${explicit ? explicit[1] : target}\"`;\n\t\t\tif (explicit) {\n\t\t\t\tif (!isAllowedDeliverChat(cfg, platform, explicit[2], origin)) {\n\t\t\t\t\treturn `deliver target \"${target}\" is not an allowed chat for ${platform}`;\n\t\t\t\t}\n\t\t\t} else if (!platformCfg.homeChannel) {\n\t\t\t\treturn `no homeChannel configured for ${platform}`;\n\t\t\t}\n\t\t}\n\t\treturn undefined;\n\t};\n}\n\n/** Wrap the run output with a compact cron header. */\nexport function wrapCronContent(job: CronJob, content: string): string {\n\treturn `Cron: ${job.name}\\n———\\n${content}`;\n}\n\n/**\n * The platform deliverer installed at the `@lunr/cron-delivery` bridge.\n * Every target is attempted; the first error is returned (null on success).\n */\nexport function createPlatformDeliverer(adapters: Map<string, PlatformAdapter>, cfg: GatewayConfig): DeliveryBridge {\n\treturn async (job, content) => {\n\t\tconst targets = job.deliver\n\t\t\t.split(\",\")\n\t\t\t.map((t) => t.trim())\n\t\t\t.filter(Boolean);\n\t\tlet firstError: string | null = null;\n\t\tfor (const target of targets) {\n\t\t\tif (target === \"local\") continue; // output file already written by the scheduler\n\t\t\tconst resolved = resolveTarget(target, job, cfg);\n\t\t\tif (typeof resolved === \"string\") {\n\t\t\t\tfirstError ??= resolved;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (!isAllowedDeliverChat(cfg, resolved.platform, resolved.chatId, job.origin)) {\n\t\t\t\tfirstError ??= `deliver target \"${target}\" is not an allowed chat for ${resolved.platform}`;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst adapter = adapters.get(resolved.platform);\n\t\t\tif (!adapter) {\n\t\t\t\tfirstError ??= `no adapter connected for ${resolved.platform}`;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst wrapped = wrapCronContent(job, content);\n\t\t\tfor (const chunk of splitMessage(wrapped, adapter.maxMessageLength)) {\n\t\t\t\ttry {\n\t\t\t\t\tconst result = await adapter.send(resolved.chatId, chunk, {\n\t\t\t\t\t\tthreadId: resolved.threadId,\n\t\t\t\t\t});\n\t\t\t\t\tif (!result.success) {\n\t\t\t\t\t\tfirstError ??= `${resolved.platform} send failed: ${result.error ?? \"unknown error\"}`;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t} catch (err) {\n\t\t\t\t\tfirstError ??= `${resolved.platform} send failed: ${err instanceof Error ? err.message : String(err)}`;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn firstError;\n\t};\n}\n\n/** Race one prompt attempt against its share of the job budget. */\nfunction withAttemptTimeout<T>(promise: Promise<T>, ms: number): Promise<T> {\n\treturn Promise.race([\n\t\tpromise,\n\t\tnew Promise<never>((_, reject) => {\n\t\t\tconst timer = setTimeout(() => reject(new Error(`attempt timed out after ${ms}ms`)), ms);\n\t\t\t// If the attempt settles first this promise is discarded; the timer must not keep the process alive.\n\t\t\ttimer.unref?.();\n\t\t}),\n\t]);\n}\n\n/**\n * Read settings.json `cronFallbackModels` (\"provider/modelId\" entries).\n * Fresh read per fire so edits apply without a daemon restart; invalid\n * entries are skipped with a log line. Never throws.\n */\nasync function readCronFallbackModels(): Promise<CronModelRef[]> {\n\ttry {\n\t\tconst [{ getAgentDir }, { SettingsManager }] = await Promise.all([\n\t\t\timport(\"../config.ts\"),\n\t\t\timport(\"../core/settings-manager.ts\"),\n\t\t]);\n\t\tconst settingsManager = SettingsManager.create(process.cwd(), getAgentDir(), { projectTrusted: false });\n\t\tconst out: CronModelRef[] = [];\n\t\tfor (const entry of settingsManager.getCronFallbackModels()) {\n\t\t\tconst idx = entry.indexOf(\"/\");\n\t\t\tif (idx <= 0 || idx === entry.length - 1) {\n\t\t\t\tconsole.error(\n\t\t\t\t\t`[gateway cron] ignoring invalid cronFallbackModels entry \"${entry}\" (want \"provider/modelId\")`,\n\t\t\t\t);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tout.push({ provider: entry.slice(0, idx), modelId: entry.slice(idx + 1) });\n\t\t}\n\t\treturn out;\n\t} catch (err) {\n\t\tconsole.error(\n\t\t\t`[gateway cron] failed to read cronFallbackModels: ${err instanceof Error ? err.message : String(err)}`,\n\t\t);\n\t\treturn [];\n\t}\n}\n\n/**\n * Start the cron scheduler inside the gateway daemon. Starts even with zero\n * stored jobs — jobs can be created later from chats. stop() halts the loop.\n */\nexport function startGatewayCron(options: GatewayCronOptions): { stop(): void; intervalMs: number } {\n\tconst { adapters, cfg } = options;\n\tconst sessionFactory = options.sessionFactory ?? defaultCronSessionFactory;\n\tconst platformDeliverer = createPlatformDeliverer(adapters, cfg);\n\n\t// Explicit so runJob can split it into per-attempt budgets that sum to (at\n\t// most) the scheduler's outer race (core/cron/scheduler.ts runSchedulerTick).\n\tconst jobTimeoutMs = 5 * 60 * 1000;\n\n\t// Reject deliver targets that are not local, origin, a configured home channel,\n\t// or an explicit chat in the platform allowlist / the job's origin.\n\tsetCronDeliverValidator(createDeliverValidator(cfg));\n\n\t// Replace the local-notify bridge lunr-cron registered with the platform deliverer.\n\t(globalThis as Record<symbol, unknown>)[DELIVERY_BRIDGE_SYMBOL] = platformDeliverer;\n\n\tconst runJob = async (prompt: string, job: CronJob): Promise<string> => {\n\t\tconst fallbacks = options.fallbackModels ?? (await readCronFallbackModels());\n\t\tconst candidates: Array<CronModelRef | undefined> = [undefined, ...fallbacks];\n\t\tconst attemptTimeoutMs = Math.floor(jobTimeoutMs / candidates.length);\n\t\tconst errors: string[] = [];\n\t\tbeginCronFire();\n\t\ttry {\n\t\t\tfor (const candidate of candidates) {\n\t\t\t\tconst label = candidate ? `${candidate.provider}/${candidate.modelId}` : \"default model\";\n\t\t\t\tlet session: BridgeSession | undefined;\n\t\t\t\ttry {\n\t\t\t\t\tsession = await sessionFactory(job, candidate);\n\t\t\t\t\t// Loading the builtin extensions re-registered lunr-cron's local-notify\n\t\t\t\t\t// bridge; restore the platform deliverer before any delivery re-reads it.\n\t\t\t\t\t(globalThis as Record<symbol, unknown>)[DELIVERY_BRIDGE_SYMBOL] = platformDeliverer;\n\t\t\t\t\tawait withAttemptTimeout(session.prompt(prompt, { source: \"extension\" }), attemptTimeoutMs);\n\t\t\t\t\tconst text = extractFinalText(session);\n\t\t\t\t\t// The marker lands in the output file (the audit trail); [SILENT] as\n\t\t\t\t\t// the last line still suppresses delivery (scheduler isSilent check).\n\t\t\t\t\treturn candidate ? `[fell back to ${label}]\\n${text}` : text;\n\t\t\t\t} catch (err) {\n\t\t\t\t\terrors.push(`${label}: ${err instanceof Error ? err.message : String(err)}`);\n\t\t\t\t} finally {\n\t\t\t\t\tif (session) await shutdownBridgeSession(session, \"quit\");\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow new Error(errors.join(\" | \") || \"no model candidates\");\n\t\t} finally {\n\t\t\tendCronFire();\n\t\t}\n\t};\n\n\tconst deliverResult = async (job: CronJob, content: string): Promise<void> => {\n\t\t// Re-read the bridge on every delivery (same pattern as lunr-cron).\n\t\tconst bridge = (globalThis as Record<symbol, unknown>)[DELIVERY_BRIDGE_SYMBOL] as DeliveryBridge | undefined;\n\t\tif (!bridge) throw new Error(\"no cron delivery bridge registered\");\n\t\tconst err = await bridge(job, content);\n\t\tif (err) throw new Error(err);\n\t};\n\n\tconst scheduler = startScheduler({ runJob, deliverResult, intervalMs: options.intervalMs, jobTimeoutMs });\n\treturn { stop: () => scheduler.stop(), intervalMs: options.intervalMs ?? 60_000 };\n}\n"]}
1
+ {"version":3,"file":"cron.d.ts","sourceRoot":"","sources":["../../src/gateway/cron.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAKH,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAInE,OAAO,EAAE,KAAK,aAAa,EAAyB,MAAM,mBAAmB,CAAC;AAE9E,OAAO,EAAE,KAAK,aAAa,EAAwC,MAAM,aAAa,CAAC;AAEvF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAIlD,KAAK,cAAc,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;AAEhF,qEAAqE;AACrE,MAAM,WAAW,YAAY;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,kBAAkB,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,aAAa,CAAC,EAAE,YAAY,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC;AAExG,MAAM,WAAW,kBAAkB;IAClC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACvC,GAAG,EAAE,aAAa,CAAC;IACnB,kCAAkC;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iFAAiF;IACjF,cAAc,CAAC,EAAE,kBAAkB,CAAC;IACpC,kHAAkH;IAClH,cAAc,CAAC,EAAE,YAAY,EAAE,CAAC;IAChC,6DAA6D;IAC7D,SAAS,CAAC,EAAE,MAAM,aAAa,CAAC;IAChC,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB;AAgJD,sEAAsE;AACtE,wBAAgB,oBAAoB,CACnC,GAAG,EAAE,aAAa,EAClB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,aAAa,GAAG,IAAI,GAC3B,OAAO,CAMT;AAED,wBAAgB,sBAAsB,CACrC,GAAG,EAAE,aAAa,GAChB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,IAAI,KAAK,MAAM,GAAG,SAAS,CAuBxE;AAED,sDAAsD;AACtD,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAErE;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CACtC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,EACtC,MAAM,EAAE,aAAa,GAAG,CAAC,MAAM,aAAa,CAAC,GAC3C,cAAc,CAyDhB;AAkCD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,kBAAkB,GAAG;IAAE,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CA8D3G","sourcesContent":["/**\n * lunR: gateway cron runner + delivery (Phase 4 of the cron/gateway roadmap).\n *\n * startGatewayCron() runs the core/cron scheduler inside the `lunr gateway`\n * daemon:\n *\n * - runJob: each fire gets a FRESH headless agent session (createAgentSession\n * with SessionManager.inMemory — cron runs never write session files and\n * never touch the per-chat gateway sessions; the files under\n * <agentDir>/cron/output/ are the audit trail). The shared fire-guard\n * (core/cron/fire-guard) brackets the turn so the `cron` tool refuses to\n * run inside it (jobs cannot schedule jobs).\n * - deliverResult: replaces the `@lunr/cron-delivery` bridge on globalThis\n * with a platform deliverer. Targets come from job.deliver\n * (comma-separated): \"local\" (no-op — the output file is already written),\n * \"origin\" (the identified, currently authorized requester chat), a bare\n * platform name (that platform's homeChannel), or\n * \"<platform>:<chatId>[:<threadId>]\" (explicit). Content is wrapped as\n * \"Cron: <name>\" and split to the adapter's maxMessageLength.\n *\n * The compatibility delivery bridge exposes the platform deliverer. The scheduler\n * retains its own callback so another session cannot redirect its output.\n *\n * Fallback models: settings.json `cronFallbackModels`\n * (\"provider/modelId\" entries) are tried in order only when session setup fails before prompt dispatch.\n * An admitted failure may have external effects and is never replayed automatically; a successful fallback run prefixes\n * \"[fell back to provider/modelId]\" to the output. TUI fires are unaffected\n * (they use the live session's model).\n */\n\nimport type { AgentMessage } from \"@ashx-j/lunr-agent\";\nimport type { Api, Model } from \"@ashx-j/lunr-ai\";\nimport { beginCronFire, endCronFire } from \"../core/cron/fire-guard.ts\";\nimport type { CronJob, CronJobOrigin } from \"../core/cron/jobs.ts\";\nimport { setCronDeliverValidator } from \"../core/cron/jobs.ts\";\nimport { startScheduler } from \"../core/cron/scheduler.ts\";\nimport { createPermissionContext, deletePermissionContext } from \"../core/permissions.ts\";\nimport { type BridgeSession, shutdownBridgeSession } from \"./agent-bridge.ts\";\nimport { isAuthorized } from \"./authz.ts\";\nimport { type GatewayConfig, loadGatewayConfig, platformConfigFor } from \"./config.ts\";\nimport { splitMessage } from \"./text.ts\";\nimport type { PlatformAdapter } from \"./types.ts\";\n\nconst DELIVERY_BRIDGE_SYMBOL = Symbol.for(\"@lunr/cron-delivery\");\n\ntype DeliveryBridge = (job: CronJob, content: string) => Promise<string | null>;\n\n/** Test seam / default: one fresh headless session per cron fire. */\nexport interface CronModelRef {\n\tprovider: string;\n\tmodelId: string;\n}\n\nexport type CronSessionFactory = (job: CronJob, modelOverride?: CronModelRef) => Promise<BridgeSession>;\n\nexport interface GatewayCronOptions {\n\tadapters: Map<string, PlatformAdapter>;\n\tcfg: GatewayConfig;\n\t/** Tick interval; default 60s. */\n\tintervalMs?: number;\n\t/** Session factory for cron fires; defaults to a real headless agent session. */\n\tsessionFactory?: CronSessionFactory;\n\t/** Test seam: fallback models. When omitted, read fresh from settings.json `cronFallbackModels` on every fire. */\n\tfallbackModels?: CronModelRef[];\n\t/** Config seam; production always reloads current grants. */\n\tgetConfig?: () => GatewayConfig;\n\tjobTimeoutMs?: number;\n}\n\n/** Default factory: fresh in-memory headless session, mirroring agent-bridge's wiring. */\nasync function defaultCronSessionFactory(job: CronJob, modelOverride?: CronModelRef): Promise<BridgeSession> {\n\tconst [\n\t\t{ loadAllBuiltinExtensions },\n\t\t{ getAgentDir },\n\t\t{ registerCustomizeBridge },\n\t\t{ registerMemoryCapBridge },\n\t\t{ registerModelTierBridge },\n\t\t{ createAgentSessionFromServices, createAgentSessionServices },\n\t\t{ SessionManager },\n\t\t{ SettingsManager },\n\t\t{ bindRuntimeBridges },\n\t] = await Promise.all([\n\t\timport(\"../builtin-extensions/index.ts\"),\n\t\timport(\"../config.ts\"),\n\t\timport(\"../core/customize.ts\"),\n\t\timport(\"../core/memory-cap.ts\"),\n\t\timport(\"../core/model-tiers.ts\"),\n\t\timport(\"../core/agent-session-services.ts\"),\n\t\timport(\"../core/session-manager.ts\"),\n\t\timport(\"../core/settings-manager.ts\"),\n\t\timport(\"../core/runtime-bridges.ts\"),\n\t]);\n\tconst cwd = job.workdir ?? process.cwd();\n\tconst agentDir = getAgentDir();\n\tconst settingsManager = SettingsManager.create(cwd, agentDir, { projectTrusted: false });\n\tregisterModelTierBridge(settingsManager);\n\tregisterMemoryCapBridge(settingsManager);\n\tregisterCustomizeBridge(settingsManager);\n\n\t// In-memory on purpose: cron runs must not persist session files or pollute\n\t// the per-chat gateway sessions — <agentDir>/cron/output/ is the audit trail.\n\tconst sessionManager = SessionManager.inMemory(cwd);\n\n\t// Services-first (mirrors main.ts): extension-registered providers (e.g.\n\t// ollama-cloud) must land in the shared ModelRuntime BEFORE session\n\t// creation — otherwise findInitialModel can't resolve the user's default\n\t// model and silently falls back to an arbitrary catalog provider.\n\tconst services = await createAgentSessionServices({\n\t\tcwd,\n\t\tagentDir,\n\t\tsettingsManager,\n\t\tresourceLoaderOptions: { extensionFactories: await loadAllBuiltinExtensions() },\n\t});\n\t// Fallback-model attempts pin the session model explicitly; an unresolvable\n\t// or unauthenticated override fails the attempt so the next fallback runs.\n\tlet model: Model<Api> | undefined;\n\tif (modelOverride) {\n\t\tconst resolved = services.modelRuntime.getModel(modelOverride.provider, modelOverride.modelId);\n\t\tif (!resolved) throw new Error(`model not found: ${modelOverride.provider}/${modelOverride.modelId}`);\n\t\tif (!services.modelRuntime.hasConfiguredAuth(resolved.provider)) {\n\t\t\tthrow new Error(`no configured auth for provider: ${modelOverride.provider}`);\n\t\t}\n\t\tmodel = resolved;\n\t}\n\tconst { session } = await createAgentSessionFromServices({ services, sessionManager, model });\n\tconst permissionId = sessionManager.getSessionId();\n\tcreatePermissionContext(permissionId, settingsManager.getDefaultPermissionMode(), false);\n\tconst dispose = session.dispose.bind(session);\n\tsession.dispose = () => {\n\t\tdeletePermissionContext(permissionId);\n\t\tdispose();\n\t};\n\ttry {\n\t\tbindRuntimeBridges({ session, services });\n\t\tawait session.bindExtensions({\n\t\t\tmode: \"print\",\n\t\t\tonError: (err) => console.error(`[gateway cron] extension error (${err.extensionPath}): ${err.error}`),\n\t\t});\n\t\treturn session;\n\t} catch (error) {\n\t\tawait shutdownBridgeSession(session, \"quit\");\n\t\tthrow error;\n\t}\n}\n\n/** Final assistant text, print-mode style; throws on error/aborted stop. */\nfunction extractFinalText(messages: AgentMessage[]): string {\n\tconst last = messages[messages.length - 1];\n\tif (last?.role !== \"assistant\") return \"\";\n\tconst assistant = last as {\n\t\tstopReason?: string;\n\t\terrorMessage?: string;\n\t\tcontent?: Array<{ type: string; text?: string }>;\n\t};\n\tif (assistant.stopReason === \"error\" || assistant.stopReason === \"aborted\") {\n\t\tthrow new Error(assistant.errorMessage || `Request ${assistant.stopReason}`);\n\t}\n\tlet text = \"\";\n\tfor (const content of assistant.content ?? []) {\n\t\tif (content.type === \"text\") text += content.text ?? \"\";\n\t}\n\treturn text;\n}\n\ninterface ResolvedTarget {\n\tplatform: string;\n\tchatId: string;\n\tthreadId?: string;\n}\n\nconst EXPLICIT_TARGET_RE = /^([a-z0-9_-]+):([^:]+)(?::([^:]+))?$/i;\n\n/** Resolve one deliver target to a concrete destination. Returns an error string on failure. */\nfunction resolveTarget(target: string, job: CronJob, cfg: GatewayConfig): ResolvedTarget | string {\n\tif (target === \"origin\") {\n\t\tconst origin = job.origin;\n\t\tif (origin?.platform && origin.chatId && origin.userId) {\n\t\t\treturn { platform: origin.platform, chatId: origin.chatId, threadId: origin.threadId };\n\t\t}\n\t\treturn 'deliver target \"origin\": job has no origin requester identity; use /cron rebind from an approved gateway chat';\n\t}\n\n\tconst explicit = EXPLICIT_TARGET_RE.exec(target);\n\tconst platform = explicit ? explicit[1].toLowerCase() : target.toLowerCase();\n\tif (platformConfigFor(cfg, platform) === undefined) {\n\t\treturn `unknown platform \"${explicit ? explicit[1] : target}\"`;\n\t}\n\tif (explicit) {\n\t\treturn { platform, chatId: explicit[2], threadId: explicit[3] };\n\t}\n\t// Bare platform name → its homeChannel.\n\tconst home = platformConfigFor(cfg, platform)?.homeChannel;\n\tif (!home) return `no homeChannel configured for ${platform}`;\n\treturn { platform, chatId: home };\n}\n\n/** Rebuild the source from durable identity, never from persisted adapter role grants. */\nfunction isAuthorizedOrigin(cfg: GatewayConfig, origin?: CronJobOrigin | null): boolean {\n\tif (!origin?.userId) return false;\n\treturn isAuthorized(\n\t\t{\n\t\t\tplatform: origin.platform,\n\t\t\tchatId: origin.chatId,\n\t\t\tuserId: origin.userId,\n\t\t\tchatType: origin.chatType === \"group\" ? \"group\" : origin.chatType === \"channel\" ? \"channel\" : \"dm\",\n\t\t\tthreadId: origin.threadId,\n\t\t},\n\t\tcfg,\n\t);\n}\n\n/** True when a resolved chat may receive cron output for this job. */\nexport function isAllowedDeliverChat(\n\tcfg: GatewayConfig,\n\tplatform: string,\n\tchatId: string,\n\torigin?: CronJobOrigin | null,\n): boolean {\n\tconst platformCfg = platformConfigFor(cfg, platform);\n\tif (!platformCfg) return false;\n\tif (platformCfg.homeChannel && platformCfg.homeChannel === chatId) return true;\n\tif (platformCfg.allowedChats?.includes(chatId)) return true;\n\treturn origin?.platform === platform && origin.chatId === chatId && isAuthorizedOrigin(cfg, origin);\n}\n\nexport function createDeliverValidator(\n\tcfg: GatewayConfig,\n): (deliver: string, origin?: CronJobOrigin | null) => string | undefined {\n\treturn (deliver, origin) => {\n\t\tconst targets = deliver\n\t\t\t.split(\",\")\n\t\t\t.map((t) => t.trim())\n\t\t\t.filter(Boolean);\n\t\tfor (const target of targets) {\n\t\t\tif (target === \"local\") continue;\n\t\t\tif (target === \"origin\") continue; // delivery time resolves/fails with a sensible error\n\t\t\tconst explicit = EXPLICIT_TARGET_RE.exec(target);\n\t\t\tconst platform = explicit ? explicit[1].toLowerCase() : target.toLowerCase();\n\t\t\tconst platformCfg = platformConfigFor(cfg, platform);\n\t\t\tif (!platformCfg) return `unknown platform \"${explicit ? explicit[1] : target}\"`;\n\t\t\tif (explicit) {\n\t\t\t\tif (!isAllowedDeliverChat(cfg, platform, explicit[2], origin)) {\n\t\t\t\t\treturn `deliver target \"${target}\" is not an allowed chat for ${platform}`;\n\t\t\t\t}\n\t\t\t} else if (!platformCfg.homeChannel) {\n\t\t\t\treturn `no homeChannel configured for ${platform}`;\n\t\t\t}\n\t\t}\n\t\treturn undefined;\n\t};\n}\n\n/** Wrap the run output with a compact cron header. */\nexport function wrapCronContent(job: CronJob, content: string): string {\n\treturn `Cron: ${job.name}\\n———\\n${content}`;\n}\n\n/**\n * The platform deliverer installed at the `@lunr/cron-delivery` bridge.\n * Every target is attempted; the first error is returned (null on success).\n */\nexport function createPlatformDeliverer(\n\tadapters: Map<string, PlatformAdapter>,\n\tconfig: GatewayConfig | (() => GatewayConfig),\n): DeliveryBridge {\n\tconst getConfig = typeof config === \"function\" ? config : () => config;\n\treturn async (job, content) => {\n\t\tconst targets = job.deliver\n\t\t\t.split(\",\")\n\t\t\t.map((t) => t.trim())\n\t\t\t.filter(Boolean);\n\t\tlet firstError: string | null = null;\n\t\tfor (const target of targets) {\n\t\t\tif (target === \"local\") continue; // output file already written by the scheduler\n\t\t\tconst cfg = getConfig();\n\t\t\tconst resolved = resolveTarget(target, job, cfg);\n\t\t\tif (typeof resolved === \"string\") {\n\t\t\t\tfirstError ??= resolved;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (!isAllowedDeliverChat(cfg, resolved.platform, resolved.chatId, job.origin)) {\n\t\t\t\tfirstError ??= `deliver target \"${target}\" is not an allowed chat for ${resolved.platform}`;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst adapter = adapters.get(resolved.platform);\n\t\t\tif (!adapter) {\n\t\t\t\tfirstError ??= `no adapter connected for ${resolved.platform}`;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst wrapped = wrapCronContent(job, content);\n\t\t\tfor (const chunk of splitMessage(wrapped, adapter.maxMessageLength)) {\n\t\t\t\ttry {\n\t\t\t\t\tconst live = getConfig();\n\t\t\t\t\tconst current = resolveTarget(target, job, live);\n\t\t\t\t\tif (typeof current === \"string\") throw new Error(current);\n\t\t\t\t\tif (\n\t\t\t\t\t\tcurrent.platform !== resolved.platform ||\n\t\t\t\t\t\tcurrent.chatId !== resolved.chatId ||\n\t\t\t\t\t\tcurrent.threadId !== resolved.threadId\n\t\t\t\t\t)\n\t\t\t\t\t\tthrow new Error(\"cron delivery destination changed\");\n\t\t\t\t\tif (target === \"origin\" && !isAuthorizedOrigin(live, job.origin)) {\n\t\t\t\t\t\tthrow new Error(\"cron origin requester access revoked; use /cron rebind\");\n\t\t\t\t\t}\n\t\t\t\t\tif (!isAllowedDeliverChat(live, resolved.platform, resolved.chatId, job.origin))\n\t\t\t\t\t\tthrow new Error(`deliver target \"${target}\" is not an allowed chat for ${resolved.platform}`);\n\t\t\t\t\tconst result = await adapter.send(resolved.chatId, chunk, {\n\t\t\t\t\t\tthreadId: resolved.threadId,\n\t\t\t\t\t});\n\t\t\t\t\tif (!result.success) {\n\t\t\t\t\t\tfirstError ??= `${resolved.platform} send failed: ${result.error ?? \"unknown error\"}`;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t} catch (err) {\n\t\t\t\t\tfirstError ??= `${resolved.platform} send failed: ${err instanceof Error ? err.message : String(err)}`;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn firstError;\n\t};\n}\n\n/**\n * Read settings.json `cronFallbackModels` (\"provider/modelId\" entries).\n * Fresh read per fire so edits apply without a daemon restart; invalid\n * entries are skipped with a log line. Never throws.\n */\nasync function readCronFallbackModels(): Promise<CronModelRef[]> {\n\ttry {\n\t\tconst [{ getAgentDir }, { SettingsManager }] = await Promise.all([\n\t\t\timport(\"../config.ts\"),\n\t\t\timport(\"../core/settings-manager.ts\"),\n\t\t]);\n\t\tconst settingsManager = SettingsManager.create(process.cwd(), getAgentDir(), { projectTrusted: false });\n\t\tconst out: CronModelRef[] = [];\n\t\tfor (const entry of settingsManager.getCronFallbackModels()) {\n\t\t\tconst idx = entry.indexOf(\"/\");\n\t\t\tif (idx <= 0 || idx === entry.length - 1) {\n\t\t\t\tconsole.error(\n\t\t\t\t\t`[gateway cron] ignoring invalid cronFallbackModels entry \"${entry}\" (want \"provider/modelId\")`,\n\t\t\t\t);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tout.push({ provider: entry.slice(0, idx), modelId: entry.slice(idx + 1) });\n\t\t}\n\t\treturn out;\n\t} catch (err) {\n\t\tconsole.error(\n\t\t\t`[gateway cron] failed to read cronFallbackModels: ${err instanceof Error ? err.message : String(err)}`,\n\t\t);\n\t\treturn [];\n\t}\n}\n\n/**\n * Start the cron scheduler inside the gateway daemon. Starts even with zero\n * stored jobs — jobs can be created later from chats. stop() cancels admitted work, awaits session cleanup and releases the lease last.\n */\nexport function startGatewayCron(options: GatewayCronOptions): { stop(): Promise<void>; intervalMs: number } {\n\tconst { adapters } = options;\n\tconst getConfig = options.getConfig ?? loadGatewayConfig;\n\tconst sessionFactory = options.sessionFactory ?? defaultCronSessionFactory;\n\tconst platformDeliverer = createPlatformDeliverer(adapters, getConfig);\n\n\t// One budget covers setup, owned prompt cancellation and session settlement.\n\tconst jobTimeoutMs = options.jobTimeoutMs ?? 5 * 60 * 1000;\n\n\t// Reject deliver targets that are not local, origin, a configured home channel,\n\t// or an explicit chat in the platform allowlist / the job's origin.\n\tsetCronDeliverValidator((deliver, origin) => createDeliverValidator(getConfig())(deliver, origin));\n\n\t// Retain the compatibility delivery bridge for integrations.\n\t(globalThis as Record<symbol, unknown>)[DELIVERY_BRIDGE_SYMBOL] = platformDeliverer;\n\n\tconst runJob = async (prompt: string, job: CronJob, signal: AbortSignal): Promise<string> => {\n\t\tconst fallbacks = options.fallbackModels ?? (await readCronFallbackModels());\n\t\tconst candidates: Array<CronModelRef | undefined> = [undefined, ...fallbacks];\n\t\tconst errors: string[] = [];\n\t\tbeginCronFire();\n\t\ttry {\n\t\t\tfor (const candidate of candidates) {\n\t\t\t\tsignal.throwIfAborted();\n\t\t\t\tconst label = candidate ? `${candidate.provider}/${candidate.modelId}` : \"default model\";\n\t\t\t\tlet session: BridgeSession | undefined;\n\t\t\t\tlet dispatched = false;\n\t\t\t\ttry {\n\t\t\t\t\tsession = await sessionFactory(job, candidate);\n\t\t\t\t\tsignal.throwIfAborted();\n\t\t\t\t\tif (!session.promptWithCompletion) throw new Error(\"cron session lacks owned prompt admission\");\n\t\t\t\t\tdispatched = true;\n\t\t\t\t\tconst result = await session.promptWithCompletion(prompt, { source: \"extension\", signal });\n\t\t\t\t\tconst text = extractFinalText(result.messages);\n\t\t\t\t\t// The marker lands in the output file (the audit trail); [SILENT] as\n\t\t\t\t\t// the last line still suppresses delivery (scheduler isSilent check).\n\t\t\t\t\treturn candidate ? `[fell back to ${label}]\\n${text}` : text;\n\t\t\t\t} catch (err) {\n\t\t\t\t\terrors.push(`${label}: ${err instanceof Error ? err.message : String(err)}`);\n\t\t\t\t\tif (dispatched || signal.aborted) throw new Error(errors.join(\" | \"));\n\t\t\t\t} finally {\n\t\t\t\t\tif (session) {\n\t\t\t\t\t\t// The factory owns this fresh session, including extension-queued follow-ups.\n\t\t\t\t\t\tawait session.drain?.();\n\t\t\t\t\t\tawait shutdownBridgeSession(session, \"quit\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow new Error(errors.join(\" | \") || \"no model candidates\");\n\t\t} finally {\n\t\t\tendCronFire();\n\t\t}\n\t};\n\n\tconst deliverResult = async (job: CronJob, content: string): Promise<void> => {\n\t\t// Keep delivery bound to this operator even if another session changes a bridge.\n\t\tconst err = await platformDeliverer(job, content);\n\t\tif (err) throw new Error(err);\n\t};\n\n\tconst scheduler = startScheduler({ runJob, deliverResult, intervalMs: options.intervalMs, jobTimeoutMs });\n\treturn { stop: () => scheduler.stop(), intervalMs: options.intervalMs ?? 60_000 };\n}\n"]}