@ashx-j/lunr 0.2.25 → 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 (729) hide show
  1. package/CHANGELOG.md +31 -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/index.d.ts.map +1 -1
  12. package/dist/builtin-extensions/index.js +1 -0
  13. package/dist/builtin-extensions/index.js.map +1 -1
  14. package/dist/builtin-extensions/lunr-computer-use.d.ts +3 -0
  15. package/dist/builtin-extensions/lunr-computer-use.d.ts.map +1 -0
  16. package/dist/builtin-extensions/lunr-computer-use.js +179 -0
  17. package/dist/builtin-extensions/lunr-computer-use.js.map +1 -0
  18. package/dist/builtin-extensions/lunr-cron.d.ts +4 -5
  19. package/dist/builtin-extensions/lunr-cron.d.ts.map +1 -1
  20. package/dist/builtin-extensions/lunr-cron.js +94 -108
  21. package/dist/builtin-extensions/lunr-cron.js.map +1 -1
  22. package/dist/builtin-extensions/lunr-local-providers/local-servers.d.ts.map +1 -1
  23. package/dist/builtin-extensions/lunr-local-providers/local-servers.js +3 -1
  24. package/dist/builtin-extensions/lunr-local-providers/local-servers.js.map +1 -1
  25. package/dist/builtin-extensions/narumiruna-pi-goal/src/commands.d.ts.map +1 -1
  26. package/dist/builtin-extensions/narumiruna-pi-goal/src/commands.js +2 -2
  27. package/dist/builtin-extensions/narumiruna-pi-goal/src/commands.js.map +1 -1
  28. package/dist/builtin-extensions/narumiruna-pi-goal/src/goal.d.ts.map +1 -1
  29. package/dist/builtin-extensions/narumiruna-pi-goal/src/goal.js +1 -1
  30. package/dist/builtin-extensions/narumiruna-pi-goal/src/goal.js.map +1 -1
  31. package/dist/builtin-extensions/narumiruna-pi-goal/src/runtime.d.ts.map +1 -1
  32. package/dist/builtin-extensions/narumiruna-pi-goal/src/runtime.js +1 -1
  33. package/dist/builtin-extensions/narumiruna-pi-goal/src/runtime.js.map +1 -1
  34. package/dist/builtin-extensions/pi-intercom/index.d.ts.map +1 -1
  35. package/dist/builtin-extensions/pi-intercom/index.js +2 -2
  36. package/dist/builtin-extensions/pi-intercom/index.js.map +1 -1
  37. package/dist/builtin-extensions/pi-lsp-extension/bemol-extension/index.d.ts +1 -1
  38. package/dist/builtin-extensions/pi-lsp-extension/bemol-extension/index.d.ts.map +1 -1
  39. package/dist/builtin-extensions/pi-lsp-extension/bemol-extension/index.js +1 -1
  40. package/dist/builtin-extensions/pi-lsp-extension/bemol-extension/index.js.map +1 -1
  41. package/dist/builtin-extensions/pi-lsp-extension/src/index.d.ts.map +1 -1
  42. package/dist/builtin-extensions/pi-lsp-extension/src/index.js +1 -15
  43. package/dist/builtin-extensions/pi-lsp-extension/src/index.js.map +1 -1
  44. package/dist/builtin-extensions/pi-lsp-extension/src/lsp-client.d.ts +6 -0
  45. package/dist/builtin-extensions/pi-lsp-extension/src/lsp-client.d.ts.map +1 -1
  46. package/dist/builtin-extensions/pi-lsp-extension/src/lsp-client.js +187 -132
  47. package/dist/builtin-extensions/pi-lsp-extension/src/lsp-client.js.map +1 -1
  48. package/dist/builtin-extensions/pi-lsp-extension/src/lsp-manager.d.ts +8 -0
  49. package/dist/builtin-extensions/pi-lsp-extension/src/lsp-manager.d.ts.map +1 -1
  50. package/dist/builtin-extensions/pi-lsp-extension/src/lsp-manager.js +142 -112
  51. package/dist/builtin-extensions/pi-lsp-extension/src/lsp-manager.js.map +1 -1
  52. package/dist/builtin-extensions/pi-lsp-extension/src/tools/code-rewrite.d.ts +12 -1
  53. package/dist/builtin-extensions/pi-lsp-extension/src/tools/code-rewrite.d.ts.map +1 -1
  54. package/dist/builtin-extensions/pi-lsp-extension/src/tools/code-rewrite.js +14 -7
  55. package/dist/builtin-extensions/pi-lsp-extension/src/tools/code-rewrite.js.map +1 -1
  56. package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/rewrite-engine.d.ts +11 -3
  57. package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/rewrite-engine.d.ts.map +1 -1
  58. package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/rewrite-engine.js +67 -41
  59. package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/rewrite-engine.js.map +1 -1
  60. package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/search-engine.d.ts +4 -2
  61. package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/search-engine.d.ts.map +1 -1
  62. package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/search-engine.js +3 -0
  63. package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/search-engine.js.map +1 -1
  64. package/dist/builtin-extensions/pi-mcp-adapter/commands.d.ts +2 -1
  65. package/dist/builtin-extensions/pi-mcp-adapter/commands.d.ts.map +1 -1
  66. package/dist/builtin-extensions/pi-mcp-adapter/commands.js +6 -6
  67. package/dist/builtin-extensions/pi-mcp-adapter/commands.js.map +1 -1
  68. package/dist/builtin-extensions/pi-mcp-adapter/config.d.ts +1 -1
  69. package/dist/builtin-extensions/pi-mcp-adapter/config.d.ts.map +1 -1
  70. package/dist/builtin-extensions/pi-mcp-adapter/config.js +11 -5
  71. package/dist/builtin-extensions/pi-mcp-adapter/config.js.map +1 -1
  72. package/dist/builtin-extensions/pi-mcp-adapter/direct-tool-executor.d.ts.map +1 -1
  73. package/dist/builtin-extensions/pi-mcp-adapter/direct-tool-executor.js +2 -2
  74. package/dist/builtin-extensions/pi-mcp-adapter/direct-tool-executor.js.map +1 -1
  75. package/dist/builtin-extensions/pi-mcp-adapter/host-html-template.d.ts.map +1 -1
  76. package/dist/builtin-extensions/pi-mcp-adapter/host-html-template.js +1 -1
  77. package/dist/builtin-extensions/pi-mcp-adapter/host-html-template.js.map +1 -1
  78. package/dist/builtin-extensions/pi-mcp-adapter/index.d.ts.map +1 -1
  79. package/dist/builtin-extensions/pi-mcp-adapter/index.js +48 -40
  80. package/dist/builtin-extensions/pi-mcp-adapter/index.js.map +1 -1
  81. package/dist/builtin-extensions/pi-mcp-adapter/init.d.ts.map +1 -1
  82. package/dist/builtin-extensions/pi-mcp-adapter/init.js +3 -1
  83. package/dist/builtin-extensions/pi-mcp-adapter/init.js.map +1 -1
  84. package/dist/builtin-extensions/pi-mcp-adapter/mcp-auth-flow.d.ts +12 -40
  85. package/dist/builtin-extensions/pi-mcp-adapter/mcp-auth-flow.d.ts.map +1 -1
  86. package/dist/builtin-extensions/pi-mcp-adapter/mcp-auth-flow.js +166 -235
  87. package/dist/builtin-extensions/pi-mcp-adapter/mcp-auth-flow.js.map +1 -1
  88. package/dist/builtin-extensions/pi-mcp-adapter/mcp-callback-server.d.ts +5 -0
  89. package/dist/builtin-extensions/pi-mcp-adapter/mcp-callback-server.d.ts.map +1 -1
  90. package/dist/builtin-extensions/pi-mcp-adapter/mcp-callback-server.js +43 -13
  91. package/dist/builtin-extensions/pi-mcp-adapter/mcp-callback-server.js.map +1 -1
  92. package/dist/builtin-extensions/pi-mcp-adapter/mcp-oauth-provider.d.ts +14 -3
  93. package/dist/builtin-extensions/pi-mcp-adapter/mcp-oauth-provider.d.ts.map +1 -1
  94. package/dist/builtin-extensions/pi-mcp-adapter/mcp-oauth-provider.js +73 -21
  95. package/dist/builtin-extensions/pi-mcp-adapter/mcp-oauth-provider.js.map +1 -1
  96. package/dist/builtin-extensions/pi-mcp-adapter/proxy-modes.d.ts.map +1 -1
  97. package/dist/builtin-extensions/pi-mcp-adapter/proxy-modes.js +4 -4
  98. package/dist/builtin-extensions/pi-mcp-adapter/proxy-modes.js.map +1 -1
  99. package/dist/builtin-extensions/pi-mcp-adapter/server-manager.d.ts.map +1 -1
  100. package/dist/builtin-extensions/pi-mcp-adapter/server-manager.js +2 -2
  101. package/dist/builtin-extensions/pi-mcp-adapter/server-manager.js.map +1 -1
  102. package/dist/builtin-extensions/pi-mcp-adapter/state.d.ts +2 -0
  103. package/dist/builtin-extensions/pi-mcp-adapter/state.d.ts.map +1 -1
  104. package/dist/builtin-extensions/pi-mcp-adapter/state.js.map +1 -1
  105. package/dist/builtin-extensions/pi-ollama-cloud/index.d.ts +1 -1
  106. package/dist/builtin-extensions/pi-ollama-cloud/index.d.ts.map +1 -1
  107. package/dist/builtin-extensions/pi-ollama-cloud/index.js +1 -1
  108. package/dist/builtin-extensions/pi-ollama-cloud/index.js.map +1 -1
  109. package/dist/builtin-extensions/pi-ollama-cloud/models.d.ts +11 -5
  110. package/dist/builtin-extensions/pi-ollama-cloud/models.d.ts.map +1 -1
  111. package/dist/builtin-extensions/pi-ollama-cloud/models.js +12 -32
  112. package/dist/builtin-extensions/pi-ollama-cloud/models.js.map +1 -1
  113. package/dist/builtin-extensions/pi-prompt-template-model/index.d.ts.map +1 -1
  114. package/dist/builtin-extensions/pi-prompt-template-model/index.js +5 -3
  115. package/dist/builtin-extensions/pi-prompt-template-model/index.js.map +1 -1
  116. package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.d.ts +2 -1
  117. package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.d.ts.map +1 -1
  118. package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.js +21 -12
  119. package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.js.map +1 -1
  120. package/dist/builtin-extensions/pi-prompt-template-model/tool-manager.d.ts.map +1 -1
  121. package/dist/builtin-extensions/pi-prompt-template-model/tool-manager.js +7 -24
  122. package/dist/builtin-extensions/pi-prompt-template-model/tool-manager.js.map +1 -1
  123. package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts.map +1 -1
  124. package/dist/builtin-extensions/pi-subagents/src/extension/index.js +39 -77
  125. package/dist/builtin-extensions/pi-subagents/src/extension/index.js.map +1 -1
  126. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.d.ts.map +1 -1
  127. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js +1 -1
  128. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js.map +1 -1
  129. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.d.ts +4 -4
  130. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.d.ts.map +1 -1
  131. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.js +8 -5
  132. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.js.map +1 -1
  133. package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.d.ts +1 -1
  134. package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.d.ts.map +1 -1
  135. package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.js +15 -31
  136. package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.js.map +1 -1
  137. package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.d.ts.map +1 -1
  138. package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.js +7 -2
  139. package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.js.map +1 -1
  140. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.d.ts +1 -0
  141. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.d.ts.map +1 -1
  142. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.js +21 -4
  143. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.js.map +1 -1
  144. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.d.ts.map +1 -1
  145. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.js +11 -4
  146. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.js.map +1 -1
  147. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.d.ts.map +1 -1
  148. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.js +121 -25
  149. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.js.map +1 -1
  150. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.d.ts.map +1 -1
  151. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js +25 -5
  152. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js.map +1 -1
  153. package/dist/builtin-extensions/pi-subagents/src/runs/shared/chain-outputs.d.ts +1 -0
  154. package/dist/builtin-extensions/pi-subagents/src/runs/shared/chain-outputs.d.ts.map +1 -1
  155. package/dist/builtin-extensions/pi-subagents/src/runs/shared/chain-outputs.js +5 -0
  156. package/dist/builtin-extensions/pi-subagents/src/runs/shared/chain-outputs.js.map +1 -1
  157. package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.d.ts +1 -1
  158. package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.d.ts.map +1 -1
  159. package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.js +2 -0
  160. package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.js.map +1 -1
  161. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.d.ts +1 -1
  162. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.d.ts.map +1 -1
  163. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.js +1 -1
  164. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.js.map +1 -1
  165. package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.d.ts +7 -8
  166. package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.d.ts.map +1 -1
  167. package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.js +60 -32
  168. package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.js.map +1 -1
  169. package/dist/builtin-extensions/pi-subagents/src/shared/utils.d.ts +1 -1
  170. package/dist/builtin-extensions/pi-subagents/src/shared/utils.d.ts.map +1 -1
  171. package/dist/builtin-extensions/pi-subagents/src/shared/utils.js +15 -5
  172. package/dist/builtin-extensions/pi-subagents/src/shared/utils.js.map +1 -1
  173. package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.d.ts.map +1 -1
  174. package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.js +4 -3
  175. package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.js.map +1 -1
  176. package/dist/builtin-extensions/pi-subagents/src/tui/communication.d.ts.map +1 -1
  177. package/dist/builtin-extensions/pi-subagents/src/tui/communication.js +1 -1
  178. package/dist/builtin-extensions/pi-subagents/src/tui/communication.js.map +1 -1
  179. package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts +2 -1
  180. package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts.map +1 -1
  181. package/dist/builtin-extensions/pi-subagents/src/tui/render.js +22 -11
  182. package/dist/builtin-extensions/pi-subagents/src/tui/render.js.map +1 -1
  183. package/dist/builtin-extensions/pi-subagents/src/watchdog/review.d.ts.map +1 -1
  184. package/dist/builtin-extensions/pi-subagents/src/watchdog/review.js +3 -3
  185. package/dist/builtin-extensions/pi-subagents/src/watchdog/review.js.map +1 -1
  186. package/dist/builtin-extensions/pi-tps.d.ts.map +1 -1
  187. package/dist/builtin-extensions/pi-tps.js +20 -17
  188. package/dist/builtin-extensions/pi-tps.js.map +1 -1
  189. package/dist/builtin-extensions/pi-web-access/activity.d.ts +1 -0
  190. package/dist/builtin-extensions/pi-web-access/activity.d.ts.map +1 -1
  191. package/dist/builtin-extensions/pi-web-access/activity.js +27 -5
  192. package/dist/builtin-extensions/pi-web-access/activity.js.map +1 -1
  193. package/dist/builtin-extensions/pi-web-access/bounded-body.d.ts +3 -0
  194. package/dist/builtin-extensions/pi-web-access/bounded-body.d.ts.map +1 -0
  195. package/dist/builtin-extensions/pi-web-access/bounded-body.js +43 -0
  196. package/dist/builtin-extensions/pi-web-access/bounded-body.js.map +1 -0
  197. package/dist/builtin-extensions/pi-web-access/content-page.d.ts +24 -0
  198. package/dist/builtin-extensions/pi-web-access/content-page.d.ts.map +1 -0
  199. package/dist/builtin-extensions/pi-web-access/content-page.js +57 -0
  200. package/dist/builtin-extensions/pi-web-access/content-page.js.map +1 -0
  201. package/dist/builtin-extensions/pi-web-access/extract.d.ts.map +1 -1
  202. package/dist/builtin-extensions/pi-web-access/extract.js +7 -2
  203. package/dist/builtin-extensions/pi-web-access/extract.js.map +1 -1
  204. package/dist/builtin-extensions/pi-web-access/github-extract.d.ts +0 -1
  205. package/dist/builtin-extensions/pi-web-access/github-extract.d.ts.map +1 -1
  206. package/dist/builtin-extensions/pi-web-access/github-extract.js +147 -36
  207. package/dist/builtin-extensions/pi-web-access/github-extract.js.map +1 -1
  208. package/dist/builtin-extensions/pi-web-access/index.d.ts.map +1 -1
  209. package/dist/builtin-extensions/pi-web-access/index.js +48 -73
  210. package/dist/builtin-extensions/pi-web-access/index.js.map +1 -1
  211. package/dist/builtin-extensions/pi-web-access/session-cleanup.d.ts +12 -4
  212. package/dist/builtin-extensions/pi-web-access/session-cleanup.d.ts.map +1 -1
  213. package/dist/builtin-extensions/pi-web-access/session-cleanup.js +35 -12
  214. package/dist/builtin-extensions/pi-web-access/session-cleanup.js.map +1 -1
  215. package/dist/builtin-extensions/pi-web-access/storage.d.ts +9 -6
  216. package/dist/builtin-extensions/pi-web-access/storage.d.ts.map +1 -1
  217. package/dist/builtin-extensions/pi-web-access/storage.js +36 -24
  218. package/dist/builtin-extensions/pi-web-access/storage.js.map +1 -1
  219. package/dist/builtin-extensions/simple-pi-memory.d.ts +1 -1
  220. package/dist/builtin-extensions/simple-pi-memory.d.ts.map +1 -1
  221. package/dist/builtin-extensions/simple-pi-memory.js +1 -1
  222. package/dist/builtin-extensions/simple-pi-memory.js.map +1 -1
  223. package/dist/cli/install-cli.d.ts.map +1 -1
  224. package/dist/cli/install-cli.js +38 -30
  225. package/dist/cli/install-cli.js.map +1 -1
  226. package/dist/core/agent-session-runtime.d.ts +13 -0
  227. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  228. package/dist/core/agent-session-runtime.js +75 -11
  229. package/dist/core/agent-session-runtime.js.map +1 -1
  230. package/dist/core/agent-session-services.d.ts +1 -0
  231. package/dist/core/agent-session-services.d.ts.map +1 -1
  232. package/dist/core/agent-session-services.js +1 -0
  233. package/dist/core/agent-session-services.js.map +1 -1
  234. package/dist/core/agent-session.d.ts +40 -6
  235. package/dist/core/agent-session.d.ts.map +1 -1
  236. package/dist/core/agent-session.js +309 -76
  237. package/dist/core/agent-session.js.map +1 -1
  238. package/dist/core/browser/runtime.d.ts +2 -0
  239. package/dist/core/browser/runtime.d.ts.map +1 -1
  240. package/dist/core/browser/runtime.js +80 -45
  241. package/dist/core/browser/runtime.js.map +1 -1
  242. package/dist/core/browser/setup.d.ts.map +1 -1
  243. package/dist/core/browser/setup.js +12 -1
  244. package/dist/core/browser/setup.js.map +1 -1
  245. package/dist/core/computer-use/adapter.d.ts +28 -0
  246. package/dist/core/computer-use/adapter.d.ts.map +1 -0
  247. package/dist/core/computer-use/adapter.js +138 -0
  248. package/dist/core/computer-use/adapter.js.map +1 -0
  249. package/dist/core/computer-use/image.d.ts +27 -0
  250. package/dist/core/computer-use/image.d.ts.map +1 -0
  251. package/dist/core/computer-use/image.js +84 -0
  252. package/dist/core/computer-use/image.js.map +1 -0
  253. package/dist/core/computer-use/lease.d.ts +18 -0
  254. package/dist/core/computer-use/lease.d.ts.map +1 -0
  255. package/dist/core/computer-use/lease.js +129 -0
  256. package/dist/core/computer-use/lease.js.map +1 -0
  257. package/dist/core/computer-use/macos-runtime.d.ts +14 -0
  258. package/dist/core/computer-use/macos-runtime.d.ts.map +1 -0
  259. package/dist/core/computer-use/macos-runtime.js +148 -0
  260. package/dist/core/computer-use/macos-runtime.js.map +1 -0
  261. package/dist/core/computer-use/policy.d.ts +19 -0
  262. package/dist/core/computer-use/policy.d.ts.map +1 -0
  263. package/dist/core/computer-use/policy.js +67 -0
  264. package/dist/core/computer-use/policy.js.map +1 -0
  265. package/dist/core/computer-use/release.generated.d.ts +31 -0
  266. package/dist/core/computer-use/release.generated.d.ts.map +1 -0
  267. package/dist/core/computer-use/release.generated.js +36 -0
  268. package/dist/core/computer-use/release.generated.js.map +1 -0
  269. package/dist/core/computer-use/runtime.d.ts +13 -0
  270. package/dist/core/computer-use/runtime.d.ts.map +1 -0
  271. package/dist/core/computer-use/runtime.js +158 -0
  272. package/dist/core/computer-use/runtime.js.map +1 -0
  273. package/dist/core/computer-use/schemas.d.ts +100 -0
  274. package/dist/core/computer-use/schemas.d.ts.map +1 -0
  275. package/dist/core/computer-use/schemas.js +96 -0
  276. package/dist/core/computer-use/schemas.js.map +1 -0
  277. package/dist/core/computer-use/windows-desktop.d.ts +3 -0
  278. package/dist/core/computer-use/windows-desktop.d.ts.map +1 -0
  279. package/dist/core/computer-use/windows-desktop.js +48 -0
  280. package/dist/core/computer-use/windows-desktop.js.map +1 -0
  281. package/dist/core/computer-use/workflow.d.ts +38 -0
  282. package/dist/core/computer-use/workflow.d.ts.map +1 -0
  283. package/dist/core/computer-use/workflow.js +900 -0
  284. package/dist/core/computer-use/workflow.js.map +1 -0
  285. package/dist/core/cron/jobs.d.ts +26 -8
  286. package/dist/core/cron/jobs.d.ts.map +1 -1
  287. package/dist/core/cron/jobs.js +357 -232
  288. package/dist/core/cron/jobs.js.map +1 -1
  289. package/dist/core/cron/origin-context.d.ts +1 -0
  290. package/dist/core/cron/origin-context.d.ts.map +1 -1
  291. package/dist/core/cron/origin-context.js.map +1 -1
  292. package/dist/core/cron/scheduler.d.ts +22 -17
  293. package/dist/core/cron/scheduler.d.ts.map +1 -1
  294. package/dist/core/cron/scheduler.js +153 -73
  295. package/dist/core/cron/scheduler.js.map +1 -1
  296. package/dist/core/extensions/index.d.ts +1 -1
  297. package/dist/core/extensions/index.d.ts.map +1 -1
  298. package/dist/core/extensions/index.js.map +1 -1
  299. package/dist/core/extensions/loader.d.ts.map +1 -1
  300. package/dist/core/extensions/loader.js +4 -0
  301. package/dist/core/extensions/loader.js.map +1 -1
  302. package/dist/core/extensions/runner.d.ts +1 -0
  303. package/dist/core/extensions/runner.d.ts.map +1 -1
  304. package/dist/core/extensions/runner.js +8 -0
  305. package/dist/core/extensions/runner.js.map +1 -1
  306. package/dist/core/extensions/types.d.ts +8 -0
  307. package/dist/core/extensions/types.d.ts.map +1 -1
  308. package/dist/core/extensions/types.js.map +1 -1
  309. package/dist/core/footer-data-provider.d.ts +4 -0
  310. package/dist/core/footer-data-provider.d.ts.map +1 -1
  311. package/dist/core/footer-data-provider.js +22 -1
  312. package/dist/core/footer-data-provider.js.map +1 -1
  313. package/dist/core/large-subagent-launch.d.ts +1 -1
  314. package/dist/core/large-subagent-launch.d.ts.map +1 -1
  315. package/dist/core/large-subagent-launch.js +7 -7
  316. package/dist/core/large-subagent-launch.js.map +1 -1
  317. package/dist/core/model-registry.d.ts +2 -0
  318. package/dist/core/model-registry.d.ts.map +1 -1
  319. package/dist/core/model-registry.js +5 -0
  320. package/dist/core/model-registry.js.map +1 -1
  321. package/dist/core/model-runtime.d.ts +4 -1
  322. package/dist/core/model-runtime.d.ts.map +1 -1
  323. package/dist/core/model-runtime.js +40 -4
  324. package/dist/core/model-runtime.js.map +1 -1
  325. package/dist/core/package-manager.d.ts.map +1 -1
  326. package/dist/core/package-manager.js.map +1 -1
  327. package/dist/core/permissions.d.ts +4 -4
  328. package/dist/core/permissions.d.ts.map +1 -1
  329. package/dist/core/permissions.js +25 -38
  330. package/dist/core/permissions.js.map +1 -1
  331. package/dist/core/plan-mode.d.ts +5 -13
  332. package/dist/core/plan-mode.d.ts.map +1 -1
  333. package/dist/core/plan-mode.js +135 -116
  334. package/dist/core/plan-mode.js.map +1 -1
  335. package/dist/core/project-trust.d.ts.map +1 -1
  336. package/dist/core/project-trust.js +1 -1
  337. package/dist/core/project-trust.js.map +1 -1
  338. package/dist/core/prompt-resource-bridge.d.ts +12 -0
  339. package/dist/core/prompt-resource-bridge.d.ts.map +1 -0
  340. package/dist/core/prompt-resource-bridge.js +9 -0
  341. package/dist/core/prompt-resource-bridge.js.map +1 -0
  342. package/dist/core/protected-targets.d.ts +6 -0
  343. package/dist/core/protected-targets.d.ts.map +1 -0
  344. package/dist/core/protected-targets.js +45 -0
  345. package/dist/core/protected-targets.js.map +1 -0
  346. package/dist/core/resource-loader.d.ts.map +1 -1
  347. package/dist/core/resource-loader.js +7 -0
  348. package/dist/core/resource-loader.js.map +1 -1
  349. package/dist/core/rollback.d.ts +19 -3
  350. package/dist/core/rollback.d.ts.map +1 -1
  351. package/dist/core/rollback.js +172 -56
  352. package/dist/core/rollback.js.map +1 -1
  353. package/dist/core/runtime-credentials.d.ts +3 -0
  354. package/dist/core/runtime-credentials.d.ts.map +1 -1
  355. package/dist/core/runtime-credentials.js +14 -1
  356. package/dist/core/runtime-credentials.js.map +1 -1
  357. package/dist/core/sdk.d.ts +3 -0
  358. package/dist/core/sdk.d.ts.map +1 -1
  359. package/dist/core/sdk.js +1 -0
  360. package/dist/core/sdk.js.map +1 -1
  361. package/dist/core/session-manager.d.ts +6 -0
  362. package/dist/core/session-manager.d.ts.map +1 -1
  363. package/dist/core/session-manager.js +95 -32
  364. package/dist/core/session-manager.js.map +1 -1
  365. package/dist/core/session-ownership.d.ts.map +1 -1
  366. package/dist/core/session-ownership.js +8 -3
  367. package/dist/core/session-ownership.js.map +1 -1
  368. package/dist/core/session-retention.d.ts.map +1 -1
  369. package/dist/core/session-retention.js +18 -7
  370. package/dist/core/session-retention.js.map +1 -1
  371. package/dist/core/session-startup-settings.d.ts +10 -0
  372. package/dist/core/session-startup-settings.d.ts.map +1 -0
  373. package/dist/core/session-startup-settings.js +70 -0
  374. package/dist/core/session-startup-settings.js.map +1 -0
  375. package/dist/core/settings-manager.d.ts +6 -0
  376. package/dist/core/settings-manager.d.ts.map +1 -1
  377. package/dist/core/settings-manager.js +19 -0
  378. package/dist/core/settings-manager.js.map +1 -1
  379. package/dist/core/subagent-event-transport.d.ts +3 -0
  380. package/dist/core/subagent-event-transport.d.ts.map +1 -0
  381. package/dist/core/subagent-event-transport.js +61 -0
  382. package/dist/core/subagent-event-transport.js.map +1 -0
  383. package/dist/core/subscriptions.d.ts +16 -7
  384. package/dist/core/subscriptions.d.ts.map +1 -1
  385. package/dist/core/subscriptions.js +96 -55
  386. package/dist/core/subscriptions.js.map +1 -1
  387. package/dist/core/trust-manager.d.ts +2 -1
  388. package/dist/core/trust-manager.d.ts.map +1 -1
  389. package/dist/core/trust-manager.js +6 -1
  390. package/dist/core/trust-manager.js.map +1 -1
  391. package/dist/core/update-check.d.ts.map +1 -1
  392. package/dist/core/update-check.js.map +1 -1
  393. package/dist/core/usage-adapters/kimi-coding.d.ts +2 -2
  394. package/dist/core/usage-adapters/kimi-coding.d.ts.map +1 -1
  395. package/dist/core/usage-adapters/kimi-coding.js +2 -2
  396. package/dist/core/usage-adapters/kimi-coding.js.map +1 -1
  397. package/dist/core/usage-adapters/openai-codex.d.ts +3 -2
  398. package/dist/core/usage-adapters/openai-codex.d.ts.map +1 -1
  399. package/dist/core/usage-adapters/openai-codex.js +3 -3
  400. package/dist/core/usage-adapters/openai-codex.js.map +1 -1
  401. package/dist/core/usage-adapters/xai.d.ts +2 -2
  402. package/dist/core/usage-adapters/xai.d.ts.map +1 -1
  403. package/dist/core/usage-adapters/xai.js +3 -3
  404. package/dist/core/usage-adapters/xai.js.map +1 -1
  405. package/dist/core/usage-adapters/zai.d.ts +2 -2
  406. package/dist/core/usage-adapters/zai.d.ts.map +1 -1
  407. package/dist/core/usage-adapters/zai.js +2 -2
  408. package/dist/core/usage-adapters/zai.js.map +1 -1
  409. package/dist/core/usage-service.d.ts +9 -2
  410. package/dist/core/usage-service.d.ts.map +1 -1
  411. package/dist/core/usage-service.js +95 -50
  412. package/dist/core/usage-service.js.map +1 -1
  413. package/dist/gateway/adapters/discord.d.ts.map +1 -1
  414. package/dist/gateway/adapters/discord.js +2 -2
  415. package/dist/gateway/adapters/discord.js.map +1 -1
  416. package/dist/gateway/agent-bridge.d.ts +9 -1
  417. package/dist/gateway/agent-bridge.d.ts.map +1 -1
  418. package/dist/gateway/agent-bridge.js +91 -37
  419. package/dist/gateway/agent-bridge.js.map +1 -1
  420. package/dist/gateway/approval.d.ts.map +1 -1
  421. package/dist/gateway/approval.js +3 -3
  422. package/dist/gateway/approval.js.map +1 -1
  423. package/dist/gateway/authz.d.ts +4 -4
  424. package/dist/gateway/authz.d.ts.map +1 -1
  425. package/dist/gateway/authz.js +8 -12
  426. package/dist/gateway/authz.js.map +1 -1
  427. package/dist/gateway/buttons.d.ts +8 -1
  428. package/dist/gateway/buttons.d.ts.map +1 -1
  429. package/dist/gateway/buttons.js +76 -18
  430. package/dist/gateway/buttons.js.map +1 -1
  431. package/dist/gateway/commands.d.ts +1 -0
  432. package/dist/gateway/commands.d.ts.map +1 -1
  433. package/dist/gateway/commands.js +12 -10
  434. package/dist/gateway/commands.js.map +1 -1
  435. package/dist/gateway/cron.d.ts +12 -11
  436. package/dist/gateway/cron.d.ts.map +1 -1
  437. package/dist/gateway/cron.js +85 -62
  438. package/dist/gateway/cron.js.map +1 -1
  439. package/dist/gateway/index.d.ts.map +1 -1
  440. package/dist/gateway/index.js +5 -4
  441. package/dist/gateway/index.js.map +1 -1
  442. package/dist/gateway/mobile-commands.d.ts +1 -0
  443. package/dist/gateway/mobile-commands.d.ts.map +1 -1
  444. package/dist/gateway/mobile-commands.js +64 -22
  445. package/dist/gateway/mobile-commands.js.map +1 -1
  446. package/dist/gateway/presenter.d.ts +12 -2
  447. package/dist/gateway/presenter.d.ts.map +1 -1
  448. package/dist/gateway/presenter.js +74 -39
  449. package/dist/gateway/presenter.js.map +1 -1
  450. package/dist/gateway/router.d.ts +2 -2
  451. package/dist/gateway/router.d.ts.map +1 -1
  452. package/dist/gateway/router.js +22 -9
  453. package/dist/gateway/router.js.map +1 -1
  454. package/dist/gateway/service.d.ts +2 -0
  455. package/dist/gateway/service.d.ts.map +1 -1
  456. package/dist/gateway/service.js +153 -0
  457. package/dist/gateway/service.js.map +1 -1
  458. package/dist/gateway/setup.d.ts.map +1 -1
  459. package/dist/gateway/setup.js +6 -4
  460. package/dist/gateway/setup.js.map +1 -1
  461. package/dist/main.d.ts.map +1 -1
  462. package/dist/main.js +86 -33
  463. package/dist/main.js.map +1 -1
  464. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  465. package/dist/modes/interactive/components/assistant-message.js +6 -4
  466. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  467. package/dist/modes/interactive/components/copyable-text.d.ts.map +1 -1
  468. package/dist/modes/interactive/components/copyable-text.js +3 -2
  469. package/dist/modes/interactive/components/copyable-text.js.map +1 -1
  470. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
  471. package/dist/modes/interactive/components/extension-editor.js +1 -1
  472. package/dist/modes/interactive/components/extension-editor.js.map +1 -1
  473. package/dist/modes/interactive/components/settings-selector.d.ts +4 -0
  474. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  475. package/dist/modes/interactive/components/settings-selector.js +20 -0
  476. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  477. package/dist/modes/interactive/interactive-mode.d.ts +2 -2
  478. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  479. package/dist/modes/interactive/interactive-mode.js +104 -109
  480. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  481. package/dist/modes/interactive/smooth-streaming.d.ts.map +1 -1
  482. package/dist/modes/interactive/smooth-streaming.js.map +1 -1
  483. package/dist/modes/print-mode.d.ts.map +1 -1
  484. package/dist/modes/print-mode.js +9 -1
  485. package/dist/modes/print-mode.js.map +1 -1
  486. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  487. package/dist/modes/rpc/rpc-mode.js +2 -1
  488. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  489. package/dist/node-runtime/adapter-247RTYLS.js +16 -0
  490. package/dist/node-runtime/agent-session-services-KDMSPQDY.js +53 -0
  491. package/dist/node-runtime/{brave-UWDA3I22.js → brave-2AFFAXNN.js} +1 -1
  492. package/dist/node-runtime/{builtin-extensions-ZLAX7TUH.js → builtin-extensions-OX6KELNX.js} +9 -7
  493. package/dist/node-runtime/{chunk-QH6YL7VK.js → chunk-252ZVPPF.js} +3 -3
  494. package/dist/node-runtime/{chunk-PCEW76PM.js → chunk-2OIPYKLZ.js} +6 -6
  495. package/dist/node-runtime/{chunk-XBWPBZBN.js → chunk-2SWW7KMW.js} +1 -1
  496. package/dist/node-runtime/{chunk-UQUCFAJ3.js → chunk-2VIW3IMF.js} +40 -7
  497. package/dist/node-runtime/{chunk-UOEDI7RP.js → chunk-4KNKQGHM.js} +2 -2
  498. package/dist/node-runtime/{chunk-FQMM2EZ2.js → chunk-64XTQNLA.js} +29 -7
  499. package/dist/node-runtime/{chunk-NRKGMJYU.js → chunk-6O3IW3IA.js} +2 -2
  500. package/dist/node-runtime/{chunk-5ZQXRPMC.js → chunk-6ZZHGUSA.js} +2 -2
  501. package/dist/node-runtime/chunk-A2WO6WIN.js +1197 -0
  502. package/dist/node-runtime/{chunk-ZXSGTGJ6.js → chunk-APVM5NEU.js} +169 -148
  503. package/dist/node-runtime/{chunk-RC7DMV45.js → chunk-AYHH7YSD.js} +205 -144
  504. package/dist/node-runtime/{chunk-LWYIVUGV.js → chunk-B2IBAXNX.js} +48 -31
  505. package/dist/node-runtime/{chunk-M3LZLQW2.js → chunk-BDRGN3L2.js} +1 -0
  506. package/dist/node-runtime/{chunk-GJ2RDBRL.js → chunk-BYC6RKCN.js} +4 -2
  507. package/dist/node-runtime/{chunk-KWIYUUZK.js → chunk-C3P6Q3B2.js} +469 -283
  508. package/dist/node-runtime/{chunk-YCUZEGJG.js → chunk-DQSCFU7R.js} +17 -8
  509. package/dist/node-runtime/chunk-EBLAZVSA.js +4170 -0
  510. package/dist/node-runtime/{chunk-2KIPT4HJ.js → chunk-EPR2F3GU.js} +68 -20
  511. package/dist/node-runtime/{chunk-CSFI6YXL.js → chunk-ES6PBSIE.js} +1 -1
  512. package/dist/node-runtime/{chunk-IF24A3FH.js → chunk-EVM653DD.js} +4 -4
  513. package/dist/node-runtime/{chunk-HTFRRDSF.js → chunk-F2SMQ6ES.js} +3 -2
  514. package/dist/node-runtime/chunk-F2V2F4ZG.js +114 -0
  515. package/dist/node-runtime/chunk-FE3WZI7F.js +290 -0
  516. package/dist/node-runtime/{chunk-GYIXXQAO.js → chunk-FIRA54AC.js} +2 -5
  517. package/dist/node-runtime/{chunk-6VYZ5UFP.js → chunk-FLGEEH27.js} +1 -1
  518. package/dist/node-runtime/{chunk-5EFIU3OM.js → chunk-FTKEZL27.js} +1 -1
  519. package/dist/node-runtime/chunk-FY4A63RK.js +73 -0
  520. package/dist/node-runtime/chunk-FYIFPFXE.js +98 -0
  521. package/dist/node-runtime/{chunk-HMBGROQK.js → chunk-GLDXBBL6.js} +3 -3
  522. package/dist/node-runtime/{chunk-KWA4OC2J.js → chunk-H6YBCWKG.js} +1 -1
  523. package/dist/node-runtime/{chunk-2MI5OPMN.js → chunk-HNNHHJAB.js} +68 -50
  524. package/dist/node-runtime/{chunk-6XL67VVY.js → chunk-HUD2RFJW.js} +17 -2
  525. package/dist/node-runtime/{chunk-I54LGHWM.js → chunk-I2H5QMWW.js} +3 -3
  526. package/dist/node-runtime/chunk-IAZSK7KK.js +108 -0
  527. package/dist/node-runtime/{chunk-2HHLJWGD.js → chunk-IHHTWSXN.js} +9 -9
  528. package/dist/node-runtime/{chunk-DAPBPCBP.js → chunk-IPP5BIV5.js} +25 -3
  529. package/dist/node-runtime/{chunk-QFWG2RVL.js → chunk-IXG6F4NT.js} +11 -0
  530. package/dist/node-runtime/{chunk-RDDAZOMU.js → chunk-JL4HYQXK.js} +1 -1
  531. package/dist/node-runtime/{chunk-CDVHZOOK.js → chunk-JQYNHAKX.js} +1 -1
  532. package/dist/node-runtime/{chunk-WF7PGWRZ.js → chunk-JWEVT363.js} +37 -28
  533. package/dist/node-runtime/{chunk-2HMIRK7W.js → chunk-LHV3V67B.js} +5 -5
  534. package/dist/node-runtime/{chunk-UAEOTO52.js → chunk-MNQXDFPV.js} +6 -2
  535. package/dist/node-runtime/{chunk-IJIFHRTB.js → chunk-MQPKUHRN.js} +165 -85
  536. package/dist/node-runtime/{chunk-MPKSOJBT.js → chunk-NHATCSOI.js} +4 -7
  537. package/dist/node-runtime/{chunk-RMQZU2YU.js → chunk-NNNR3QIY.js} +1 -1
  538. package/dist/node-runtime/{chunk-RWTKOC3B.js → chunk-QBTJG3UM.js} +1 -1
  539. package/dist/node-runtime/{chunk-E4D3IGP2.js → chunk-QNVMKNNN.js} +20 -17
  540. package/dist/node-runtime/{chunk-GS42T6MX.js → chunk-QW3AAHWN.js} +1 -1
  541. package/dist/node-runtime/{chunk-7S3T6YEA.js → chunk-R4WSB2MQ.js} +5 -5
  542. package/dist/node-runtime/{chunk-B4HP6ZWM.js → chunk-RHCGYWO7.js} +1 -1
  543. package/dist/node-runtime/{chunk-3XPLBUEM.js → chunk-RLGY2QIL.js} +49 -59
  544. package/dist/node-runtime/{chunk-KKUTQQV7.js → chunk-RYRGL7P4.js} +1 -1
  545. package/dist/node-runtime/{chunk-AD6VXAO7.js → chunk-TCT6PCUR.js} +47 -115
  546. package/dist/node-runtime/chunk-U5F4IC7R.js +53 -0
  547. package/dist/node-runtime/{chunk-OCVIXVTZ.js → chunk-UBWW2PID.js} +13 -2
  548. package/dist/node-runtime/{chunk-HFVZUPFJ.js → chunk-UNUZICC4.js} +3 -3
  549. package/dist/node-runtime/{chunk-LQP3RB67.js → chunk-UYRKUKFE.js} +1 -1
  550. package/dist/node-runtime/{chunk-DSIKTUPW.js → chunk-VSUEAI7O.js} +2993 -3820
  551. package/dist/node-runtime/{chunk-NAY6UUQZ.js → chunk-WDIVLMOH.js} +1 -1
  552. package/dist/node-runtime/{chunk-E24EO34J.js → chunk-WPXUR3HE.js} +1 -1
  553. package/dist/node-runtime/{chunk-SLVOAQOY.js → chunk-WXYNALHD.js} +113 -1
  554. package/dist/node-runtime/{chunk-KJ6DWS3K.js → chunk-XEOCUEUJ.js} +121 -60
  555. package/dist/node-runtime/chunk-YD3IZAZ7.js +47 -0
  556. package/dist/node-runtime/chunk-YSB6URMT.js +41 -0
  557. package/dist/node-runtime/{chunk-VQFSUJJG.js → chunk-ZDJUR45D.js} +430 -129
  558. package/dist/node-runtime/{chunk-YDO2F2IA.js → chunk-ZEVFBFNF.js} +95 -142
  559. package/dist/node-runtime/chunk-ZIQUS5QO.js +180 -0
  560. package/dist/node-runtime/cli-runtime.js +4 -4
  561. package/dist/node-runtime/{command-6WDOYKS6.js → command-3HMSY6W2.js} +5 -5
  562. package/dist/node-runtime/{commands-NZLSOHPE.js → commands-D6A6H4TS.js} +11 -16
  563. package/dist/node-runtime/commands-OCSSEEWJ.js +37 -0
  564. package/dist/node-runtime/{config-QDD5PUE2.js → config-CU7M7BTK.js} +1 -1
  565. package/dist/node-runtime/{config-D4QUPAHX.js → config-DS7XLMEM.js} +2 -2
  566. package/dist/node-runtime/{direct-tool-executor-77GW4F5P.js → direct-tool-executor-2QJXVQD2.js} +8 -10
  567. package/dist/node-runtime/{exa-LL64QZR2.js → exa-6VBZNPGE.js} +1 -1
  568. package/dist/node-runtime/{export-html-VM4J2MNR.js → export-html-BRWF5AHI.js} +4 -4
  569. package/dist/node-runtime/{extension-input-E7BJZ35H.js → extension-input-VBBMX7YV.js} +5 -5
  570. package/dist/node-runtime/{extension-selector-WU42XDTU.js → extension-selector-T5AOG5XB.js} +5 -5
  571. package/dist/node-runtime/{extract-EQJE7FZZ.js → extract-BFX2N35A.js} +3 -3
  572. package/dist/node-runtime/{gateway-INAYBF4Q.js → gateway-6623C2U3.js} +61 -53
  573. package/dist/node-runtime/{gemini-search-35OCRFLN.js → gemini-search-C66QHDT6.js} +2 -2
  574. package/dist/node-runtime/{gemini-url-context-UQY3PHHW.js → gemini-url-context-T7DEK73R.js} +3 -3
  575. package/dist/node-runtime/{github-extract-F64RZOEA.js → github-extract-HOGE3D6F.js} +107 -38
  576. package/dist/node-runtime/{goal-NJEE5CTU.js → goal-AIHEDUYA.js} +5 -5
  577. package/dist/node-runtime/index.js +54 -48
  578. package/dist/node-runtime/{init-HS6NQXSK.js → init-JBQJIPYI.js} +3 -4
  579. package/dist/node-runtime/{install-cli-KL4UDDAD.js → install-cli-INGHIVBY.js} +30 -25
  580. package/dist/node-runtime/interactive-mode-FM5DNUSW.js +74 -0
  581. package/dist/node-runtime/{interactive-view-NGFAMHPW.js → interactive-view-K33PM4OS.js} +8 -8
  582. package/dist/node-runtime/{lsp-manager-3ASUSO4T.js → lsp-manager-S554V5HR.js} +240 -155
  583. package/dist/node-runtime/{lunr-browser-IR7TL3J7.js → lunr-browser-H4FDOR3C.js} +7 -7
  584. package/dist/node-runtime/lunr-computer-use-VDP2QNRQ.js +158 -0
  585. package/dist/node-runtime/{lunr-cron-LWIZJM2N.js → lunr-cron-LKVA5CZZ.js} +94 -79
  586. package/dist/node-runtime/main.js +42 -39
  587. package/dist/node-runtime/{mobile-commands-J7OJEKFO.js → mobile-commands-XT3NQXLD.js} +13 -12
  588. package/dist/node-runtime/{model-runtime-OO5HFLWE.js → model-runtime-MZ2JMDV4.js} +4 -4
  589. package/dist/node-runtime/{openai-search-B3MSNCQA.js → openai-search-K72LJDYN.js} +1 -1
  590. package/dist/node-runtime/{package-manager-cli-VYZM5WHN.js → package-manager-cli-CYM262SI.js} +20 -19
  591. package/dist/node-runtime/{parallel-AI2MNSCU.js → parallel-X724NCNU.js} +1 -1
  592. package/dist/node-runtime/{perplexity-QVJW3I35.js → perplexity-RDHQHVMK.js} +2 -2
  593. package/dist/node-runtime/{pi-intercom-QM53RLTS.js → pi-intercom-NHHEPBMI.js} +2 -2
  594. package/dist/node-runtime/{pi-mcp-adapter-5UKBZP44.js → pi-mcp-adapter-PP3GQJQ2.js} +98 -94
  595. package/dist/node-runtime/{pi-ollama-cloud-2F3Y2QNM.js → pi-ollama-cloud-4MNWIMFN.js} +11 -24
  596. package/dist/node-runtime/{pi-prompt-template-model-QWTCGLJU.js → pi-prompt-template-model-FTGELLS5.js} +32 -36
  597. package/dist/node-runtime/{pi-subagents-DNY7EAIG.js → pi-subagents-LT3CTO4E.js} +114 -116
  598. package/dist/node-runtime/{pi-web-access-WTGMNZ32.js → pi-web-access-Z3LP246C.js} +144 -108
  599. package/dist/node-runtime/{print-mode-XSFM26EL.js → print-mode-2XHN5SUA.js} +4 -3
  600. package/dist/node-runtime/{process-registry-4FAKZQOL.js → process-registry-Q4QWIU33.js} +3 -3
  601. package/dist/node-runtime/{proxy-modes-LGEUYD7R.js → proxy-modes-VEGC6QG5.js} +9 -13
  602. package/dist/node-runtime/rpc-entry.js +42 -39
  603. package/dist/node-runtime/{rpc-mode-O3XV4SID.js → rpc-mode-32DHJPEJ.js} +4 -4
  604. package/dist/node-runtime/{runtime-4VA6JKNF.js → runtime-EDUUGAQD.js} +56 -46
  605. package/dist/node-runtime/runtime-UGXM4NPQ.js +21 -0
  606. package/dist/node-runtime/{runtime-bridges-VRDDR73P.js → runtime-bridges-DNKMNJCF.js} +8 -7
  607. package/dist/node-runtime/{service-MDQIPQ26.js → service-IHLGFLBT.js} +6 -4
  608. package/dist/node-runtime/{session-handoff-GWARVEWT.js → session-handoff-LNSPDTKY.js} +4 -4
  609. package/dist/node-runtime/{session-manager-JB5J6XBN.js → session-manager-YIFIAVGC.js} +3 -3
  610. package/dist/node-runtime/{session-selector-GIM4DHQ2.js → session-selector-I73U3EIO.js} +7 -7
  611. package/dist/node-runtime/{settings-manager-J4SPQPDJ.js → settings-manager-P2TKGYTR.js} +6 -5
  612. package/dist/node-runtime/{setup-JBKOLJ6F.js → setup-H7CCELIL.js} +15 -1
  613. package/dist/node-runtime/{setup-CQ2NLVK5.js → setup-OLQ4GXWS.js} +22 -21
  614. package/dist/node-runtime/{src-IVPNZ2BX.js → src-6RV4PXKJ.js} +64 -36
  615. package/dist/node-runtime/{subagent-executor-KZZQGAKV.js → subagent-executor-Q5F7DBVM.js} +141 -62
  616. package/dist/node-runtime/{tavily-WEZFVFP7.js → tavily-KZBFYQB6.js} +1 -1
  617. package/dist/node-runtime/{theme-UOO5RVFN.js → theme-YLVZKKZD.js} +2 -2
  618. package/dist/node-runtime/{trust-manager-MMISNCYO.js → trust-manager-ZCU76D23.js} +2 -2
  619. package/dist/node-runtime/{update-cli-GTFJC7XK.js → update-cli-F3XXJANQ.js} +7 -6
  620. package/dist/node-runtime/{usage-service-LFB2SWYV.js → usage-service-CPAGBED5.js} +1 -1
  621. package/dist/node-runtime/{video-extract-OOZHR7SU.js → video-extract-UPKYIBW3.js} +3 -3
  622. package/dist/node-runtime/workflow-ICDI4N3J.js +767 -0
  623. package/dist/node-runtime/{youtube-extract-FNPAUNHU.js → youtube-extract-77NT7FWH.js} +4 -4
  624. package/dist/utils/clipboard-image.d.ts.map +1 -1
  625. package/dist/utils/clipboard-image.js.map +1 -1
  626. package/dist/utils/exif-orientation.d.ts.map +1 -1
  627. package/dist/utils/exif-orientation.js +25 -10
  628. package/dist/utils/exif-orientation.js.map +1 -1
  629. package/dist/utils/image-resize-core.d.ts +2 -0
  630. package/dist/utils/image-resize-core.d.ts.map +1 -1
  631. package/dist/utils/image-resize-core.js +12 -0
  632. package/dist/utils/image-resize-core.js.map +1 -1
  633. package/dist/utils/paths.d.ts +4 -0
  634. package/dist/utils/paths.d.ts.map +1 -1
  635. package/dist/utils/paths.js +33 -2
  636. package/dist/utils/paths.js.map +1 -1
  637. package/dist/utils/sanitize-terminal-text.d.ts +7 -0
  638. package/dist/utils/sanitize-terminal-text.d.ts.map +1 -0
  639. package/dist/utils/sanitize-terminal-text.js +67 -0
  640. package/dist/utils/sanitize-terminal-text.js.map +1 -0
  641. package/docs/browser.md +1 -1
  642. package/docs/computer-use.md +362 -0
  643. package/docs/custom-provider.md +3 -3
  644. package/docs/extensions.md +8 -4
  645. package/docs/features.md +22 -12
  646. package/docs/keybindings.md +1 -1
  647. package/docs/models.md +5 -5
  648. package/docs/packages.md +1 -1
  649. package/docs/providers.md +2 -2
  650. package/docs/rpc.md +7 -7
  651. package/docs/security.md +10 -5
  652. package/docs/sessions.md +2 -2
  653. package/docs/skills.md +1 -1
  654. package/docs/terminal-setup.md +7 -7
  655. package/docs/themes.md +1 -1
  656. package/docs/usage.md +1 -1
  657. package/examples/extensions/auto-commit-on-exit.ts +1 -1
  658. package/examples/extensions/bash-spawn-hook.ts +1 -1
  659. package/examples/extensions/built-in-tool-renderer.ts +1 -1
  660. package/examples/extensions/claude-rules.ts +1 -1
  661. package/examples/extensions/commands.ts +1 -1
  662. package/examples/extensions/custom-compaction.ts +1 -1
  663. package/examples/extensions/custom-provider-anthropic/index.ts +3 -3
  664. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  665. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  666. package/examples/extensions/custom-provider-gitlab-duo/index.ts +1 -1
  667. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  668. package/examples/extensions/doom-overlay/index.ts +1 -1
  669. package/examples/extensions/git-merge-and-resolve.ts +2 -2
  670. package/examples/extensions/gondolin/index.ts +1 -1
  671. package/examples/extensions/gondolin/package-lock.json +2 -2
  672. package/examples/extensions/gondolin/package.json +1 -1
  673. package/examples/extensions/hidden-thinking-label.ts +1 -1
  674. package/examples/extensions/inline-bash.ts +2 -2
  675. package/examples/extensions/input-transform-streaming.ts +2 -2
  676. package/examples/extensions/input-transform.ts +2 -2
  677. package/examples/extensions/interactive-shell.ts +1 -1
  678. package/examples/extensions/kimi-deferred-tools.ts +1 -1
  679. package/examples/extensions/mac-system-theme.ts +1 -1
  680. package/examples/extensions/minimal-mode.ts +1 -1
  681. package/examples/extensions/modal-editor.ts +1 -1
  682. package/examples/extensions/model-status.ts +1 -1
  683. package/examples/extensions/notify.ts +3 -3
  684. package/examples/extensions/overlay-qa-tests.ts +1 -1
  685. package/examples/extensions/overlay-test.ts +1 -1
  686. package/examples/extensions/pirate.ts +1 -1
  687. package/examples/extensions/preset.ts +3 -3
  688. package/examples/extensions/project-trust.ts +4 -4
  689. package/examples/extensions/prompt-customizer.ts +1 -1
  690. package/examples/extensions/rainbow-editor.ts +1 -1
  691. package/examples/extensions/rpc-demo.ts +1 -1
  692. package/examples/extensions/sandbox/index.ts +7 -7
  693. package/examples/extensions/sandbox/package-lock.json +2 -2
  694. package/examples/extensions/sandbox/package.json +1 -1
  695. package/examples/extensions/shutdown-command.ts +5 -5
  696. package/examples/extensions/ssh.ts +2 -2
  697. package/examples/extensions/subagent/README.md +3 -3
  698. package/examples/extensions/subagent/index.ts +2 -2
  699. package/examples/extensions/titlebar-spinner.ts +1 -1
  700. package/examples/extensions/tool-override.ts +1 -1
  701. package/examples/extensions/tools.ts +1 -1
  702. package/examples/extensions/with-deps/package-lock.json +2 -2
  703. package/examples/extensions/with-deps/package.json +1 -1
  704. package/examples/extensions/working-indicator.ts +1 -1
  705. package/examples/extensions/working-message-test.ts +1 -1
  706. package/examples/sdk/01-minimal.ts +1 -1
  707. package/examples/sdk/03-custom-prompt.ts +1 -1
  708. package/examples/sdk/04-skills.ts +1 -1
  709. package/examples/sdk/06-extensions.ts +2 -2
  710. package/examples/sdk/08-prompt-templates.ts +1 -1
  711. package/install-lock/package-lock.json +3841 -0
  712. package/install-lock/package.json +18 -0
  713. package/native/computer-use/LICENSE.md +21 -0
  714. package/npm-shrinkwrap.json +3858 -0
  715. package/package.json +15 -9
  716. package/dist/modes/interactive/components/exit-card.d.ts +0 -22
  717. package/dist/modes/interactive/components/exit-card.d.ts.map +0 -1
  718. package/dist/modes/interactive/components/exit-card.js +0 -69
  719. package/dist/modes/interactive/components/exit-card.js.map +0 -1
  720. package/dist/node-runtime/agent-session-services-YXXFCP5J.js +0 -49
  721. package/dist/node-runtime/chunk-4HXHDDCF.js +0 -16
  722. package/dist/node-runtime/chunk-4TLO4PO2.js +0 -3427
  723. package/dist/node-runtime/chunk-AUXVGBO4.js +0 -19
  724. package/dist/node-runtime/chunk-OVX6X377.js +0 -50
  725. package/dist/node-runtime/chunk-QTU6AKNJ.js +0 -773
  726. package/dist/node-runtime/chunk-TORR5XBV.js +0 -356
  727. package/dist/node-runtime/commands-QC6VUZJQ.js +0 -36
  728. package/dist/node-runtime/interactive-mode-Z5M7WYYZ.js +0 -72
  729. package/dist/node-runtime/mcp-auth-flow-QIXHW6QN.js +0 -32
@@ -1 +1 @@
1
- {"version":3,"file":"jobs.js","sourceRoot":"","sources":["../../../src/core/cron/jobs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC9G,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EACN,iCAAiC,EACjC,2BAA2B,EAC3B,gBAAgB,GAChB,MAAM,wBAAwB,CAAC;AAgFhC,8EAA8E;AAC9E,YAAY;AACZ,8EAA8E;AAE9E,+DAA+D;AAC/D,MAAM,CAAC,MAAM,iBAAiB,GAAG,OAAO,CAAC;AACzC,gEAAgE;AAChE,MAAM,YAAY,GAAG,OAAO,CAAC;AAC7B,MAAM,YAAY,GAAG,SAAS,CAAC;AAC/B,gCAAgC;AAChC,MAAM,CAAC,MAAM,gBAAgB,GAAG,EAAE,CAAC;AACnC,4DAA4D;AAC5D,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,CAAC;AAEvC,MAAM,YAAY,GAAG,EAAE,CAAC;AAExB,8EAA8E;AAC9E,sBAAsB;AACtB,8EAA8E;AAE9E,IAAI,eAAmC,CAAC;AACxC,IAAI,KAA4B,CAAC;AACjC,IAAI,UAAU,GAAkB,OAAO,CAAC,OAAO,EAAE,CAAC;AAElD;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,GAAuB,EAAQ;IAC7D,eAAe,GAAG,GAAG,CAAC;IACtB,KAAK,GAAG,SAAS,CAAC;IAClB,UAAU,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;AAAA,CAC/B;AAED,SAAS,OAAO,GAAW;IAC1B,OAAO,IAAI,CAAC,eAAe,IAAI,WAAW,EAAE,EAAE,MAAM,CAAC,CAAC;AAAA,CACtD;AAED,SAAS,QAAQ,GAAW;IAC3B,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,WAAW,CAAC,CAAC;AAAA,CACpC;AAED,SAAS,SAAS,CAAC,KAAa,EAAU;IACzC,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;AAAA,CACxC;AAED,SAAS,QAAQ,GAAc;IAC9B,IAAI,KAAK;QAAE,OAAO,KAAK,CAAC;IACxB,MAAM,IAAI,GAAG,QAAQ,EAAE,CAAC;IACxB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACvB,KAAK,GAAG,EAAE,CAAC;QACX,OAAO,KAAK,CAAC;IACd,CAAC;IACD,IAAI,CAAC;QACJ,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;QACvD,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,CAAE,MAAM,CAAC,IAAkB,CAAC,CAAC,CAAC,EAAE,CAAC;IACvE,CAAC;IAAC,MAAM,CAAC;QACR,KAAK,GAAG,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,KAAK,CAAC;AAAA,CACb;AAED,uGAAuG;AACvG,SAAS,OAAO,GAAkB;IACjC,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,KAAK,IAAI,EAAE,EAAE,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACtG,MAAM,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;QAC/B,SAAS,CAAC,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1C,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,cAAc,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAC3E,aAAa,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;QACtC,UAAU,CAAC,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAC;IAAA,CAC5B,CAAC,CAAC;IACH,UAAU,GAAG,CAAC,CAAC,IAAI,CAClB,GAAG,EAAE,CAAC,SAAS,EACf,GAAG,EAAE,CAAC,SAAS,CACf,CAAC;IACF,OAAO,CAAC,CAAC;AAAA,CACT;AAWD,MAAM,WAAW,GAAG,4BAA4B,CAAC;AACjD,MAAM,WAAW,GAAG,oBAAoB,CAAC;AAEzC,SAAS,SAAS,CAAC,KAAa,EAAE,IAAY,EAAU;IACvD,MAAM,CAAC,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IAC7B,MAAM,MAAM,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACrD,OAAO,KAAK,GAAG,MAAM,CAAC;AAAA,CACtB;AAED;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,KAAa,EAAE,GAAG,GAAS,IAAI,IAAI,EAAE,EAAkB;IACpF,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC/C,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;IAEhD,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxC,IAAI,QAAQ,EAAE,CAAC;QACd,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5D,IAAI,OAAO,IAAI,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,IAAI,GAAG,CAAC,CAAC;QACjE,OAAO;YACN,QAAQ,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE;YACvC,eAAe,EAAE,SAAS,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,EAAE;SAC3E,CAAC;IACH,CAAC;IAED,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxC,IAAI,QAAQ,EAAE,CAAC;QACd,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5D,IAAI,OAAO,IAAI,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,IAAI,GAAG,CAAC,CAAC;QACjE,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,OAAO,GAAG,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;QACvE,OAAO,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC;IACrE,CAAC;IAED,IAAI,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACrC,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC5B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;YACvB,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;YACzC,OAAO,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC;QACtE,CAAC;IACF,CAAC;IAED,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClC,IAAI,CAAC;YACJ,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CAAC,4BAA4B,IAAI,MAAM,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC3G,CAAC;QACD,OAAO,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC;IAC1E,CAAC;IAED,MAAM,IAAI,KAAK,CACd,2BAA2B,KAAK,gFAAgF,CAChH,CAAC;AAAA,CACF;AAED,8EAA8E;AAC9E,uBAAuB;AACvB,8EAA8E;AAE9E;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,GAAY,EAAE,GAAG,GAAS,IAAI,IAAI,EAAE,EAAe;IACjF,MAAM,CAAC,GAAG,GAAG,CAAC,QAAQ,CAAC;IACvB,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QACvB,IAAI,GAAG,CAAC,MAAM,CAAC,SAAS,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;QAC1C,IAAI,CAAC,CAAC,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QAC1B,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAChC,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;YAAE,OAAO,IAAI,CAAC;QAC/C,OAAO,GAAG,CAAC,OAAO,EAAE,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,iBAAiB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;IAC5E,CAAC;IACD,IAAI,CAAC,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC/E,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC;IAC7D,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,IAAK,CAAC,CAAC;IAC/B,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;AAAA,CACnE;AAED,uFAAuF;AACvF,SAAS,QAAQ,CAAC,GAAY,EAAE,GAAS,EAAU;IAClD,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,UAAU;QAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC;IAClF,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAClC,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAK,CAAC,CAAC;QAC1C,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,CAAC,CAAC;YAAE,OAAO,YAAY,CAAC;QAC5B,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAC1B,IAAI,CAAC,CAAC;YAAE,OAAO,YAAY,CAAC;QAC5B,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;IAC/C,CAAC;IACD,OAAO,CAAC,CAAC;AAAA,CACT;AAED,4DAA4D;AAC5D,SAAS,aAAa,CAAC,GAAY,EAAE,KAAW,EAAe;IAC9D,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QACtC,MAAM,MAAM,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC;QACpD,IAAI,MAAM,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QAC7B,2FAA2F;QAC3F,IAAI,IAAI,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,GAAG,MAAM,CAAC;QAC1G,OAAO,IAAI,IAAI,KAAK,CAAC,OAAO,EAAE;YAAE,IAAI,IAAI,MAAM,CAAC;QAC/C,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC;IACvB,CAAC;IACD,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAClC,OAAO,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAK,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACpD,CAAC;IACD,OAAO,IAAI,CAAC;AAAA,CACZ;AAED,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E,IAAI,YAAY,GAAa,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;AACxD,IAAI,gBAAsG,CAAC;AAE3G;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAe,EAAQ;IAC1D,YAAY,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAAA,CACvD;AAED;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CACtC,EAAwF,EACjF;IACP,gBAAgB,GAAG,EAAE,CAAC;AAAA,CACtB;AAED,mDAAmD;AACnD,MAAM,UAAU,mBAAmB,GAAS;IAC3C,YAAY,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;IAC1C,gBAAgB,GAAG,SAAS,CAAC;AAAA,CAC7B;AAED,SAAS,eAAe,CAAC,OAAe,EAAE,IAAY,EAAW;IAChE,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACrD,MAAM,QAAQ,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACxD,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,QAAQ,GAAG,CAAC,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,QAAQ,IAAI,CAAC,CAAC;AAAA,CAC5G;AAED,SAAS,eAAe,CAAC,OAAe,EAAsB;IAC7D,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACnC,IAAI,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,eAAe,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC;QAC3F,OAAO,WAAW,OAAO,2BAA2B,CAAC;IACtD,CAAC;IACD,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,eAAe,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC;QACpE,OAAO,WAAW,OAAO,iCAAiC,CAAC;IAC5D,CAAC;IACD,OAAO,SAAS,CAAC;AAAA,CACjB;AAED,SAAS,oBAAoB,CAAC,OAAe,EAAE,MAA6B,EAAsB;IACjG,IAAI,2BAA2B,CAAC,OAAO,CAAC,IAAI,CAAC,gBAAgB,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACjF,OAAO,iCAAiC,EAAE,CAAC;IAC5C,CAAC;IACD,OAAO,gBAAgB,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;AAAA,CAC3C;AAED,SAAS,UAAU,CAAC,MAAc,EAAU;IAC3C,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAChE,OAAO,CAAC,KAAK,IAAI,UAAU,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC;AAAA,CACpD;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,KAAqB,EAAoB;IACxE,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IACnC,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAC3D,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QACnB,MAAM,GAAG,GAAG,eAAe,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC3C,IAAI,GAAG;YAAE,MAAM,IAAI,KAAK,CAAC,cAAc,GAAG,EAAE,CAAC,CAAC;IAC/C,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QACnB,MAAM,GAAG,GAAG,oBAAoB,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QAC9D,IAAI,GAAG;YAAE,MAAM,IAAI,KAAK,CAAC,cAAc,GAAG,EAAE,CAAC,CAAC;IAC/C,CAAC;IACD,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,MAAM,MAAM,GAAG,aAAa,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;IAClD,MAAM,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,MAAM,CAAC;IAClD,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC;IACpD,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC;QAC/D,MAAM,IAAI,KAAK,CAAC,4DAA4D,KAAK,EAAE,CAAC,CAAC;IACtF,CAAC;IACD,MAAM,GAAG,GAAY;QACpB,EAAE,EAAE,UAAU,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;QACjD,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,YAAY,CAAC;QACvE,MAAM;QACN,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,eAAe,EAAE,MAAM,CAAC,eAAe;QACvC,MAAM,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,EAAE;QAC/B,OAAO,EAAE,IAAI;QACb,KAAK,EAAE,WAAW;QAClB,SAAS,EAAE,GAAG,CAAC,WAAW,EAAE;QAC5B,SAAS,EAAE,IAAI;QACf,SAAS,EAAE,IAAI;QACf,UAAU,EAAE,IAAI;QAChB,SAAS,EAAE,IAAI;QACf,iBAAiB,EAAE,IAAI;QACvB,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,OAAO;QACzC,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,IAAI;QAC5B,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,OAAO,EAAE,KAAK,CAAC,OAAO;KACtB,CAAC;IACF,GAAG,CAAC,SAAS,GAAG,cAAc,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,WAAW,EAAE,IAAI,IAAI,CAAC;IAChE,QAAQ,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACrB,MAAM,OAAO,EAAE,CAAC;IAChB,OAAO,GAAG,CAAC;AAAA,CACX;AAED,qGAAqG;AACrG,MAAM,UAAU,MAAM,CAAC,QAAgB,EAAW;IACjD,MAAM,IAAI,GAAG,QAAQ,EAAE,CAAC;IACxB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC;IACjD,IAAI,IAAI;QAAE,OAAO,IAAI,CAAC;IACtB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;IACvD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;IAC1C,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CACd,kBAAkB,QAAQ,mBAAmB,MAAM,CAAC,MAAM,aAAa,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAC5G,CAAC;IACH,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,wBAAwB,QAAQ,GAAG,CAAC,CAAC;AAAA,CACrD;AAED,MAAM,UAAU,QAAQ,GAAc;IACrC,OAAO,CAAC,GAAG,QAAQ,EAAE,CAAC,CAAC;AAAA,CACvB;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,QAAgB,EAAE,KAAe,EAAoB;IACpF,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC7B,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS;QAAE,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,YAAY,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC;IAC9F,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QACjC,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YACnB,MAAM,GAAG,GAAG,eAAe,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC3C,IAAI,GAAG;gBAAE,MAAM,IAAI,KAAK,CAAC,cAAc,GAAG,EAAE,CAAC,CAAC;QAC/C,CAAC;QACD,GAAG,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;IAC7B,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QACjC,MAAM,GAAG,GAAG,oBAAoB,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;QAC5E,IAAI,GAAG;YAAE,MAAM,IAAI,KAAK,CAAC,cAAc,GAAG,EAAE,CAAC,CAAC;QAC9C,GAAG,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,OAAO,CAAC;IAC/C,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAChC,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QACnC,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAC3D,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC;IACrB,CAAC;IACD,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QAClC,MAAM,MAAM,GAAG,aAAa,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC7C,GAAG,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;QAC/B,GAAG,CAAC,eAAe,GAAG,MAAM,CAAC,eAAe,CAAC;QAC7C,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,MAAM;YAAE,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC;QAC1D,GAAG,CAAC,SAAS,GAAG,cAAc,CAAC,GAAG,CAAC,EAAE,WAAW,EAAE,IAAI,IAAI,CAAC;IAC5D,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS;QAAE,GAAG,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;IAC7D,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAC/B,IAAI,KAAK,CAAC,KAAK,KAAK,IAAI,IAAI,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC;YACjF,MAAM,IAAI,KAAK,CAAC,4DAA4D,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;QAC5F,CAAC;QACD,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,MAAM;YAAE,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;IAClE,CAAC;IACD,IAAI,KAAK,CAAC,WAAW,KAAK,SAAS;QAAE,GAAG,CAAC,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC;IACzE,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS;QAAE,GAAG,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;IAC1D,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS;QAAE,GAAG,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;IACnE,IAAI,KAAK,CAAC,iBAAiB,KAAK,SAAS;QAAE,GAAG,CAAC,iBAAiB,GAAG,KAAK,CAAC,iBAAiB,CAAC;IAC3F,MAAM,OAAO,EAAE,CAAC;IAChB,OAAO,GAAG,CAAC;AAAA,CACX;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,QAAgB,EAAoB;IAClE,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC7B,IAAI,GAAG,CAAC,KAAK,KAAK,WAAW;QAAE,GAAG,CAAC,KAAK,GAAG,QAAQ,CAAC;IACpD,MAAM,OAAO,EAAE,CAAC;IAChB,OAAO,GAAG,CAAC;AAAA,CACX;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,QAAgB,EAAoB;IACnE,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC7B,IAAI,GAAG,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC5B,GAAG,CAAC,KAAK,GAAG,WAAW,CAAC;QACxB,GAAG,CAAC,SAAS,GAAG,cAAc,CAAC,GAAG,CAAC,EAAE,WAAW,EAAE,IAAI,IAAI,CAAC;IAC5D,CAAC;IACD,MAAM,OAAO,EAAE,CAAC;IAChB,OAAO,GAAG,CAAC;AAAA,CACX;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,QAAgB,EAAoB;IACnE,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC7B,MAAM,IAAI,GAAG,QAAQ,EAAE,CAAC;IACxB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IAClC,MAAM,OAAO,EAAE,CAAC;IAChB,OAAO,GAAG,CAAC;AAAA,CACX;AAED,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,GAAG,GAAS,IAAI,IAAI,EAAE,EAAsB;IAC5E,MAAM,GAAG,GAAc,EAAE,CAAC;IAC1B,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,EAAE,CAAC;QAC9B,IAAI,CAAC,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,KAAK,KAAK,QAAQ,IAAI,GAAG,CAAC,KAAK,KAAK,WAAW;YAAE,SAAS;QAClF,IAAI,CAAC,GAAG,CAAC,SAAS;YAAE,SAAS;QAC7B,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC;QAC/C,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,OAAO,EAAE,GAAG,IAAI;YAAE,SAAS;QAEzD,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAClC,IAAI,GAAG,CAAC,OAAO,EAAE,GAAG,IAAI,IAAI,iBAAiB,EAAE,CAAC;gBAC/C,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACf,CAAC;iBAAM,CAAC;gBACP,GAAG,CAAC,KAAK,GAAG,OAAO,CAAC;gBACpB,GAAG,CAAC,UAAU,GAAG,OAAO,CAAC;gBACzB,GAAG,CAAC,SAAS,GAAG,yDAAyD,CAAC;gBAC1E,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC;gBACrB,OAAO,GAAG,IAAI,CAAC;YAChB,CAAC;YACD,SAAS;QACV,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,EAAE,YAAY,CAAC,EAAE,YAAY,CAAC,CAAC;QACrF,IAAI,GAAG,CAAC,OAAO,EAAE,GAAG,IAAI,GAAG,KAAK,EAAE,CAAC;YAClC,GAAG,CAAC,SAAS,GAAG,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,WAAW,EAAE,IAAI,IAAI,CAAC;YAC/D,OAAO,GAAG,IAAI,CAAC;QAChB,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACf,CAAC;IACD,IAAI,OAAO;QAAE,MAAM,OAAO,EAAE,CAAC;IAC7B,OAAO,GAAG,CAAC;AAAA,CACX;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,KAAa,EAAoB;IACrE,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC1B,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAClC,2EAA2E;QAC3E,+EAA+E;QAC/E,GAAG,CAAC,SAAS,GAAG,aAAa,CAAC,GAAG,EAAE,IAAI,IAAI,EAAE,CAAC,EAAE,WAAW,EAAE,IAAI,cAAc,CAAC,GAAG,CAAC,EAAE,WAAW,EAAE,IAAI,IAAI,CAAC;QAC5G,MAAM,OAAO,EAAE,CAAC;IACjB,CAAC;IACD,OAAO,GAAG,CAAC;AAAA,CACX;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,KAAa,EAAE,MAAiD,EAAoB;IACpH,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC1B,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,GAAG,CAAC,SAAS,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;IAClC,GAAG,CAAC,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC;IAC/B,GAAG,CAAC,SAAS,GAAG,MAAM,CAAC,KAAK,IAAI,IAAI,CAAC;IACrC,GAAG,CAAC,MAAM,CAAC,SAAS,IAAI,CAAC,CAAC;IAC1B,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,KAAK,IAAI,IAAI,GAAG,CAAC,MAAM,CAAC,SAAS,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAC3E,GAAG,CAAC,KAAK,GAAG,WAAW,CAAC;QACxB,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC;IACtB,CAAC;SAAM,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QAC7C,4EAA4E;QAC5E,8EAA8E;QAC9E,yDAAyD;QACzD,MAAM,OAAO,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;QAC9D,IAAI,OAAO,CAAC,OAAO,EAAE,GAAG,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC;YACvC,iEAA+D;YAC/D,GAAG,CAAC,SAAS,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;QACvC,CAAC;aAAM,CAAC;YACP,GAAG,CAAC,SAAS,GAAG,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,WAAW,EAAE,IAAI,IAAI,CAAC;QAChE,CAAC;IACF,CAAC;SAAM,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QACzC,GAAG,CAAC,SAAS,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAK,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,WAAW,EAAE,IAAI,IAAI,CAAC;IAClF,CAAC;IACD,MAAM,OAAO,EAAE,CAAC;IAChB,OAAO,GAAG,CAAC;AAAA,CACX;AAED,8EAA8E;AAC9E,iBAAiB;AACjB,8EAA8E;AAE9E,SAAS,WAAW,CAAC,CAAO,EAAU;IACrC,MAAM,CAAC,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACpD,OAAO,GAAG,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,EAAE,CAAC;AAAA,CAClI;AAED,SAAS,UAAU,CAAC,KAAa,EAAQ;IACxC,MAAM,CAAC,GAAG,kDAAkD,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACzE,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,IAAI,EAAE,CAAC;IAC1B,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAAA,CACxG;AAED,IAAI,eAAe,GAAG,EAAE,CAAC;AAEzB,+GAA+G;AAC/G,SAAS,eAAe,GAAW;IAClC,IAAI,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC;IACnB,IAAI,KAAK,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;IAC3B,IAAI,KAAK,IAAI,eAAe,EAAE,CAAC;QAC9B,CAAC,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;QAC3D,KAAK,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;IACxB,CAAC;IACD,eAAe,GAAG,KAAK,CAAC;IACxB,OAAO,KAAK,CAAC;AAAA,CACb;AAED,SAAS,eAAe,CAAC,KAAa,EAAY;IACjD,MAAM,GAAG,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IAC7B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,CAAC;IAChC,OAAO,WAAW,CAAC,GAAG,CAAC;SACrB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;SAChC,IAAI,EAAE,CAAC;AAAA,CACT;AAED,iGAAiG;AACjG,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,KAAa,EAAE,OAAe,EAAmB;IACpF,MAAM,GAAG,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IAC7B,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACpC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,eAAe,EAAE,KAAK,CAAC,CAAC;IAClD,aAAa,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACtC,MAAM,KAAK,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IACrC,OAAO,KAAK,CAAC,MAAM,GAAG,gBAAgB,EAAE,CAAC;QACxC,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC;QAC7B,IAAI,MAAM;YAAE,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACxD,CAAC;IACD,OAAO,IAAI,CAAC;AAAA,CACZ;AAED,6EAA6E;AAC7E,MAAM,UAAU,kBAAkB,CAAC,KAAa,EAAiB;IAChE,MAAM,KAAK,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IACrC,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACvC,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,IAAI,CAAC;QACJ,OAAO,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC;IAC9D,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,IAAI,CAAC;IACb,CAAC;AAAA,CACD","sourcesContent":["/**\n * lunR: cron job model + persistent store (Phase 1 of the cron/gateway roadmap).\n *\n * Jobs persist at `<agentDir>/cron/jobs.json` (`{ jobs: [...], updated_at }`),\n * agentDir resolved via getAgentDir() (honors PI_CODING_AGENT_DIR, defaults\n * ~/.lunr/agent). Writes are atomic (tmp file in the same dir + rename) and\n * serialized through an in-process promise queue — single-process, no locks.\n *\n * Per-run output goes to `<agentDir>/cron/output/<jobId>/<YYYY-MM-DD_HH-MM-SS>.md`\n * with a retention cap of the newest 50 files per job.\n *\n * Tests inject a base dir via setCronBaseDir() so no real agent dir is touched.\n */\n\nimport { randomUUID } from \"node:crypto\";\nimport { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, rmSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { isAbsolute, join, normalize, resolve } from \"node:path\";\nimport { Cron } from \"croner\";\nimport { getAgentDir } from \"../../config.ts\";\nimport {\n\tchatPlatformDeliverBlockedMessage,\n\tdeliverMentionsChatPlatform,\n\tisFeatureEnabled,\n} from \"../install-features.ts\";\n\n// ---------------------------------------------------------------------------\n// Model\n// ---------------------------------------------------------------------------\n\nexport type CronScheduleKind = \"once\" | \"interval\" | \"cron\";\n\nexport interface CronSchedule {\n\tkind: CronScheduleKind;\n\t/** ISO timestamp, one-shots only. */\n\trunAt?: string;\n\t/** Interval length in minutes, interval kind only. */\n\tminutes?: number;\n\t/** 5-field cron expression, cron kind only. */\n\texpr?: string;\n}\n\nexport interface CronJobOrigin {\n\tplatform: string;\n\tchatId: string;\n\tthreadId?: string;\n\tchatType?: string;\n}\n\nexport type CronJobState = \"scheduled\" | \"paused\" | \"completed\" | \"error\";\nexport type CronJobStatus = \"ok\" | \"error\";\n\nexport interface CronJob {\n\tid: string;\n\tname: string;\n\tprompt: string;\n\tschedule: CronSchedule;\n\tscheduleDisplay: string;\n\trepeat: { times: number | null; completed: number };\n\tenabled: boolean;\n\tstate: CronJobState;\n\tcreatedAt: string;\n\tnextRunAt: string | null;\n\tlastRunAt: string | null;\n\tlastStatus: CronJobStatus | null;\n\tlastError: string | null;\n\tlastDeliveryError: string | null;\n\t/** \"local\" | \"origin\" | \"telegram[:chatId]\" | \"discord[:chatId]\" (comma-combinable). v1 TUI only uses \"local\". */\n\tdeliver: string;\n\torigin?: CronJobOrigin | null;\n\t/** Job IDs whose latest output (8K chars cap each) is prepended to the prompt. */\n\tcontextFrom?: string[];\n\tworkdir?: string;\n}\n\nexport interface CreateJobInput {\n\tprompt: string;\n\t/** Raw schedule input, parsed by parseSchedule(). */\n\tschedule: string;\n\tname?: string;\n\t/** Repetition cap; null = forever. One-shots are always times=1. */\n\ttimes?: number | null;\n\tdeliver?: string;\n\tcontextFrom?: string[];\n\tworkdir?: string;\n\torigin?: CronJobOrigin | null;\n}\n\nexport interface JobPatch {\n\tname?: string;\n\tprompt?: string;\n\t/** Raw schedule input; reparsed and re-anchors nextRunAt. */\n\tschedule?: string;\n\tdeliver?: string;\n\tenabled?: boolean;\n\ttimes?: number | null;\n\tcontextFrom?: string[];\n\tworkdir?: string;\n\torigin?: CronJobOrigin | null;\n\t/** Internal: manual-run trigger and delivery-error bookkeeping. */\n\tnextRunAt?: string | null;\n\tlastDeliveryError?: string | null;\n}\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/** Flat recovery grace for one-shots: fire up to 120s late. */\nexport const ONE_SHOT_GRACE_MS = 120_000;\n/** Recurring grace window clamps: at least 120s, at most 2h. */\nconst MIN_GRACE_MS = 120_000;\nconst MAX_GRACE_MS = 7_200_000;\n/** Per-job output retention. */\nexport const OUTPUT_RETENTION = 50;\n/** Cap per upstream job output injected via contextFrom. */\nexport const CONTEXT_OUTPUT_CAP = 8000;\n\nconst MAX_NAME_LEN = 50;\n\n// ---------------------------------------------------------------------------\n// Paths + store state\n// ---------------------------------------------------------------------------\n\nlet baseDirOverride: string | undefined;\nlet cache: CronJob[] | undefined;\nlet writeQueue: Promise<void> = Promise.resolve();\n\n/**\n * Override the base dir (defaults to the agent dir) and reset the in-memory\n * cache + write queue. Passing undefined restores the default. For tests.\n */\nexport function setCronBaseDir(dir: string | undefined): void {\n\tbaseDirOverride = dir;\n\tcache = undefined;\n\twriteQueue = Promise.resolve();\n}\n\nfunction cronDir(): string {\n\treturn join(baseDirOverride ?? getAgentDir(), \"cron\");\n}\n\nfunction jobsFile(): string {\n\treturn join(cronDir(), \"jobs.json\");\n}\n\nfunction outputDir(jobId: string): string {\n\treturn join(cronDir(), \"output\", jobId);\n}\n\nfunction loadJobs(): CronJob[] {\n\tif (cache) return cache;\n\tconst file = jobsFile();\n\tif (!existsSync(file)) {\n\t\tcache = [];\n\t\treturn cache;\n\t}\n\ttry {\n\t\tconst parsed = JSON.parse(readFileSync(file, \"utf-8\"));\n\t\tcache = Array.isArray(parsed?.jobs) ? (parsed.jobs as CronJob[]) : [];\n\t} catch {\n\t\tcache = [];\n\t}\n\treturn cache;\n}\n\n/** Queue an atomic write of the in-memory store. Rejects only for the caller; the chain self-heals. */\nfunction persist(): Promise<void> {\n\tconst snapshot = JSON.stringify({ jobs: cache ?? [], updated_at: new Date().toISOString() }, null, 2);\n\tconst p = writeQueue.then(() => {\n\t\tmkdirSync(cronDir(), { recursive: true });\n\t\tconst tmp = join(cronDir(), `.jobs.json.${process.pid}.${Date.now()}.tmp`);\n\t\twriteFileSync(tmp, snapshot, \"utf-8\");\n\t\trenameSync(tmp, jobsFile());\n\t});\n\twriteQueue = p.then(\n\t\t() => undefined,\n\t\t() => undefined,\n\t);\n\treturn p;\n}\n\n// ---------------------------------------------------------------------------\n// Schedule parsing\n// ---------------------------------------------------------------------------\n\nexport interface ParsedSchedule {\n\tschedule: CronSchedule;\n\tscheduleDisplay: string;\n}\n\nconst INTERVAL_RE = /^every\\s+(\\d+)\\s*([mhd])$/i;\nconst DURATION_RE = /^(\\d+)\\s*([mhd])$/i;\n\nfunction toMinutes(value: number, unit: string): number {\n\tconst u = unit.toLowerCase();\n\tconst factor = u === \"d\" ? 1440 : u === \"h\" ? 60 : 1;\n\treturn value * factor;\n}\n\n/**\n * Parse a schedule input:\n * - `every 30m` / `every 2h` / `every 1d` → interval (minutes; d = 1440)\n * - bare `30m` / `2h` / `1d` → one-shot at now + duration\n * - ISO timestamp → one-shot at that time\n * - 5-field cron expression (validated via croner; throws on invalid)\n */\nexport function parseSchedule(input: string, now: Date = new Date()): ParsedSchedule {\n\tconst text = input.trim().replace(/\\s+/g, \" \");\n\tif (!text) throw new Error(\"schedule is empty\");\n\n\tconst interval = INTERVAL_RE.exec(text);\n\tif (interval) {\n\t\tconst minutes = toMinutes(Number(interval[1]), interval[2]);\n\t\tif (minutes <= 0) throw new Error(`invalid interval: \"${text}\"`);\n\t\treturn {\n\t\t\tschedule: { kind: \"interval\", minutes },\n\t\t\tscheduleDisplay: `every ${Number(interval[1])}${interval[2].toLowerCase()}`,\n\t\t};\n\t}\n\n\tconst duration = DURATION_RE.exec(text);\n\tif (duration) {\n\t\tconst minutes = toMinutes(Number(duration[1]), duration[2]);\n\t\tif (minutes <= 0) throw new Error(`invalid duration: \"${text}\"`);\n\t\tconst runAt = new Date(now.getTime() + minutes * 60_000).toISOString();\n\t\treturn { schedule: { kind: \"once\", runAt }, scheduleDisplay: text };\n\t}\n\n\tif (/^\\d{4}-\\d{2}-\\d{2}/.test(text)) {\n\t\tconst ts = Date.parse(text);\n\t\tif (!Number.isNaN(ts)) {\n\t\t\tconst runAt = new Date(ts).toISOString();\n\t\t\treturn { schedule: { kind: \"once\", runAt }, scheduleDisplay: runAt };\n\t\t}\n\t}\n\n\tif (text.split(\" \").length === 5) {\n\t\ttry {\n\t\t\tnew Cron(text);\n\t\t} catch (err) {\n\t\t\tthrow new Error(`invalid cron expression \"${text}\": ${err instanceof Error ? err.message : String(err)}`);\n\t\t}\n\t\treturn { schedule: { kind: \"cron\", expr: text }, scheduleDisplay: text };\n\t}\n\n\tthrow new Error(\n\t\t`unrecognized schedule: \"${input}\" (expected \"every 30m\", \"2h\", an ISO timestamp, or a 5-field cron expression)`,\n\t);\n}\n\n// ---------------------------------------------------------------------------\n// Next-run computation\n// ---------------------------------------------------------------------------\n\n/**\n * Compute the next run time for a job:\n * - once: the stored runAt, recoverable within a 120s grace if never run; null after that or once run.\n * - interval: (lastRunAt ?? createdAt) + minutes.\n * - cron: croner nextRun after (lastRunAt ?? now).\n */\nexport function computeNextRun(job: CronJob, now: Date = new Date()): Date | null {\n\tconst s = job.schedule;\n\tif (s.kind === \"once\") {\n\t\tif (job.repeat.completed > 0) return null;\n\t\tif (!s.runAt) return null;\n\t\tconst runAt = new Date(s.runAt);\n\t\tif (Number.isNaN(runAt.getTime())) return null;\n\t\treturn now.getTime() - runAt.getTime() <= ONE_SHOT_GRACE_MS ? runAt : null;\n\t}\n\tif (s.kind === \"interval\") {\n\t\tconst base = job.lastRunAt ? new Date(job.lastRunAt) : new Date(job.createdAt);\n\t\treturn new Date(base.getTime() + (s.minutes ?? 0) * 60_000);\n\t}\n\tconst cron = new Cron(s.expr!);\n\treturn cron.nextRun(job.lastRunAt ? new Date(job.lastRunAt) : now);\n}\n\n/** Approximate schedule period in ms (recurring jobs only) for grace-window sizing. */\nfunction periodMs(job: CronJob, now: Date): number {\n\tif (job.schedule.kind === \"interval\") return (job.schedule.minutes ?? 0) * 60_000;\n\tif (job.schedule.kind === \"cron\") {\n\t\tconst cron = new Cron(job.schedule.expr!);\n\t\tconst a = cron.nextRun(now);\n\t\tif (!a) return MAX_GRACE_MS;\n\t\tconst b = cron.nextRun(a);\n\t\tif (!b) return MAX_GRACE_MS;\n\t\treturn Math.max(b.getTime() - a.getTime(), 1);\n\t}\n\treturn 0;\n}\n\n/** Next slot strictly after `after` for a recurring job. */\nfunction nextSlotAfter(job: CronJob, after: Date): Date | null {\n\tif (job.schedule.kind === \"interval\") {\n\t\tconst period = (job.schedule.minutes ?? 0) * 60_000;\n\t\tif (period <= 0) return null;\n\t\t// Step forward from the stored nextRunAt (or now) until strictly in the future of `after`.\n\t\tlet slot = job.nextRunAt ? new Date(job.nextRunAt).getTime() : new Date(job.createdAt).getTime() + period;\n\t\twhile (slot <= after.getTime()) slot += period;\n\t\treturn new Date(slot);\n\t}\n\tif (job.schedule.kind === \"cron\") {\n\t\treturn new Cron(job.schedule.expr!).nextRun(after);\n\t}\n\treturn null;\n}\n\n// ---------------------------------------------------------------------------\n// Validation\n// ---------------------------------------------------------------------------\n\nlet workdirRoots: string[] = [process.cwd(), homedir()];\nlet deliverValidator: ((deliver: string, origin?: CronJobOrigin | null) => string | undefined) | undefined;\n\n/**\n * Configure the allowed absolute roots for cron job workdirs. Relative workdirs\n * are resolved against process.cwd() and must fall under one of these roots.\n * Default roots are process.cwd() and the user's home directory.\n */\nexport function setCronWorkdirRoots(roots: string[]): void {\n\tworkdirRoots = roots.map((r) => normalize(resolve(r)));\n}\n\n/**\n * Configure a deliver-target validator. When set, createJob/updateJob reject\n * deliver strings that the validator does not approve. The gateway uses this\n * to prevent delivery to arbitrary chats.\n */\nexport function setCronDeliverValidator(\n\tfn: ((deliver: string, origin?: CronJobOrigin | null) => string | undefined) | undefined,\n): void {\n\tdeliverValidator = fn;\n}\n\n/** Test seam: restore default validation state. */\nexport function resetCronValidators(): void {\n\tworkdirRoots = [process.cwd(), homedir()];\n\tdeliverValidator = undefined;\n}\n\nfunction isPathUnderRoot(absPath: string, root: string): boolean {\n\tconst normRoot = normalize(root).replace(/\\\\$/g, \"\");\n\tconst normPath = normalize(absPath).replace(/\\\\$/g, \"\");\n\treturn normPath === normRoot || normPath.startsWith(`${normRoot}/`) || normPath.startsWith(`${normRoot}\\\\`);\n}\n\nfunction validateWorkdir(workdir: string): string | undefined {\n\tconst candidate = resolve(workdir);\n\tif (isAbsolute(workdir) && !workdirRoots.some((root) => isPathUnderRoot(candidate, root))) {\n\t\treturn `workdir ${workdir} is outside allowed roots`;\n\t}\n\tif (!workdirRoots.some((root) => isPathUnderRoot(candidate, root))) {\n\t\treturn `workdir ${workdir} resolves outside allowed roots`;\n\t}\n\treturn undefined;\n}\n\nfunction runDeliverValidation(deliver: string, origin?: CronJobOrigin | null): string | undefined {\n\tif (deliverMentionsChatPlatform(deliver) && !isFeatureEnabled(\"chat-platforms\")) {\n\t\treturn chatPlatformDeliverBlockedMessage();\n\t}\n\treturn deliverValidator?.(deliver, origin);\n}\n\nfunction deriveName(prompt: string): string {\n\tconst first = prompt.split(\"\\n\")[0].replace(/\\s+/g, \" \").trim();\n\treturn (first || \"cron job\").slice(0, MAX_NAME_LEN);\n}\n\nexport async function createJob(input: CreateJobInput): Promise<CronJob> {\n\tconst prompt = input.prompt.trim();\n\tif (!prompt) throw new Error(\"createJob: prompt is empty\");\n\tif (input.workdir) {\n\t\tconst err = validateWorkdir(input.workdir);\n\t\tif (err) throw new Error(`createJob: ${err}`);\n\t}\n\tif (input.deliver) {\n\t\tconst err = runDeliverValidation(input.deliver, input.origin);\n\t\tif (err) throw new Error(`createJob: ${err}`);\n\t}\n\tconst now = new Date();\n\tconst parsed = parseSchedule(input.schedule, now);\n\tconst isOneShot = parsed.schedule.kind === \"once\";\n\tconst times = isOneShot ? 1 : (input.times ?? null);\n\tif (times !== null && (!Number.isInteger(times) || times < 1)) {\n\t\tthrow new Error(`createJob: times must be a positive integer or null, got ${times}`);\n\t}\n\tconst job: CronJob = {\n\t\tid: randomUUID().replaceAll(\"-\", \"\").slice(0, 12),\n\t\tname: (input.name?.trim() || deriveName(prompt)).slice(0, MAX_NAME_LEN),\n\t\tprompt,\n\t\tschedule: parsed.schedule,\n\t\tscheduleDisplay: parsed.scheduleDisplay,\n\t\trepeat: { times, completed: 0 },\n\t\tenabled: true,\n\t\tstate: \"scheduled\",\n\t\tcreatedAt: now.toISOString(),\n\t\tnextRunAt: null,\n\t\tlastRunAt: null,\n\t\tlastStatus: null,\n\t\tlastError: null,\n\t\tlastDeliveryError: null,\n\t\tdeliver: input.deliver?.trim() || \"local\",\n\t\torigin: input.origin ?? null,\n\t\tcontextFrom: input.contextFrom,\n\t\tworkdir: input.workdir,\n\t};\n\tjob.nextRunAt = computeNextRun(job, now)?.toISOString() ?? null;\n\tloadJobs().push(job);\n\tawait persist();\n\treturn job;\n}\n\n/** Look up a job by id, then by unique name. Throws when not found or when the name is ambiguous. */\nexport function getJob(idOrName: string): CronJob {\n\tconst jobs = loadJobs();\n\tconst byId = jobs.find((j) => j.id === idOrName);\n\tif (byId) return byId;\n\tconst byName = jobs.filter((j) => j.name === idOrName);\n\tif (byName.length === 1) return byName[0];\n\tif (byName.length > 1) {\n\t\tthrow new Error(\n\t\t\t`cron job name \"${idOrName}\" is ambiguous (${byName.length} matches: ${byName.map((j) => j.id).join(\", \")})`,\n\t\t);\n\t}\n\tthrow new Error(`no cron job matches \"${idOrName}\"`);\n}\n\nexport function listJobs(): CronJob[] {\n\treturn [...loadJobs()];\n}\n\nexport async function updateJob(idOrName: string, patch: JobPatch): Promise<CronJob> {\n\tconst job = getJob(idOrName);\n\tif (patch.name !== undefined) job.name = patch.name.trim().slice(0, MAX_NAME_LEN) || job.name;\n\tif (patch.workdir !== undefined) {\n\t\tif (patch.workdir) {\n\t\t\tconst err = validateWorkdir(patch.workdir);\n\t\t\tif (err) throw new Error(`updateJob: ${err}`);\n\t\t}\n\t\tjob.workdir = patch.workdir;\n\t}\n\tif (patch.deliver !== undefined) {\n\t\tconst err = runDeliverValidation(patch.deliver, patch.origin ?? job.origin);\n\t\tif (err) throw new Error(`updateJob: ${err}`);\n\t\tjob.deliver = patch.deliver.trim() || \"local\";\n\t}\n\tif (patch.prompt !== undefined) {\n\t\tconst prompt = patch.prompt.trim();\n\t\tif (!prompt) throw new Error(\"updateJob: prompt is empty\");\n\t\tjob.prompt = prompt;\n\t}\n\tif (patch.schedule !== undefined) {\n\t\tconst parsed = parseSchedule(patch.schedule);\n\t\tjob.schedule = parsed.schedule;\n\t\tjob.scheduleDisplay = parsed.scheduleDisplay;\n\t\tif (parsed.schedule.kind === \"once\") job.repeat.times = 1;\n\t\tjob.nextRunAt = computeNextRun(job)?.toISOString() ?? null;\n\t}\n\tif (patch.enabled !== undefined) job.enabled = patch.enabled;\n\tif (patch.times !== undefined) {\n\t\tif (patch.times !== null && (!Number.isInteger(patch.times) || patch.times < 1)) {\n\t\t\tthrow new Error(`updateJob: times must be a positive integer or null, got ${patch.times}`);\n\t\t}\n\t\tif (job.schedule.kind !== \"once\") job.repeat.times = patch.times;\n\t}\n\tif (patch.contextFrom !== undefined) job.contextFrom = patch.contextFrom;\n\tif (patch.origin !== undefined) job.origin = patch.origin;\n\tif (patch.nextRunAt !== undefined) job.nextRunAt = patch.nextRunAt;\n\tif (patch.lastDeliveryError !== undefined) job.lastDeliveryError = patch.lastDeliveryError;\n\tawait persist();\n\treturn job;\n}\n\nexport async function pauseJob(idOrName: string): Promise<CronJob> {\n\tconst job = getJob(idOrName);\n\tif (job.state !== \"completed\") job.state = \"paused\";\n\tawait persist();\n\treturn job;\n}\n\nexport async function resumeJob(idOrName: string): Promise<CronJob> {\n\tconst job = getJob(idOrName);\n\tif (job.state === \"paused\") {\n\t\tjob.state = \"scheduled\";\n\t\tjob.nextRunAt = computeNextRun(job)?.toISOString() ?? null;\n\t}\n\tawait persist();\n\treturn job;\n}\n\nexport async function removeJob(idOrName: string): Promise<CronJob> {\n\tconst job = getJob(idOrName);\n\tconst jobs = loadJobs();\n\tjobs.splice(jobs.indexOf(job), 1);\n\tawait persist();\n\treturn job;\n}\n\n// ---------------------------------------------------------------------------\n// Scheduling\n// ---------------------------------------------------------------------------\n\n/**\n * Jobs due to fire now. Skips disabled/paused/completed jobs and jobs without a\n * nextRunAt. One-shots fire up to 120s late (flat recovery grace); beyond that\n * they are marked state \"error\" and skipped. Recurring jobs whose nextRunAt is\n * older than the grace window — min(max(period/2, 120s), 2h) — are fast-forwarded\n * to their next future slot but still fire ONCE now (collapse backlog, no burst).\n */\nexport async function getDueJobs(now: Date = new Date()): Promise<CronJob[]> {\n\tconst due: CronJob[] = [];\n\tlet changed = false;\n\tfor (const job of loadJobs()) {\n\t\tif (!job.enabled || job.state === \"paused\" || job.state === \"completed\") continue;\n\t\tif (!job.nextRunAt) continue;\n\t\tconst next = new Date(job.nextRunAt).getTime();\n\t\tif (Number.isNaN(next) || now.getTime() < next) continue;\n\n\t\tif (job.schedule.kind === \"once\") {\n\t\t\tif (now.getTime() - next <= ONE_SHOT_GRACE_MS) {\n\t\t\t\tdue.push(job);\n\t\t\t} else {\n\t\t\t\tjob.state = \"error\";\n\t\t\t\tjob.lastStatus = \"error\";\n\t\t\t\tjob.lastError = \"missed one-shot schedule beyond the 120s recovery grace\";\n\t\t\t\tjob.nextRunAt = null;\n\t\t\t\tchanged = true;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst grace = Math.min(Math.max(periodMs(job, now) / 2, MIN_GRACE_MS), MAX_GRACE_MS);\n\t\tif (now.getTime() - next > grace) {\n\t\t\tjob.nextRunAt = nextSlotAfter(job, now)?.toISOString() ?? null;\n\t\t\tchanged = true;\n\t\t}\n\t\tdue.push(job);\n\t}\n\tif (changed) await persist();\n\treturn due;\n}\n\n/**\n * Advance a recurring job to its next slot. Called by the scheduler BEFORE\n * execution so a crash mid-run loses at most that run (at-most-once).\n */\nexport async function advanceNextRun(jobId: string): Promise<CronJob> {\n\tconst job = getJob(jobId);\n\tif (job.schedule.kind !== \"once\") {\n\t\t// Advance to the first slot strictly after NOW: the job fires once for the\n\t\t// current slot, and the next fire is the next future slot (no catch-up burst).\n\t\tjob.nextRunAt = nextSlotAfter(job, new Date())?.toISOString() ?? computeNextRun(job)?.toISOString() ?? null;\n\t\tawait persist();\n\t}\n\treturn job;\n}\n\n/**\n * Record a finished run: lastRunAt/lastStatus/lastError, repeat.completed++,\n * then either complete the job (finite repeats exhausted, one-shots included)\n * or re-anchor nextRunAt off the previous scheduled slot (no drift).\n */\nexport async function markJobRun(jobId: string, result: { status: CronJobStatus; error?: string }): Promise<CronJob> {\n\tconst job = getJob(jobId);\n\tconst now = new Date();\n\tjob.lastRunAt = now.toISOString();\n\tjob.lastStatus = result.status;\n\tjob.lastError = result.error ?? null;\n\tjob.repeat.completed += 1;\n\tif (job.repeat.times !== null && job.repeat.completed >= job.repeat.times) {\n\t\tjob.state = \"completed\";\n\t\tjob.nextRunAt = null;\n\t} else if (job.schedule.kind === \"interval\") {\n\t\t// Anchor to the previous scheduled slot + period to avoid cumulative drift.\n\t\t// If advanceNextRun already moved nextRunAt into the future (scheduler path),\n\t\t// keep it; otherwise (manual run) step forward from now.\n\t\tconst current = job.nextRunAt ? new Date(job.nextRunAt) : now;\n\t\tif (current.getTime() > now.getTime()) {\n\t\t\t// Already advanced by the scheduler — keep the scheduled slot.\n\t\t\tjob.nextRunAt = current.toISOString();\n\t\t} else {\n\t\t\tjob.nextRunAt = nextSlotAfter(job, now)?.toISOString() ?? null;\n\t\t}\n\t} else if (job.schedule.kind === \"cron\") {\n\t\tjob.nextRunAt = new Cron(job.schedule.expr!).nextRun(now)?.toISOString() ?? null;\n\t}\n\tawait persist();\n\treturn job;\n}\n\n// ---------------------------------------------------------------------------\n// Per-run output\n// ---------------------------------------------------------------------------\n\nfunction formatStamp(d: Date): string {\n\tconst p = (n: number) => String(n).padStart(2, \"0\");\n\treturn `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())}_${p(d.getHours())}-${p(d.getMinutes())}-${p(d.getSeconds())}`;\n}\n\nfunction parseStamp(stamp: string): Date {\n\tconst m = /^(\\d{4})-(\\d{2})-(\\d{2})_(\\d{2})-(\\d{2})-(\\d{2})/.exec(stamp);\n\tif (!m) return new Date();\n\treturn new Date(Number(m[1]), Number(m[2]) - 1, Number(m[3]), Number(m[4]), Number(m[5]), Number(m[6]));\n}\n\nlet lastOutputStamp = \"\";\n\n/** Monotonic timestamp stamp: never collides within the process, keeps lexicographic = chronological order. */\nfunction nextOutputStamp(): string {\n\tlet d = new Date();\n\tlet stamp = formatStamp(d);\n\tif (stamp <= lastOutputStamp) {\n\t\td = new Date(parseStamp(lastOutputStamp).getTime() + 1000);\n\t\tstamp = formatStamp(d);\n\t}\n\tlastOutputStamp = stamp;\n\treturn stamp;\n}\n\nfunction listOutputFiles(jobId: string): string[] {\n\tconst dir = outputDir(jobId);\n\tif (!existsSync(dir)) return [];\n\treturn readdirSync(dir)\n\t\t.filter((f) => f.endsWith(\".md\"))\n\t\t.sort();\n}\n\n/** Save a run's output and prune to the newest OUTPUT_RETENTION files. Returns the file path. */\nexport async function saveJobOutput(jobId: string, content: string): Promise<string> {\n\tconst dir = outputDir(jobId);\n\tmkdirSync(dir, { recursive: true });\n\tconst file = join(dir, `${nextOutputStamp()}.md`);\n\twriteFileSync(file, content, \"utf-8\");\n\tconst files = listOutputFiles(jobId);\n\twhile (files.length > OUTPUT_RETENTION) {\n\t\tconst oldest = files.shift();\n\t\tif (oldest) rmSync(join(dir, oldest), { force: true });\n\t}\n\treturn file;\n}\n\n/** Content of the newest output file for a job, or null when none exists. */\nexport function getLatestJobOutput(jobId: string): string | null {\n\tconst files = listOutputFiles(jobId);\n\tconst latest = files[files.length - 1];\n\tif (!latest) return null;\n\ttry {\n\t\treturn readFileSync(join(outputDir(jobId), latest), \"utf-8\");\n\t} catch {\n\t\treturn null;\n\t}\n}\n"]}
1
+ {"version":3,"file":"jobs.js","sourceRoot":"","sources":["../../../src/core/cron/jobs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EACN,UAAU,EACV,SAAS,EACT,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,MAAM,EACN,QAAQ,EACR,aAAa,GACb,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAChF,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,QAAQ,MAAM,iBAAiB,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EACN,iCAAiC,EACjC,2BAA2B,EAC3B,gBAAgB,GAChB,MAAM,wBAAwB,CAAC;AAsFhC,8EAA8E;AAC9E,YAAY;AACZ,8EAA8E;AAE9E,+DAA+D;AAC/D,MAAM,CAAC,MAAM,iBAAiB,GAAG,OAAO,CAAC;AACzC,gCAAgC;AAChC,MAAM,CAAC,MAAM,gBAAgB,GAAG,EAAE,CAAC;AACnC,4DAA4D;AAC5D,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,CAAC;AAEvC,MAAM,YAAY,GAAG,EAAE,CAAC;AAExB,8EAA8E;AAC9E,sBAAsB;AACtB,8EAA8E;AAE9E,IAAI,eAAmC,CAAC;AACxC,IAAI,eAAsC,CAAC;AAC3C,IAAI,UAAU,GAAkB,OAAO,CAAC,OAAO,EAAE,CAAC;AAElD;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,GAAuB,EAAQ;IAC7D,eAAe,GAAG,GAAG,CAAC;IACtB,eAAe,GAAG,SAAS,CAAC;IAC5B,UAAU,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;AAAA,CAC/B;AAED,SAAS,OAAO,GAAW;IAC1B,OAAO,IAAI,CAAC,eAAe,IAAI,WAAW,EAAE,EAAE,MAAM,CAAC,CAAC;AAAA,CACtD;AAED,SAAS,QAAQ,GAAW;IAC3B,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,WAAW,CAAC,CAAC;AAAA,CACpC;AAED,SAAS,SAAS,CAAC,KAAa,EAAU;IACzC,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;AAAA,CACxC;AAED,SAAS,QAAQ,GAAc;IAC9B,IAAI,eAAe;QAAE,OAAO,eAAe,CAAC;IAC5C,MAAM,IAAI,GAAG,QAAQ,EAAE,CAAC;IACxB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IACjC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;IACvD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAC5E,OAAO,MAAM,CAAC,IAAiB,CAAC;AAAA,CAChC;AAED,oFAAoF;AACpF,SAAS,UAAU,CAAI,EAAW,EAAc;IAC/C,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;IACtB,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IACpC,MAAM,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;QAC7C,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACpC,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE;YACzC,QAAQ,EAAE,KAAK;YACf,OAAO,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE;SAC1D,CAAC,CAAC;QACH,IAAI,CAAC;YACJ,eAAe,GAAG,QAAQ,EAAE,CAAC;YAC7B,MAAM,MAAM,GAAG,EAAE,EAAE,CAAC;YACpB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,cAAc,UAAU,EAAE,MAAM,CAAC,CAAC;YACxD,IAAI,CAAC;gBACJ,aAAa,CACZ,GAAG,EACH,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CACxF,CAAC;gBACF,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YACvB,CAAC;oBAAS,CAAC;gBACV,MAAM,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YAC9B,CAAC;YACD,OAAO,eAAe,CAAC,MAAM,CAAC,CAAC;QAChC,CAAC;gBAAS,CAAC;YACV,eAAe,GAAG,SAAS,CAAC;YAC5B,MAAM,OAAO,EAAE,CAAC;QACjB,CAAC;IAAA,CACD,CAAC,CAAC;IACH,UAAU,GAAG,SAAS,CAAC,IAAI,CAC1B,GAAG,EAAE,CAAC,SAAS,EACf,GAAG,EAAE,CAAC,SAAS,CACf,CAAC;IACF,OAAO,SAAS,CAAC;AAAA,CACjB;AAED,yFAAyF;AACzF,MAAM,CAAC,KAAK,UAAU,qBAAqB,GAA0C;IACpF,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;IACtB,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACpC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IACpC,MAAM,SAAS,GAAG,GAAG,IAAI,aAAa,CAAC;IACvC,MAAM,OAAO,GAAG,OAAO,CAAC;IACxB,IAAI,UAAU,CAAC,GAAG,IAAI,OAAO,CAAC,EAAE,CAAC;QAChC,IAAI,KAAc,CAAC;QACnB,IAAI,CAAC;YACJ,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC;YACrD,IACC,CAAC,KAAK;gBACN,OAAO,KAAK,KAAK,QAAQ;gBACzB,CAAC,CAAC,KAAK,IAAI,KAAK,CAAC;gBACjB,OAAO,KAAK,CAAC,GAAG,KAAK,QAAQ;gBAC7B,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC;gBAC5B,KAAK,CAAC,GAAG,IAAI,CAAC;gBACd,KAAK,CAAC,GAAG,GAAG,aAAa;gBAEzB,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;QACjD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,yEAAyE;YACzE,qEAAqE;YACrE,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI,OAAO,CAAC;gBAAE,OAAO,qBAAqB,EAAE,CAAC;YAChE,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACxD,IAAI,CAAC;oBACJ,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,CAAC,GAAG,IAAI,OAAO,CAAC,CAAC,OAAO,GAAG,OAAO;wBAAE,OAAO,IAAI,CAAC;gBAC1E,CAAC;gBAAC,OAAO,SAAS,EAAE,CAAC;oBACpB,IAAK,SAAmC,CAAC,IAAI,KAAK,QAAQ;wBAAE,OAAO,qBAAqB,EAAE,CAAC;gBAC5F,CAAC;YACF,CAAC;YACD,MAAM,IAAI,KAAK,CACd,2HAA2H;gBAC1H,eAAe,IAAI,aAAa,SAAS,+EAA+E,EACzH,EAAE,KAAK,EAAE,KAAK,EAAE,CAChB,CAAC;QACH,CAAC;QACD,IAAI,CAAC;YACJ,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YAC3B,OAAO,IAAI,CAAC;QACb,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,IAAK,KAA+B,CAAC,IAAI,KAAK,OAAO;gBAAE,OAAO,IAAI,CAAC;QACpE,CAAC;IACF,CAAC;IACD,IAAI,OAA4B,CAAC;IACjC,IAAI,CAAC;QACJ,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;IAC1E,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,IAAK,KAA+B,CAAC,IAAI,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC;QACrE,MAAM,KAAK,CAAC;IACb,CAAC;IACD,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,yBAAyB,UAAU,EAAE,MAAM,CAAC,CAAC;IACxE,IAAI,CAAC;QACJ,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QAC9D,UAAU,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IACjC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,MAAM,OAAO,EAAE,CAAC;QAChB,MAAM,KAAK,CAAC;IACb,CAAC;YAAS,CAAC;QACV,MAAM,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACnC,CAAC;IACD,OAAO,KAAK,IAAI,EAAE,CAAC;QAClB,IAAI,CAAC;YACJ,MAAM,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACpC,CAAC;gBAAS,CAAC;YACV,MAAM,OAAO,EAAE,CAAC;QACjB,CAAC;IAAA,CACD,CAAC;AAAA,CACF;AAWD,MAAM,WAAW,GAAG,4BAA4B,CAAC;AACjD,MAAM,WAAW,GAAG,oBAAoB,CAAC;AAEzC,SAAS,SAAS,CAAC,KAAa,EAAE,IAAY,EAAU;IACvD,MAAM,CAAC,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IAC7B,MAAM,MAAM,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACrD,OAAO,KAAK,GAAG,MAAM,CAAC;AAAA,CACtB;AAED;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,KAAa,EAAE,GAAG,GAAS,IAAI,IAAI,EAAE,EAAkB;IACpF,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC/C,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;IAEhD,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxC,IAAI,QAAQ,EAAE,CAAC;QACd,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5D,IAAI,OAAO,IAAI,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,IAAI,GAAG,CAAC,CAAC;QACjE,OAAO;YACN,QAAQ,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE;YACvC,eAAe,EAAE,SAAS,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,EAAE;SAC3E,CAAC;IACH,CAAC;IAED,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxC,IAAI,QAAQ,EAAE,CAAC;QACd,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5D,IAAI,OAAO,IAAI,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,IAAI,GAAG,CAAC,CAAC;QACjE,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,OAAO,GAAG,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;QACvE,OAAO,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC;IACrE,CAAC;IAED,IAAI,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACrC,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC5B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;YACvB,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;YACzC,OAAO,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC;QACtE,CAAC;IACF,CAAC;IAED,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClC,IAAI,CAAC;YACJ,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CAAC,4BAA4B,IAAI,MAAM,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC3G,CAAC;QACD,OAAO,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC;IAC1E,CAAC;IAED,MAAM,IAAI,KAAK,CACd,2BAA2B,KAAK,gFAAgF,CAChH,CAAC;AAAA,CACF;AAED,8EAA8E;AAC9E,uBAAuB;AACvB,8EAA8E;AAE9E;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,GAAY,EAAE,GAAG,GAAS,IAAI,IAAI,EAAE,EAAe;IACjF,MAAM,CAAC,GAAG,GAAG,CAAC,QAAQ,CAAC;IACvB,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QACvB,IAAI,GAAG,CAAC,MAAM,CAAC,SAAS,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;QAC1C,IAAI,CAAC,CAAC,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QAC1B,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAChC,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;YAAE,OAAO,IAAI,CAAC;QAC/C,OAAO,GAAG,CAAC,OAAO,EAAE,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,iBAAiB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;IAC5E,CAAC;IACD,IAAI,CAAC,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC/E,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC;IAC7D,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,IAAK,CAAC,CAAC;IAC/B,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;AAAA,CACnE;AAED,4DAA4D;AAC5D,SAAS,aAAa,CAAC,GAAY,EAAE,KAAW,EAAe;IAC9D,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QACtC,MAAM,MAAM,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC;QACpD,IAAI,MAAM,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QAC7B,2FAA2F;QAC3F,IAAI,IAAI,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,GAAG,MAAM,CAAC;QAC1G,OAAO,IAAI,IAAI,KAAK,CAAC,OAAO,EAAE;YAAE,IAAI,IAAI,MAAM,CAAC;QAC/C,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC;IACvB,CAAC;IACD,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAClC,OAAO,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAK,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACpD,CAAC;IACD,OAAO,IAAI,CAAC;AAAA,CACZ;AAED,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E,IAAI,YAAY,GAAa,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;AACxD,IAAI,gBAAsG,CAAC;AAE3G;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAe,EAAQ;IAC1D,YAAY,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAAA,CACvD;AAED;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CACtC,EAAwF,EACjF;IACP,gBAAgB,GAAG,EAAE,CAAC;AAAA,CACtB;AAED,mDAAmD;AACnD,MAAM,UAAU,mBAAmB,GAAS;IAC3C,YAAY,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;IAC1C,gBAAgB,GAAG,SAAS,CAAC;AAAA,CAC7B;AAED,SAAS,eAAe,CAAC,OAAe,EAAE,IAAY,EAAW;IAChE,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACpC,OAAO,GAAG,KAAK,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,GAAG,EAAE,CAAC,IAAI,GAAG,KAAK,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;AAAA,CACvF;AAED,SAAS,eAAe,CAAC,OAAe,EAAE,MAA6B,EAAsB;IAC5F,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7E,MAAM,KAAK,GAAG,MAAM;QACnB,CAAC,CAAC,CAAC,iBAAiB,EAAE,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;YAC3D,IAAI,CAAC;gBACJ,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;YAC7B,CAAC;YAAC,MAAM,CAAC;gBACR,OAAO,EAAE,CAAC;YACX,CAAC;QAAA,CACD,CAAC;QACH,CAAC,CAAC,YAAY,CAAC;IAChB,IAAI,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,eAAe,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC;QACpF,OAAO,WAAW,OAAO,2BAA2B,CAAC;IACtD,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,eAAe,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC;QAC7D,OAAO,WAAW,OAAO,iCAAiC,CAAC;IAC5D,CAAC;IACD,OAAO,SAAS,CAAC;AAAA,CACjB;AAED,SAAS,oBAAoB,CAAC,OAAe,EAAE,MAA6B,EAAsB;IACjG,IAAI,2BAA2B,CAAC,OAAO,CAAC,IAAI,CAAC,gBAAgB,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACjF,OAAO,iCAAiC,EAAE,CAAC;IAC5C,CAAC;IACD,OAAO,gBAAgB,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;AAAA,CAC3C;AAED,SAAS,UAAU,CAAC,MAAc,EAAU;IAC3C,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAChE,OAAO,CAAC,KAAK,IAAI,UAAU,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC;AAAA,CACpD;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,KAAqB,EAAoB;IACxE,OAAO,UAAU,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QACnC,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAC3D,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YACnB,MAAM,GAAG,GAAG,eAAe,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;YACzD,IAAI,GAAG;gBAAE,MAAM,IAAI,KAAK,CAAC,cAAc,GAAG,EAAE,CAAC,CAAC;QAC/C,CAAC;QACD,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YACnB,MAAM,GAAG,GAAG,oBAAoB,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;YAC9D,IAAI,GAAG;gBAAE,MAAM,IAAI,KAAK,CAAC,cAAc,GAAG,EAAE,CAAC,CAAC;QAC/C,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,MAAM,GAAG,aAAa,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QAClD,MAAM,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,MAAM,CAAC;QAClD,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC;QACpD,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC;YAC/D,MAAM,IAAI,KAAK,CAAC,4DAA4D,KAAK,EAAE,CAAC,CAAC;QACtF,CAAC;QACD,MAAM,GAAG,GAAY;YACpB,EAAE,EAAE,UAAU,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;YACjD,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,YAAY,CAAC;YACvE,MAAM;YACN,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,eAAe,EAAE,MAAM,CAAC,eAAe;YACvC,MAAM,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,EAAE;YAC/B,OAAO,EAAE,IAAI;YACb,KAAK,EAAE,WAAW;YAClB,SAAS,EAAE,GAAG,CAAC,WAAW,EAAE;YAC5B,SAAS,EAAE,IAAI;YACf,SAAS,EAAE,IAAI;YACf,UAAU,EAAE,IAAI;YAChB,SAAS,EAAE,IAAI;YACf,iBAAiB,EAAE,IAAI;YACvB,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,OAAO;YACzC,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,IAAI;YAC5B,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,OAAO,EAAE,KAAK,CAAC,OAAO;SACtB,CAAC;QACF,GAAG,CAAC,SAAS,GAAG,cAAc,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,WAAW,EAAE,IAAI,IAAI,CAAC;QAChE,QAAQ,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACrB,OAAO,GAAG,CAAC;IAAA,CACX,CAAC,CAAC;AAAA,CACH;AAED,qGAAqG;AACrG,MAAM,UAAU,MAAM,CAAC,QAAgB,EAAW;IACjD,MAAM,IAAI,GAAG,QAAQ,EAAE,CAAC;IACxB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC;IACjD,IAAI,IAAI;QAAE,OAAO,IAAI,CAAC;IACtB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;IACvD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;IAC1C,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CACd,kBAAkB,QAAQ,mBAAmB,MAAM,CAAC,MAAM,aAAa,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAC5G,CAAC;IACH,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,wBAAwB,QAAQ,GAAG,CAAC,CAAC;AAAA,CACrD;AAED,MAAM,UAAU,QAAQ,GAAc;IACrC,OAAO,CAAC,GAAG,QAAQ,EAAE,CAAC,CAAC;AAAA,CACvB;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,QAAgB,EAAE,KAAe,EAAoB;IACpF,OAAO,UAAU,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC7B,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS;YAAE,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,YAAY,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC;QAC9F,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YACjC,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;gBACnB,MAAM,GAAG,GAAG,eAAe,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;gBACvE,IAAI,GAAG;oBAAE,MAAM,IAAI,KAAK,CAAC,cAAc,GAAG,EAAE,CAAC,CAAC;YAC/C,CAAC;YACD,GAAG,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;QAC7B,CAAC;QACD,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YACjC,MAAM,GAAG,GAAG,oBAAoB,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;YAC5E,IAAI,GAAG;gBAAE,MAAM,IAAI,KAAK,CAAC,cAAc,GAAG,EAAE,CAAC,CAAC;YAC9C,GAAG,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,OAAO,CAAC;QAC/C,CAAC;QACD,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAChC,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YACnC,IAAI,CAAC,MAAM;gBAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;YAC3D,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,CAAC;QACD,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YAClC,MAAM,MAAM,GAAG,aAAa,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YAC7C,GAAG,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;YAC/B,GAAG,CAAC,eAAe,GAAG,MAAM,CAAC,eAAe,CAAC;YAC7C,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,MAAM;gBAAE,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC;YAC1D,GAAG,CAAC,SAAS,GAAG,cAAc,CAAC,GAAG,CAAC,EAAE,WAAW,EAAE,IAAI,IAAI,CAAC;QAC5D,CAAC;QACD,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS;YAAE,GAAG,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;QAC7D,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC/B,IAAI,KAAK,CAAC,KAAK,KAAK,IAAI,IAAI,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC;gBACjF,MAAM,IAAI,KAAK,CAAC,4DAA4D,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;YAC5F,CAAC;YACD,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,MAAM;gBAAE,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;QAClE,CAAC;QACD,IAAI,KAAK,CAAC,WAAW,KAAK,SAAS;YAAE,GAAG,CAAC,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC;QACzE,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS;YAAE,GAAG,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;QAC1D,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS;YAAE,GAAG,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;QACnE,IAAI,KAAK,CAAC,iBAAiB,KAAK,SAAS;YAAE,GAAG,CAAC,iBAAiB,GAAG,KAAK,CAAC,iBAAiB,CAAC;QAC3F,OAAO,GAAG,CAAC;IAAA,CACX,CAAC,CAAC;AAAA,CACH;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,QAAgB,EAAoB;IAClE,OAAO,UAAU,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC7B,IAAI,GAAG,CAAC,KAAK,KAAK,WAAW;YAAE,GAAG,CAAC,KAAK,GAAG,QAAQ,CAAC;QACpD,OAAO,GAAG,CAAC;IAAA,CACX,CAAC,CAAC;AAAA,CACH;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,QAAgB,EAAoB;IACnE,OAAO,UAAU,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC7B,IAAI,GAAG,CAAC,WAAW;YAClB,MAAM,IAAI,KAAK,CAAC,2FAA2F,CAAC,CAAC;QAC9G,IAAI,GAAG,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC5B,GAAG,CAAC,KAAK,GAAG,WAAW,CAAC;YACxB,GAAG,CAAC,SAAS,GAAG,cAAc,CAAC,GAAG,CAAC,EAAE,WAAW,EAAE,IAAI,IAAI,CAAC;QAC5D,CAAC;QACD,OAAO,GAAG,CAAC;IAAA,CACX,CAAC,CAAC;AAAA,CACH;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,QAAgB,EAAoB;IACnE,OAAO,UAAU,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC7B,MAAM,IAAI,GAAG,QAAQ,EAAE,CAAC;QACxB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QAClC,OAAO,GAAG,CAAC;IAAA,CACX,CAAC,CAAC;AAAA,CACH;AAED,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,GAAG,GAAS,IAAI,IAAI,EAAE,EAAsB;IAC5E,OAAO,UAAU,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,GAAG,GAAc,EAAE,CAAC;QAC1B,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,EAAE,CAAC;YAC9B,IAAI,CAAC,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,KAAK,KAAK,WAAW,IAAI,GAAG,CAAC,SAAS;gBAAE,SAAS;YACzE,IAAI,CAAC,GAAG,CAAC,SAAS;gBAAE,SAAS;YAC7B,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC;YAC/C,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,OAAO,EAAE,GAAG,IAAI;gBAAE,SAAS;YAEzD,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBAClC,IAAI,GAAG,CAAC,OAAO,EAAE,GAAG,IAAI,IAAI,iBAAiB,EAAE,CAAC;oBAC/C,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBACf,CAAC;qBAAM,CAAC;oBACP,GAAG,CAAC,KAAK,GAAG,OAAO,CAAC;oBACpB,GAAG,CAAC,UAAU,GAAG,OAAO,CAAC;oBACzB,GAAG,CAAC,SAAS,GAAG,yDAAyD,CAAC;oBAC1E,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC;gBACtB,CAAC;gBACD,SAAS;YACV,CAAC;YAED,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACf,CAAC;QACD,OAAO,GAAG,CAAC;IAAA,CACX,CAAC,CAAC;AAAA,CACH;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,KAAa,EAAoB;IACrE,OAAO,UAAU,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QAC1B,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAClC,2EAA2E;YAC3E,+EAA+E;YAC/E,GAAG,CAAC,SAAS,GAAG,aAAa,CAAC,GAAG,EAAE,IAAI,IAAI,EAAE,CAAC,EAAE,WAAW,EAAE,IAAI,cAAc,CAAC,GAAG,CAAC,EAAE,WAAW,EAAE,IAAI,IAAI,CAAC;QAC7G,CAAC;QACD,OAAO,GAAG,CAAC;IAAA,CACX,CAAC,CAAC;AAAA,CACH;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC/B,KAAa,EACb,MAAiE,EACvC;IAC1B,OAAO,UAAU,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,GAAG,GAAG,QAAQ,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,KAAK,CAAC,CAAC;QACvD,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,GAAG,CAAC,SAAS,EAAE,EAAE,KAAK,MAAM,CAAC,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAC9E,OAAO,GAAG,CAAC,SAAS,CAAC;QACrB,OAAO,GAAG,CAAC,WAAW,CAAC;QACvB,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,GAAG,CAAC,SAAS,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;QAClC,GAAG,CAAC,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC;QAC/B,GAAG,CAAC,SAAS,GAAG,MAAM,CAAC,KAAK,IAAI,IAAI,CAAC;QACrC,GAAG,CAAC,MAAM,CAAC,SAAS,IAAI,CAAC,CAAC;QAC1B,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,KAAK,IAAI,IAAI,GAAG,CAAC,MAAM,CAAC,SAAS,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YAC3E,GAAG,CAAC,KAAK,GAAG,WAAW,CAAC;YACxB,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,CAAC;aAAM,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YAC9D,4EAA4E;YAC5E,8EAA8E;YAC9E,yDAAyD;YACzD,MAAM,OAAO,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;YAC9D,IAAI,OAAO,CAAC,OAAO,EAAE,GAAG,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC;gBACvC,iEAA+D;gBAC/D,GAAG,CAAC,SAAS,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;YACvC,CAAC;iBAAM,CAAC;gBACP,GAAG,CAAC,SAAS,GAAG,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,WAAW,EAAE,IAAI,IAAI,CAAC;YAChE,CAAC;QACF,CAAC;aAAM,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC1D,GAAG,CAAC,SAAS,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAK,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,WAAW,EAAE,IAAI,IAAI,CAAC;QAClF,CAAC;QACD,OAAO,GAAG,CAAC;IAAA,CACX,CAAC,CAAC;AAAA,CACH;AAED,uEAAuE;AACvE,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,KAAa,EAAE,GAAS,EAAE,MAAM,GAAG,KAAK,EAA2B;IACpG,OAAO,UAAU,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,GAAG,GAAG,QAAQ,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,KAAK,CAAC,CAAC;QACvD,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,SAAS;YAAE,OAAO,IAAI,CAAC;QACvC,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,KAAK,KAAK,WAAW,IAAI,CAAC,GAAG,CAAC,SAAS,IAAI,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,GAAG,CAAC;YAC5G,OAAO,IAAI,CAAC;QACb,GAAG,CAAC,SAAS,GAAG,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,WAAW,EAAE,GAAG,CAAC,SAAS,EAAE,SAAS,EAAE,GAAG,CAAC,WAAW,EAAE,EAAE,CAAC;QAC/F,GAAG,CAAC,SAAS,GAAG,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,WAAW,EAAE,IAAI,IAAI,CAAC,CAAC;QACvG,GAAG,CAAC,SAAS,CAAC,UAAU,GAAG,GAAG,CAAC,SAAS,CAAC;QACzC,OAAO,GAAG,CAAC;IAAA,CACX,CAAC,CAAC;AAAA,CACH;AAED,iFAAiF;AACjF,MAAM,CAAC,KAAK,UAAU,sBAAsB,GAAkB;IAC7D,MAAM,UAAU,CAAC,GAAG,EAAE,CAAC;QACtB,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,EAAE,CAAC;YAC9B,IAAI,CAAC,GAAG,CAAC,SAAS;gBAAE,SAAS;YAC7B,GAAG,CAAC,KAAK,GAAG,QAAQ,CAAC;YACrB,GAAG,CAAC,UAAU,GAAG,OAAO,CAAC;YACzB,GAAG,CAAC,SAAS,GAAG,yEAAyE,CAAC;YAC1F,GAAG,CAAC,WAAW,GAAG,IAAI,CAAC;YACvB,OAAO,GAAG,CAAC,SAAS,CAAC;QACtB,CAAC;IAAA,CACD,CAAC,CAAC;AAAA,CACH;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,KAAa,EAAE,KAAa,EAAiB;IAC9E,MAAM,UAAU,CAAC,GAAG,EAAE,CAAC;QACtB,MAAM,GAAG,GAAG,QAAQ,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,KAAK,CAAC,CAAC;QACvD,IAAI,GAAG,EAAE,SAAS,EAAE,EAAE,KAAK,KAAK;YAAE,OAAO;QACzC,IAAI,GAAG,CAAC,SAAS,KAAK,GAAG,CAAC,SAAS,CAAC,UAAU;YAAE,GAAG,CAAC,SAAS,GAAG,GAAG,CAAC,SAAS,CAAC,WAAW,CAAC;QAC1F,OAAO,GAAG,CAAC,SAAS,CAAC;IAAA,CACrB,CAAC,CAAC;AAAA,CACH;AAED,8EAA8E;AAC9E,iBAAiB;AACjB,8EAA8E;AAE9E,SAAS,WAAW,CAAC,CAAO,EAAU;IACrC,MAAM,CAAC,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACpD,OAAO,GAAG,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,EAAE,CAAC;AAAA,CAClI;AAED,SAAS,UAAU,CAAC,KAAa,EAAQ;IACxC,MAAM,CAAC,GAAG,kDAAkD,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACzE,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,IAAI,EAAE,CAAC;IAC1B,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAAA,CACxG;AAED,IAAI,eAAe,GAAG,EAAE,CAAC;AAEzB,+GAA+G;AAC/G,SAAS,eAAe,GAAW;IAClC,IAAI,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC;IACnB,IAAI,KAAK,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;IAC3B,IAAI,KAAK,IAAI,eAAe,EAAE,CAAC;QAC9B,CAAC,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;QAC3D,KAAK,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;IACxB,CAAC;IACD,eAAe,GAAG,KAAK,CAAC;IACxB,OAAO,KAAK,CAAC;AAAA,CACb;AAED,SAAS,eAAe,CAAC,KAAa,EAAY;IACjD,MAAM,GAAG,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IAC7B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,CAAC;IAChC,OAAO,WAAW,CAAC,GAAG,CAAC;SACrB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;SAChC,IAAI,EAAE,CAAC;AAAA,CACT;AAED,iGAAiG;AACjG,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,KAAa,EAAE,OAAe,EAAmB;IACpF,MAAM,GAAG,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IAC7B,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACpC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,eAAe,EAAE,KAAK,CAAC,CAAC;IAClD,aAAa,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACtC,MAAM,KAAK,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IACrC,OAAO,KAAK,CAAC,MAAM,GAAG,gBAAgB,EAAE,CAAC;QACxC,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC;QAC7B,IAAI,MAAM;YAAE,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACxD,CAAC;IACD,OAAO,IAAI,CAAC;AAAA,CACZ;AAED,6EAA6E;AAC7E,MAAM,UAAU,kBAAkB,CAAC,KAAa,EAAiB;IAChE,MAAM,KAAK,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IACrC,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACvC,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,IAAI,CAAC;QACJ,OAAO,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC;IAC9D,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,IAAI,CAAC;IACb,CAAC;AAAA,CACD","sourcesContent":["/**\n * lunR: cron job model + persistent store (Phase 1 of the cron/gateway roadmap).\n *\n * Jobs persist at `<agentDir>/cron/jobs.json` (`{ jobs: [...], updated_at }`),\n * agentDir resolved via getAgentDir() (honors PI_CODING_AGENT_DIR, defaults\n * ~/.lunr/agent). Writes are atomic (tmp file in the same dir + rename) and\n * serialized with a cross-process read-modify-write lock over fresh data.\n *\n * Per-run output goes to `<agentDir>/cron/output/<jobId>/<YYYY-MM-DD_HH-MM-SS>.md`\n * with a retention cap of the newest 50 files per job.\n *\n * Tests inject a base dir via setCronBaseDir() so no real agent dir is touched.\n */\n\nimport { randomUUID } from \"node:crypto\";\nimport {\n\texistsSync,\n\tmkdirSync,\n\treaddirSync,\n\treadFileSync,\n\trealpathSync,\n\trenameSync,\n\trmSync,\n\tstatSync,\n\twriteFileSync,\n} from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { isAbsolute, join, normalize, relative, resolve, sep } from \"node:path\";\nimport { Cron } from \"croner\";\nimport lockfile from \"proper-lockfile\";\nimport { getAgentDir } from \"../../config.ts\";\nimport { loadGatewayConfig } from \"../../gateway/config.ts\";\nimport {\n\tchatPlatformDeliverBlockedMessage,\n\tdeliverMentionsChatPlatform,\n\tisFeatureEnabled,\n} from \"../install-features.ts\";\n\n// ---------------------------------------------------------------------------\n// Model\n// ---------------------------------------------------------------------------\n\nexport type CronScheduleKind = \"once\" | \"interval\" | \"cron\";\n\nexport interface CronSchedule {\n\tkind: CronScheduleKind;\n\t/** ISO timestamp, one-shots only. */\n\trunAt?: string;\n\t/** Interval length in minutes, interval kind only. */\n\tminutes?: number;\n\t/** 5-field cron expression, cron kind only. */\n\texpr?: string;\n}\n\nexport interface CronJobOrigin {\n\t/** Requester identity, absent on legacy jobs. Never persist adapter role grants. */\n\tuserId?: string;\n\tplatform: string;\n\tchatId: string;\n\tthreadId?: string;\n\tchatType?: string;\n}\n\nexport type CronJobState = \"scheduled\" | \"paused\" | \"completed\" | \"error\";\nexport type CronJobStatus = \"ok\" | \"error\";\n\nexport interface CronJob {\n\tid: string;\n\tname: string;\n\tprompt: string;\n\tschedule: CronSchedule;\n\tscheduleDisplay: string;\n\trepeat: { times: number | null; completed: number };\n\tenabled: boolean;\n\tstate: CronJobState;\n\tcreatedAt: string;\n\tnextRunAt: string | null;\n\tlastRunAt: string | null;\n\tlastStatus: CronJobStatus | null;\n\tlastError: string | null;\n\tlastDeliveryError: string | null;\n\t/** \"local\" | \"origin\" | \"telegram[:chatId]\" | \"discord[:chatId]\" (comma-combinable). v1 TUI only uses \"local\". */\n\tdeliver: string;\n\torigin?: CronJobOrigin | null;\n\t/** Job IDs whose latest output (8K chars cap each) is prepended to the prompt. */\n\tcontextFrom?: string[];\n\tworkdir?: string;\n\t/** Unknown interrupted effects require an explicit run, rather than ordinary resume. */\n\tinterrupted?: boolean;\n\t/** Durable claim written before dispatch. Interrupted claims require explicit retry. */\n\tactiveRun?: { id: string; scheduledAt: string | null; startedAt: string; advancedTo?: string | null };\n}\n\nexport interface CreateJobInput {\n\tprompt: string;\n\t/** Raw schedule input, parsed by parseSchedule(). */\n\tschedule: string;\n\tname?: string;\n\t/** Repetition cap; null = forever. One-shots are always times=1. */\n\ttimes?: number | null;\n\tdeliver?: string;\n\tcontextFrom?: string[];\n\tworkdir?: string;\n\torigin?: CronJobOrigin | null;\n}\n\nexport interface JobPatch {\n\tname?: string;\n\tprompt?: string;\n\t/** Raw schedule input; reparsed and re-anchors nextRunAt. */\n\tschedule?: string;\n\tdeliver?: string;\n\tenabled?: boolean;\n\ttimes?: number | null;\n\tcontextFrom?: string[];\n\tworkdir?: string;\n\torigin?: CronJobOrigin | null;\n\t/** Internal: manual-run trigger and delivery-error bookkeeping. */\n\tnextRunAt?: string | null;\n\tlastDeliveryError?: string | null;\n}\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/** Flat recovery grace for one-shots: fire up to 120s late. */\nexport const ONE_SHOT_GRACE_MS = 120_000;\n/** Per-job output retention. */\nexport const OUTPUT_RETENTION = 50;\n/** Cap per upstream job output injected via contextFrom. */\nexport const CONTEXT_OUTPUT_CAP = 8000;\n\nconst MAX_NAME_LEN = 50;\n\n// ---------------------------------------------------------------------------\n// Paths + store state\n// ---------------------------------------------------------------------------\n\nlet baseDirOverride: string | undefined;\nlet transactionJobs: CronJob[] | undefined;\nlet writeQueue: Promise<void> = Promise.resolve();\n\n/**\n * Override the base dir (defaults to the agent dir) and reset the in-memory\n * transaction queue. Passing undefined restores the default. For tests.\n */\nexport function setCronBaseDir(dir: string | undefined): void {\n\tbaseDirOverride = dir;\n\ttransactionJobs = undefined;\n\twriteQueue = Promise.resolve();\n}\n\nfunction cronDir(): string {\n\treturn join(baseDirOverride ?? getAgentDir(), \"cron\");\n}\n\nfunction jobsFile(): string {\n\treturn join(cronDir(), \"jobs.json\");\n}\n\nfunction outputDir(jobId: string): string {\n\treturn join(cronDir(), \"output\", jobId);\n}\n\nfunction loadJobs(): CronJob[] {\n\tif (transactionJobs) return transactionJobs;\n\tconst file = jobsFile();\n\tif (!existsSync(file)) return [];\n\tconst parsed = JSON.parse(readFileSync(file, \"utf-8\"));\n\tif (!Array.isArray(parsed?.jobs)) throw new Error(\"invalid cron job store\");\n\treturn parsed.jobs as CronJob[];\n}\n\n/** Each mutation reads the latest snapshot while holding the profile store lock. */\nfunction mutateJobs<T>(fn: () => T): Promise<T> {\n\tconst dir = cronDir();\n\tconst file = join(dir, \"jobs.json\");\n\tconst operation = writeQueue.then(async () => {\n\t\tmkdirSync(dir, { recursive: true });\n\t\tconst release = await lockfile.lock(file, {\n\t\t\trealpath: false,\n\t\t\tretries: { retries: 100, minTimeout: 10, maxTimeout: 100 },\n\t\t});\n\t\ttry {\n\t\t\ttransactionJobs = loadJobs();\n\t\t\tconst result = fn();\n\t\t\tconst tmp = join(dir, `.jobs.json.${randomUUID()}.tmp`);\n\t\t\ttry {\n\t\t\t\twriteFileSync(\n\t\t\t\t\ttmp,\n\t\t\t\t\tJSON.stringify({ jobs: transactionJobs, updated_at: new Date().toISOString() }, null, 2),\n\t\t\t\t);\n\t\t\t\trenameSync(tmp, file);\n\t\t\t} finally {\n\t\t\t\trmSync(tmp, { force: true });\n\t\t\t}\n\t\t\treturn structuredClone(result);\n\t\t} finally {\n\t\t\ttransactionJobs = undefined;\n\t\t\tawait release();\n\t\t}\n\t});\n\twriteQueue = operation.then(\n\t\t() => undefined,\n\t\t() => undefined,\n\t);\n\treturn operation;\n}\n\n/** Acquire the non-preemptive profile scheduler lease. A live PID is never displaced. */\nexport async function acquireSchedulerLease(): Promise<(() => Promise<void>) | null> {\n\tconst dir = cronDir();\n\tmkdirSync(dir, { recursive: true });\n\tconst file = join(dir, \"scheduler\");\n\tconst ownerFile = `${file}.owner.json`;\n\tconst staleMs = 120_000;\n\tif (existsSync(`${file}.lock`)) {\n\t\tlet owner: unknown;\n\t\ttry {\n\t\t\towner = JSON.parse(readFileSync(ownerFile, \"utf-8\"));\n\t\t\tif (\n\t\t\t\t!owner ||\n\t\t\t\ttypeof owner !== \"object\" ||\n\t\t\t\t!(\"pid\" in owner) ||\n\t\t\t\ttypeof owner.pid !== \"number\" ||\n\t\t\t\t!Number.isInteger(owner.pid) ||\n\t\t\t\towner.pid <= 0 ||\n\t\t\t\towner.pid > 2_147_483_647\n\t\t\t)\n\t\t\t\tthrow new Error(\"invalid scheduler owner PID\");\n\t\t} catch (error) {\n\t\t\t// A competing operator may still be publishing its owner record. Missing\n\t\t\t// or malformed metadata never proves that an existing owner is dead.\n\t\t\tif (!existsSync(`${file}.lock`)) return acquireSchedulerLease();\n\t\t\tif ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n\t\t\t\ttry {\n\t\t\t\t\tif (Date.now() - statSync(`${file}.lock`).mtimeMs < staleMs) return null;\n\t\t\t\t} catch (lockError) {\n\t\t\t\t\tif ((lockError as NodeJS.ErrnoException).code === \"ENOENT\") return acquireSchedulerLease();\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow new Error(\n\t\t\t\t`Cron scheduler ownership cannot be verified. Before repairing it, confirm every operator using this profile has stopped. ` +\n\t\t\t\t\t`Then remove ${file}.lock and ${ownerFile}, and restart scheduling. Never remove them while an operator may be running.`,\n\t\t\t\t{ cause: error },\n\t\t\t);\n\t\t}\n\t\ttry {\n\t\t\tprocess.kill(owner.pid, 0);\n\t\t\treturn null;\n\t\t} catch (error) {\n\t\t\tif ((error as NodeJS.ErrnoException).code !== \"ESRCH\") return null;\n\t\t}\n\t}\n\tlet release: () => Promise<void>;\n\ttry {\n\t\trelease = await lockfile.lock(file, { realpath: false, stale: staleMs });\n\t} catch (error) {\n\t\tif ((error as NodeJS.ErrnoException).code === \"ELOCKED\") return null;\n\t\tthrow error;\n\t}\n\tconst ownerTmp = join(dir, `.scheduler.owner.json.${randomUUID()}.tmp`);\n\ttry {\n\t\twriteFileSync(ownerTmp, JSON.stringify({ pid: process.pid }));\n\t\trenameSync(ownerTmp, ownerFile);\n\t} catch (error) {\n\t\tawait release();\n\t\tthrow error;\n\t} finally {\n\t\trmSync(ownerTmp, { force: true });\n\t}\n\treturn async () => {\n\t\ttry {\n\t\t\trmSync(ownerFile, { force: true });\n\t\t} finally {\n\t\t\tawait release();\n\t\t}\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// Schedule parsing\n// ---------------------------------------------------------------------------\n\nexport interface ParsedSchedule {\n\tschedule: CronSchedule;\n\tscheduleDisplay: string;\n}\n\nconst INTERVAL_RE = /^every\\s+(\\d+)\\s*([mhd])$/i;\nconst DURATION_RE = /^(\\d+)\\s*([mhd])$/i;\n\nfunction toMinutes(value: number, unit: string): number {\n\tconst u = unit.toLowerCase();\n\tconst factor = u === \"d\" ? 1440 : u === \"h\" ? 60 : 1;\n\treturn value * factor;\n}\n\n/**\n * Parse a schedule input:\n * - `every 30m` / `every 2h` / `every 1d` → interval (minutes; d = 1440)\n * - bare `30m` / `2h` / `1d` → one-shot at now + duration\n * - ISO timestamp → one-shot at that time\n * - 5-field cron expression (validated via croner; throws on invalid)\n */\nexport function parseSchedule(input: string, now: Date = new Date()): ParsedSchedule {\n\tconst text = input.trim().replace(/\\s+/g, \" \");\n\tif (!text) throw new Error(\"schedule is empty\");\n\n\tconst interval = INTERVAL_RE.exec(text);\n\tif (interval) {\n\t\tconst minutes = toMinutes(Number(interval[1]), interval[2]);\n\t\tif (minutes <= 0) throw new Error(`invalid interval: \"${text}\"`);\n\t\treturn {\n\t\t\tschedule: { kind: \"interval\", minutes },\n\t\t\tscheduleDisplay: `every ${Number(interval[1])}${interval[2].toLowerCase()}`,\n\t\t};\n\t}\n\n\tconst duration = DURATION_RE.exec(text);\n\tif (duration) {\n\t\tconst minutes = toMinutes(Number(duration[1]), duration[2]);\n\t\tif (minutes <= 0) throw new Error(`invalid duration: \"${text}\"`);\n\t\tconst runAt = new Date(now.getTime() + minutes * 60_000).toISOString();\n\t\treturn { schedule: { kind: \"once\", runAt }, scheduleDisplay: text };\n\t}\n\n\tif (/^\\d{4}-\\d{2}-\\d{2}/.test(text)) {\n\t\tconst ts = Date.parse(text);\n\t\tif (!Number.isNaN(ts)) {\n\t\t\tconst runAt = new Date(ts).toISOString();\n\t\t\treturn { schedule: { kind: \"once\", runAt }, scheduleDisplay: runAt };\n\t\t}\n\t}\n\n\tif (text.split(\" \").length === 5) {\n\t\ttry {\n\t\t\tnew Cron(text);\n\t\t} catch (err) {\n\t\t\tthrow new Error(`invalid cron expression \"${text}\": ${err instanceof Error ? err.message : String(err)}`);\n\t\t}\n\t\treturn { schedule: { kind: \"cron\", expr: text }, scheduleDisplay: text };\n\t}\n\n\tthrow new Error(\n\t\t`unrecognized schedule: \"${input}\" (expected \"every 30m\", \"2h\", an ISO timestamp, or a 5-field cron expression)`,\n\t);\n}\n\n// ---------------------------------------------------------------------------\n// Next-run computation\n// ---------------------------------------------------------------------------\n\n/**\n * Compute the next run time for a job:\n * - once: the stored runAt, recoverable within a 120s grace if never run; null after that or once run.\n * - interval: (lastRunAt ?? createdAt) + minutes.\n * - cron: croner nextRun after (lastRunAt ?? now).\n */\nexport function computeNextRun(job: CronJob, now: Date = new Date()): Date | null {\n\tconst s = job.schedule;\n\tif (s.kind === \"once\") {\n\t\tif (job.repeat.completed > 0) return null;\n\t\tif (!s.runAt) return null;\n\t\tconst runAt = new Date(s.runAt);\n\t\tif (Number.isNaN(runAt.getTime())) return null;\n\t\treturn now.getTime() - runAt.getTime() <= ONE_SHOT_GRACE_MS ? runAt : null;\n\t}\n\tif (s.kind === \"interval\") {\n\t\tconst base = job.lastRunAt ? new Date(job.lastRunAt) : new Date(job.createdAt);\n\t\treturn new Date(base.getTime() + (s.minutes ?? 0) * 60_000);\n\t}\n\tconst cron = new Cron(s.expr!);\n\treturn cron.nextRun(job.lastRunAt ? new Date(job.lastRunAt) : now);\n}\n\n/** Next slot strictly after `after` for a recurring job. */\nfunction nextSlotAfter(job: CronJob, after: Date): Date | null {\n\tif (job.schedule.kind === \"interval\") {\n\t\tconst period = (job.schedule.minutes ?? 0) * 60_000;\n\t\tif (period <= 0) return null;\n\t\t// Step forward from the stored nextRunAt (or now) until strictly in the future of `after`.\n\t\tlet slot = job.nextRunAt ? new Date(job.nextRunAt).getTime() : new Date(job.createdAt).getTime() + period;\n\t\twhile (slot <= after.getTime()) slot += period;\n\t\treturn new Date(slot);\n\t}\n\tif (job.schedule.kind === \"cron\") {\n\t\treturn new Cron(job.schedule.expr!).nextRun(after);\n\t}\n\treturn null;\n}\n\n// ---------------------------------------------------------------------------\n// Validation\n// ---------------------------------------------------------------------------\n\nlet workdirRoots: string[] = [process.cwd(), homedir()];\nlet deliverValidator: ((deliver: string, origin?: CronJobOrigin | null) => string | undefined) | undefined;\n\n/**\n * Configure the allowed absolute roots for cron job workdirs. Relative workdirs\n * are resolved against process.cwd() and must fall under one of these roots.\n * Default roots are process.cwd() and the user's home directory.\n */\nexport function setCronWorkdirRoots(roots: string[]): void {\n\tworkdirRoots = roots.map((r) => normalize(resolve(r)));\n}\n\n/**\n * Configure a deliver-target validator. When set, createJob/updateJob reject\n * deliver strings that the validator does not approve. The gateway uses this\n * to prevent delivery to arbitrary chats.\n */\nexport function setCronDeliverValidator(\n\tfn: ((deliver: string, origin?: CronJobOrigin | null) => string | undefined) | undefined,\n): void {\n\tdeliverValidator = fn;\n}\n\n/** Test seam: restore default validation state. */\nexport function resetCronValidators(): void {\n\tworkdirRoots = [process.cwd(), homedir()];\n\tdeliverValidator = undefined;\n}\n\nfunction isPathUnderRoot(absPath: string, root: string): boolean {\n\tconst rel = relative(root, absPath);\n\treturn rel === \"\" || (!rel.startsWith(`..${sep}`) && rel !== \"..\" && !isAbsolute(rel));\n}\n\nfunction validateWorkdir(workdir: string, origin?: CronJobOrigin | null): string | undefined {\n\tconst candidate = origin ? realpathSync(resolve(workdir)) : resolve(workdir);\n\tconst roots = origin\n\t\t? (loadGatewayConfig().projectRoots ?? []).flatMap((root) => {\n\t\t\t\ttry {\n\t\t\t\t\treturn [realpathSync(root)];\n\t\t\t\t} catch {\n\t\t\t\t\treturn [];\n\t\t\t\t}\n\t\t\t})\n\t\t: workdirRoots;\n\tif (isAbsolute(workdir) && !roots.some((root) => isPathUnderRoot(candidate, root))) {\n\t\treturn `workdir ${workdir} is outside allowed roots`;\n\t}\n\tif (!roots.some((root) => isPathUnderRoot(candidate, root))) {\n\t\treturn `workdir ${workdir} resolves outside allowed roots`;\n\t}\n\treturn undefined;\n}\n\nfunction runDeliverValidation(deliver: string, origin?: CronJobOrigin | null): string | undefined {\n\tif (deliverMentionsChatPlatform(deliver) && !isFeatureEnabled(\"chat-platforms\")) {\n\t\treturn chatPlatformDeliverBlockedMessage();\n\t}\n\treturn deliverValidator?.(deliver, origin);\n}\n\nfunction deriveName(prompt: string): string {\n\tconst first = prompt.split(\"\\n\")[0].replace(/\\s+/g, \" \").trim();\n\treturn (first || \"cron job\").slice(0, MAX_NAME_LEN);\n}\n\nexport async function createJob(input: CreateJobInput): Promise<CronJob> {\n\treturn mutateJobs(() => {\n\t\tconst prompt = input.prompt.trim();\n\t\tif (!prompt) throw new Error(\"createJob: prompt is empty\");\n\t\tif (input.workdir) {\n\t\t\tconst err = validateWorkdir(input.workdir, input.origin);\n\t\t\tif (err) throw new Error(`createJob: ${err}`);\n\t\t}\n\t\tif (input.deliver) {\n\t\t\tconst err = runDeliverValidation(input.deliver, input.origin);\n\t\t\tif (err) throw new Error(`createJob: ${err}`);\n\t\t}\n\t\tconst now = new Date();\n\t\tconst parsed = parseSchedule(input.schedule, now);\n\t\tconst isOneShot = parsed.schedule.kind === \"once\";\n\t\tconst times = isOneShot ? 1 : (input.times ?? null);\n\t\tif (times !== null && (!Number.isInteger(times) || times < 1)) {\n\t\t\tthrow new Error(`createJob: times must be a positive integer or null, got ${times}`);\n\t\t}\n\t\tconst job: CronJob = {\n\t\t\tid: randomUUID().replaceAll(\"-\", \"\").slice(0, 12),\n\t\t\tname: (input.name?.trim() || deriveName(prompt)).slice(0, MAX_NAME_LEN),\n\t\t\tprompt,\n\t\t\tschedule: parsed.schedule,\n\t\t\tscheduleDisplay: parsed.scheduleDisplay,\n\t\t\trepeat: { times, completed: 0 },\n\t\t\tenabled: true,\n\t\t\tstate: \"scheduled\",\n\t\t\tcreatedAt: now.toISOString(),\n\t\t\tnextRunAt: null,\n\t\t\tlastRunAt: null,\n\t\t\tlastStatus: null,\n\t\t\tlastError: null,\n\t\t\tlastDeliveryError: null,\n\t\t\tdeliver: input.deliver?.trim() || \"local\",\n\t\t\torigin: input.origin ?? null,\n\t\t\tcontextFrom: input.contextFrom,\n\t\t\tworkdir: input.workdir,\n\t\t};\n\t\tjob.nextRunAt = computeNextRun(job, now)?.toISOString() ?? null;\n\t\tloadJobs().push(job);\n\t\treturn job;\n\t});\n}\n\n/** Look up a job by id, then by unique name. Throws when not found or when the name is ambiguous. */\nexport function getJob(idOrName: string): CronJob {\n\tconst jobs = loadJobs();\n\tconst byId = jobs.find((j) => j.id === idOrName);\n\tif (byId) return byId;\n\tconst byName = jobs.filter((j) => j.name === idOrName);\n\tif (byName.length === 1) return byName[0];\n\tif (byName.length > 1) {\n\t\tthrow new Error(\n\t\t\t`cron job name \"${idOrName}\" is ambiguous (${byName.length} matches: ${byName.map((j) => j.id).join(\", \")})`,\n\t\t);\n\t}\n\tthrow new Error(`no cron job matches \"${idOrName}\"`);\n}\n\nexport function listJobs(): CronJob[] {\n\treturn [...loadJobs()];\n}\n\nexport async function updateJob(idOrName: string, patch: JobPatch): Promise<CronJob> {\n\treturn mutateJobs(() => {\n\t\tconst job = getJob(idOrName);\n\t\tif (patch.name !== undefined) job.name = patch.name.trim().slice(0, MAX_NAME_LEN) || job.name;\n\t\tif (patch.workdir !== undefined) {\n\t\t\tif (patch.workdir) {\n\t\t\t\tconst err = validateWorkdir(patch.workdir, patch.origin ?? job.origin);\n\t\t\t\tif (err) throw new Error(`updateJob: ${err}`);\n\t\t\t}\n\t\t\tjob.workdir = patch.workdir;\n\t\t}\n\t\tif (patch.deliver !== undefined) {\n\t\t\tconst err = runDeliverValidation(patch.deliver, patch.origin ?? job.origin);\n\t\t\tif (err) throw new Error(`updateJob: ${err}`);\n\t\t\tjob.deliver = patch.deliver.trim() || \"local\";\n\t\t}\n\t\tif (patch.prompt !== undefined) {\n\t\t\tconst prompt = patch.prompt.trim();\n\t\t\tif (!prompt) throw new Error(\"updateJob: prompt is empty\");\n\t\t\tjob.prompt = prompt;\n\t\t}\n\t\tif (patch.schedule !== undefined) {\n\t\t\tconst parsed = parseSchedule(patch.schedule);\n\t\t\tjob.schedule = parsed.schedule;\n\t\t\tjob.scheduleDisplay = parsed.scheduleDisplay;\n\t\t\tif (parsed.schedule.kind === \"once\") job.repeat.times = 1;\n\t\t\tjob.nextRunAt = computeNextRun(job)?.toISOString() ?? null;\n\t\t}\n\t\tif (patch.enabled !== undefined) job.enabled = patch.enabled;\n\t\tif (patch.times !== undefined) {\n\t\t\tif (patch.times !== null && (!Number.isInteger(patch.times) || patch.times < 1)) {\n\t\t\t\tthrow new Error(`updateJob: times must be a positive integer or null, got ${patch.times}`);\n\t\t\t}\n\t\t\tif (job.schedule.kind !== \"once\") job.repeat.times = patch.times;\n\t\t}\n\t\tif (patch.contextFrom !== undefined) job.contextFrom = patch.contextFrom;\n\t\tif (patch.origin !== undefined) job.origin = patch.origin;\n\t\tif (patch.nextRunAt !== undefined) job.nextRunAt = patch.nextRunAt;\n\t\tif (patch.lastDeliveryError !== undefined) job.lastDeliveryError = patch.lastDeliveryError;\n\t\treturn job;\n\t});\n}\n\nexport async function pauseJob(idOrName: string): Promise<CronJob> {\n\treturn mutateJobs(() => {\n\t\tconst job = getJob(idOrName);\n\t\tif (job.state !== \"completed\") job.state = \"paused\";\n\t\treturn job;\n\t});\n}\n\nexport async function resumeJob(idOrName: string): Promise<CronJob> {\n\treturn mutateJobs(() => {\n\t\tconst job = getJob(idOrName);\n\t\tif (job.interrupted)\n\t\t\tthrow new Error(\"interrupted run has unknown effects; inspect them and use cron run for a deliberate retry\");\n\t\tif (job.state === \"paused\") {\n\t\t\tjob.state = \"scheduled\";\n\t\t\tjob.nextRunAt = computeNextRun(job)?.toISOString() ?? null;\n\t\t}\n\t\treturn job;\n\t});\n}\n\nexport async function removeJob(idOrName: string): Promise<CronJob> {\n\treturn mutateJobs(() => {\n\t\tconst job = getJob(idOrName);\n\t\tconst jobs = loadJobs();\n\t\tjobs.splice(jobs.indexOf(job), 1);\n\t\treturn job;\n\t});\n}\n\n// ---------------------------------------------------------------------------\n// Scheduling\n// ---------------------------------------------------------------------------\n\n/**\n * Jobs due to fire now. Skips disabled/paused/completed jobs and jobs without a\n * nextRunAt. One-shots fire up to 120s late (flat recovery grace); beyond that\n * they are marked state \"error\" and skipped. Recurring backlog fires once;\n * claiming the occurrence advances it to the next future slot without a burst.\n */\nexport async function getDueJobs(now: Date = new Date()): Promise<CronJob[]> {\n\treturn mutateJobs(() => {\n\t\tconst due: CronJob[] = [];\n\t\tfor (const job of loadJobs()) {\n\t\t\tif (!job.enabled || job.state !== \"scheduled\" || job.activeRun) continue;\n\t\t\tif (!job.nextRunAt) continue;\n\t\t\tconst next = new Date(job.nextRunAt).getTime();\n\t\t\tif (Number.isNaN(next) || now.getTime() < next) continue;\n\n\t\t\tif (job.schedule.kind === \"once\") {\n\t\t\t\tif (now.getTime() - next <= ONE_SHOT_GRACE_MS) {\n\t\t\t\t\tdue.push(job);\n\t\t\t\t} else {\n\t\t\t\t\tjob.state = \"error\";\n\t\t\t\t\tjob.lastStatus = \"error\";\n\t\t\t\t\tjob.lastError = \"missed one-shot schedule beyond the 120s recovery grace\";\n\t\t\t\t\tjob.nextRunAt = null;\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tdue.push(job);\n\t\t}\n\t\treturn due;\n\t});\n}\n\n/**\n * Advance a recurring job to its next slot. Scheduler dispatch uses claimJobRun\n * instead so one-shots and recurring work both retain a durable claim.\n */\nexport async function advanceNextRun(jobId: string): Promise<CronJob> {\n\treturn mutateJobs(() => {\n\t\tconst job = getJob(jobId);\n\t\tif (job.schedule.kind !== \"once\") {\n\t\t\t// Advance to the first slot strictly after NOW: the job fires once for the\n\t\t\t// current slot, and the next fire is the next future slot (no catch-up burst).\n\t\t\tjob.nextRunAt = nextSlotAfter(job, new Date())?.toISOString() ?? computeNextRun(job)?.toISOString() ?? null;\n\t\t}\n\t\treturn job;\n\t});\n}\n\n/**\n * Record a finished run: lastRunAt/lastStatus/lastError, repeat.completed++,\n * then either complete the job (finite repeats exhausted, one-shots included)\n * or re-anchor nextRunAt off the previous scheduled slot (no drift).\n */\nexport async function markJobRun(\n\tjobId: string,\n\tresult: { status: CronJobStatus; error?: string; runId?: string },\n): Promise<CronJob | null> {\n\treturn mutateJobs(() => {\n\t\tconst job = loadJobs().find((job) => job.id === jobId);\n\t\tif (!job || (result.runId && job.activeRun?.id !== result.runId)) return null;\n\t\tdelete job.activeRun;\n\t\tdelete job.interrupted;\n\t\tconst now = new Date();\n\t\tjob.lastRunAt = now.toISOString();\n\t\tjob.lastStatus = result.status;\n\t\tjob.lastError = result.error ?? null;\n\t\tjob.repeat.completed += 1;\n\t\tif (job.repeat.times !== null && job.repeat.completed >= job.repeat.times) {\n\t\t\tjob.state = \"completed\";\n\t\t\tjob.nextRunAt = null;\n\t\t} else if (!result.runId && job.schedule.kind === \"interval\") {\n\t\t\t// Anchor to the previous scheduled slot + period to avoid cumulative drift.\n\t\t\t// If advanceNextRun already moved nextRunAt into the future (scheduler path),\n\t\t\t// keep it; otherwise (manual run) step forward from now.\n\t\t\tconst current = job.nextRunAt ? new Date(job.nextRunAt) : now;\n\t\t\tif (current.getTime() > now.getTime()) {\n\t\t\t\t// Already advanced by the scheduler — keep the scheduled slot.\n\t\t\t\tjob.nextRunAt = current.toISOString();\n\t\t\t} else {\n\t\t\t\tjob.nextRunAt = nextSlotAfter(job, now)?.toISOString() ?? null;\n\t\t\t}\n\t\t} else if (!result.runId && job.schedule.kind === \"cron\") {\n\t\t\tjob.nextRunAt = new Cron(job.schedule.expr!).nextRun(now)?.toISOString() ?? null;\n\t\t}\n\t\treturn job;\n\t});\n}\n\n/** Claim only a still-due, enabled occurrence from the fresh store. */\nexport async function claimJobRun(jobId: string, now: Date, manual = false): Promise<CronJob | null> {\n\treturn mutateJobs(() => {\n\t\tconst job = loadJobs().find((job) => job.id === jobId);\n\t\tif (!job || job.activeRun) return null;\n\t\tif (!manual && (!job.enabled || job.state !== \"scheduled\" || !job.nextRunAt || new Date(job.nextRunAt) > now))\n\t\t\treturn null;\n\t\tjob.activeRun = { id: randomUUID(), scheduledAt: job.nextRunAt, startedAt: now.toISOString() };\n\t\tjob.nextRunAt = job.schedule.kind === \"once\" ? null : (nextSlotAfter(job, now)?.toISOString() ?? null);\n\t\tjob.activeRun.advancedTo = job.nextRunAt;\n\t\treturn job;\n\t});\n}\n\n/** Recover uncertain interrupted work without replaying its external effects. */\nexport async function recoverInterruptedRuns(): Promise<void> {\n\tawait mutateJobs(() => {\n\t\tfor (const job of loadJobs()) {\n\t\t\tif (!job.activeRun) continue;\n\t\t\tjob.state = \"paused\";\n\t\t\tjob.lastStatus = \"error\";\n\t\t\tjob.lastError = \"interrupted run has unknown effects; use cron run to retry deliberately\";\n\t\t\tjob.interrupted = true;\n\t\t\tdelete job.activeRun;\n\t\t}\n\t});\n}\n\nexport async function deferJobRun(jobId: string, runId: string): Promise<void> {\n\tawait mutateJobs(() => {\n\t\tconst job = loadJobs().find((job) => job.id === jobId);\n\t\tif (job?.activeRun?.id !== runId) return;\n\t\tif (job.nextRunAt === job.activeRun.advancedTo) job.nextRunAt = job.activeRun.scheduledAt;\n\t\tdelete job.activeRun;\n\t});\n}\n\n// ---------------------------------------------------------------------------\n// Per-run output\n// ---------------------------------------------------------------------------\n\nfunction formatStamp(d: Date): string {\n\tconst p = (n: number) => String(n).padStart(2, \"0\");\n\treturn `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())}_${p(d.getHours())}-${p(d.getMinutes())}-${p(d.getSeconds())}`;\n}\n\nfunction parseStamp(stamp: string): Date {\n\tconst m = /^(\\d{4})-(\\d{2})-(\\d{2})_(\\d{2})-(\\d{2})-(\\d{2})/.exec(stamp);\n\tif (!m) return new Date();\n\treturn new Date(Number(m[1]), Number(m[2]) - 1, Number(m[3]), Number(m[4]), Number(m[5]), Number(m[6]));\n}\n\nlet lastOutputStamp = \"\";\n\n/** Monotonic timestamp stamp: never collides within the process, keeps lexicographic = chronological order. */\nfunction nextOutputStamp(): string {\n\tlet d = new Date();\n\tlet stamp = formatStamp(d);\n\tif (stamp <= lastOutputStamp) {\n\t\td = new Date(parseStamp(lastOutputStamp).getTime() + 1000);\n\t\tstamp = formatStamp(d);\n\t}\n\tlastOutputStamp = stamp;\n\treturn stamp;\n}\n\nfunction listOutputFiles(jobId: string): string[] {\n\tconst dir = outputDir(jobId);\n\tif (!existsSync(dir)) return [];\n\treturn readdirSync(dir)\n\t\t.filter((f) => f.endsWith(\".md\"))\n\t\t.sort();\n}\n\n/** Save a run's output and prune to the newest OUTPUT_RETENTION files. Returns the file path. */\nexport async function saveJobOutput(jobId: string, content: string): Promise<string> {\n\tconst dir = outputDir(jobId);\n\tmkdirSync(dir, { recursive: true });\n\tconst file = join(dir, `${nextOutputStamp()}.md`);\n\twriteFileSync(file, content, \"utf-8\");\n\tconst files = listOutputFiles(jobId);\n\twhile (files.length > OUTPUT_RETENTION) {\n\t\tconst oldest = files.shift();\n\t\tif (oldest) rmSync(join(dir, oldest), { force: true });\n\t}\n\treturn file;\n}\n\n/** Content of the newest output file for a job, or null when none exists. */\nexport function getLatestJobOutput(jobId: string): string | null {\n\tconst files = listOutputFiles(jobId);\n\tconst latest = files[files.length - 1];\n\tif (!latest) return null;\n\ttry {\n\t\treturn readFileSync(join(outputDir(jobId), latest), \"utf-8\");\n\t} catch {\n\t\treturn null;\n\t}\n}\n"]}
@@ -10,6 +10,7 @@
10
10
  * and behavior is unchanged (jobs default to "local" delivery).
11
11
  */
12
12
  export interface CronOriginContext {
13
+ userId?: string;
13
14
  platform: string;
14
15
  chatId: string;
15
16
  threadId?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"origin-context.d.ts","sourceRoot":"","sources":["../../../src/core/cron/origin-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,MAAM,WAAW,iBAAiB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAID,qFAAqF;AACrF,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,iBAAiB,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAE1E;AAED,oFAAoF;AACpF,wBAAgB,aAAa,IAAI,iBAAiB,GAAG,SAAS,CAE7D","sourcesContent":["/**\n * lunR: cron origin context (Phase 4 of the cron/gateway roadmap).\n *\n * AsyncLocalStorage carrying the chat a gateway turn came from. The gateway\n * agent bridge wraps session.prompt() in runWithOrigin(source, ...) so any\n * tool executing during that turn (e.g. the `cron` tool's create action) can\n * stamp jobs with the chat as their delivery origin. AsyncLocalStorage\n * propagates through awaited async calls, so deeply-nested tool execution\n * still sees the origin. Outside a gateway turn currentOrigin() is undefined\n * and behavior is unchanged (jobs default to \"local\" delivery).\n */\n\nimport { AsyncLocalStorage } from \"node:async_hooks\";\n\nexport interface CronOriginContext {\n\tplatform: string;\n\tchatId: string;\n\tthreadId?: string;\n\tchatType?: string;\n}\n\nconst storage = new AsyncLocalStorage<CronOriginContext>();\n\n/** Run fn with `origin` visible to currentOrigin() for the whole async call tree. */\nexport function runWithOrigin<T>(origin: CronOriginContext, fn: () => T): T {\n\treturn storage.run(origin, fn);\n}\n\n/** The origin of the current async context, or undefined outside a gateway turn. */\nexport function currentOrigin(): CronOriginContext | undefined {\n\treturn storage.getStore();\n}\n"]}
1
+ {"version":3,"file":"origin-context.d.ts","sourceRoot":"","sources":["../../../src/core/cron/origin-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,MAAM,WAAW,iBAAiB;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAID,qFAAqF;AACrF,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,iBAAiB,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAE1E;AAED,oFAAoF;AACpF,wBAAgB,aAAa,IAAI,iBAAiB,GAAG,SAAS,CAE7D","sourcesContent":["/**\n * lunR: cron origin context (Phase 4 of the cron/gateway roadmap).\n *\n * AsyncLocalStorage carrying the chat a gateway turn came from. The gateway\n * agent bridge wraps session.prompt() in runWithOrigin(source, ...) so any\n * tool executing during that turn (e.g. the `cron` tool's create action) can\n * stamp jobs with the chat as their delivery origin. AsyncLocalStorage\n * propagates through awaited async calls, so deeply-nested tool execution\n * still sees the origin. Outside a gateway turn currentOrigin() is undefined\n * and behavior is unchanged (jobs default to \"local\" delivery).\n */\n\nimport { AsyncLocalStorage } from \"node:async_hooks\";\n\nexport interface CronOriginContext {\n\tuserId?: string;\n\tplatform: string;\n\tchatId: string;\n\tthreadId?: string;\n\tchatType?: string;\n}\n\nconst storage = new AsyncLocalStorage<CronOriginContext>();\n\n/** Run fn with `origin` visible to currentOrigin() for the whole async call tree. */\nexport function runWithOrigin<T>(origin: CronOriginContext, fn: () => T): T {\n\treturn storage.run(origin, fn);\n}\n\n/** The origin of the current async context, or undefined outside a gateway turn. */\nexport function currentOrigin(): CronOriginContext | undefined {\n\treturn storage.getStore();\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"origin-context.js","sourceRoot":"","sources":["../../../src/core/cron/origin-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AASrD,MAAM,OAAO,GAAG,IAAI,iBAAiB,EAAqB,CAAC;AAE3D,qFAAqF;AACrF,MAAM,UAAU,aAAa,CAAI,MAAyB,EAAE,EAAW,EAAK;IAC3E,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AAAA,CAC/B;AAED,oFAAoF;AACpF,MAAM,UAAU,aAAa,GAAkC;IAC9D,OAAO,OAAO,CAAC,QAAQ,EAAE,CAAC;AAAA,CAC1B","sourcesContent":["/**\n * lunR: cron origin context (Phase 4 of the cron/gateway roadmap).\n *\n * AsyncLocalStorage carrying the chat a gateway turn came from. The gateway\n * agent bridge wraps session.prompt() in runWithOrigin(source, ...) so any\n * tool executing during that turn (e.g. the `cron` tool's create action) can\n * stamp jobs with the chat as their delivery origin. AsyncLocalStorage\n * propagates through awaited async calls, so deeply-nested tool execution\n * still sees the origin. Outside a gateway turn currentOrigin() is undefined\n * and behavior is unchanged (jobs default to \"local\" delivery).\n */\n\nimport { AsyncLocalStorage } from \"node:async_hooks\";\n\nexport interface CronOriginContext {\n\tplatform: string;\n\tchatId: string;\n\tthreadId?: string;\n\tchatType?: string;\n}\n\nconst storage = new AsyncLocalStorage<CronOriginContext>();\n\n/** Run fn with `origin` visible to currentOrigin() for the whole async call tree. */\nexport function runWithOrigin<T>(origin: CronOriginContext, fn: () => T): T {\n\treturn storage.run(origin, fn);\n}\n\n/** The origin of the current async context, or undefined outside a gateway turn. */\nexport function currentOrigin(): CronOriginContext | undefined {\n\treturn storage.getStore();\n}\n"]}
1
+ {"version":3,"file":"origin-context.js","sourceRoot":"","sources":["../../../src/core/cron/origin-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAUrD,MAAM,OAAO,GAAG,IAAI,iBAAiB,EAAqB,CAAC;AAE3D,qFAAqF;AACrF,MAAM,UAAU,aAAa,CAAI,MAAyB,EAAE,EAAW,EAAK;IAC3E,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AAAA,CAC/B;AAED,oFAAoF;AACpF,MAAM,UAAU,aAAa,GAAkC;IAC9D,OAAO,OAAO,CAAC,QAAQ,EAAE,CAAC;AAAA,CAC1B","sourcesContent":["/**\n * lunR: cron origin context (Phase 4 of the cron/gateway roadmap).\n *\n * AsyncLocalStorage carrying the chat a gateway turn came from. The gateway\n * agent bridge wraps session.prompt() in runWithOrigin(source, ...) so any\n * tool executing during that turn (e.g. the `cron` tool's create action) can\n * stamp jobs with the chat as their delivery origin. AsyncLocalStorage\n * propagates through awaited async calls, so deeply-nested tool execution\n * still sees the origin. Outside a gateway turn currentOrigin() is undefined\n * and behavior is unchanged (jobs default to \"local\" delivery).\n */\n\nimport { AsyncLocalStorage } from \"node:async_hooks\";\n\nexport interface CronOriginContext {\n\tuserId?: string;\n\tplatform: string;\n\tchatId: string;\n\tthreadId?: string;\n\tchatType?: string;\n}\n\nconst storage = new AsyncLocalStorage<CronOriginContext>();\n\n/** Run fn with `origin` visible to currentOrigin() for the whole async call tree. */\nexport function runWithOrigin<T>(origin: CronOriginContext, fn: () => T): T {\n\treturn storage.run(origin, fn);\n}\n\n/** The origin of the current async context, or undefined outside a gateway turn. */\nexport function currentOrigin(): CronOriginContext | undefined {\n\treturn storage.getStore();\n}\n"]}
@@ -3,8 +3,8 @@
3
3
  *
4
4
  * startScheduler() runs an unref'd, self-rescheduling setTimeout loop (default
5
5
  * 60s tick). Tick errors are caught — the loop never dies. Each tick collects
6
- * due jobs and runs them SEQUENTIALLY; recurring jobs are advanceNextRun()'d
7
- * BEFORE execution (at-most-once: a crash mid-run never double-fires).
6
+ * due jobs and runs them sequentially under a profile lease and durable occurrence
7
+ * claims. Interrupted work pauses for deliberate retry.
8
8
  *
9
9
  * Per due job: build the prompt (cron-hint prefix + contextFrom upstream
10
10
  * outputs at an 8K cap each + job.prompt) → runJob → saveJobOutput →
@@ -13,15 +13,16 @@
13
13
  * compact one-line error. Delivery errors land in job.lastDeliveryError.
14
14
  *
15
15
  * The scheduler knows nothing about delivery channels: runJob/deliverResult
16
- * are injected (the lunr-cron builtin extension wires the TUI + the
17
- * @lunr/cron-delivery bridge; the Phase 4 gateway replaces that bridge).
16
+ * are injected by the TUI extension or gateway operator.
18
17
  */
19
18
  import type { CronJob } from "./jobs.ts";
20
19
  export interface SchedulerDeps {
21
- /** Run one job turn; resolves with the final assistant text. */
22
- runJob: (prompt: string, job: CronJob) => Promise<string>;
20
+ /** Run one admitted turn. Await owned cancellation cleanup before resolving or rejecting. */
21
+ runJob: (prompt: string, job: CronJob, signal: AbortSignal) => Promise<string>;
23
22
  /** Deliver a result (or failure notice) to the job's targets. Throws on failure. */
24
23
  deliverResult: (job: CronJob, content: string) => Promise<void>;
24
+ /** Idle check before claiming; atomic admission must still be enforced by runJob. */
25
+ canRun?: () => boolean;
25
26
  /** Tick interval; default 60s. */
26
27
  intervalMs?: number;
27
28
  /** Per-job wall-clock timeout; default 5 minutes. */
@@ -34,18 +35,22 @@ export declare function cronPromptPrefix(job: CronJob): string;
34
35
  export declare function isSilent(text: string): boolean;
35
36
  /** cron-hint prefix + contextFrom upstream outputs (8K chars cap each) + job prompt. */
36
37
  export declare function buildJobPrompt(job: CronJob): string;
37
- /**
38
- * Execute one due job through the full pipeline. Never throws — run errors,
39
- * empty responses and delivery errors are recorded on the job.
40
- */
41
- export declare function executeJob(job: CronJob, deps: SchedulerDeps): Promise<void>;
42
- /** One scheduler tick: run every due job sequentially. Exported for tests. */
38
+ /** Admission failed before dispatch. Keep the occurrence due instead of recording a run. */
39
+ export declare class CronAdmissionDeferred extends Error {
40
+ }
41
+ /** One owned execution, including cooperative cancellation settlement and its terminal result. */
42
+ export declare function executeJob(job: CronJob, deps: SchedulerDeps, stopSignal?: AbortSignal): Promise<{
43
+ status: "settled";
44
+ } | {
45
+ status: "deferred";
46
+ reason: string;
47
+ }>;
48
+ /** A standalone tick owns the same lease as the long-lived operators. */
43
49
  export declare function runSchedulerTick(deps: SchedulerDeps, now?: Date): Promise<void>;
44
- /**
45
- * Start the scheduler loop. Unref'd so it never keeps the process alive;
46
- * tick errors are swallowed so the loop never dies.
47
- */
50
+ /** First healthy operator retains ownership until all admitted work and delivery settle. */
48
51
  export declare function startScheduler(deps: SchedulerDeps): {
49
- stop(): void;
52
+ isOwner: () => boolean;
53
+ run(jobId: string): Promise<void>;
54
+ stop(): Promise<void>;
50
55
  };
51
56
  //# sourceMappingURL=scheduler.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../../../src/core/cron/scheduler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAYzC,MAAM,WAAW,aAAa;IAC7B,gEAAgE;IAChE,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC1D,oFAAoF;IACpF,aAAa,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE,kCAAkC;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qDAAqD;IACrD,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,UAAU,aAAa,CAAC;AAErC,gFAAgF;AAChF,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAErD;AAED,yFAAuF;AACvF,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAK9C;AAED,wFAAwF;AACxF,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAUnD;AAyBD;;;GAGG;AACH,wBAAsB,UAAU,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAiCjF;AAED,8EAA8E;AAC9E,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,aAAa,EAAE,GAAG,GAAE,IAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAyBjG;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,aAAa,GAAG;IAAE,IAAI,IAAI,IAAI,CAAA;CAAE,CA0BpE","sourcesContent":["/**\n * lunR: cron scheduler loop (Phase 1 of the cron/gateway roadmap).\n *\n * startScheduler() runs an unref'd, self-rescheduling setTimeout loop (default\n * 60s tick). Tick errors are caught — the loop never dies. Each tick collects\n * due jobs and runs them SEQUENTIALLY; recurring jobs are advanceNextRun()'d\n * BEFORE execution (at-most-once: a crash mid-run never double-fires).\n *\n * Per due job: build the prompt (cron-hint prefix + contextFrom upstream\n * outputs at an 8K cap each + job.prompt) → runJob → saveJobOutput →\n * [SILENT] check (whole response, or first/last line) → deliverResult.\n * Empty responses are soft failures; all failures attempt delivery of a\n * compact one-line error. Delivery errors land in job.lastDeliveryError.\n *\n * The scheduler knows nothing about delivery channels: runJob/deliverResult\n * are injected (the lunr-cron builtin extension wires the TUI + the\n * @lunr/cron-delivery bridge; the Phase 4 gateway replaces that bridge).\n */\n\nimport type { CronJob } from \"./jobs.ts\";\nimport {\n\tadvanceNextRun,\n\tCONTEXT_OUTPUT_CAP,\n\tgetDueJobs,\n\tgetJob,\n\tgetLatestJobOutput,\n\tmarkJobRun,\n\tsaveJobOutput,\n\tupdateJob,\n} from \"./jobs.ts\";\n\nexport interface SchedulerDeps {\n\t/** Run one job turn; resolves with the final assistant text. */\n\trunJob: (prompt: string, job: CronJob) => Promise<string>;\n\t/** Deliver a result (or failure notice) to the job's targets. Throws on failure. */\n\tdeliverResult: (job: CronJob, content: string) => Promise<void>;\n\t/** Tick interval; default 60s. */\n\tintervalMs?: number;\n\t/** Per-job wall-clock timeout; default 5 minutes. */\n\tjobTimeoutMs?: number;\n}\n\nexport const SILENT_TAG = \"[SILENT]\";\n\n/** Prefix telling the model it runs unattended and how to suppress delivery. */\nexport function cronPromptPrefix(job: CronJob): string {\n\treturn `You are running as a scheduled cron job '${job.name}'. Delivery of your final response is automatic; respond with ${SILENT_TAG} to suppress delivery.`;\n}\n\n/** Whole response, or the first/last line, is exactly [SILENT] → suppress delivery. */\nexport function isSilent(text: string): boolean {\n\tconst trimmed = text.trim();\n\tif (trimmed === SILENT_TAG) return true;\n\tconst lines = trimmed.split(\"\\n\");\n\treturn lines[0].trim() === SILENT_TAG || lines[lines.length - 1].trim() === SILENT_TAG;\n}\n\n/** cron-hint prefix + contextFrom upstream outputs (8K chars cap each) + job prompt. */\nexport function buildJobPrompt(job: CronJob): string {\n\tconst parts = [cronPromptPrefix(job)];\n\tfor (const upstreamId of job.contextFrom ?? []) {\n\t\tconst output = getLatestJobOutput(upstreamId);\n\t\tif (output) {\n\t\t\tparts.push(`Latest output from cron job '${upstreamId}':\\n${output.slice(0, CONTEXT_OUTPUT_CAP)}`);\n\t\t}\n\t}\n\tparts.push(job.prompt);\n\treturn parts.join(\"\\n\\n\");\n}\n\nfunction errorMessage(err: unknown): string {\n\treturn err instanceof Error ? err.message : String(err);\n}\n\nfunction oneLine(text: string): string {\n\treturn text.replace(/\\s+/g, \" \").trim().slice(0, 200);\n}\n\nasync function recordDeliveryError(jobId: string, error: string | null, previous: string | null): Promise<void> {\n\tif (error === null && previous === null) return; // avoid a pointless write\n\tawait updateJob(jobId, { lastDeliveryError: error });\n}\n\n/** Failures always attempt delivery of a compact one-line error. */\nasync function deliverFailure(job: CronJob, deps: SchedulerDeps, message: string): Promise<void> {\n\ttry {\n\t\tawait deps.deliverResult(job, `Cron job '${job.name}' failed: ${oneLine(message)}`);\n\t\tawait recordDeliveryError(job.id, null, job.lastDeliveryError);\n\t} catch (err) {\n\t\tawait recordDeliveryError(job.id, errorMessage(err), job.lastDeliveryError);\n\t}\n}\n\n/**\n * Execute one due job through the full pipeline. Never throws — run errors,\n * empty responses and delivery errors are recorded on the job.\n */\nexport async function executeJob(job: CronJob, deps: SchedulerDeps): Promise<void> {\n\tlet text: string;\n\ttry {\n\t\ttext = await deps.runJob(buildJobPrompt(job), job);\n\t} catch (err) {\n\t\tconst message = errorMessage(err);\n\t\tawait markJobRun(job.id, { status: \"error\", error: message });\n\t\tawait deliverFailure(job, deps, message);\n\t\treturn;\n\t}\n\n\tif (!text.trim()) {\n\t\t// Empty response = soft failure.\n\t\tawait markJobRun(job.id, { status: \"error\", error: \"empty response\" });\n\t\tawait deliverFailure(job, deps, \"empty response\");\n\t\treturn;\n\t}\n\n\tawait saveJobOutput(job.id, text);\n\tif (isSilent(text)) {\n\t\t// Output is saved; delivery is suppressed.\n\t\tawait markJobRun(job.id, { status: \"ok\" });\n\t\treturn;\n\t}\n\n\tlet deliveryError: string | null = null;\n\ttry {\n\t\tawait deps.deliverResult(job, text);\n\t} catch (err) {\n\t\tdeliveryError = errorMessage(err);\n\t}\n\tawait markJobRun(job.id, { status: \"ok\" });\n\tawait recordDeliveryError(job.id, deliveryError, job.lastDeliveryError);\n}\n\n/** One scheduler tick: run every due job sequentially. Exported for tests. */\nexport async function runSchedulerTick(deps: SchedulerDeps, now: Date = new Date()): Promise<void> {\n\tconst due = await getDueJobs(now);\n\tconst jobTimeoutMs = deps.jobTimeoutMs ?? 5 * 60 * 1000;\n\tfor (const dueJob of due) {\n\t\tif (dueJob.schedule.kind !== \"once\") await advanceNextRun(dueJob.id);\n\t\tconst job = getJob(dueJob.id);\n\t\tlet timedOut = false;\n\t\tconst executePromise = executeJob(job, deps);\n\t\tconst timeoutPromise = new Promise<never>((_, reject) => {\n\t\t\tconst timer = setTimeout(() => {\n\t\t\t\ttimedOut = true;\n\t\t\t\treject(new Error(`timed out after ${jobTimeoutMs}ms`));\n\t\t\t}, jobTimeoutMs);\n\t\t\t// If executeJob finishes, this promise is discarded; the timer must not keep the process alive.\n\t\t\ttimer.unref?.();\n\t\t});\n\t\ttry {\n\t\t\tawait Promise.race([executePromise, timeoutPromise]);\n\t\t} catch (err) {\n\t\t\tif (!timedOut) throw err;\n\t\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\t\tawait markJobRun(job.id, { status: \"error\", error: message });\n\t\t\tawait deliverFailure(job, deps, message);\n\t\t}\n\t}\n}\n\n/**\n * Start the scheduler loop. Unref'd so it never keeps the process alive;\n * tick errors are swallowed so the loop never dies.\n */\nexport function startScheduler(deps: SchedulerDeps): { stop(): void } {\n\tconst intervalMs = deps.intervalMs ?? 60_000;\n\tlet stopped = false;\n\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\n\tconst loop = async (): Promise<void> => {\n\t\tif (stopped) return;\n\t\ttry {\n\t\t\tawait runSchedulerTick(deps);\n\t\t} catch {\n\t\t\t// never kill the loop\n\t\t}\n\t\tif (stopped) return;\n\t\ttimer = setTimeout(loop, intervalMs);\n\t\ttimer.unref?.();\n\t};\n\n\ttimer = setTimeout(loop, intervalMs);\n\ttimer.unref?.();\n\n\treturn {\n\t\tstop(): void {\n\t\t\tstopped = true;\n\t\t\tif (timer) clearTimeout(timer);\n\t\t},\n\t};\n}\n"]}
1
+ {"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../../../src/core/cron/scheduler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAczC,MAAM,WAAW,aAAa;IAC7B,6FAA6F;IAC7F,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/E,oFAAoF;IACpF,aAAa,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE,qFAAqF;IACrF,MAAM,CAAC,EAAE,MAAM,OAAO,CAAC;IACvB,kCAAkC;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qDAAqD;IACrD,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,UAAU,aAAa,CAAC;AAErC,gFAAgF;AAChF,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAErD;AAED,yFAAuF;AACvF,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAK9C;AAED,wFAAwF;AACxF,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAUnD;AA6BD,4FAA4F;AAC5F,qBAAa,qBAAsB,SAAQ,KAAK;CAAG;AAEnD,kGAAkG;AAClG,wBAAsB,UAAU,CAC/B,GAAG,EAAE,OAAO,EACZ,IAAI,EAAE,aAAa,EACnB,UAAU,CAAC,EAAE,WAAW,GACtB,OAAO,CAAC;IAAE,MAAM,EAAE,SAAS,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CA0CzE;AAiBD,yEAAyE;AACzE,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,aAAa,EAAE,GAAG,GAAE,IAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CASjG;AAED,4FAA4F;AAC5F,wBAAgB,cAAc,CAAC,IAAI,EAAE,aAAa;;;;EA+EjD","sourcesContent":["/**\n * lunR: cron scheduler loop (Phase 1 of the cron/gateway roadmap).\n *\n * startScheduler() runs an unref'd, self-rescheduling setTimeout loop (default\n * 60s tick). Tick errors are caught — the loop never dies. Each tick collects\n * due jobs and runs them sequentially under a profile lease and durable occurrence\n * claims. Interrupted work pauses for deliberate retry.\n *\n * Per due job: build the prompt (cron-hint prefix + contextFrom upstream\n * outputs at an 8K cap each + job.prompt) → runJob → saveJobOutput →\n * [SILENT] check (whole response, or first/last line) → deliverResult.\n * Empty responses are soft failures; all failures attempt delivery of a\n * compact one-line error. Delivery errors land in job.lastDeliveryError.\n *\n * The scheduler knows nothing about delivery channels: runJob/deliverResult\n * are injected by the TUI extension or gateway operator.\n */\n\nimport type { CronJob } from \"./jobs.ts\";\nimport {\n\tacquireSchedulerLease,\n\tCONTEXT_OUTPUT_CAP,\n\tclaimJobRun,\n\tdeferJobRun,\n\tgetDueJobs,\n\tgetLatestJobOutput,\n\tmarkJobRun,\n\trecoverInterruptedRuns,\n\tsaveJobOutput,\n\tupdateJob,\n} from \"./jobs.ts\";\n\nexport interface SchedulerDeps {\n\t/** Run one admitted turn. Await owned cancellation cleanup before resolving or rejecting. */\n\trunJob: (prompt: string, job: CronJob, signal: AbortSignal) => Promise<string>;\n\t/** Deliver a result (or failure notice) to the job's targets. Throws on failure. */\n\tdeliverResult: (job: CronJob, content: string) => Promise<void>;\n\t/** Idle check before claiming; atomic admission must still be enforced by runJob. */\n\tcanRun?: () => boolean;\n\t/** Tick interval; default 60s. */\n\tintervalMs?: number;\n\t/** Per-job wall-clock timeout; default 5 minutes. */\n\tjobTimeoutMs?: number;\n}\n\nexport const SILENT_TAG = \"[SILENT]\";\n\n/** Prefix telling the model it runs unattended and how to suppress delivery. */\nexport function cronPromptPrefix(job: CronJob): string {\n\treturn `You are running as a scheduled cron job '${job.name}'. Delivery of your final response is automatic; respond with ${SILENT_TAG} to suppress delivery.`;\n}\n\n/** Whole response, or the first/last line, is exactly [SILENT] → suppress delivery. */\nexport function isSilent(text: string): boolean {\n\tconst trimmed = text.trim();\n\tif (trimmed === SILENT_TAG) return true;\n\tconst lines = trimmed.split(\"\\n\");\n\treturn lines[0].trim() === SILENT_TAG || lines[lines.length - 1].trim() === SILENT_TAG;\n}\n\n/** cron-hint prefix + contextFrom upstream outputs (8K chars cap each) + job prompt. */\nexport function buildJobPrompt(job: CronJob): string {\n\tconst parts = [cronPromptPrefix(job)];\n\tfor (const upstreamId of job.contextFrom ?? []) {\n\t\tconst output = getLatestJobOutput(upstreamId);\n\t\tif (output) {\n\t\t\tparts.push(`Latest output from cron job '${upstreamId}':\\n${output.slice(0, CONTEXT_OUTPUT_CAP)}`);\n\t\t}\n\t}\n\tparts.push(job.prompt);\n\treturn parts.join(\"\\n\\n\");\n}\n\nfunction errorMessage(err: unknown): string {\n\treturn err instanceof Error ? err.message : String(err);\n}\n\nfunction oneLine(text: string): string {\n\treturn text.replace(/\\s+/g, \" \").trim().slice(0, 200);\n}\n\nasync function recordDeliveryError(jobId: string, error: string | null, previous: string | null): Promise<void> {\n\tif (error === null && previous === null) return; // avoid a pointless write\n\ttry {\n\t\tawait updateJob(jobId, { lastDeliveryError: error });\n\t} catch (err) {\n\t\tif (!String(err).includes(\"no cron job matches\")) throw err;\n\t}\n}\n\n/** Failures always attempt delivery of a compact one-line error. */\nasync function deliverFailure(job: CronJob, deps: SchedulerDeps, message: string): Promise<void> {\n\ttry {\n\t\tawait deps.deliverResult(job, `Cron job '${job.name}' failed: ${oneLine(message)}`);\n\t\tawait recordDeliveryError(job.id, null, job.lastDeliveryError);\n\t} catch (err) {\n\t\tawait recordDeliveryError(job.id, errorMessage(err), job.lastDeliveryError);\n\t}\n}\n\n/** Admission failed before dispatch. Keep the occurrence due instead of recording a run. */\nexport class CronAdmissionDeferred extends Error {}\n\n/** One owned execution, including cooperative cancellation settlement and its terminal result. */\nexport async function executeJob(\n\tjob: CronJob,\n\tdeps: SchedulerDeps,\n\tstopSignal?: AbortSignal,\n): Promise<{ status: \"settled\" } | { status: \"deferred\"; reason: string }> {\n\tconst controller = new AbortController();\n\tconst cancel = () => controller.abort(stopSignal?.reason ?? new Error(\"scheduler stopped\"));\n\tstopSignal?.addEventListener(\"abort\", cancel, { once: true });\n\tif (stopSignal?.aborted) cancel();\n\tconst timeoutMs = deps.jobTimeoutMs ?? 5 * 60 * 1000;\n\tconst timer = setTimeout(() => controller.abort(new Error(`timed out after ${timeoutMs}ms`)), timeoutMs);\n\ttimer.unref?.();\n\tlet text = \"\";\n\tlet failure: string | undefined;\n\ttry {\n\t\tcontroller.signal.throwIfAborted();\n\t\ttext = await deps.runJob(buildJobPrompt(job), job, controller.signal);\n\t\tcontroller.signal.throwIfAborted();\n\t\tif (!text.trim()) throw new Error(\"empty response\");\n\t} catch (error) {\n\t\tif (error instanceof CronAdmissionDeferred && !controller.signal.aborted && job.activeRun) {\n\t\t\tawait deferJobRun(job.id, job.activeRun.id);\n\t\t\treturn { status: \"deferred\", reason: error.message };\n\t\t}\n\t\tfailure = errorMessage(controller.signal.aborted ? controller.signal.reason : error);\n\t} finally {\n\t\tclearTimeout(timer);\n\t\tstopSignal?.removeEventListener(\"abort\", cancel);\n\t}\n\tif (failure) {\n\t\tawait markJobRun(job.id, { status: \"error\", error: failure, runId: job.activeRun?.id });\n\t\tawait deliverFailure(job, deps, failure);\n\t\treturn { status: \"settled\" };\n\t}\n\tawait saveJobOutput(job.id, text);\n\tlet deliveryError: string | null = null;\n\tif (!isSilent(text)) {\n\t\ttry {\n\t\t\tawait deps.deliverResult(job, text);\n\t\t} catch (error) {\n\t\t\tdeliveryError = errorMessage(error);\n\t\t}\n\t}\n\tawait markJobRun(job.id, { status: \"ok\", runId: job.activeRun?.id });\n\tawait recordDeliveryError(job.id, deliveryError, job.lastDeliveryError);\n\treturn { status: \"settled\" };\n}\n\nasync function tick(deps: SchedulerDeps, now: Date, signal: AbortSignal): Promise<void> {\n\tconst due = await getDueJobs(now);\n\tfor (const dueJob of due) {\n\t\tif (signal.aborted || deps.canRun?.() === false) break;\n\t\tconst job = await claimJobRun(dueJob.id, now);\n\t\tif (job) {\n\t\t\tif (signal.aborted) {\n\t\t\t\tawait deferJobRun(job.id, job.activeRun!.id);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tawait executeJob(job, deps, signal);\n\t\t}\n\t}\n}\n\n/** A standalone tick owns the same lease as the long-lived operators. */\nexport async function runSchedulerTick(deps: SchedulerDeps, now: Date = new Date()): Promise<void> {\n\tconst release = await acquireSchedulerLease();\n\tif (!release) return;\n\ttry {\n\t\tawait recoverInterruptedRuns();\n\t\tawait tick(deps, now, new AbortController().signal);\n\t} finally {\n\t\tawait release();\n\t}\n}\n\n/** First healthy operator retains ownership until all admitted work and delivery settle. */\nexport function startScheduler(deps: SchedulerDeps) {\n\tconst controller = new AbortController();\n\tconst intervalMs = deps.intervalMs ?? 60_000;\n\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\tlet release: (() => Promise<void>) | null = null;\n\tlet active: Promise<void> | undefined;\n\tlet stopping: Promise<void> | undefined;\n\tconst ready = acquireSchedulerLease().then(async (lease) => {\n\t\trelease = lease;\n\t\tif (lease) {\n\t\t\ttry {\n\t\t\t\tawait recoverInterruptedRuns();\n\t\t\t} catch (error) {\n\t\t\t\tawait lease();\n\t\t\t\trelease = null;\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\t});\n\t// Attach a rejection handler immediately; the first timer may be a minute away.\n\tvoid ready.catch(() => {});\n\tconst loop = async (): Promise<void> => {\n\t\tif (controller.signal.aborted) return;\n\t\ttry {\n\t\t\tawait ready;\n\t\t\tif (release && !controller.signal.aborted && !active) {\n\t\t\t\tactive = tick(deps, new Date(), controller.signal);\n\t\t\t\ttry {\n\t\t\t\t\tawait active;\n\t\t\t\t} finally {\n\t\t\t\t\tactive = undefined;\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsole.error(\"[cron] scheduler tick failed\", error);\n\t\t}\n\t\tif (!controller.signal.aborted) {\n\t\t\ttimer = setTimeout(loop, intervalMs);\n\t\t\ttimer.unref?.();\n\t\t}\n\t};\n\ttimer = setTimeout(loop, intervalMs);\n\ttimer.unref?.();\n\treturn {\n\t\tisOwner: () => release !== null && !controller.signal.aborted,\n\t\tasync run(jobId: string): Promise<void> {\n\t\t\tawait ready;\n\t\t\tif (!release) throw new Error(\"another process owns the cron scheduler; run the job from that operator\");\n\t\t\tif (controller.signal.aborted) throw new Error(\"cron scheduler is stopping\");\n\t\t\tif (active || deps.canRun?.() === false) throw new Error(\"cron operator is busy; retry when idle\");\n\t\t\tactive = (async () => {\n\t\t\t\tconst job = await claimJobRun(jobId, new Date(), true);\n\t\t\t\tif (!job) throw new Error(\"cron job is missing or already running\");\n\t\t\t\tconst result = await executeJob(job, deps, controller.signal);\n\t\t\t\tif (result.status === \"deferred\")\n\t\t\t\t\tthrow new CronAdmissionDeferred(`Cron job was not admitted: ${result.reason}`);\n\t\t\t})();\n\t\t\ttry {\n\t\t\t\tawait active;\n\t\t\t} finally {\n\t\t\t\tactive = undefined;\n\t\t\t}\n\t\t},\n\t\tstop(): Promise<void> {\n\t\t\tif (stopping) return stopping;\n\t\t\tcontroller.abort(new Error(\"scheduler stopped\"));\n\t\t\tif (timer) clearTimeout(timer);\n\t\t\tstopping = (async () => {\n\t\t\t\tawait ready;\n\t\t\t\ttry {\n\t\t\t\t\tawait active;\n\t\t\t\t} finally {\n\t\t\t\t\tif (release) await release();\n\t\t\t\t\trelease = null;\n\t\t\t\t}\n\t\t\t})();\n\t\t\treturn stopping;\n\t\t},\n\t};\n}\n"]}