@ashx-j/lunr 0.2.26 → 0.2.28

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 (697) hide show
  1. package/CHANGELOG.md +25 -1
  2. package/LICENSE +22 -0
  3. package/dist/builtin-extensions/ashxj-thinking.d.ts +1 -1
  4. package/dist/builtin-extensions/ashxj-thinking.d.ts.map +1 -1
  5. package/dist/builtin-extensions/ashxj-thinking.js +1 -1
  6. package/dist/builtin-extensions/ashxj-thinking.js.map +1 -1
  7. package/dist/builtin-extensions/ashxj-tui.d.ts +11 -1
  8. package/dist/builtin-extensions/ashxj-tui.d.ts.map +1 -1
  9. package/dist/builtin-extensions/ashxj-tui.js +6 -10
  10. package/dist/builtin-extensions/ashxj-tui.js.map +1 -1
  11. package/dist/builtin-extensions/lunr-cron.d.ts +4 -5
  12. package/dist/builtin-extensions/lunr-cron.d.ts.map +1 -1
  13. package/dist/builtin-extensions/lunr-cron.js +94 -108
  14. package/dist/builtin-extensions/lunr-cron.js.map +1 -1
  15. package/dist/builtin-extensions/lunr-local-providers/local-servers.d.ts.map +1 -1
  16. package/dist/builtin-extensions/lunr-local-providers/local-servers.js +3 -1
  17. package/dist/builtin-extensions/lunr-local-providers/local-servers.js.map +1 -1
  18. package/dist/builtin-extensions/narumiruna-pi-goal/src/accounting.d.ts.map +1 -1
  19. package/dist/builtin-extensions/narumiruna-pi-goal/src/accounting.js +5 -2
  20. package/dist/builtin-extensions/narumiruna-pi-goal/src/accounting.js.map +1 -1
  21. package/dist/builtin-extensions/narumiruna-pi-goal/src/commands.d.ts.map +1 -1
  22. package/dist/builtin-extensions/narumiruna-pi-goal/src/commands.js +2 -2
  23. package/dist/builtin-extensions/narumiruna-pi-goal/src/commands.js.map +1 -1
  24. package/dist/builtin-extensions/narumiruna-pi-goal/src/goal.d.ts.map +1 -1
  25. package/dist/builtin-extensions/narumiruna-pi-goal/src/goal.js +1 -1
  26. package/dist/builtin-extensions/narumiruna-pi-goal/src/goal.js.map +1 -1
  27. package/dist/builtin-extensions/narumiruna-pi-goal/src/runtime.d.ts.map +1 -1
  28. package/dist/builtin-extensions/narumiruna-pi-goal/src/runtime.js +1 -1
  29. package/dist/builtin-extensions/narumiruna-pi-goal/src/runtime.js.map +1 -1
  30. package/dist/builtin-extensions/pi-intercom/index.d.ts.map +1 -1
  31. package/dist/builtin-extensions/pi-intercom/index.js +2 -2
  32. package/dist/builtin-extensions/pi-intercom/index.js.map +1 -1
  33. package/dist/builtin-extensions/pi-lsp-extension/bemol-extension/index.d.ts +1 -1
  34. package/dist/builtin-extensions/pi-lsp-extension/bemol-extension/index.d.ts.map +1 -1
  35. package/dist/builtin-extensions/pi-lsp-extension/bemol-extension/index.js +1 -1
  36. package/dist/builtin-extensions/pi-lsp-extension/bemol-extension/index.js.map +1 -1
  37. package/dist/builtin-extensions/pi-lsp-extension/src/index.d.ts.map +1 -1
  38. package/dist/builtin-extensions/pi-lsp-extension/src/index.js +1 -15
  39. package/dist/builtin-extensions/pi-lsp-extension/src/index.js.map +1 -1
  40. package/dist/builtin-extensions/pi-lsp-extension/src/lsp-client.d.ts +6 -0
  41. package/dist/builtin-extensions/pi-lsp-extension/src/lsp-client.d.ts.map +1 -1
  42. package/dist/builtin-extensions/pi-lsp-extension/src/lsp-client.js +187 -132
  43. package/dist/builtin-extensions/pi-lsp-extension/src/lsp-client.js.map +1 -1
  44. package/dist/builtin-extensions/pi-lsp-extension/src/lsp-manager.d.ts +8 -0
  45. package/dist/builtin-extensions/pi-lsp-extension/src/lsp-manager.d.ts.map +1 -1
  46. package/dist/builtin-extensions/pi-lsp-extension/src/lsp-manager.js +142 -112
  47. package/dist/builtin-extensions/pi-lsp-extension/src/lsp-manager.js.map +1 -1
  48. package/dist/builtin-extensions/pi-lsp-extension/src/tools/code-rewrite.d.ts +12 -1
  49. package/dist/builtin-extensions/pi-lsp-extension/src/tools/code-rewrite.d.ts.map +1 -1
  50. package/dist/builtin-extensions/pi-lsp-extension/src/tools/code-rewrite.js +14 -7
  51. package/dist/builtin-extensions/pi-lsp-extension/src/tools/code-rewrite.js.map +1 -1
  52. package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/rewrite-engine.d.ts +11 -3
  53. package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/rewrite-engine.d.ts.map +1 -1
  54. package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/rewrite-engine.js +67 -41
  55. package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/rewrite-engine.js.map +1 -1
  56. package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/search-engine.d.ts +4 -2
  57. package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/search-engine.d.ts.map +1 -1
  58. package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/search-engine.js +3 -0
  59. package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/search-engine.js.map +1 -1
  60. package/dist/builtin-extensions/pi-mcp-adapter/commands.d.ts +2 -1
  61. package/dist/builtin-extensions/pi-mcp-adapter/commands.d.ts.map +1 -1
  62. package/dist/builtin-extensions/pi-mcp-adapter/commands.js +6 -6
  63. package/dist/builtin-extensions/pi-mcp-adapter/commands.js.map +1 -1
  64. package/dist/builtin-extensions/pi-mcp-adapter/config.d.ts +1 -1
  65. package/dist/builtin-extensions/pi-mcp-adapter/config.d.ts.map +1 -1
  66. package/dist/builtin-extensions/pi-mcp-adapter/config.js +11 -5
  67. package/dist/builtin-extensions/pi-mcp-adapter/config.js.map +1 -1
  68. package/dist/builtin-extensions/pi-mcp-adapter/direct-tool-executor.d.ts.map +1 -1
  69. package/dist/builtin-extensions/pi-mcp-adapter/direct-tool-executor.js +2 -2
  70. package/dist/builtin-extensions/pi-mcp-adapter/direct-tool-executor.js.map +1 -1
  71. package/dist/builtin-extensions/pi-mcp-adapter/host-html-template.d.ts.map +1 -1
  72. package/dist/builtin-extensions/pi-mcp-adapter/host-html-template.js +1 -1
  73. package/dist/builtin-extensions/pi-mcp-adapter/host-html-template.js.map +1 -1
  74. package/dist/builtin-extensions/pi-mcp-adapter/index.d.ts.map +1 -1
  75. package/dist/builtin-extensions/pi-mcp-adapter/index.js +48 -40
  76. package/dist/builtin-extensions/pi-mcp-adapter/index.js.map +1 -1
  77. package/dist/builtin-extensions/pi-mcp-adapter/init.d.ts.map +1 -1
  78. package/dist/builtin-extensions/pi-mcp-adapter/init.js +3 -1
  79. package/dist/builtin-extensions/pi-mcp-adapter/init.js.map +1 -1
  80. package/dist/builtin-extensions/pi-mcp-adapter/mcp-auth-flow.d.ts +12 -40
  81. package/dist/builtin-extensions/pi-mcp-adapter/mcp-auth-flow.d.ts.map +1 -1
  82. package/dist/builtin-extensions/pi-mcp-adapter/mcp-auth-flow.js +166 -235
  83. package/dist/builtin-extensions/pi-mcp-adapter/mcp-auth-flow.js.map +1 -1
  84. package/dist/builtin-extensions/pi-mcp-adapter/mcp-callback-server.d.ts +5 -0
  85. package/dist/builtin-extensions/pi-mcp-adapter/mcp-callback-server.d.ts.map +1 -1
  86. package/dist/builtin-extensions/pi-mcp-adapter/mcp-callback-server.js +43 -13
  87. package/dist/builtin-extensions/pi-mcp-adapter/mcp-callback-server.js.map +1 -1
  88. package/dist/builtin-extensions/pi-mcp-adapter/mcp-oauth-provider.d.ts +14 -3
  89. package/dist/builtin-extensions/pi-mcp-adapter/mcp-oauth-provider.d.ts.map +1 -1
  90. package/dist/builtin-extensions/pi-mcp-adapter/mcp-oauth-provider.js +73 -21
  91. package/dist/builtin-extensions/pi-mcp-adapter/mcp-oauth-provider.js.map +1 -1
  92. package/dist/builtin-extensions/pi-mcp-adapter/proxy-modes.d.ts.map +1 -1
  93. package/dist/builtin-extensions/pi-mcp-adapter/proxy-modes.js +4 -4
  94. package/dist/builtin-extensions/pi-mcp-adapter/proxy-modes.js.map +1 -1
  95. package/dist/builtin-extensions/pi-mcp-adapter/server-manager.d.ts.map +1 -1
  96. package/dist/builtin-extensions/pi-mcp-adapter/server-manager.js +2 -2
  97. package/dist/builtin-extensions/pi-mcp-adapter/server-manager.js.map +1 -1
  98. package/dist/builtin-extensions/pi-mcp-adapter/state.d.ts +2 -0
  99. package/dist/builtin-extensions/pi-mcp-adapter/state.d.ts.map +1 -1
  100. package/dist/builtin-extensions/pi-mcp-adapter/state.js.map +1 -1
  101. package/dist/builtin-extensions/pi-ollama-cloud/index.d.ts +1 -1
  102. package/dist/builtin-extensions/pi-ollama-cloud/index.d.ts.map +1 -1
  103. package/dist/builtin-extensions/pi-ollama-cloud/index.js +1 -1
  104. package/dist/builtin-extensions/pi-ollama-cloud/index.js.map +1 -1
  105. package/dist/builtin-extensions/pi-ollama-cloud/models.d.ts +11 -5
  106. package/dist/builtin-extensions/pi-ollama-cloud/models.d.ts.map +1 -1
  107. package/dist/builtin-extensions/pi-ollama-cloud/models.js +12 -32
  108. package/dist/builtin-extensions/pi-ollama-cloud/models.js.map +1 -1
  109. package/dist/builtin-extensions/pi-prompt-template-model/index.d.ts.map +1 -1
  110. package/dist/builtin-extensions/pi-prompt-template-model/index.js +5 -3
  111. package/dist/builtin-extensions/pi-prompt-template-model/index.js.map +1 -1
  112. package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.d.ts +2 -1
  113. package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.d.ts.map +1 -1
  114. package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.js +21 -12
  115. package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.js.map +1 -1
  116. package/dist/builtin-extensions/pi-prompt-template-model/tool-manager.d.ts.map +1 -1
  117. package/dist/builtin-extensions/pi-prompt-template-model/tool-manager.js +7 -24
  118. package/dist/builtin-extensions/pi-prompt-template-model/tool-manager.js.map +1 -1
  119. package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts.map +1 -1
  120. package/dist/builtin-extensions/pi-subagents/src/extension/index.js +39 -77
  121. package/dist/builtin-extensions/pi-subagents/src/extension/index.js.map +1 -1
  122. package/dist/builtin-extensions/pi-subagents/src/runs/background/chain-root-attachment.d.ts +4 -1
  123. package/dist/builtin-extensions/pi-subagents/src/runs/background/chain-root-attachment.d.ts.map +1 -1
  124. package/dist/builtin-extensions/pi-subagents/src/runs/background/chain-root-attachment.js +2 -0
  125. package/dist/builtin-extensions/pi-subagents/src/runs/background/chain-root-attachment.js.map +1 -1
  126. package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.d.ts +6 -1
  127. package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.d.ts.map +1 -1
  128. package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.js +17 -31
  129. package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.js.map +1 -1
  130. package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.d.ts.map +1 -1
  131. package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.js +7 -2
  132. package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.js.map +1 -1
  133. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.d.ts +5 -1
  134. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.d.ts.map +1 -1
  135. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.js +78 -42
  136. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.js.map +1 -1
  137. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.d.ts.map +1 -1
  138. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.js +8 -1
  139. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.js.map +1 -1
  140. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.d.ts +0 -3
  141. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.d.ts.map +1 -1
  142. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.js +134 -28
  143. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.js.map +1 -1
  144. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.d.ts.map +1 -1
  145. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js +26 -5
  146. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js.map +1 -1
  147. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.d.ts +1 -1
  148. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.d.ts.map +1 -1
  149. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.js +1 -1
  150. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.js.map +1 -1
  151. package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.d.ts +7 -8
  152. package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.d.ts.map +1 -1
  153. package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.js +60 -32
  154. package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.js.map +1 -1
  155. package/dist/builtin-extensions/pi-subagents/src/shared/session-tokens.d.ts +7 -1
  156. package/dist/builtin-extensions/pi-subagents/src/shared/session-tokens.d.ts.map +1 -1
  157. package/dist/builtin-extensions/pi-subagents/src/shared/session-tokens.js +70 -38
  158. package/dist/builtin-extensions/pi-subagents/src/shared/session-tokens.js.map +1 -1
  159. package/dist/builtin-extensions/pi-subagents/src/shared/types.d.ts +9 -0
  160. package/dist/builtin-extensions/pi-subagents/src/shared/types.d.ts.map +1 -1
  161. package/dist/builtin-extensions/pi-subagents/src/shared/types.js.map +1 -1
  162. package/dist/builtin-extensions/pi-subagents/src/shared/utils.d.ts +1 -1
  163. package/dist/builtin-extensions/pi-subagents/src/shared/utils.d.ts.map +1 -1
  164. package/dist/builtin-extensions/pi-subagents/src/shared/utils.js +15 -5
  165. package/dist/builtin-extensions/pi-subagents/src/shared/utils.js.map +1 -1
  166. package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.d.ts.map +1 -1
  167. package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.js +4 -3
  168. package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.js.map +1 -1
  169. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.d.ts.map +1 -1
  170. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.js +13 -62
  171. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.js.map +1 -1
  172. package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts +1 -1
  173. package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts.map +1 -1
  174. package/dist/builtin-extensions/pi-subagents/src/tui/render.js +18 -9
  175. package/dist/builtin-extensions/pi-subagents/src/tui/render.js.map +1 -1
  176. package/dist/builtin-extensions/pi-subagents/src/watchdog/review.d.ts.map +1 -1
  177. package/dist/builtin-extensions/pi-subagents/src/watchdog/review.js +3 -3
  178. package/dist/builtin-extensions/pi-subagents/src/watchdog/review.js.map +1 -1
  179. package/dist/builtin-extensions/pi-tps.d.ts.map +1 -1
  180. package/dist/builtin-extensions/pi-tps.js +28 -17
  181. package/dist/builtin-extensions/pi-tps.js.map +1 -1
  182. package/dist/builtin-extensions/pi-web-access/activity.d.ts +1 -0
  183. package/dist/builtin-extensions/pi-web-access/activity.d.ts.map +1 -1
  184. package/dist/builtin-extensions/pi-web-access/activity.js +27 -5
  185. package/dist/builtin-extensions/pi-web-access/activity.js.map +1 -1
  186. package/dist/builtin-extensions/pi-web-access/bounded-body.d.ts +3 -0
  187. package/dist/builtin-extensions/pi-web-access/bounded-body.d.ts.map +1 -0
  188. package/dist/builtin-extensions/pi-web-access/bounded-body.js +43 -0
  189. package/dist/builtin-extensions/pi-web-access/bounded-body.js.map +1 -0
  190. package/dist/builtin-extensions/pi-web-access/content-page.d.ts +24 -0
  191. package/dist/builtin-extensions/pi-web-access/content-page.d.ts.map +1 -0
  192. package/dist/builtin-extensions/pi-web-access/content-page.js +57 -0
  193. package/dist/builtin-extensions/pi-web-access/content-page.js.map +1 -0
  194. package/dist/builtin-extensions/pi-web-access/extract.d.ts.map +1 -1
  195. package/dist/builtin-extensions/pi-web-access/extract.js +7 -2
  196. package/dist/builtin-extensions/pi-web-access/extract.js.map +1 -1
  197. package/dist/builtin-extensions/pi-web-access/github-extract.d.ts +0 -1
  198. package/dist/builtin-extensions/pi-web-access/github-extract.d.ts.map +1 -1
  199. package/dist/builtin-extensions/pi-web-access/github-extract.js +147 -36
  200. package/dist/builtin-extensions/pi-web-access/github-extract.js.map +1 -1
  201. package/dist/builtin-extensions/pi-web-access/index.d.ts.map +1 -1
  202. package/dist/builtin-extensions/pi-web-access/index.js +48 -73
  203. package/dist/builtin-extensions/pi-web-access/index.js.map +1 -1
  204. package/dist/builtin-extensions/pi-web-access/session-cleanup.d.ts +12 -4
  205. package/dist/builtin-extensions/pi-web-access/session-cleanup.d.ts.map +1 -1
  206. package/dist/builtin-extensions/pi-web-access/session-cleanup.js +35 -12
  207. package/dist/builtin-extensions/pi-web-access/session-cleanup.js.map +1 -1
  208. package/dist/builtin-extensions/pi-web-access/storage.d.ts +9 -6
  209. package/dist/builtin-extensions/pi-web-access/storage.d.ts.map +1 -1
  210. package/dist/builtin-extensions/pi-web-access/storage.js +36 -24
  211. package/dist/builtin-extensions/pi-web-access/storage.js.map +1 -1
  212. package/dist/builtin-extensions/simple-pi-memory.d.ts +1 -1
  213. package/dist/builtin-extensions/simple-pi-memory.d.ts.map +1 -1
  214. package/dist/builtin-extensions/simple-pi-memory.js +1 -1
  215. package/dist/builtin-extensions/simple-pi-memory.js.map +1 -1
  216. package/dist/catalog/models.json +1 -1
  217. package/dist/catalog/providers/google-vertex.json +1 -1
  218. package/dist/catalog/providers/google.json +1 -1
  219. package/dist/catalog/publication.json +3 -3
  220. package/dist/cli/install-cli.d.ts.map +1 -1
  221. package/dist/cli/install-cli.js +38 -30
  222. package/dist/cli/install-cli.js.map +1 -1
  223. package/dist/core/agent-session-runtime.d.ts +13 -0
  224. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  225. package/dist/core/agent-session-runtime.js +75 -11
  226. package/dist/core/agent-session-runtime.js.map +1 -1
  227. package/dist/core/agent-session-services.d.ts +1 -0
  228. package/dist/core/agent-session-services.d.ts.map +1 -1
  229. package/dist/core/agent-session-services.js +1 -0
  230. package/dist/core/agent-session-services.js.map +1 -1
  231. package/dist/core/agent-session.d.ts +46 -21
  232. package/dist/core/agent-session.d.ts.map +1 -1
  233. package/dist/core/agent-session.js +344 -126
  234. package/dist/core/agent-session.js.map +1 -1
  235. package/dist/core/browser/runtime.d.ts +2 -0
  236. package/dist/core/browser/runtime.d.ts.map +1 -1
  237. package/dist/core/browser/runtime.js +80 -45
  238. package/dist/core/browser/runtime.js.map +1 -1
  239. package/dist/core/browser/setup.d.ts.map +1 -1
  240. package/dist/core/browser/setup.js +12 -1
  241. package/dist/core/browser/setup.js.map +1 -1
  242. package/dist/core/cache-stats.d.ts +1 -1
  243. package/dist/core/cache-stats.d.ts.map +1 -1
  244. package/dist/core/cache-stats.js +1 -1
  245. package/dist/core/cache-stats.js.map +1 -1
  246. package/dist/core/compaction/branch-summarization.d.ts +2 -1
  247. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  248. package/dist/core/compaction/branch-summarization.js +1 -0
  249. package/dist/core/compaction/branch-summarization.js.map +1 -1
  250. package/dist/core/compaction/compaction.d.ts +5 -11
  251. package/dist/core/compaction/compaction.d.ts.map +1 -1
  252. package/dist/core/compaction/compaction.js +38 -92
  253. package/dist/core/compaction/compaction.js.map +1 -1
  254. package/dist/core/computer-use/adapter.d.ts.map +1 -1
  255. package/dist/core/computer-use/adapter.js +7 -2
  256. package/dist/core/computer-use/adapter.js.map +1 -1
  257. package/dist/core/computer-use/image.d.ts.map +1 -1
  258. package/dist/core/computer-use/image.js +17 -5
  259. package/dist/core/computer-use/image.js.map +1 -1
  260. package/dist/core/computer-use/schemas.d.ts.map +1 -1
  261. package/dist/core/computer-use/schemas.js +23 -6
  262. package/dist/core/computer-use/schemas.js.map +1 -1
  263. package/dist/core/computer-use/workflow.d.ts.map +1 -1
  264. package/dist/core/computer-use/workflow.js +459 -119
  265. package/dist/core/computer-use/workflow.js.map +1 -1
  266. package/dist/core/context-breakdown.d.ts +2 -2
  267. package/dist/core/context-breakdown.d.ts.map +1 -1
  268. package/dist/core/context-breakdown.js +22 -20
  269. package/dist/core/context-breakdown.js.map +1 -1
  270. package/dist/core/cron/jobs.d.ts +26 -8
  271. package/dist/core/cron/jobs.d.ts.map +1 -1
  272. package/dist/core/cron/jobs.js +357 -232
  273. package/dist/core/cron/jobs.js.map +1 -1
  274. package/dist/core/cron/origin-context.d.ts +1 -0
  275. package/dist/core/cron/origin-context.d.ts.map +1 -1
  276. package/dist/core/cron/origin-context.js.map +1 -1
  277. package/dist/core/cron/scheduler.d.ts +22 -17
  278. package/dist/core/cron/scheduler.d.ts.map +1 -1
  279. package/dist/core/cron/scheduler.js +153 -73
  280. package/dist/core/cron/scheduler.js.map +1 -1
  281. package/dist/core/extensions/index.d.ts +1 -1
  282. package/dist/core/extensions/index.d.ts.map +1 -1
  283. package/dist/core/extensions/index.js.map +1 -1
  284. package/dist/core/extensions/runner.d.ts +1 -0
  285. package/dist/core/extensions/runner.d.ts.map +1 -1
  286. package/dist/core/extensions/runner.js +8 -0
  287. package/dist/core/extensions/runner.js.map +1 -1
  288. package/dist/core/extensions/types.d.ts +11 -1
  289. package/dist/core/extensions/types.d.ts.map +1 -1
  290. package/dist/core/extensions/types.js.map +1 -1
  291. package/dist/core/footer-data-provider.d.ts +4 -0
  292. package/dist/core/footer-data-provider.d.ts.map +1 -1
  293. package/dist/core/footer-data-provider.js +22 -1
  294. package/dist/core/footer-data-provider.js.map +1 -1
  295. package/dist/core/large-subagent-launch.d.ts +1 -1
  296. package/dist/core/large-subagent-launch.d.ts.map +1 -1
  297. package/dist/core/large-subagent-launch.js +7 -7
  298. package/dist/core/large-subagent-launch.js.map +1 -1
  299. package/dist/core/model-registry.d.ts +2 -0
  300. package/dist/core/model-registry.d.ts.map +1 -1
  301. package/dist/core/model-registry.js +5 -0
  302. package/dist/core/model-registry.js.map +1 -1
  303. package/dist/core/model-runtime.d.ts +4 -1
  304. package/dist/core/model-runtime.d.ts.map +1 -1
  305. package/dist/core/model-runtime.js +40 -4
  306. package/dist/core/model-runtime.js.map +1 -1
  307. package/dist/core/package-manager.d.ts.map +1 -1
  308. package/dist/core/package-manager.js.map +1 -1
  309. package/dist/core/permissions.d.ts +3 -3
  310. package/dist/core/permissions.d.ts.map +1 -1
  311. package/dist/core/permissions.js +11 -35
  312. package/dist/core/permissions.js.map +1 -1
  313. package/dist/core/plan-mode.d.ts +5 -13
  314. package/dist/core/plan-mode.d.ts.map +1 -1
  315. package/dist/core/plan-mode.js +126 -116
  316. package/dist/core/plan-mode.js.map +1 -1
  317. package/dist/core/project-trust.d.ts.map +1 -1
  318. package/dist/core/project-trust.js +1 -1
  319. package/dist/core/project-trust.js.map +1 -1
  320. package/dist/core/prompt-resource-bridge.d.ts +12 -0
  321. package/dist/core/prompt-resource-bridge.d.ts.map +1 -0
  322. package/dist/core/prompt-resource-bridge.js +9 -0
  323. package/dist/core/prompt-resource-bridge.js.map +1 -0
  324. package/dist/core/protected-targets.d.ts +6 -0
  325. package/dist/core/protected-targets.d.ts.map +1 -0
  326. package/dist/core/protected-targets.js +45 -0
  327. package/dist/core/protected-targets.js.map +1 -0
  328. package/dist/core/resource-loader.d.ts.map +1 -1
  329. package/dist/core/resource-loader.js +7 -0
  330. package/dist/core/resource-loader.js.map +1 -1
  331. package/dist/core/rollback.d.ts +19 -3
  332. package/dist/core/rollback.d.ts.map +1 -1
  333. package/dist/core/rollback.js +172 -56
  334. package/dist/core/rollback.js.map +1 -1
  335. package/dist/core/runtime-credentials.d.ts +3 -0
  336. package/dist/core/runtime-credentials.d.ts.map +1 -1
  337. package/dist/core/runtime-credentials.js +14 -1
  338. package/dist/core/runtime-credentials.js.map +1 -1
  339. package/dist/core/sdk.d.ts +3 -0
  340. package/dist/core/sdk.d.ts.map +1 -1
  341. package/dist/core/sdk.js +1 -0
  342. package/dist/core/sdk.js.map +1 -1
  343. package/dist/core/session-manager.d.ts +11 -1
  344. package/dist/core/session-manager.d.ts.map +1 -1
  345. package/dist/core/session-manager.js +111 -33
  346. package/dist/core/session-manager.js.map +1 -1
  347. package/dist/core/session-ownership.d.ts.map +1 -1
  348. package/dist/core/session-ownership.js +8 -3
  349. package/dist/core/session-ownership.js.map +1 -1
  350. package/dist/core/session-retention.d.ts.map +1 -1
  351. package/dist/core/session-retention.js +18 -7
  352. package/dist/core/session-retention.js.map +1 -1
  353. package/dist/core/session-startup-settings.d.ts +10 -0
  354. package/dist/core/session-startup-settings.d.ts.map +1 -0
  355. package/dist/core/session-startup-settings.js +70 -0
  356. package/dist/core/session-startup-settings.js.map +1 -0
  357. package/dist/core/subscriptions.d.ts +16 -7
  358. package/dist/core/subscriptions.d.ts.map +1 -1
  359. package/dist/core/subscriptions.js +96 -55
  360. package/dist/core/subscriptions.js.map +1 -1
  361. package/dist/core/trust-manager.d.ts +2 -1
  362. package/dist/core/trust-manager.d.ts.map +1 -1
  363. package/dist/core/trust-manager.js +6 -1
  364. package/dist/core/trust-manager.js.map +1 -1
  365. package/dist/core/update-check.d.ts.map +1 -1
  366. package/dist/core/update-check.js.map +1 -1
  367. package/dist/core/usage-accounting.d.ts +47 -0
  368. package/dist/core/usage-accounting.d.ts.map +1 -0
  369. package/dist/core/usage-accounting.js +205 -0
  370. package/dist/core/usage-accounting.js.map +1 -0
  371. package/dist/core/usage-adapters/kimi-coding.d.ts +2 -2
  372. package/dist/core/usage-adapters/kimi-coding.d.ts.map +1 -1
  373. package/dist/core/usage-adapters/kimi-coding.js +2 -2
  374. package/dist/core/usage-adapters/kimi-coding.js.map +1 -1
  375. package/dist/core/usage-adapters/openai-codex.d.ts +3 -2
  376. package/dist/core/usage-adapters/openai-codex.d.ts.map +1 -1
  377. package/dist/core/usage-adapters/openai-codex.js +3 -3
  378. package/dist/core/usage-adapters/openai-codex.js.map +1 -1
  379. package/dist/core/usage-adapters/xai.d.ts +2 -2
  380. package/dist/core/usage-adapters/xai.d.ts.map +1 -1
  381. package/dist/core/usage-adapters/xai.js +3 -3
  382. package/dist/core/usage-adapters/xai.js.map +1 -1
  383. package/dist/core/usage-adapters/zai.d.ts +2 -2
  384. package/dist/core/usage-adapters/zai.d.ts.map +1 -1
  385. package/dist/core/usage-adapters/zai.js +2 -2
  386. package/dist/core/usage-adapters/zai.js.map +1 -1
  387. package/dist/core/usage-history.d.ts +1 -18
  388. package/dist/core/usage-history.d.ts.map +1 -1
  389. package/dist/core/usage-history.js +46 -114
  390. package/dist/core/usage-history.js.map +1 -1
  391. package/dist/core/usage-service.d.ts +9 -2
  392. package/dist/core/usage-service.d.ts.map +1 -1
  393. package/dist/core/usage-service.js +95 -50
  394. package/dist/core/usage-service.js.map +1 -1
  395. package/dist/gateway/agent-bridge.d.ts +9 -1
  396. package/dist/gateway/agent-bridge.d.ts.map +1 -1
  397. package/dist/gateway/agent-bridge.js +91 -37
  398. package/dist/gateway/agent-bridge.js.map +1 -1
  399. package/dist/gateway/buttons.d.ts +8 -1
  400. package/dist/gateway/buttons.d.ts.map +1 -1
  401. package/dist/gateway/buttons.js +76 -18
  402. package/dist/gateway/buttons.js.map +1 -1
  403. package/dist/gateway/commands.d.ts +1 -0
  404. package/dist/gateway/commands.d.ts.map +1 -1
  405. package/dist/gateway/commands.js +10 -4
  406. package/dist/gateway/commands.js.map +1 -1
  407. package/dist/gateway/cron.d.ts +12 -11
  408. package/dist/gateway/cron.d.ts.map +1 -1
  409. package/dist/gateway/cron.js +65 -56
  410. package/dist/gateway/cron.js.map +1 -1
  411. package/dist/gateway/index.d.ts.map +1 -1
  412. package/dist/gateway/index.js +2 -1
  413. package/dist/gateway/index.js.map +1 -1
  414. package/dist/gateway/mobile-commands.d.ts +1 -0
  415. package/dist/gateway/mobile-commands.d.ts.map +1 -1
  416. package/dist/gateway/mobile-commands.js +69 -15
  417. package/dist/gateway/mobile-commands.js.map +1 -1
  418. package/dist/gateway/presenter.d.ts +12 -2
  419. package/dist/gateway/presenter.d.ts.map +1 -1
  420. package/dist/gateway/presenter.js +73 -38
  421. package/dist/gateway/presenter.js.map +1 -1
  422. package/dist/gateway/router.d.ts +2 -2
  423. package/dist/gateway/router.d.ts.map +1 -1
  424. package/dist/gateway/router.js +17 -2
  425. package/dist/gateway/router.js.map +1 -1
  426. package/dist/gateway/service.d.ts +2 -0
  427. package/dist/gateway/service.d.ts.map +1 -1
  428. package/dist/gateway/service.js +153 -0
  429. package/dist/gateway/service.js.map +1 -1
  430. package/dist/main.d.ts.map +1 -1
  431. package/dist/main.js +86 -33
  432. package/dist/main.js.map +1 -1
  433. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  434. package/dist/modes/interactive/components/assistant-message.js +6 -4
  435. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  436. package/dist/modes/interactive/components/context-view.d.ts.map +1 -1
  437. package/dist/modes/interactive/components/context-view.js +2 -2
  438. package/dist/modes/interactive/components/context-view.js.map +1 -1
  439. package/dist/modes/interactive/components/copyable-text.d.ts.map +1 -1
  440. package/dist/modes/interactive/components/copyable-text.js +3 -2
  441. package/dist/modes/interactive/components/copyable-text.js.map +1 -1
  442. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
  443. package/dist/modes/interactive/components/extension-editor.js +1 -1
  444. package/dist/modes/interactive/components/extension-editor.js.map +1 -1
  445. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  446. package/dist/modes/interactive/components/footer.js +8 -12
  447. package/dist/modes/interactive/components/footer.js.map +1 -1
  448. package/dist/modes/interactive/components/usage-view.d.ts +5 -0
  449. package/dist/modes/interactive/components/usage-view.d.ts.map +1 -1
  450. package/dist/modes/interactive/components/usage-view.js +21 -6
  451. package/dist/modes/interactive/components/usage-view.js.map +1 -1
  452. package/dist/modes/interactive/interactive-mode.d.ts +3 -7
  453. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  454. package/dist/modes/interactive/interactive-mode.js +151 -131
  455. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  456. package/dist/modes/interactive/smooth-streaming.d.ts.map +1 -1
  457. package/dist/modes/interactive/smooth-streaming.js.map +1 -1
  458. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  459. package/dist/modes/rpc/rpc-mode.js +2 -1
  460. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  461. package/dist/node-runtime/{adapter-VFG7WNPX.js → adapter-247RTYLS.js} +4 -5
  462. package/dist/node-runtime/agent-session-services-RTUGP3XR.js +54 -0
  463. package/dist/node-runtime/{brave-UWDA3I22.js → brave-2AFFAXNN.js} +1 -1
  464. package/dist/node-runtime/{builtin-extensions-I2HIFEMY.js → builtin-extensions-N4EUD6SB.js} +8 -7
  465. package/dist/node-runtime/{chunk-QH6YL7VK.js → chunk-252ZVPPF.js} +3 -3
  466. package/dist/node-runtime/{chunk-PCEW76PM.js → chunk-2OIPYKLZ.js} +6 -6
  467. package/dist/node-runtime/{chunk-XBWPBZBN.js → chunk-2SWW7KMW.js} +1 -1
  468. package/dist/node-runtime/{chunk-UQUCFAJ3.js → chunk-2VIW3IMF.js} +40 -7
  469. package/dist/node-runtime/{chunk-UOEDI7RP.js → chunk-4KNKQGHM.js} +2 -2
  470. package/dist/node-runtime/chunk-4QRUZ64T.js +1203 -0
  471. package/dist/node-runtime/{chunk-FQMM2EZ2.js → chunk-64XTQNLA.js} +29 -7
  472. package/dist/node-runtime/{chunk-SPVDBUOS.js → chunk-6O3IW3IA.js} +2 -2
  473. package/dist/node-runtime/{chunk-5ZQXRPMC.js → chunk-6ZZHGUSA.js} +2 -2
  474. package/dist/node-runtime/{chunk-WIF24I7G.js → chunk-APVM5NEU.js} +149 -144
  475. package/dist/node-runtime/{chunk-LWYIVUGV.js → chunk-B2IBAXNX.js} +48 -31
  476. package/dist/node-runtime/{chunk-M3LZLQW2.js → chunk-BDRGN3L2.js} +1 -0
  477. package/dist/node-runtime/{chunk-LJTIVM7I.js → chunk-BMRXLQWQ.js} +464 -160
  478. package/dist/node-runtime/{chunk-GJ2RDBRL.js → chunk-BYC6RKCN.js} +4 -2
  479. package/dist/node-runtime/{chunk-T4DA4XE7.js → chunk-DFMPRAQQ.js} +162 -82
  480. package/dist/node-runtime/{chunk-SN2KSMPQ.js → chunk-DQSCFU7R.js} +13 -7
  481. package/dist/node-runtime/{chunk-UVWCDQYF.js → chunk-E5DQGNJI.js} +455 -278
  482. package/dist/node-runtime/{chunk-4SBQAI4T.js → chunk-EBLAZVSA.js} +2058 -73
  483. package/dist/node-runtime/{chunk-CSFI6YXL.js → chunk-ES6PBSIE.js} +1 -1
  484. package/dist/node-runtime/{chunk-IF24A3FH.js → chunk-EVM653DD.js} +4 -4
  485. package/dist/node-runtime/{chunk-HTFRRDSF.js → chunk-F2SMQ6ES.js} +3 -2
  486. package/dist/node-runtime/chunk-F2V2F4ZG.js +114 -0
  487. package/dist/node-runtime/{chunk-IKU6Y7DL.js → chunk-FE3WZI7F.js} +9 -6
  488. package/dist/node-runtime/{chunk-6VYZ5UFP.js → chunk-FLGEEH27.js} +1 -1
  489. package/dist/node-runtime/{chunk-5EFIU3OM.js → chunk-FTKEZL27.js} +1 -1
  490. package/dist/node-runtime/{chunk-RGQAEOM5.js → chunk-FYIFPFXE.js} +23 -6
  491. package/dist/node-runtime/{chunk-HMBGROQK.js → chunk-GLDXBBL6.js} +3 -3
  492. package/dist/node-runtime/{chunk-KWA4OC2J.js → chunk-H6YBCWKG.js} +1 -1
  493. package/dist/node-runtime/{chunk-2MI5OPMN.js → chunk-HNNHHJAB.js} +68 -50
  494. package/dist/node-runtime/{chunk-I74LN5JG.js → chunk-HUD2RFJW.js} +2 -2
  495. package/dist/node-runtime/{chunk-XHIRAZ26.js → chunk-IAZSK7KK.js} +1 -1
  496. package/dist/node-runtime/{chunk-GYIXXQAO.js → chunk-ICKGAKWX.js} +23 -59
  497. package/dist/node-runtime/{chunk-X3PGBLQ7.js → chunk-IHHTWSXN.js} +9 -9
  498. package/dist/node-runtime/{chunk-DAPBPCBP.js → chunk-IPP5BIV5.js} +25 -3
  499. package/dist/node-runtime/{chunk-QFWG2RVL.js → chunk-IXG6F4NT.js} +11 -0
  500. package/dist/node-runtime/{chunk-L24TPBS4.js → chunk-JEK35V2M.js} +45 -31
  501. package/dist/node-runtime/{chunk-RDDAZOMU.js → chunk-JL4HYQXK.js} +1 -1
  502. package/dist/node-runtime/{chunk-2HMIRK7W.js → chunk-LHV3V67B.js} +5 -5
  503. package/dist/node-runtime/{chunk-UAEOTO52.js → chunk-MNQXDFPV.js} +6 -2
  504. package/dist/node-runtime/{chunk-MPKSOJBT.js → chunk-NHATCSOI.js} +4 -7
  505. package/dist/node-runtime/{chunk-RMQZU2YU.js → chunk-NNNR3QIY.js} +1 -1
  506. package/dist/node-runtime/{chunk-2KIPT4HJ.js → chunk-PWHTSQC4.js} +83 -21
  507. package/dist/node-runtime/{chunk-RWTKOC3B.js → chunk-QBTJG3UM.js} +1 -1
  508. package/dist/node-runtime/{chunk-RCR3XAQY.js → chunk-QT3F6UEV.js} +233 -169
  509. package/dist/node-runtime/{chunk-GS42T6MX.js → chunk-QW3AAHWN.js} +1 -1
  510. package/dist/node-runtime/{chunk-DVQSHCVP.js → chunk-R4WSB2MQ.js} +5 -5
  511. package/dist/node-runtime/{chunk-B4HP6ZWM.js → chunk-RHCGYWO7.js} +1 -1
  512. package/dist/node-runtime/{chunk-2CFDTH5B.js → chunk-RLGY2QIL.js} +45 -59
  513. package/dist/node-runtime/{chunk-CDVHZOOK.js → chunk-RY3FJ6WI.js} +29 -27
  514. package/dist/node-runtime/{chunk-KKUTQQV7.js → chunk-RYRGL7P4.js} +1 -1
  515. package/dist/node-runtime/{chunk-I54LGHWM.js → chunk-STMX7W5I.js} +3 -3
  516. package/dist/node-runtime/chunk-SWWHZ2RI.js +158 -0
  517. package/dist/node-runtime/{chunk-5Q4A37RB.js → chunk-TCT6PCUR.js} +32 -11
  518. package/dist/node-runtime/{chunk-P7XBVXGT.js → chunk-U3YVZ6UC.js} +18 -14
  519. package/dist/node-runtime/{chunk-D5UCKPBQ.js → chunk-UBWW2PID.js} +1 -1
  520. package/dist/node-runtime/{chunk-E75WFZ33.js → chunk-UNUZICC4.js} +3 -3
  521. package/dist/node-runtime/{chunk-RAK2QA2B.js → chunk-UYRKUKFE.js} +4 -4
  522. package/dist/node-runtime/{chunk-LWJXTA6Z.js → chunk-VSUEAI7O.js} +1377 -45
  523. package/dist/node-runtime/{chunk-NAY6UUQZ.js → chunk-WDIVLMOH.js} +1 -1
  524. package/dist/node-runtime/{chunk-E24EO34J.js → chunk-WPXUR3HE.js} +1 -1
  525. package/dist/node-runtime/{chunk-SLVOAQOY.js → chunk-WXYNALHD.js} +113 -1
  526. package/dist/node-runtime/{chunk-KJ6DWS3K.js → chunk-XEOCUEUJ.js} +121 -60
  527. package/dist/node-runtime/chunk-YD3IZAZ7.js +47 -0
  528. package/dist/node-runtime/chunk-YSB6URMT.js +41 -0
  529. package/dist/node-runtime/{chunk-YWOJIGFY.js → chunk-ZEVFBFNF.js} +95 -142
  530. package/dist/node-runtime/{chunk-5B6VKFEV.js → chunk-ZIQUS5QO.js} +1 -1
  531. package/dist/node-runtime/cli-runtime.js +4 -4
  532. package/dist/node-runtime/{command-FSBU2EVZ.js → command-YRT7I2BW.js} +5 -5
  533. package/dist/node-runtime/{commands-NAAL7KNT.js → commands-2ETOWWRA.js} +16 -16
  534. package/dist/node-runtime/{commands-EMBQQVVT.js → commands-D6A6H4TS.js} +11 -18
  535. package/dist/node-runtime/{config-QDD5PUE2.js → config-CU7M7BTK.js} +1 -1
  536. package/dist/node-runtime/{config-D4QUPAHX.js → config-DS7XLMEM.js} +2 -2
  537. package/dist/node-runtime/{direct-tool-executor-4D7UXYU4.js → direct-tool-executor-2QJXVQD2.js} +6 -11
  538. package/dist/node-runtime/{exa-LL64QZR2.js → exa-6VBZNPGE.js} +1 -1
  539. package/dist/node-runtime/{export-html-VM4J2MNR.js → export-html-DBQRRMAY.js} +4 -4
  540. package/dist/node-runtime/{extension-input-E7BJZ35H.js → extension-input-VBBMX7YV.js} +5 -5
  541. package/dist/node-runtime/{extension-selector-WU42XDTU.js → extension-selector-T5AOG5XB.js} +5 -5
  542. package/dist/node-runtime/{extract-EQJE7FZZ.js → extract-BFX2N35A.js} +3 -3
  543. package/dist/node-runtime/{gateway-DQM333YV.js → gateway-V6K2CDWN.js} +51 -42
  544. package/dist/node-runtime/{gemini-search-35OCRFLN.js → gemini-search-C66QHDT6.js} +2 -2
  545. package/dist/node-runtime/{gemini-url-context-UQY3PHHW.js → gemini-url-context-T7DEK73R.js} +3 -3
  546. package/dist/node-runtime/{github-extract-F64RZOEA.js → github-extract-HOGE3D6F.js} +107 -38
  547. package/dist/node-runtime/{goal-NJEE5CTU.js → goal-J7TYMOBK.js} +14 -8
  548. package/dist/node-runtime/index.js +51 -48
  549. package/dist/node-runtime/{init-P5AUV77I.js → init-JBQJIPYI.js} +3 -6
  550. package/dist/node-runtime/{install-cli-NN4YAU44.js → install-cli-INGHIVBY.js} +30 -25
  551. package/dist/node-runtime/interactive-mode-ASZ7APYP.js +75 -0
  552. package/dist/node-runtime/{interactive-view-NGFAMHPW.js → interactive-view-K33PM4OS.js} +8 -8
  553. package/dist/node-runtime/{lsp-manager-3ASUSO4T.js → lsp-manager-S554V5HR.js} +240 -155
  554. package/dist/node-runtime/{lunr-browser-IR7TL3J7.js → lunr-browser-H4FDOR3C.js} +7 -7
  555. package/dist/node-runtime/{lunr-computer-use-Y23CCDIJ.js → lunr-computer-use-VDP2QNRQ.js} +9 -9
  556. package/dist/node-runtime/{lunr-cron-USHC4LXH.js → lunr-cron-WD3YH4CR.js} +93 -80
  557. package/dist/node-runtime/main.js +43 -41
  558. package/dist/node-runtime/{mobile-commands-O5LCHL32.js → mobile-commands-ICUXFW5V.js} +12 -12
  559. package/dist/node-runtime/{model-runtime-OO5HFLWE.js → model-runtime-MZ2JMDV4.js} +4 -4
  560. package/dist/node-runtime/{openai-search-B3MSNCQA.js → openai-search-K72LJDYN.js} +1 -1
  561. package/dist/node-runtime/{package-manager-cli-Q7BL6KZO.js → package-manager-cli-CYM262SI.js} +20 -20
  562. package/dist/node-runtime/{parallel-AI2MNSCU.js → parallel-X724NCNU.js} +1 -1
  563. package/dist/node-runtime/{perplexity-QVJW3I35.js → perplexity-RDHQHVMK.js} +2 -2
  564. package/dist/node-runtime/{pi-intercom-QM53RLTS.js → pi-intercom-NHHEPBMI.js} +2 -2
  565. package/dist/node-runtime/{pi-mcp-adapter-3PHF4KZ4.js → pi-mcp-adapter-PP3GQJQ2.js} +98 -94
  566. package/dist/node-runtime/{pi-ollama-cloud-2F3Y2QNM.js → pi-ollama-cloud-4MNWIMFN.js} +11 -24
  567. package/dist/node-runtime/{pi-prompt-template-model-QWTCGLJU.js → pi-prompt-template-model-FTGELLS5.js} +32 -36
  568. package/dist/node-runtime/{pi-subagents-7IBSSGEW.js → pi-subagents-QPU3OXE4.js} +114 -167
  569. package/dist/node-runtime/{pi-web-access-WTGMNZ32.js → pi-web-access-Z3LP246C.js} +144 -108
  570. package/dist/node-runtime/{print-mode-XQ76CYMT.js → print-mode-2XHN5SUA.js} +3 -3
  571. package/dist/node-runtime/{process-registry-4FAKZQOL.js → process-registry-Q4QWIU33.js} +3 -3
  572. package/dist/node-runtime/{proxy-modes-5FAPSZEZ.js → proxy-modes-VEGC6QG5.js} +8 -15
  573. package/dist/node-runtime/rpc-entry.js +43 -41
  574. package/dist/node-runtime/{rpc-mode-O3XV4SID.js → rpc-mode-32DHJPEJ.js} +4 -4
  575. package/dist/node-runtime/{runtime-4VA6JKNF.js → runtime-EDUUGAQD.js} +56 -46
  576. package/dist/node-runtime/{runtime-EFPPD2UW.js → runtime-UGXM4NPQ.js} +2 -2
  577. package/dist/node-runtime/{runtime-bridges-7WVCLI76.js → runtime-bridges-DNKMNJCF.js} +7 -7
  578. package/dist/node-runtime/{service-MDQIPQ26.js → service-IHLGFLBT.js} +6 -4
  579. package/dist/node-runtime/{session-handoff-GWARVEWT.js → session-handoff-LYH53ESV.js} +4 -4
  580. package/dist/node-runtime/{session-manager-JB5J6XBN.js → session-manager-ZJ3N5Q74.js} +3 -3
  581. package/dist/node-runtime/{session-selector-GIM4DHQ2.js → session-selector-I73U3EIO.js} +7 -7
  582. package/dist/node-runtime/{settings-manager-DJDM5AHM.js → settings-manager-P2TKGYTR.js} +5 -5
  583. package/dist/node-runtime/{setup-JBKOLJ6F.js → setup-H7CCELIL.js} +15 -1
  584. package/dist/node-runtime/{setup-PFBWRNUI.js → setup-OLQ4GXWS.js} +17 -17
  585. package/dist/node-runtime/{src-IVPNZ2BX.js → src-6RV4PXKJ.js} +64 -36
  586. package/dist/node-runtime/{subagent-executor-LPZ4BHWE.js → subagent-executor-UI6SHG3X.js} +412 -288
  587. package/dist/node-runtime/{tavily-WEZFVFP7.js → tavily-KZBFYQB6.js} +1 -1
  588. package/dist/node-runtime/{theme-UOO5RVFN.js → theme-YLVZKKZD.js} +2 -2
  589. package/dist/node-runtime/{trust-manager-MMISNCYO.js → trust-manager-ZCU76D23.js} +2 -2
  590. package/dist/node-runtime/{update-cli-HNMOTNGX.js → update-cli-F3XXJANQ.js} +6 -6
  591. package/dist/node-runtime/{usage-service-LFB2SWYV.js → usage-service-CPAGBED5.js} +1 -1
  592. package/dist/node-runtime/{video-extract-OOZHR7SU.js → video-extract-UPKYIBW3.js} +3 -3
  593. package/dist/node-runtime/{workflow-OHPBEFO4.js → workflow-ICDI4N3J.js} +208 -78
  594. package/dist/node-runtime/{youtube-extract-FNPAUNHU.js → youtube-extract-77NT7FWH.js} +4 -4
  595. package/dist/utils/clipboard-image.d.ts.map +1 -1
  596. package/dist/utils/clipboard-image.js.map +1 -1
  597. package/dist/utils/exif-orientation.d.ts.map +1 -1
  598. package/dist/utils/exif-orientation.js +25 -10
  599. package/dist/utils/exif-orientation.js.map +1 -1
  600. package/dist/utils/image-resize-core.d.ts.map +1 -1
  601. package/dist/utils/image-resize-core.js +2 -0
  602. package/dist/utils/image-resize-core.js.map +1 -1
  603. package/dist/utils/paths.d.ts +4 -0
  604. package/dist/utils/paths.d.ts.map +1 -1
  605. package/dist/utils/paths.js +33 -2
  606. package/dist/utils/paths.js.map +1 -1
  607. package/dist/utils/sanitize-terminal-text.d.ts +7 -0
  608. package/dist/utils/sanitize-terminal-text.d.ts.map +1 -0
  609. package/dist/utils/sanitize-terminal-text.js +67 -0
  610. package/dist/utils/sanitize-terminal-text.js.map +1 -0
  611. package/docs/browser.md +1 -1
  612. package/docs/custom-provider.md +3 -3
  613. package/docs/extensions.md +8 -4
  614. package/docs/features.md +25 -7
  615. package/docs/keybindings.md +1 -1
  616. package/docs/models.md +5 -5
  617. package/docs/packages.md +1 -1
  618. package/docs/providers.md +2 -2
  619. package/docs/rpc.md +7 -7
  620. package/docs/security.md +10 -5
  621. package/docs/sessions.md +2 -2
  622. package/docs/skills.md +1 -1
  623. package/docs/terminal-setup.md +7 -7
  624. package/docs/themes.md +1 -1
  625. package/docs/usage.md +1 -1
  626. package/examples/extensions/auto-commit-on-exit.ts +1 -1
  627. package/examples/extensions/bash-spawn-hook.ts +1 -1
  628. package/examples/extensions/built-in-tool-renderer.ts +1 -1
  629. package/examples/extensions/claude-rules.ts +1 -1
  630. package/examples/extensions/commands.ts +1 -1
  631. package/examples/extensions/custom-compaction.ts +1 -1
  632. package/examples/extensions/custom-provider-anthropic/index.ts +3 -3
  633. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  634. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  635. package/examples/extensions/custom-provider-gitlab-duo/index.ts +1 -1
  636. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  637. package/examples/extensions/doom-overlay/index.ts +1 -1
  638. package/examples/extensions/git-merge-and-resolve.ts +2 -2
  639. package/examples/extensions/gondolin/index.ts +1 -1
  640. package/examples/extensions/gondolin/package-lock.json +2 -2
  641. package/examples/extensions/gondolin/package.json +1 -1
  642. package/examples/extensions/hidden-thinking-label.ts +1 -1
  643. package/examples/extensions/inline-bash.ts +2 -2
  644. package/examples/extensions/input-transform-streaming.ts +2 -2
  645. package/examples/extensions/input-transform.ts +2 -2
  646. package/examples/extensions/interactive-shell.ts +1 -1
  647. package/examples/extensions/kimi-deferred-tools.ts +1 -1
  648. package/examples/extensions/mac-system-theme.ts +1 -1
  649. package/examples/extensions/minimal-mode.ts +1 -1
  650. package/examples/extensions/modal-editor.ts +1 -1
  651. package/examples/extensions/model-status.ts +1 -1
  652. package/examples/extensions/notify.ts +3 -3
  653. package/examples/extensions/overlay-qa-tests.ts +1 -1
  654. package/examples/extensions/overlay-test.ts +1 -1
  655. package/examples/extensions/pirate.ts +1 -1
  656. package/examples/extensions/preset.ts +3 -3
  657. package/examples/extensions/project-trust.ts +4 -4
  658. package/examples/extensions/prompt-customizer.ts +1 -1
  659. package/examples/extensions/rainbow-editor.ts +1 -1
  660. package/examples/extensions/rpc-demo.ts +1 -1
  661. package/examples/extensions/sandbox/index.ts +7 -7
  662. package/examples/extensions/sandbox/package-lock.json +2 -2
  663. package/examples/extensions/sandbox/package.json +1 -1
  664. package/examples/extensions/shutdown-command.ts +5 -5
  665. package/examples/extensions/ssh.ts +2 -2
  666. package/examples/extensions/subagent/README.md +3 -3
  667. package/examples/extensions/subagent/index.ts +2 -2
  668. package/examples/extensions/titlebar-spinner.ts +1 -1
  669. package/examples/extensions/tool-override.ts +1 -1
  670. package/examples/extensions/tools.ts +1 -1
  671. package/examples/extensions/with-deps/package-lock.json +2 -2
  672. package/examples/extensions/with-deps/package.json +1 -1
  673. package/examples/extensions/working-indicator.ts +1 -1
  674. package/examples/extensions/working-message-test.ts +1 -1
  675. package/examples/sdk/01-minimal.ts +1 -1
  676. package/examples/sdk/03-custom-prompt.ts +1 -1
  677. package/examples/sdk/04-skills.ts +1 -1
  678. package/examples/sdk/06-extensions.ts +2 -2
  679. package/examples/sdk/08-prompt-templates.ts +1 -1
  680. package/install-lock/package-lock.json +24 -24
  681. package/install-lock/package.json +2 -2
  682. package/npm-shrinkwrap.json +60 -24
  683. package/package.json +9 -9
  684. package/dist/modes/interactive/components/exit-card.d.ts +0 -22
  685. package/dist/modes/interactive/components/exit-card.d.ts.map +0 -1
  686. package/dist/modes/interactive/components/exit-card.js +0 -69
  687. package/dist/modes/interactive/components/exit-card.js.map +0 -1
  688. package/dist/node-runtime/agent-session-services-5YXS2PLF.js +0 -51
  689. package/dist/node-runtime/chunk-2IDTZAG5.js +0 -1415
  690. package/dist/node-runtime/chunk-3MISGG4S.js +0 -769
  691. package/dist/node-runtime/chunk-4HXHDDCF.js +0 -16
  692. package/dist/node-runtime/chunk-5B5QN3ZQ.js +0 -356
  693. package/dist/node-runtime/chunk-7IQGBKBJ.js +0 -2033
  694. package/dist/node-runtime/chunk-AUXVGBO4.js +0 -19
  695. package/dist/node-runtime/chunk-PTFBPO3C.js +0 -50
  696. package/dist/node-runtime/interactive-mode-YOHZVMKX.js +0 -74
  697. package/dist/node-runtime/mcp-auth-flow-QVLFVLEO.js +0 -33
@@ -6,7 +6,7 @@
6
6
  * lunR: this file is lunR-native (not an absorbed upstream extension). It wires
7
7
  * core/cron (jobs store + scheduler) into the interactive session:
8
8
  *
9
- * - `/cron list|create|pause|resume|run|remove|status` command.
9
+ * - `/cron list|create|pause|resume|run|remove|rebind|status` command.
10
10
  * - One `cron` tool (TypeBox) so the agent can manage jobs. The shared
11
11
  * core/cron/fire-guard depth counter refuses the tool while a cron-fired
12
12
  * turn is in flight — TUI-fired OR gateway-fired (jobs cannot schedule
@@ -14,49 +14,61 @@
14
14
  * - Jobs created inside a gateway chat turn are stamped with that chat as
15
15
  * their origin and default deliver to "origin" (core/cron/origin-context).
16
16
  * - Scheduler starts on session_start only in "tui" mode, stops on
17
- * session_shutdown. runJob = sendUserMessage + wait for agent_end;
18
- * deliverResult reads the `@lunr/cron-delivery` bridge on globalThis
19
- * (registered here as the local notify; the Phase 4 gateway replaces
20
- * it — core/cron/scheduler.ts never touches the bridge itself).
17
+ * session_shutdown. runJob admits and awaits one owned prompt;
18
+ * TUI delivery notifies locally and records external delivery as unavailable;
19
+ * the gateway operator performs platform delivery with current grants.
21
20
  *
22
21
  * `// @ts-nocheck` matches the builtin-extension convention.
23
22
  * Runtime imports stay on concrete core modules — never the package barrel.
24
23
  */
24
+ import { realpathSync } from "node:fs";
25
+ import { isAbsolute } from "node:path";
25
26
  import { Type } from "@sinclair/typebox";
26
27
  import { beginCronFire, endCronFire, isCronFire } from "../core/cron/fire-guard.js";
27
28
  import { createJob, getJob, listJobs, parseSchedule, pauseJob, removeJob, resumeJob, setCronDeliverValidator, updateJob, } from "../core/cron/jobs.js";
28
29
  import { currentOrigin } from "../core/cron/origin-context.js";
29
- import { executeJob, startScheduler } from "../core/cron/scheduler.js";
30
+ import { CronAdmissionDeferred, startScheduler } from "../core/cron/scheduler.js";
30
31
  import { loadGatewayConfig } from "../gateway/config.js";
31
32
  import { createDeliverValidator } from "../gateway/cron.js";
33
+ import { resolveWithinRoots } from "../gateway/mobile-commands.js";
32
34
  // ---------------------------------------------------------------------------
33
35
  // Module state
34
36
  // ---------------------------------------------------------------------------
35
- /** The cron-fired turn currently waiting for agent_end. */
36
- let pendingRun = null;
37
- let scheduler = null;
38
- let lastCtx = null;
39
- const DELIVERY_BRIDGE_SYMBOL = Symbol.for("@lunr/cron-delivery");
40
- // ---------------------------------------------------------------------------
41
- // Turn plumbing
42
- // ---------------------------------------------------------------------------
43
- /** Final assistant text from an agent_end messages array (last assistant message, text blocks only). */
37
+ /** Last assistant message of this admitted request only. */
44
38
  function extractAssistantText(messages) {
45
39
  for (let i = messages.length - 1; i >= 0; i--) {
46
40
  const msg = messages[i];
47
41
  if (msg?.role !== "assistant")
48
42
  continue;
49
- const parts = Array.isArray(msg.content) ? msg.content : [];
50
- const text = parts
51
- .filter((p) => p?.type === "text")
52
- .map((p) => String(p.text ?? ""))
53
- .join("")
54
- .trim();
55
- if (text)
56
- return text;
43
+ if (msg.stopReason === "error" || msg.stopReason === "aborted")
44
+ throw new Error(msg.errorMessage || `Request ${msg.stopReason}`);
45
+ return (msg.content ?? []).filter((part) => part.type === "text").map((part) => part.text ?? "").join("").trim();
57
46
  }
58
47
  return "";
59
48
  }
49
+ /** Both creation routes keep the current project, requester and explicit delivery choice. */
50
+ function createInContext(input, ctx) {
51
+ const origin = currentOrigin();
52
+ const workdir = origin ? resolveWithinRoots(ctx.cwd, loadGatewayConfig().projectRoots ?? []) : ctx.cwd;
53
+ return createJob({ ...input, workdir, origin: origin ? { ...origin } : null, deliver: input.deliver ?? (origin ? "origin" : "local") });
54
+ }
55
+ /** A TUI owns its current project; it must not silently execute another project's job. */
56
+ function requireTuiJobWorkdir(job, ctx) {
57
+ if (!job.workdir || !isAbsolute(job.workdir))
58
+ throw new CronAdmissionDeferred("The job has no saved absolute project directory. Recreate it from the intended project before running it in a TUI.");
59
+ let saved;
60
+ let current;
61
+ try {
62
+ saved = realpathSync(job.workdir);
63
+ current = realpathSync(ctx.cwd);
64
+ }
65
+ catch {
66
+ throw new CronAdmissionDeferred("The saved or current project directory is unavailable. Restore it before running this job.");
67
+ }
68
+ const matches = process.platform === "win32" ? saved.toLowerCase() === current.toLowerCase() : saved === current;
69
+ if (!matches)
70
+ throw new CronAdmissionDeferred("The job belongs to another project. Run it from a TUI in its saved project, or stop this scheduler so the gateway can own execution.");
71
+ }
60
72
  // ---------------------------------------------------------------------------
61
73
  // Formatting helpers
62
74
  // ---------------------------------------------------------------------------
@@ -74,16 +86,16 @@ function formatJobList() {
74
86
  const jobs = listJobs();
75
87
  if (jobs.length === 0)
76
88
  return "No cron jobs. Create one with /cron create <schedule> <prompt>.";
77
- const lines = jobs.map((j) => `${j.id} ${j.state}${j.enabled ? "" : " (disabled)"} ${j.scheduleDisplay} next=${fmtTime(j.nextRunAt)} last=${j.lastStatus ?? "-"}${j.lastError ? ` (${j.lastError})` : ""} ${j.name}`);
89
+ const lines = jobs.map((j) => `${j.id} ${j.state}${j.enabled ? "" : " (disabled)"} ${j.scheduleDisplay} next=${fmtTime(j.nextRunAt)} last=${j.lastStatus ?? "-"}${j.lastError ? ` (${j.lastError})` : ""}${j.lastDeliveryError ? ` delivery-error=${j.lastDeliveryError}` : ""} ${j.name}`);
78
90
  return `Cron jobs (${jobs.length}):\n${lines.join("\n")}`;
79
91
  }
80
- function formatStatus() {
92
+ function formatStatus(running) {
81
93
  const jobs = listJobs();
82
94
  const count = (s) => jobs.filter((j) => j.state === s).length;
83
95
  const next = jobs
84
96
  .filter((j) => j.enabled && j.state === "scheduled" && j.nextRunAt)
85
97
  .sort((a, b) => String(a.nextRunAt).localeCompare(String(b.nextRunAt)))[0];
86
- return (`Cron: scheduler ${scheduler ? "running" : "stopped"}; ${jobs.length} job(s) — ` +
98
+ return (`Cron: scheduler ${running ? "owner" : "not owner"}; ${jobs.length} job(s) — ` +
87
99
  `${count("scheduled")} scheduled, ${count("paused")} paused, ${count("completed")} completed, ${count("error")} error.` +
88
100
  (next ? ` Next: '${next.name}' at ${fmtTime(next.nextRunAt)}.` : ""));
89
101
  }
@@ -91,85 +103,60 @@ function formatStatus() {
91
103
  // Extension
92
104
  // ---------------------------------------------------------------------------
93
105
  export default function (pi) {
94
- // Same allowlist the gateway uses, so a TUI session cannot persist a job
95
- // that later posts to a chat the bot can reach but is not allowed.
96
- setCronDeliverValidator(createDeliverValidator(loadGatewayConfig()));
97
- // --- Local delivery bridge (Phase 4 gateway replaces this) ---
98
- globalThis[DELIVERY_BRIDGE_SYMBOL] = async (job, _content) => {
106
+ let scheduler = null;
107
+ let lastCtx = null;
108
+ setCronDeliverValidator((deliver, origin) => createDeliverValidator(loadGatewayConfig())(deliver, origin));
109
+ const deliverResult = async (job, _content) => {
110
+ if (job.deliver.split(",").some((target) => target.trim() !== "local")) {
111
+ throw new Error("platform delivery unavailable from this TUI operator; restart scheduling in the gateway after stopping this operator");
112
+ }
113
+ lastCtx?.ui.notify(`Cron job '${job.name}' finished`, "info");
114
+ };
115
+ const runJob = async (prompt, job, signal) => {
116
+ const ctx = lastCtx;
117
+ if (!ctx?.isIdle() || ctx.hasPendingMessages())
118
+ throw new CronAdmissionDeferred("session is busy");
119
+ requireTuiJobWorkdir(job, ctx);
120
+ if (!ctx.promptWithCompletion)
121
+ throw new Error("owned cron admission unavailable");
122
+ beginCronFire();
99
123
  try {
100
- lastCtx?.ui.notify(`Cron job '${job.name}' finished`, "info");
101
- return null;
124
+ const result = await ctx.promptWithCompletion(prompt, { source: "extension", signal }).catch((error) => {
125
+ // Only the runtime's pre-dispatch admission rejection permits a deferred retry.
126
+ if (error instanceof Error && /^Session is busy\. Retry the scheduled prompt after its work settles\.$/.test(error.message)) {
127
+ throw new CronAdmissionDeferred(error.message);
128
+ }
129
+ throw error;
130
+ });
131
+ return extractAssistantText(result.messages);
102
132
  }
103
- catch (err) {
104
- return String(err?.message ?? err);
133
+ finally {
134
+ endCronFire();
105
135
  }
106
136
  };
107
- // --- Scheduler deps (TUI) ---
108
- const runJob = (prompt, _job) => {
109
- if (pendingRun)
110
- return Promise.reject(new Error("another cron job turn is already in flight"));
111
- return new Promise((resolve, reject) => {
112
- beginCronFire();
113
- pendingRun = { resolve, reject };
114
- try {
115
- pi.sendUserMessage(prompt);
116
- }
117
- catch (err) {
118
- pendingRun = null;
119
- endCronFire();
120
- reject(err);
121
- }
122
- });
123
- };
124
- const deliverResult = async (job, content) => {
125
- const bridge = globalThis[DELIVERY_BRIDGE_SYMBOL];
126
- if (!bridge)
127
- throw new Error("no cron delivery bridge registered");
128
- const err = await bridge(job, content);
129
- if (err)
130
- throw new Error(String(err));
137
+ const schedulerDeps = { runJob, deliverResult, canRun: () => !!lastCtx?.isIdle() && !lastCtx.hasPendingMessages() };
138
+ const triggerRun = async (job, _ctx) => {
139
+ if (!scheduler)
140
+ throw new Error("cron runs require the owning TUI operator; use cron run there, or wait for the gateway schedule");
141
+ await scheduler.run(job.id);
142
+ return `Cron job '${job.name}' (${job.id}) finished. Check cron list for run or delivery errors.`;
131
143
  };
132
- const schedulerDeps = { runJob, deliverResult };
133
- /** Manual trigger: run inline when idle, otherwise make the job due for the next tick. */
134
- const triggerRun = async (job, ctx) => {
135
- if (ctx.isIdle()) {
136
- try {
137
- await executeJob(getJob(job.id), schedulerDeps);
138
- return `Cron job '${job.name}' (${job.id}) finished.`;
139
- }
140
- catch (err) {
141
- return `Cron job '${job.name}' (${job.id}) failed: ${String(err?.message ?? err)}`;
142
- }
143
- }
144
- await updateJob(job.id, { nextRunAt: new Date().toISOString() });
145
- return `Cron job '${job.name}' (${job.id}) queued for the next scheduler tick.`;
146
- };
147
- // --- Resolve the cron-fired turn when the agent turn ends ---
148
- pi.on("agent_end", (event) => {
149
- if (!pendingRun)
150
- return;
151
- const pending = pendingRun;
152
- pendingRun = null;
153
- endCronFire();
154
- pending.resolve(extractAssistantText(event.messages ?? []));
155
- });
156
- // --- Scheduler lifecycle: TUI sessions only ---
157
- pi.on("session_start", (_event, ctx) => {
144
+ pi.on("session_start", async (_event, ctx) => {
158
145
  lastCtx = ctx;
159
146
  if (ctx.mode !== "tui")
160
147
  return;
161
- scheduler?.stop();
148
+ await scheduler?.stop();
162
149
  scheduler = startScheduler(schedulerDeps);
163
150
  });
164
- pi.on("session_shutdown", () => {
165
- scheduler?.stop();
151
+ pi.on("session_shutdown", async () => {
152
+ await scheduler?.stop();
166
153
  scheduler = null;
167
154
  });
168
155
  // --- /cron command ---
169
156
  pi.registerCommand("cron", {
170
- description: "Manage cron jobs: /cron list | create <schedule> <prompt> | pause|resume|run|remove <id-or-name> | status",
157
+ description: "Manage cron jobs: /cron list | create <schedule> <prompt> | pause|resume|run|remove|rebind <id-or-name> | status",
171
158
  getArgumentCompletions: (prefix) => {
172
- const subs = ["list", "create", "pause", "resume", "run", "remove", "status"];
159
+ const subs = ["list", "create", "pause", "resume", "run", "remove", "status", "rebind"];
173
160
  const lower = prefix.toLowerCase();
174
161
  return subs
175
162
  .filter((s) => s.startsWith(lower))
@@ -186,7 +173,7 @@ export default function (pi) {
186
173
  return;
187
174
  }
188
175
  case "status": {
189
- ctx.ui.notify(formatStatus(), "info");
176
+ ctx.ui.notify(formatStatus(scheduler?.isOwner() ?? false), "info");
190
177
  return;
191
178
  }
192
179
  case "create": {
@@ -207,10 +194,11 @@ export default function (pi) {
207
194
  ctx.ui.notify("Usage: /cron create <schedule> <prompt> — e.g. /cron create every 30m check the deploy", "error");
208
195
  return;
209
196
  }
210
- const job = await createJob({ prompt, schedule: tokens.slice(0, used).join(" ") });
197
+ const job = await createInContext({ prompt, schedule: tokens.slice(0, used).join(" ") }, ctx);
211
198
  ctx.ui.notify(`Created cron job '${job.name}' (${job.id}) — ${job.scheduleDisplay}, next run ${fmtTime(job.nextRunAt)}.`, "info");
212
199
  return;
213
200
  }
201
+ case "rebind":
214
202
  case "pause":
215
203
  case "resume":
216
204
  case "remove":
@@ -220,7 +208,14 @@ export default function (pi) {
220
208
  ctx.ui.notify(`Usage: /cron ${sub} <id-or-name>`, "error");
221
209
  return;
222
210
  }
223
- if (sub === "pause") {
211
+ if (sub === "rebind") {
212
+ const origin = currentOrigin();
213
+ if (!origin?.userId)
214
+ throw new Error("cron rebind requires an approved gateway requester");
215
+ await updateJob(idOrName, { origin: { ...origin } });
216
+ ctx.ui.notify("Cron requester rebound to this gateway chat.", "info");
217
+ }
218
+ else if (sub === "pause") {
224
219
  const job = await pauseJob(idOrName);
225
220
  ctx.ui.notify(`Paused cron job '${job.name}' (${job.id}).`, "info");
226
221
  }
@@ -239,7 +234,7 @@ export default function (pi) {
239
234
  return;
240
235
  }
241
236
  default: {
242
- ctx.ui.notify("Usage: /cron list | create <schedule> <prompt> | pause|resume|run|remove <id-or-name> | status", "error");
237
+ ctx.ui.notify("Usage: /cron list | create <schedule> <prompt> | pause|resume|run|remove|rebind <id-or-name> | status", "error");
243
238
  }
244
239
  }
245
240
  }
@@ -253,10 +248,11 @@ export default function (pi) {
253
248
  name: "cron",
254
249
  label: "Cron",
255
250
  description: [
256
- "Manage scheduled cron jobs that run prompts unattended in this session.",
257
- "Actions: create (needs prompt + schedule), list, update (id + fields), pause, resume, remove, run (trigger now).",
251
+ "Manage profile-wide scheduled jobs. One operator owns execution; busy sessions defer scheduled work.",
252
+ "TUI execution requires the job's saved project to match the current project. Recreate jobs without a saved project from the intended project.",
253
+ "Actions: create (needs prompt + schedule), list, update (id + fields), pause, resume, remove, run (trigger on the owning TUI operator; otherwise returns an owner error).",
258
254
  "Schedule formats: 'every 30m' / 'every 2h' / 'every 1d' (recurring), '30m'/'2h' or an ISO timestamp (one-shot), or a 5-field cron expression.",
259
- "Job output is delivered automatically; the job's prompt can answer [SILENT] to suppress delivery.",
255
+ "Job output is saved locally; platform delivery requires the gateway operator and current grants. Legacy origin jobs need rebind from an approved gateway chat. The prompt can answer [SILENT] to suppress delivery.",
260
256
  ].join("\n"),
261
257
  parameters: Type.Object({
262
258
  action: Type.Union([
@@ -287,17 +283,7 @@ export default function (pi) {
287
283
  if (!params.prompt?.trim() || !params.schedule?.trim()) {
288
284
  return text("cron create: prompt and schedule are required.");
289
285
  }
290
- // Inside a gateway chat turn, stamp the chat as the delivery
291
- // origin and default deliver to "origin" (Phase 4); outside
292
- // any origin context the default stays "local".
293
- const origin = currentOrigin();
294
- const job = await createJob({
295
- prompt: params.prompt,
296
- schedule: params.schedule,
297
- name: params.name,
298
- deliver: params.deliver ?? (origin ? "origin" : undefined),
299
- origin: origin ? { ...origin } : undefined,
300
- });
286
+ const job = await createInContext({ prompt: params.prompt, schedule: params.schedule, name: params.name, deliver: params.deliver }, ctx);
301
287
  return text(`Created cron job '${job.name}' (${job.id}) — ${job.scheduleDisplay}, next run ${fmtTime(job.nextRunAt)}.`);
302
288
  }
303
289
  case "list": {
@@ -1 +1 @@
1
- {"version":3,"file":"lunr-cron.js","sourceRoot":"","sources":["../../src/builtin-extensions/lunr-cron.ts"],"names":[],"mappings":"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","sourcesContent":["// @ts-nocheck\n/**\n * lunr-cron — lunR-native scheduled jobs (Phase 1: local TUI delivery;\n * Phase 4: gateway delivery + origin stamping).\n *\n * lunR: this file is lunR-native (not an absorbed upstream extension). It wires\n * core/cron (jobs store + scheduler) into the interactive session:\n *\n * - `/cron list|create|pause|resume|run|remove|status` command.\n * - One `cron` tool (TypeBox) so the agent can manage jobs. The shared\n * core/cron/fire-guard depth counter refuses the tool while a cron-fired\n * turn is in flight — TUI-fired OR gateway-fired (jobs cannot schedule\n * jobs).\n * - Jobs created inside a gateway chat turn are stamped with that chat as\n * their origin and default deliver to \"origin\" (core/cron/origin-context).\n * - Scheduler starts on session_start only in \"tui\" mode, stops on\n * session_shutdown. runJob = sendUserMessage + wait for agent_end;\n * deliverResult reads the `@lunr/cron-delivery` bridge on globalThis\n * (registered here as the local notify; the Phase 4 gateway replaces\n * it — core/cron/scheduler.ts never touches the bridge itself).\n *\n * `// @ts-nocheck` matches the builtin-extension convention.\n * Runtime imports stay on concrete core modules — never the package barrel.\n */\n\nimport type { ExtensionAPI, ExtensionContext } from \"@ashx-j/lunr\";\nimport { Type } from \"@sinclair/typebox\";\nimport { beginCronFire, endCronFire, isCronFire } from \"../core/cron/fire-guard.ts\";\nimport {\n\tcreateJob,\n\tgetJob,\n\tlistJobs,\n\tparseSchedule,\n\tpauseJob,\n\tremoveJob,\n\tresumeJob,\n\tsetCronDeliverValidator,\n\tupdateJob,\n} from \"../core/cron/jobs.ts\";\nimport { currentOrigin } from \"../core/cron/origin-context.ts\";\nimport { executeJob, startScheduler } from \"../core/cron/scheduler.ts\";\nimport { loadGatewayConfig } from \"../gateway/config.ts\";\nimport { createDeliverValidator } from \"../gateway/cron.ts\";\n\n// ---------------------------------------------------------------------------\n// Module state\n// ---------------------------------------------------------------------------\n/** The cron-fired turn currently waiting for agent_end. */\nlet pendingRun: { resolve: (text: string) => void; reject: (err: Error) => void } | null = null;\nlet scheduler: { stop(): void } | null = null;\nlet lastCtx: ExtensionContext | null = null;\n\nconst DELIVERY_BRIDGE_SYMBOL = Symbol.for(\"@lunr/cron-delivery\");\n\n// ---------------------------------------------------------------------------\n// Turn plumbing\n// ---------------------------------------------------------------------------\n\n/** Final assistant text from an agent_end messages array (last assistant message, text blocks only). */\nfunction extractAssistantText(messages: unknown[]): string {\n\tfor (let i = messages.length - 1; i >= 0; i--) {\n\t\tconst msg = messages[i] as any;\n\t\tif (msg?.role !== \"assistant\") continue;\n\t\tconst parts = Array.isArray(msg.content) ? msg.content : [];\n\t\tconst text = parts\n\t\t\t.filter((p: any) => p?.type === \"text\")\n\t\t\t.map((p: any) => String(p.text ?? \"\"))\n\t\t\t.join(\"\")\n\t\t\t.trim();\n\t\tif (text) return text;\n\t}\n\treturn \"\";\n}\n\n// ---------------------------------------------------------------------------\n// Formatting helpers\n// ---------------------------------------------------------------------------\n\nfunction fmtTime(iso: string | null): string {\n\tif (!iso) return \"-\";\n\tconst d = new Date(iso);\n\tif (Number.isNaN(d.getTime())) return \"-\";\n\tconst p = (n: number) => String(n).padStart(2, \"0\");\n\t// Stored timestamps are UTC ISO; render in local time so users read wall-clock.\n\treturn `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())} ${p(d.getHours())}:${p(d.getMinutes())}`;\n}\n\nfunction formatJobList(): string {\n\tconst jobs = listJobs();\n\tif (jobs.length === 0) return \"No cron jobs. Create one with /cron create <schedule> <prompt>.\";\n\tconst lines = jobs.map(\n\t\t(j) =>\n\t\t\t`${j.id} ${j.state}${j.enabled ? \"\" : \" (disabled)\"} ${j.scheduleDisplay} next=${fmtTime(j.nextRunAt)} last=${j.lastStatus ?? \"-\"}${j.lastError ? ` (${j.lastError})` : \"\"} ${j.name}`,\n\t);\n\treturn `Cron jobs (${jobs.length}):\\n${lines.join(\"\\n\")}`;\n}\n\nfunction formatStatus(): string {\n\tconst jobs = listJobs();\n\tconst count = (s: string) => jobs.filter((j) => j.state === s).length;\n\tconst next = jobs\n\t\t.filter((j) => j.enabled && j.state === \"scheduled\" && j.nextRunAt)\n\t\t.sort((a, b) => String(a.nextRunAt).localeCompare(String(b.nextRunAt)))[0];\n\treturn (\n\t\t`Cron: scheduler ${scheduler ? \"running\" : \"stopped\"}; ${jobs.length} job(s) — ` +\n\t\t`${count(\"scheduled\")} scheduled, ${count(\"paused\")} paused, ${count(\"completed\")} completed, ${count(\"error\")} error.` +\n\t\t(next ? ` Next: '${next.name}' at ${fmtTime(next.nextRunAt)}.` : \"\")\n\t);\n}\n\n// ---------------------------------------------------------------------------\n// Extension\n// ---------------------------------------------------------------------------\n\nexport default function (pi: ExtensionAPI): void {\n\t// Same allowlist the gateway uses, so a TUI session cannot persist a job\n\t// that later posts to a chat the bot can reach but is not allowed.\n\tsetCronDeliverValidator(createDeliverValidator(loadGatewayConfig()));\n\n\t// --- Local delivery bridge (Phase 4 gateway replaces this) ---\n\t(globalThis as Record<symbol, unknown>)[DELIVERY_BRIDGE_SYMBOL] = async (job: { name: string }, _content: string) => {\n\t\ttry {\n\t\t\tlastCtx?.ui.notify(`Cron job '${job.name}' finished`, \"info\");\n\t\t\treturn null;\n\t\t} catch (err) {\n\t\t\treturn String((err as Error)?.message ?? err);\n\t\t}\n\t};\n\n\t// --- Scheduler deps (TUI) ---\n\tconst runJob = (prompt: string, _job: unknown): Promise<string> => {\n\t\tif (pendingRun) return Promise.reject(new Error(\"another cron job turn is already in flight\"));\n\t\treturn new Promise<string>((resolve, reject) => {\n\t\t\tbeginCronFire();\n\t\t\tpendingRun = { resolve, reject };\n\t\t\ttry {\n\t\t\t\tpi.sendUserMessage(prompt);\n\t\t\t} catch (err) {\n\t\t\t\tpendingRun = null;\n\t\t\t\tendCronFire();\n\t\t\t\treject(err as Error);\n\t\t\t}\n\t\t});\n\t};\n\n\tconst deliverResult = async (job: any, content: string): Promise<void> => {\n\t\tconst bridge = (globalThis as Record<symbol, unknown>)[DELIVERY_BRIDGE_SYMBOL] as\n\t\t\t| ((job: unknown, content: string) => Promise<string | null>)\n\t\t\t| undefined;\n\t\tif (!bridge) throw new Error(\"no cron delivery bridge registered\");\n\t\tconst err = await bridge(job, content);\n\t\tif (err) throw new Error(String(err));\n\t};\n\n\tconst schedulerDeps = { runJob, deliverResult };\n\n\t/** Manual trigger: run inline when idle, otherwise make the job due for the next tick. */\n\tconst triggerRun = async (job: any, ctx: ExtensionContext): Promise<string> => {\n\t\tif (ctx.isIdle()) {\n\t\t\ttry {\n\t\t\t\tawait executeJob(getJob(job.id), schedulerDeps);\n\t\t\t\treturn `Cron job '${job.name}' (${job.id}) finished.`;\n\t\t\t} catch (err) {\n\t\t\t\treturn `Cron job '${job.name}' (${job.id}) failed: ${String((err as Error)?.message ?? err)}`;\n\t\t\t}\n\t\t}\n\t\tawait updateJob(job.id, { nextRunAt: new Date().toISOString() });\n\t\treturn `Cron job '${job.name}' (${job.id}) queued for the next scheduler tick.`;\n\t};\n\n\t// --- Resolve the cron-fired turn when the agent turn ends ---\n\tpi.on(\"agent_end\", (event) => {\n\t\tif (!pendingRun) return;\n\t\tconst pending = pendingRun;\n\t\tpendingRun = null;\n\t\tendCronFire();\n\t\tpending.resolve(extractAssistantText(event.messages ?? []));\n\t});\n\n\t// --- Scheduler lifecycle: TUI sessions only ---\n\tpi.on(\"session_start\", (_event, ctx) => {\n\t\tlastCtx = ctx;\n\t\tif (ctx.mode !== \"tui\") return;\n\t\tscheduler?.stop();\n\t\tscheduler = startScheduler(schedulerDeps);\n\t});\n\n\tpi.on(\"session_shutdown\", () => {\n\t\tscheduler?.stop();\n\t\tscheduler = null;\n\t});\n\n\t// --- /cron command ---\n\tpi.registerCommand(\"cron\", {\n\t\tdescription: \"Manage cron jobs: /cron list | create <schedule> <prompt> | pause|resume|run|remove <id-or-name> | status\",\n\t\tgetArgumentCompletions: (prefix: string) => {\n\t\t\tconst subs = [\"list\", \"create\", \"pause\", \"resume\", \"run\", \"remove\", \"status\"];\n\t\t\tconst lower = prefix.toLowerCase();\n\t\t\treturn subs\n\t\t\t\t.filter((s) => s.startsWith(lower))\n\t\t\t\t.map((s) => ({ value: s, label: s, description: `/cron ${s}` }));\n\t\t},\n\t\thandler: async (args, ctx) => {\n\t\t\tlastCtx = ctx;\n\t\t\tconst tokens = args.trim().split(/\\s+/).filter(Boolean);\n\t\t\tconst sub = (tokens.shift() ?? \"list\").toLowerCase();\n\t\t\ttry {\n\t\t\t\tswitch (sub) {\n\t\t\t\t\tcase \"list\": {\n\t\t\t\t\t\tctx.ui.notify(formatJobList(), \"info\");\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"status\": {\n\t\t\t\t\t\tctx.ui.notify(formatStatus(), \"info\");\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"create\": {\n\t\t\t\t\t\t// Greedy: the schedule is the shortest leading token run that parses.\n\t\t\t\t\t\tlet used = 0;\n\t\t\t\t\t\tfor (let k = 1; k <= Math.min(6, tokens.length); k++) {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tparseSchedule(tokens.slice(0, k).join(\" \"));\n\t\t\t\t\t\t\t\tused = k;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t// keep extending\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst prompt = tokens.slice(used).join(\" \").trim();\n\t\t\t\t\t\tif (!used || !prompt) {\n\t\t\t\t\t\t\tctx.ui.notify(\"Usage: /cron create <schedule> <prompt> — e.g. /cron create every 30m check the deploy\", \"error\");\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst job = await createJob({ prompt, schedule: tokens.slice(0, used).join(\" \") });\n\t\t\t\t\t\tctx.ui.notify(`Created cron job '${job.name}' (${job.id}) — ${job.scheduleDisplay}, next run ${fmtTime(job.nextRunAt)}.`, \"info\");\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"pause\":\n\t\t\t\t\tcase \"resume\":\n\t\t\t\t\tcase \"remove\":\n\t\t\t\t\tcase \"run\": {\n\t\t\t\t\t\tconst idOrName = tokens.join(\" \").trim();\n\t\t\t\t\t\tif (!idOrName) {\n\t\t\t\t\t\t\tctx.ui.notify(`Usage: /cron ${sub} <id-or-name>`, \"error\");\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (sub === \"pause\") {\n\t\t\t\t\t\t\tconst job = await pauseJob(idOrName);\n\t\t\t\t\t\t\tctx.ui.notify(`Paused cron job '${job.name}' (${job.id}).`, \"info\");\n\t\t\t\t\t\t} else if (sub === \"resume\") {\n\t\t\t\t\t\t\tconst job = await resumeJob(idOrName);\n\t\t\t\t\t\t\tctx.ui.notify(`Resumed cron job '${job.name}' (${job.id}) — next run ${fmtTime(job.nextRunAt)}.`, \"info\");\n\t\t\t\t\t\t} else if (sub === \"remove\") {\n\t\t\t\t\t\t\tconst job = await removeJob(idOrName);\n\t\t\t\t\t\t\tctx.ui.notify(`Removed cron job '${job.name}' (${job.id}).`, \"info\");\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tconst job = getJob(idOrName);\n\t\t\t\t\t\t\tctx.ui.notify(await triggerRun(job, ctx), \"info\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tdefault: {\n\t\t\t\t\t\tctx.ui.notify(\"Usage: /cron list | create <schedule> <prompt> | pause|resume|run|remove <id-or-name> | status\", \"error\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\tctx.ui.notify(String((err as Error)?.message ?? err), \"error\");\n\t\t\t}\n\t\t},\n\t});\n\n\t// --- cron tool (agent-facing) ---\n\tpi.registerTool({\n\t\tname: \"cron\",\n\t\tlabel: \"Cron\",\n\t\tdescription: [\n\t\t\t\"Manage scheduled cron jobs that run prompts unattended in this session.\",\n\t\t\t\"Actions: create (needs prompt + schedule), list, update (id + fields), pause, resume, remove, run (trigger now).\",\n\t\t\t\"Schedule formats: 'every 30m' / 'every 2h' / 'every 1d' (recurring), '30m'/'2h' or an ISO timestamp (one-shot), or a 5-field cron expression.\",\n\t\t\t\"Job output is delivered automatically; the job's prompt can answer [SILENT] to suppress delivery.\",\n\t\t].join(\"\\n\"),\n\t\tparameters: Type.Object({\n\t\t\taction: Type.Union([\n\t\t\t\tType.Literal(\"create\"),\n\t\t\t\tType.Literal(\"list\"),\n\t\t\t\tType.Literal(\"update\"),\n\t\t\t\tType.Literal(\"pause\"),\n\t\t\t\tType.Literal(\"resume\"),\n\t\t\t\tType.Literal(\"remove\"),\n\t\t\t\tType.Literal(\"run\"),\n\t\t\t]),\n\t\t\tid: Type.Optional(Type.String({ description: \"Job id or unique name (all actions except create/list).\" })),\n\t\t\tname: Type.Optional(Type.String({ description: \"Display name (<=50 chars); derived from the prompt when omitted.\" })),\n\t\t\tprompt: Type.Optional(Type.String({ description: \"The prompt the job runs (create/update).\" })),\n\t\t\tschedule: Type.Optional(Type.String({ description: \"Schedule input (create/update).\" })),\n\t\t\tdeliver: Type.Optional(\n\t\t\t\tType.String({\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"Delivery target(s), comma-separated: 'local' (output file only), 'origin' (the chat that created the job), 'telegram'/'discord' (platform home channel), or 'telegram:<chatId>[:<threadId>]' / 'discord:<chatId>[:<threadId>]'. Defaults to 'origin' when created from a gateway chat, else 'local'.\",\n\t\t\t\t}),\n\t\t\t),\n\t\t}),\n\t\tasync execute(_toolCallId, params, _signal, _onUpdate, ctx) {\n\t\t\tconst text = (t: string) => ({ content: [{ type: \"text\" as const, text: t }] });\n\t\t\tif (isCronFire()) {\n\t\t\t\treturn text(\"cron: unavailable while a cron-fired turn is running (cron jobs cannot schedule cron jobs).\");\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tswitch (params.action) {\n\t\t\t\t\tcase \"create\": {\n\t\t\t\t\t\tif (!params.prompt?.trim() || !params.schedule?.trim()) {\n\t\t\t\t\t\t\treturn text(\"cron create: prompt and schedule are required.\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Inside a gateway chat turn, stamp the chat as the delivery\n\t\t\t\t\t\t// origin and default deliver to \"origin\" (Phase 4); outside\n\t\t\t\t\t\t// any origin context the default stays \"local\".\n\t\t\t\t\t\tconst origin = currentOrigin();\n\t\t\t\t\t\tconst job = await createJob({\n\t\t\t\t\t\t\tprompt: params.prompt,\n\t\t\t\t\t\t\tschedule: params.schedule,\n\t\t\t\t\t\t\tname: params.name,\n\t\t\t\t\t\t\tdeliver: params.deliver ?? (origin ? \"origin\" : undefined),\n\t\t\t\t\t\t\torigin: origin ? { ...origin } : undefined,\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn text(`Created cron job '${job.name}' (${job.id}) — ${job.scheduleDisplay}, next run ${fmtTime(job.nextRunAt)}.`);\n\t\t\t\t\t}\n\t\t\t\t\tcase \"list\": {\n\t\t\t\t\t\treturn text(formatJobList());\n\t\t\t\t\t}\n\t\t\t\t\tcase \"update\": {\n\t\t\t\t\t\tif (!params.id) return text(\"cron update: id (or unique name) is required.\");\n\t\t\t\t\t\tconst job = await updateJob(params.id, {\n\t\t\t\t\t\t\tname: params.name,\n\t\t\t\t\t\t\tprompt: params.prompt,\n\t\t\t\t\t\t\tschedule: params.schedule,\n\t\t\t\t\t\t\tdeliver: params.deliver,\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn text(`Updated cron job '${job.name}' (${job.id}) — ${job.scheduleDisplay}, next run ${fmtTime(job.nextRunAt)}.`);\n\t\t\t\t\t}\n\t\t\t\t\tcase \"pause\": {\n\t\t\t\t\t\tif (!params.id) return text(\"cron pause: id (or unique name) is required.\");\n\t\t\t\t\t\tconst job = await pauseJob(params.id);\n\t\t\t\t\t\treturn text(`Paused cron job '${job.name}' (${job.id}).`);\n\t\t\t\t\t}\n\t\t\t\t\tcase \"resume\": {\n\t\t\t\t\t\tif (!params.id) return text(\"cron resume: id (or unique name) is required.\");\n\t\t\t\t\t\tconst job = await resumeJob(params.id);\n\t\t\t\t\t\treturn text(`Resumed cron job '${job.name}' (${job.id}) — next run ${fmtTime(job.nextRunAt)}.`);\n\t\t\t\t\t}\n\t\t\t\t\tcase \"remove\": {\n\t\t\t\t\t\tif (!params.id) return text(\"cron remove: id (or unique name) is required.\");\n\t\t\t\t\t\tconst job = await removeJob(params.id);\n\t\t\t\t\t\treturn text(`Removed cron job '${job.name}' (${job.id}).`);\n\t\t\t\t\t}\n\t\t\t\t\tcase \"run\": {\n\t\t\t\t\t\tif (!params.id) return text(\"cron run: id (or unique name) is required.\");\n\t\t\t\t\t\tconst job = getJob(params.id);\n\t\t\t\t\t\treturn text(await triggerRun(job, ctx));\n\t\t\t\t\t}\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn text(`cron: unknown action \"${String(params.action)}\".`);\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\treturn text(`cron: ${String((err as Error)?.message ?? err)}`);\n\t\t\t}\n\t\t},\n\t});\n}\n"]}
1
+ {"version":3,"file":"lunr-cron.js","sourceRoot":"","sources":["../../src/builtin-extensions/lunr-cron.ts"],"names":[],"mappings":"AAAA,cAAc;AACd;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEvC,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACpF,OAAO,EACN,SAAS,EAGT,MAAM,EACN,QAAQ,EACR,aAAa,EACb,QAAQ,EACR,SAAS,EACT,SAAS,EACT,uBAAuB,EACvB,SAAS,GACT,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAClF,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAEnE,8EAA8E;AAC9E,eAAe;AACf,8EAA8E;AAC9E,4DAA4D;AAC5D,SAAS,oBAAoB,CAAC,QAAmB,EAAU;IAC1D,KAAK,IAAI,CAAC,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/C,MAAM,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAoH,CAAC;QAC3I,IAAI,GAAG,EAAE,IAAI,KAAK,WAAW;YAAE,SAAS;QACxC,IAAI,GAAG,CAAC,UAAU,KAAK,OAAO,IAAI,GAAG,CAAC,UAAU,KAAK,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,GAAG,CAAC,YAAY,IAAI,WAAW,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC;QACjI,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAClH,CAAC;IACD,OAAO,EAAE,CAAC;AAAA,CACV;AAED,6FAA6F;AAC7F,SAAS,eAAe,CAAC,KAAqB,EAAE,GAAqB,EAAE;IACtE,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;IAC/B,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,kBAAkB,CAAC,GAAG,CAAC,GAAG,EAAE,iBAAiB,EAAE,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;IACvG,OAAO,SAAS,CAAC,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;AAAA,CACxI;AAED,0FAA0F;AAC1F,SAAS,oBAAoB,CAAC,GAAY,EAAE,GAAqB,EAAQ;IACxE,IAAI,CAAC,GAAG,CAAC,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC;QAC3C,MAAM,IAAI,qBAAqB,CAAC,oHAAoH,CAAC,CAAC;IACvJ,IAAI,KAAa,CAAC;IAClB,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACJ,KAAK,GAAG,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAClC,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACjC,CAAC;IAAC,MAAM,CAAC;QACR,MAAM,IAAI,qBAAqB,CAAC,4FAA4F,CAAC,CAAC;IAC/H,CAAC;IACD,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,OAAO,CAAC;IACjH,IAAI,CAAC,OAAO;QACX,MAAM,IAAI,qBAAqB,CAAC,sIAAsI,CAAC,CAAC;AAAA,CACzK;AAED,8EAA8E;AAC9E,qBAAqB;AACrB,8EAA8E;AAE9E,SAAS,OAAO,CAAC,GAAkB,EAAU;IAC5C,IAAI,CAAC,GAAG;QAAE,OAAO,GAAG,CAAC;IACrB,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;IACxB,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;QAAE,OAAO,GAAG,CAAC;IAC1C,MAAM,CAAC,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACpD,gFAAgF;IAChF,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,EAAE,CAAC;AAAA,CAC7G;AAED,SAAS,aAAa,GAAW;IAChC,MAAM,IAAI,GAAG,QAAQ,EAAE,CAAC;IACxB,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,iEAAiE,CAAC;IAChG,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CACrB,CAAC,CAAC,EAAE,EAAE,CACL,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,KAAK,CAAC,CAAC,eAAe,UAAU,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,UAAU,IAAI,GAAG,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,CAClQ,CAAC;IACF,OAAO,cAAc,IAAI,CAAC,MAAM,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;AAAA,CAC1D;AAED,SAAS,YAAY,CAAC,OAAgB,EAAU;IAC/C,MAAM,IAAI,GAAG,QAAQ,EAAE,CAAC;IACxB,MAAM,KAAK,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;IACtE,MAAM,IAAI,GAAG,IAAI;SACf,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,KAAK,KAAK,WAAW,IAAI,CAAC,CAAC,SAAS,CAAC;SAClE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5E,OAAO,CACN,mBAAmB,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,KAAK,IAAI,CAAC,MAAM,cAAY;QAC9E,GAAG,KAAK,CAAC,WAAW,CAAC,eAAe,KAAK,CAAC,QAAQ,CAAC,YAAY,KAAK,CAAC,WAAW,CAAC,eAAe,KAAK,CAAC,OAAO,CAAC,SAAS;QACvH,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,IAAI,QAAQ,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CACpE,CAAC;AAAA,CACF;AAED,8EAA8E;AAC9E,YAAY;AACZ,8EAA8E;AAE9E,MAAM,CAAC,OAAO,WAAW,EAAgB,EAAQ;IAChD,IAAI,SAAS,GAA6C,IAAI,CAAC;IAC/D,IAAI,OAAO,GAA4B,IAAI,CAAC;IAC5C,uBAAuB,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC,sBAAsB,CAAC,iBAAiB,EAAE,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;IAE3G,MAAM,aAAa,GAAG,KAAK,EAAE,GAAY,EAAE,QAAgB,EAAiB,EAAE,CAAC;QAC9E,IAAI,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,OAAO,CAAC,EAAE,CAAC;YACxE,MAAM,IAAI,KAAK,CAAC,sHAAsH,CAAC,CAAC;QACzI,CAAC;QACD,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,aAAa,GAAG,CAAC,IAAI,YAAY,EAAE,MAAM,CAAC,CAAC;IAAA,CAC9D,CAAC;IACF,MAAM,MAAM,GAAG,KAAK,EAAE,MAAc,EAAE,GAAY,EAAE,MAAmB,EAAmB,EAAE,CAAC;QAC5F,MAAM,GAAG,GAAG,OAAO,CAAC;QACpB,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,GAAG,CAAC,kBAAkB,EAAE;YAAE,MAAM,IAAI,qBAAqB,CAAC,iBAAiB,CAAC,CAAC;QACnG,oBAAoB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC/B,IAAI,CAAC,GAAG,CAAC,oBAAoB;YAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;QACnF,aAAa,EAAE,CAAC;QAChB,IAAI,CAAC;YACJ,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,oBAAoB,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE,CAAC;gBAChH,gFAAgF;gBAChF,IAAI,KAAK,YAAY,KAAK,IAAI,yEAAyE,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;oBAC7H,MAAM,IAAI,qBAAqB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBAChD,CAAC;gBACD,MAAM,KAAK,CAAC;YAAA,CACZ,CAAC,CAAC;YACH,OAAO,oBAAoB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC9C,CAAC;gBAAS,CAAC;YAAC,WAAW,EAAE,CAAC;QAAC,CAAC;IAAA,CAC5B,CAAC;IACF,MAAM,aAAa,GAAG,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC;IACpH,MAAM,UAAU,GAAG,KAAK,EAAE,GAAY,EAAE,IAAsB,EAAmB,EAAE,CAAC;QACnF,IAAI,CAAC,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,iGAAiG,CAAC,CAAC;QACnI,MAAM,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC5B,OAAO,aAAa,GAAG,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,yDAAyD,CAAC;IAAA,CAClG,CAAC;IACF,EAAE,CAAC,EAAE,CAAC,eAAe,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC;QAC7C,OAAO,GAAG,GAAG,CAAC;QACd,IAAI,GAAG,CAAC,IAAI,KAAK,KAAK;YAAE,OAAO;QAC/B,MAAM,SAAS,EAAE,IAAI,EAAE,CAAC;QACxB,SAAS,GAAG,cAAc,CAAC,aAAa,CAAC,CAAC;IAAA,CAC1C,CAAC,CAAC;IACH,EAAE,CAAC,EAAE,CAAC,kBAAkB,EAAE,KAAK,IAAI,EAAE,CAAC;QACrC,MAAM,SAAS,EAAE,IAAI,EAAE,CAAC;QACxB,SAAS,GAAG,IAAI,CAAC;IAAA,CACjB,CAAC,CAAC;IAEH,wBAAwB;IACxB,EAAE,CAAC,eAAe,CAAC,MAAM,EAAE;QAC1B,WAAW,EAAE,kHAAkH;QAC/H,sBAAsB,EAAE,CAAC,MAAc,EAAE,EAAE,CAAC;YAC3C,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;YACxF,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;YACnC,OAAO,IAAI;iBACT,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;iBAClC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,WAAW,EAAE,SAAS,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QAAA,CAClE;QACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC;YAC7B,OAAO,GAAG,GAAG,CAAC;YACd,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YACxD,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;YACrD,IAAI,CAAC;gBACJ,QAAQ,GAAG,EAAE,CAAC;oBACb,KAAK,MAAM,EAAE,CAAC;wBACb,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,aAAa,EAAE,EAAE,MAAM,CAAC,CAAC;wBACvC,OAAO;oBACR,CAAC;oBACD,KAAK,QAAQ,EAAE,CAAC;wBACf,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,EAAE,IAAI,KAAK,CAAC,EAAE,MAAM,CAAC,CAAC;wBACnE,OAAO;oBACR,CAAC;oBACD,KAAK,QAAQ,EAAE,CAAC;wBACf,sEAAsE;wBACtE,IAAI,IAAI,GAAG,CAAC,CAAC;wBACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;4BACtD,IAAI,CAAC;gCACJ,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;gCAC5C,IAAI,GAAG,CAAC,CAAC;gCACT,MAAM;4BACP,CAAC;4BAAC,MAAM,CAAC;gCACR,iBAAiB;4BAClB,CAAC;wBACF,CAAC;wBACD,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;wBACnD,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;4BACtB,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,0FAAwF,EAAE,OAAO,CAAC,CAAC;4BACjH,OAAO;wBACR,CAAC;wBACD,MAAM,GAAG,GAAG,MAAM,eAAe,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;wBAC9F,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,qBAAqB,GAAG,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,SAAO,GAAG,CAAC,eAAe,cAAc,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;wBAClI,OAAO;oBACR,CAAC;oBACD,KAAK,QAAQ,CAAC;oBACd,KAAK,OAAO,CAAC;oBACb,KAAK,QAAQ,CAAC;oBACd,KAAK,QAAQ,CAAC;oBACd,KAAK,KAAK,EAAE,CAAC;wBACZ,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;wBACzC,IAAI,CAAC,QAAQ,EAAE,CAAC;4BACf,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,gBAAgB,GAAG,eAAe,EAAE,OAAO,CAAC,CAAC;4BAC3D,OAAO;wBACR,CAAC;wBACD,IAAI,GAAG,KAAK,QAAQ,EAAE,CAAC;4BACtB,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;4BAC/B,IAAI,CAAC,MAAM,EAAE,MAAM;gCAAE,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;4BAC3F,MAAM,SAAS,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,EAAE,GAAG,MAAM,EAAE,EAAE,CAAC,CAAC;4BACrD,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,8CAA8C,EAAE,MAAM,CAAC,CAAC;wBACvE,CAAC;6BAAM,IAAI,GAAG,KAAK,OAAO,EAAE,CAAC;4BAC5B,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,CAAC;4BACrC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,oBAAoB,GAAG,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;wBACrE,CAAC;6BAAM,IAAI,GAAG,KAAK,QAAQ,EAAE,CAAC;4BAC7B,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,CAAC;4BACtC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,qBAAqB,GAAG,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,kBAAgB,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;wBAC3G,CAAC;6BAAM,IAAI,GAAG,KAAK,QAAQ,EAAE,CAAC;4BAC7B,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,CAAC;4BACtC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,qBAAqB,GAAG,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;wBACtE,CAAC;6BAAM,CAAC;4BACP,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;4BAC7B,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;wBACnD,CAAC;wBACD,OAAO;oBACR,CAAC;oBACD,SAAS,CAAC;wBACT,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,uGAAuG,EAAE,OAAO,CAAC,CAAC;oBACjI,CAAC;gBACF,CAAC;YACF,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACd,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAE,GAAa,EAAE,OAAO,IAAI,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;YAChE,CAAC;QAAA,CACD;KACD,CAAC,CAAC;IAEH,mCAAmC;IACnC,EAAE,CAAC,YAAY,CAAC;QACf,IAAI,EAAE,MAAM;QACZ,KAAK,EAAE,MAAM;QACb,WAAW,EAAE;YACZ,sGAAsG;YACtG,+IAA+I;YAC/I,2KAA2K;YAC3K,+IAA+I;YAC/I,qNAAqN;SACrN,CAAC,IAAI,CAAC,IAAI,CAAC;QACZ,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC;YACvB,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC;gBAClB,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;gBACtB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;gBACpB,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;gBACtB,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;gBACrB,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;gBACtB,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;gBACtB,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;aACnB,CAAC;YACF,EAAE,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,yDAAyD,EAAE,CAAC,CAAC;YAC1G,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,kEAAkE,EAAE,CAAC,CAAC;YACrH,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,0CAA0C,EAAE,CAAC,CAAC;YAC/F,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,iCAAiC,EAAE,CAAC,CAAC;YACxF,OAAO,EAAE,IAAI,CAAC,QAAQ,CACrB,IAAI,CAAC,MAAM,CAAC;gBACX,WAAW,EACV,sSAAsS;aACvS,CAAC,CACF;SACD,CAAC;QACF,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE;YAC3D,MAAM,IAAI,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;YAChF,IAAI,UAAU,EAAE,EAAE,CAAC;gBAClB,OAAO,IAAI,CAAC,6FAA6F,CAAC,CAAC;YAC5G,CAAC;YACD,IAAI,CAAC;gBACJ,QAAQ,MAAM,CAAC,MAAM,EAAE,CAAC;oBACvB,KAAK,QAAQ,EAAE,CAAC;wBACf,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE,CAAC;4BACxD,OAAO,IAAI,CAAC,gDAAgD,CAAC,CAAC;wBAC/D,CAAC;wBACiB,MAAM,GAAG,GAAG,MAAM,eAAe,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,EAAE,GAAG,CAAC,CAAC;wBAC3J,OAAO,IAAI,CAAC,qBAAqB,GAAG,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,SAAO,GAAG,CAAC,eAAe,cAAc,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;oBACzH,CAAC;oBACD,KAAK,MAAM,EAAE,CAAC;wBACb,OAAO,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC;oBAC9B,CAAC;oBACD,KAAK,QAAQ,EAAE,CAAC;wBACf,IAAI,CAAC,MAAM,CAAC,EAAE;4BAAE,OAAO,IAAI,CAAC,+CAA+C,CAAC,CAAC;wBAC7E,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,EAAE,EAAE;4BACtC,IAAI,EAAE,MAAM,CAAC,IAAI;4BACjB,MAAM,EAAE,MAAM,CAAC,MAAM;4BACrB,QAAQ,EAAE,MAAM,CAAC,QAAQ;4BACzB,OAAO,EAAE,MAAM,CAAC,OAAO;yBACvB,CAAC,CAAC;wBACH,OAAO,IAAI,CAAC,qBAAqB,GAAG,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,SAAO,GAAG,CAAC,eAAe,cAAc,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;oBACzH,CAAC;oBACD,KAAK,OAAO,EAAE,CAAC;wBACd,IAAI,CAAC,MAAM,CAAC,EAAE;4BAAE,OAAO,IAAI,CAAC,8CAA8C,CAAC,CAAC;wBAC5E,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;wBACtC,OAAO,IAAI,CAAC,oBAAoB,GAAG,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC;oBAC3D,CAAC;oBACD,KAAK,QAAQ,EAAE,CAAC;wBACf,IAAI,CAAC,MAAM,CAAC,EAAE;4BAAE,OAAO,IAAI,CAAC,+CAA+C,CAAC,CAAC;wBAC7E,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;wBACvC,OAAO,IAAI,CAAC,qBAAqB,GAAG,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,kBAAgB,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;oBACjG,CAAC;oBACD,KAAK,QAAQ,EAAE,CAAC;wBACf,IAAI,CAAC,MAAM,CAAC,EAAE;4BAAE,OAAO,IAAI,CAAC,+CAA+C,CAAC,CAAC;wBAC7E,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;wBACvC,OAAO,IAAI,CAAC,qBAAqB,GAAG,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC;oBAC5D,CAAC;oBACD,KAAK,KAAK,EAAE,CAAC;wBACZ,IAAI,CAAC,MAAM,CAAC,EAAE;4BAAE,OAAO,IAAI,CAAC,4CAA4C,CAAC,CAAC;wBAC1E,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;wBAC9B,OAAO,IAAI,CAAC,MAAM,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;oBACzC,CAAC;oBACD;wBACC,OAAO,IAAI,CAAC,yBAAyB,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBAClE,CAAC;YACF,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACd,OAAO,IAAI,CAAC,SAAS,MAAM,CAAE,GAAa,EAAE,OAAO,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC;YAChE,CAAC;QAAA,CACD;KACD,CAAC,CAAC;AAAA,CACH","sourcesContent":["// @ts-nocheck\n/**\n * lunr-cron — lunR-native scheduled jobs (Phase 1: local TUI delivery;\n * Phase 4: gateway delivery + origin stamping).\n *\n * lunR: this file is lunR-native (not an absorbed upstream extension). It wires\n * core/cron (jobs store + scheduler) into the interactive session:\n *\n * - `/cron list|create|pause|resume|run|remove|rebind|status` command.\n * - One `cron` tool (TypeBox) so the agent can manage jobs. The shared\n * core/cron/fire-guard depth counter refuses the tool while a cron-fired\n * turn is in flight — TUI-fired OR gateway-fired (jobs cannot schedule\n * jobs).\n * - Jobs created inside a gateway chat turn are stamped with that chat as\n * their origin and default deliver to \"origin\" (core/cron/origin-context).\n * - Scheduler starts on session_start only in \"tui\" mode, stops on\n * session_shutdown. runJob admits and awaits one owned prompt;\n * TUI delivery notifies locally and records external delivery as unavailable;\n * the gateway operator performs platform delivery with current grants.\n *\n * `// @ts-nocheck` matches the builtin-extension convention.\n * Runtime imports stay on concrete core modules — never the package barrel.\n */\n\nimport { realpathSync } from \"node:fs\";\nimport { isAbsolute } from \"node:path\";\nimport type { ExtensionAPI, ExtensionContext } from \"@ashx-j/lunr\";\nimport { Type } from \"@sinclair/typebox\";\nimport { beginCronFire, endCronFire, isCronFire } from \"../core/cron/fire-guard.ts\";\nimport {\n\tcreateJob,\n\ttype CreateJobInput,\n\ttype CronJob,\n\tgetJob,\n\tlistJobs,\n\tparseSchedule,\n\tpauseJob,\n\tremoveJob,\n\tresumeJob,\n\tsetCronDeliverValidator,\n\tupdateJob,\n} from \"../core/cron/jobs.ts\";\nimport { currentOrigin } from \"../core/cron/origin-context.ts\";\nimport { CronAdmissionDeferred, startScheduler } from \"../core/cron/scheduler.ts\";\nimport { loadGatewayConfig } from \"../gateway/config.ts\";\nimport { createDeliverValidator } from \"../gateway/cron.ts\";\nimport { resolveWithinRoots } from \"../gateway/mobile-commands.ts\";\n\n// ---------------------------------------------------------------------------\n// Module state\n// ---------------------------------------------------------------------------\n/** Last assistant message of this admitted request only. */\nfunction extractAssistantText(messages: unknown[]): string {\n\tfor (let i = messages.length - 1; i >= 0; i--) {\n\t\tconst msg = messages[i] as { role?: string; stopReason?: string; errorMessage?: string; content?: Array<{ type: string; text?: string }> };\n\t\tif (msg?.role !== \"assistant\") continue;\n\t\tif (msg.stopReason === \"error\" || msg.stopReason === \"aborted\") throw new Error(msg.errorMessage || `Request ${msg.stopReason}`);\n\t\treturn (msg.content ?? []).filter((part) => part.type === \"text\").map((part) => part.text ?? \"\").join(\"\").trim();\n\t}\n\treturn \"\";\n}\n\n/** Both creation routes keep the current project, requester and explicit delivery choice. */\nfunction createInContext(input: CreateJobInput, ctx: ExtensionContext) {\n\tconst origin = currentOrigin();\n\tconst workdir = origin ? resolveWithinRoots(ctx.cwd, loadGatewayConfig().projectRoots ?? []) : ctx.cwd;\n\treturn createJob({ ...input, workdir, origin: origin ? { ...origin } : null, deliver: input.deliver ?? (origin ? \"origin\" : \"local\") });\n}\n\n/** A TUI owns its current project; it must not silently execute another project's job. */\nfunction requireTuiJobWorkdir(job: CronJob, ctx: ExtensionContext): void {\n\tif (!job.workdir || !isAbsolute(job.workdir))\n\t\tthrow new CronAdmissionDeferred(\"The job has no saved absolute project directory. Recreate it from the intended project before running it in a TUI.\");\n\tlet saved: string;\n\tlet current: string;\n\ttry {\n\t\tsaved = realpathSync(job.workdir);\n\t\tcurrent = realpathSync(ctx.cwd);\n\t} catch {\n\t\tthrow new CronAdmissionDeferred(\"The saved or current project directory is unavailable. Restore it before running this job.\");\n\t}\n\tconst matches = process.platform === \"win32\" ? saved.toLowerCase() === current.toLowerCase() : saved === current;\n\tif (!matches)\n\t\tthrow new CronAdmissionDeferred(\"The job belongs to another project. Run it from a TUI in its saved project, or stop this scheduler so the gateway can own execution.\");\n}\n\n// ---------------------------------------------------------------------------\n// Formatting helpers\n// ---------------------------------------------------------------------------\n\nfunction fmtTime(iso: string | null): string {\n\tif (!iso) return \"-\";\n\tconst d = new Date(iso);\n\tif (Number.isNaN(d.getTime())) return \"-\";\n\tconst p = (n: number) => String(n).padStart(2, \"0\");\n\t// Stored timestamps are UTC ISO; render in local time so users read wall-clock.\n\treturn `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())} ${p(d.getHours())}:${p(d.getMinutes())}`;\n}\n\nfunction formatJobList(): string {\n\tconst jobs = listJobs();\n\tif (jobs.length === 0) return \"No cron jobs. Create one with /cron create <schedule> <prompt>.\";\n\tconst lines = jobs.map(\n\t\t(j) =>\n\t\t\t`${j.id} ${j.state}${j.enabled ? \"\" : \" (disabled)\"} ${j.scheduleDisplay} next=${fmtTime(j.nextRunAt)} last=${j.lastStatus ?? \"-\"}${j.lastError ? ` (${j.lastError})` : \"\"}${j.lastDeliveryError ? ` delivery-error=${j.lastDeliveryError}` : \"\"} ${j.name}`,\n\t);\n\treturn `Cron jobs (${jobs.length}):\\n${lines.join(\"\\n\")}`;\n}\n\nfunction formatStatus(running: boolean): string {\n\tconst jobs = listJobs();\n\tconst count = (s: string) => jobs.filter((j) => j.state === s).length;\n\tconst next = jobs\n\t\t.filter((j) => j.enabled && j.state === \"scheduled\" && j.nextRunAt)\n\t\t.sort((a, b) => String(a.nextRunAt).localeCompare(String(b.nextRunAt)))[0];\n\treturn (\n\t\t`Cron: scheduler ${running ? \"owner\" : \"not owner\"}; ${jobs.length} job(s) — ` +\n\t\t`${count(\"scheduled\")} scheduled, ${count(\"paused\")} paused, ${count(\"completed\")} completed, ${count(\"error\")} error.` +\n\t\t(next ? ` Next: '${next.name}' at ${fmtTime(next.nextRunAt)}.` : \"\")\n\t);\n}\n\n// ---------------------------------------------------------------------------\n// Extension\n// ---------------------------------------------------------------------------\n\nexport default function (pi: ExtensionAPI): void {\n\tlet scheduler: ReturnType<typeof startScheduler> | null = null;\n\tlet lastCtx: ExtensionContext | null = null;\n\tsetCronDeliverValidator((deliver, origin) => createDeliverValidator(loadGatewayConfig())(deliver, origin));\n\n\tconst deliverResult = async (job: CronJob, _content: string): Promise<void> => {\n\t\tif (job.deliver.split(\",\").some((target) => target.trim() !== \"local\")) {\n\t\t\tthrow new Error(\"platform delivery unavailable from this TUI operator; restart scheduling in the gateway after stopping this operator\");\n\t\t}\n\t\tlastCtx?.ui.notify(`Cron job '${job.name}' finished`, \"info\");\n\t};\n\tconst runJob = async (prompt: string, job: CronJob, signal: AbortSignal): Promise<string> => {\n\t\tconst ctx = lastCtx;\n\t\tif (!ctx?.isIdle() || ctx.hasPendingMessages()) throw new CronAdmissionDeferred(\"session is busy\");\n\t\trequireTuiJobWorkdir(job, ctx);\n\t\tif (!ctx.promptWithCompletion) throw new Error(\"owned cron admission unavailable\");\n\t\tbeginCronFire();\n\t\ttry {\n\t\t\tconst result = await ctx.promptWithCompletion(prompt, { source: \"extension\", signal }).catch((error: unknown) => {\n\t\t\t\t// Only the runtime's pre-dispatch admission rejection permits a deferred retry.\n\t\t\t\tif (error instanceof Error && /^Session is busy\\. Retry the scheduled prompt after its work settles\\.$/.test(error.message)) {\n\t\t\t\t\tthrow new CronAdmissionDeferred(error.message);\n\t\t\t\t}\n\t\t\t\tthrow error;\n\t\t\t});\n\t\t\treturn extractAssistantText(result.messages);\n\t\t} finally { endCronFire(); }\n\t};\n\tconst schedulerDeps = { runJob, deliverResult, canRun: () => !!lastCtx?.isIdle() && !lastCtx.hasPendingMessages() };\n\tconst triggerRun = async (job: CronJob, _ctx: ExtensionContext): Promise<string> => {\n\t\tif (!scheduler) throw new Error(\"cron runs require the owning TUI operator; use cron run there, or wait for the gateway schedule\");\n\t\tawait scheduler.run(job.id);\n\t\treturn `Cron job '${job.name}' (${job.id}) finished. Check cron list for run or delivery errors.`;\n\t};\n\tpi.on(\"session_start\", async (_event, ctx) => {\n\t\tlastCtx = ctx;\n\t\tif (ctx.mode !== \"tui\") return;\n\t\tawait scheduler?.stop();\n\t\tscheduler = startScheduler(schedulerDeps);\n\t});\n\tpi.on(\"session_shutdown\", async () => {\n\t\tawait scheduler?.stop();\n\t\tscheduler = null;\n\t});\n\n\t// --- /cron command ---\n\tpi.registerCommand(\"cron\", {\n\t\tdescription: \"Manage cron jobs: /cron list | create <schedule> <prompt> | pause|resume|run|remove|rebind <id-or-name> | status\",\n\t\tgetArgumentCompletions: (prefix: string) => {\n\t\t\tconst subs = [\"list\", \"create\", \"pause\", \"resume\", \"run\", \"remove\", \"status\", \"rebind\"];\n\t\t\tconst lower = prefix.toLowerCase();\n\t\t\treturn subs\n\t\t\t\t.filter((s) => s.startsWith(lower))\n\t\t\t\t.map((s) => ({ value: s, label: s, description: `/cron ${s}` }));\n\t\t},\n\t\thandler: async (args, ctx) => {\n\t\t\tlastCtx = ctx;\n\t\t\tconst tokens = args.trim().split(/\\s+/).filter(Boolean);\n\t\t\tconst sub = (tokens.shift() ?? \"list\").toLowerCase();\n\t\t\ttry {\n\t\t\t\tswitch (sub) {\n\t\t\t\t\tcase \"list\": {\n\t\t\t\t\t\tctx.ui.notify(formatJobList(), \"info\");\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"status\": {\n\t\t\t\t\t\tctx.ui.notify(formatStatus(scheduler?.isOwner() ?? false), \"info\");\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"create\": {\n\t\t\t\t\t\t// Greedy: the schedule is the shortest leading token run that parses.\n\t\t\t\t\t\tlet used = 0;\n\t\t\t\t\t\tfor (let k = 1; k <= Math.min(6, tokens.length); k++) {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tparseSchedule(tokens.slice(0, k).join(\" \"));\n\t\t\t\t\t\t\t\tused = k;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t// keep extending\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst prompt = tokens.slice(used).join(\" \").trim();\n\t\t\t\t\t\tif (!used || !prompt) {\n\t\t\t\t\t\t\tctx.ui.notify(\"Usage: /cron create <schedule> <prompt> — e.g. /cron create every 30m check the deploy\", \"error\");\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst job = await createInContext({ prompt, schedule: tokens.slice(0, used).join(\" \") }, ctx);\n\t\t\t\t\t\tctx.ui.notify(`Created cron job '${job.name}' (${job.id}) — ${job.scheduleDisplay}, next run ${fmtTime(job.nextRunAt)}.`, \"info\");\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"rebind\":\n\t\t\t\t\tcase \"pause\":\n\t\t\t\t\tcase \"resume\":\n\t\t\t\t\tcase \"remove\":\n\t\t\t\t\tcase \"run\": {\n\t\t\t\t\t\tconst idOrName = tokens.join(\" \").trim();\n\t\t\t\t\t\tif (!idOrName) {\n\t\t\t\t\t\t\tctx.ui.notify(`Usage: /cron ${sub} <id-or-name>`, \"error\");\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (sub === \"rebind\") {\n\t\t\t\t\t\t\tconst origin = currentOrigin();\n\t\t\t\t\t\t\tif (!origin?.userId) throw new Error(\"cron rebind requires an approved gateway requester\");\n\t\t\t\t\t\t\tawait updateJob(idOrName, { origin: { ...origin } });\n\t\t\t\t\t\t\tctx.ui.notify(\"Cron requester rebound to this gateway chat.\", \"info\");\n\t\t\t\t\t\t} else if (sub === \"pause\") {\n\t\t\t\t\t\t\tconst job = await pauseJob(idOrName);\n\t\t\t\t\t\t\tctx.ui.notify(`Paused cron job '${job.name}' (${job.id}).`, \"info\");\n\t\t\t\t\t\t} else if (sub === \"resume\") {\n\t\t\t\t\t\t\tconst job = await resumeJob(idOrName);\n\t\t\t\t\t\t\tctx.ui.notify(`Resumed cron job '${job.name}' (${job.id}) — next run ${fmtTime(job.nextRunAt)}.`, \"info\");\n\t\t\t\t\t\t} else if (sub === \"remove\") {\n\t\t\t\t\t\t\tconst job = await removeJob(idOrName);\n\t\t\t\t\t\t\tctx.ui.notify(`Removed cron job '${job.name}' (${job.id}).`, \"info\");\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tconst job = getJob(idOrName);\n\t\t\t\t\t\t\tctx.ui.notify(await triggerRun(job, ctx), \"info\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tdefault: {\n\t\t\t\t\t\tctx.ui.notify(\"Usage: /cron list | create <schedule> <prompt> | pause|resume|run|remove|rebind <id-or-name> | status\", \"error\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\tctx.ui.notify(String((err as Error)?.message ?? err), \"error\");\n\t\t\t}\n\t\t},\n\t});\n\n\t// --- cron tool (agent-facing) ---\n\tpi.registerTool({\n\t\tname: \"cron\",\n\t\tlabel: \"Cron\",\n\t\tdescription: [\n\t\t\t\"Manage profile-wide scheduled jobs. One operator owns execution; busy sessions defer scheduled work.\",\n\t\t\t\"TUI execution requires the job's saved project to match the current project. Recreate jobs without a saved project from the intended project.\",\n\t\t\t\"Actions: create (needs prompt + schedule), list, update (id + fields), pause, resume, remove, run (trigger on the owning TUI operator; otherwise returns an owner error).\",\n\t\t\t\"Schedule formats: 'every 30m' / 'every 2h' / 'every 1d' (recurring), '30m'/'2h' or an ISO timestamp (one-shot), or a 5-field cron expression.\",\n\t\t\t\"Job output is saved locally; platform delivery requires the gateway operator and current grants. Legacy origin jobs need rebind from an approved gateway chat. The prompt can answer [SILENT] to suppress delivery.\",\n\t\t].join(\"\\n\"),\n\t\tparameters: Type.Object({\n\t\t\taction: Type.Union([\n\t\t\t\tType.Literal(\"create\"),\n\t\t\t\tType.Literal(\"list\"),\n\t\t\t\tType.Literal(\"update\"),\n\t\t\t\tType.Literal(\"pause\"),\n\t\t\t\tType.Literal(\"resume\"),\n\t\t\t\tType.Literal(\"remove\"),\n\t\t\t\tType.Literal(\"run\"),\n\t\t\t]),\n\t\t\tid: Type.Optional(Type.String({ description: \"Job id or unique name (all actions except create/list).\" })),\n\t\t\tname: Type.Optional(Type.String({ description: \"Display name (<=50 chars); derived from the prompt when omitted.\" })),\n\t\t\tprompt: Type.Optional(Type.String({ description: \"The prompt the job runs (create/update).\" })),\n\t\t\tschedule: Type.Optional(Type.String({ description: \"Schedule input (create/update).\" })),\n\t\t\tdeliver: Type.Optional(\n\t\t\t\tType.String({\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"Delivery target(s), comma-separated: 'local' (output file only), 'origin' (the chat that created the job), 'telegram'/'discord' (platform home channel), or 'telegram:<chatId>[:<threadId>]' / 'discord:<chatId>[:<threadId>]'. Defaults to 'origin' when created from a gateway chat, else 'local'.\",\n\t\t\t\t}),\n\t\t\t),\n\t\t}),\n\t\tasync execute(_toolCallId, params, _signal, _onUpdate, ctx) {\n\t\t\tconst text = (t: string) => ({ content: [{ type: \"text\" as const, text: t }] });\n\t\t\tif (isCronFire()) {\n\t\t\t\treturn text(\"cron: unavailable while a cron-fired turn is running (cron jobs cannot schedule cron jobs).\");\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tswitch (params.action) {\n\t\t\t\t\tcase \"create\": {\n\t\t\t\t\t\tif (!params.prompt?.trim() || !params.schedule?.trim()) {\n\t\t\t\t\t\t\treturn text(\"cron create: prompt and schedule are required.\");\n\t\t\t\t\t\t}\n const job = await createInContext({ prompt: params.prompt, schedule: params.schedule, name: params.name, deliver: params.deliver }, ctx);\n\t\t\t\t\t\treturn text(`Created cron job '${job.name}' (${job.id}) — ${job.scheduleDisplay}, next run ${fmtTime(job.nextRunAt)}.`);\n\t\t\t\t\t}\n\t\t\t\t\tcase \"list\": {\n\t\t\t\t\t\treturn text(formatJobList());\n\t\t\t\t\t}\n\t\t\t\t\tcase \"update\": {\n\t\t\t\t\t\tif (!params.id) return text(\"cron update: id (or unique name) is required.\");\n\t\t\t\t\t\tconst job = await updateJob(params.id, {\n\t\t\t\t\t\t\tname: params.name,\n\t\t\t\t\t\t\tprompt: params.prompt,\n\t\t\t\t\t\t\tschedule: params.schedule,\n\t\t\t\t\t\t\tdeliver: params.deliver,\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn text(`Updated cron job '${job.name}' (${job.id}) — ${job.scheduleDisplay}, next run ${fmtTime(job.nextRunAt)}.`);\n\t\t\t\t\t}\n\t\t\t\t\tcase \"pause\": {\n\t\t\t\t\t\tif (!params.id) return text(\"cron pause: id (or unique name) is required.\");\n\t\t\t\t\t\tconst job = await pauseJob(params.id);\n\t\t\t\t\t\treturn text(`Paused cron job '${job.name}' (${job.id}).`);\n\t\t\t\t\t}\n\t\t\t\t\tcase \"resume\": {\n\t\t\t\t\t\tif (!params.id) return text(\"cron resume: id (or unique name) is required.\");\n\t\t\t\t\t\tconst job = await resumeJob(params.id);\n\t\t\t\t\t\treturn text(`Resumed cron job '${job.name}' (${job.id}) — next run ${fmtTime(job.nextRunAt)}.`);\n\t\t\t\t\t}\n\t\t\t\t\tcase \"remove\": {\n\t\t\t\t\t\tif (!params.id) return text(\"cron remove: id (or unique name) is required.\");\n\t\t\t\t\t\tconst job = await removeJob(params.id);\n\t\t\t\t\t\treturn text(`Removed cron job '${job.name}' (${job.id}).`);\n\t\t\t\t\t}\n\t\t\t\t\tcase \"run\": {\n\t\t\t\t\t\tif (!params.id) return text(\"cron run: id (or unique name) is required.\");\n\t\t\t\t\t\tconst job = getJob(params.id);\n\t\t\t\t\t\treturn text(await triggerRun(job, ctx));\n\t\t\t\t\t}\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn text(`cron: unknown action \"${String(params.action)}\".`);\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\treturn text(`cron: ${String((err as Error)?.message ?? err)}`);\n\t\t\t}\n\t\t},\n\t});\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"local-servers.d.ts","sourceRoot":"","sources":["../../../src/builtin-extensions/lunr-local-providers/local-servers.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAE3E,MAAM,WAAW,eAAe;IAC/B,4DAA4D;IAC5D,UAAU,EAAE,MAAM,CAAC;IACnB,+CAA+C;IAC/C,WAAW,EAAE,MAAM,CAAC;IACpB,sDAAsD;IACtD,WAAW,EAAE,MAAM,CAAC;IACpB,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,+DAA+D;IAC/D,OAAO,EAAE,MAAM,CAAC;IAChB,gEAAgE;IAChE,SAAS,EAAE,MAAM,CAAC;IAClB,sEAAsE;IACtE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,8DAA8D;IAC9D,QAAQ,EAAE,MAAM,CAAC;CACjB;AAOD,eAAO,MAAM,YAAY,EAAE,eAS1B,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,eAQvB,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,SAAS,eAAe,EAA8B,CAAC;AAEnF;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,EAAE,CA+B1D;AAuBD;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACvC,IAAI,EAAE,eAAe,EACrB,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,WAAW,GAClB,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAQ1B;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,mBAAmB,CAU7D","sourcesContent":["/**\n * Local model server discovery for lunR (Ollama, LM Studio).\n *\n * Pure functions with no runtime imports so the probing and response\n * normalization can be harness-tested directly against a mock HTTP server.\n * The extension factory lives in index.ts.\n */\n\nimport type { ProviderModelConfig } from \"@ashx-j/lunr\";\n\nexport interface LocalServerSpec {\n\t/** Provider id used for registration and auth.json keys. */\n\tproviderId: string;\n\t/** Display name shown in /login and /model. */\n\tdisplayName: string;\n\t/** Bare product name used in probe/login messages. */\n\tproductName: string;\n\t/** localhost port, for failure messages. */\n\tport: number;\n\t/** OpenAI-compatible base URL registered with the provider. */\n\tbaseUrl: string;\n\t/** OpenAI-style model listing endpoint ({ data: [{ id }] }). */\n\tmodelsUrl: string;\n\t/** Ollama-only fallback listing endpoint ({ models: [{ name }] }). */\n\ttagsUrl?: string;\n\t/** Dummy credential value; local servers need no real key. */\n\tdummyKey: string;\n}\n\n// Use IPv4 loopback. `localhost` can prefer ::1 and hang on Windows when the\n// server only listens on 127.0.0.1.\nconst OLLAMA_ORIGIN = \"http://127.0.0.1:11434\";\nconst LM_STUDIO_ORIGIN = \"http://127.0.0.1:1234\";\n\nexport const OLLAMA_LOCAL: LocalServerSpec = {\n\tproviderId: \"ollama-local\",\n\tdisplayName: \"Ollama (local)\",\n\tproductName: \"Ollama\",\n\tport: 11434,\n\tbaseUrl: `${OLLAMA_ORIGIN}/v1`,\n\tmodelsUrl: `${OLLAMA_ORIGIN}/v1/models`,\n\ttagsUrl: `${OLLAMA_ORIGIN}/api/tags`,\n\tdummyKey: \"ollama\",\n};\n\nexport const LM_STUDIO: LocalServerSpec = {\n\tproviderId: \"lm-studio\",\n\tdisplayName: \"LM Studio (local)\",\n\tproductName: \"LM Studio\",\n\tport: 1234,\n\tbaseUrl: `${LM_STUDIO_ORIGIN}/v1`,\n\tmodelsUrl: `${LM_STUDIO_ORIGIN}/v1/models`,\n\tdummyKey: \"local\",\n};\n\nexport const LOCAL_SERVERS: readonly LocalServerSpec[] = [OLLAMA_LOCAL, LM_STUDIO];\n\n/**\n * Normalize the two known listing shapes into a deduped id list:\n * - OpenAI style `{ data: [{ id, ... }] }` (Ollama /v1/models, LM Studio)\n * - Ollama /api/tags `{ models: [{ name, ... }] }`\n * Bare string arrays and `id`/`name`/`model` entry fields are tolerated.\n */\nexport function extractModelIds(payload: unknown): string[] {\n\tconst ids: string[] = [];\n\tconst push = (value: unknown): void => {\n\t\tif (typeof value === \"string\" && value.length > 0 && !ids.includes(value)) {\n\t\t\tids.push(value);\n\t\t}\n\t};\n\tconst fromEntry = (entry: unknown): void => {\n\t\tif (typeof entry === \"string\") {\n\t\t\tpush(entry);\n\t\t\treturn;\n\t\t}\n\t\tif (entry !== null && typeof entry === \"object\") {\n\t\t\tconst record = entry as Record<string, unknown>;\n\t\t\tpush(record.id ?? record.name ?? record.model);\n\t\t}\n\t};\n\tif (Array.isArray(payload)) {\n\t\tfor (const entry of payload) fromEntry(entry);\n\t\treturn ids;\n\t}\n\tif (payload !== null && typeof payload === \"object\") {\n\t\tconst record = payload as Record<string, unknown>;\n\t\tif (Array.isArray(record.data)) {\n\t\t\tfor (const entry of record.data) fromEntry(entry);\n\t\t}\n\t\tif (Array.isArray(record.models)) {\n\t\t\tfor (const entry of record.models) fromEntry(entry);\n\t\t}\n\t}\n\treturn ids;\n}\n\n/** Fetch JSON with a hard timeout; null on any network/HTTP/parse failure. Never throws. */\nasync function fetchJson(url: string, timeoutMs: number, signal?: AbortSignal): Promise<unknown | null> {\n\tconst controller = new AbortController();\n\tconst timer = setTimeout(() => controller.abort(), timeoutMs);\n\tconst onAbort = (): void => controller.abort();\n\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\n\ttry {\n\t\tconst response = await fetch(url, {\n\t\t\theaders: { accept: \"application/json\" },\n\t\t\tsignal: controller.signal,\n\t\t});\n\t\tif (!response.ok) return null;\n\t\treturn (await response.json()) as unknown;\n\t} catch {\n\t\treturn null;\n\t} finally {\n\t\tclearTimeout(timer);\n\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t}\n}\n\n/**\n * Probe a local server for its model list.\n * Returns a (possibly empty) id list when the server responded, or null when\n * nothing usable answered — unreachable port, non-JSON, or error status on\n * every known endpoint. Never throws; worst-case delay is ~timeoutMs per\n * endpoint.\n */\nexport async function fetchLocalModelIds(\n\tspec: LocalServerSpec,\n\ttimeoutMs: number,\n\tsignal?: AbortSignal,\n): Promise<string[] | null> {\n\tconst payload = await fetchJson(spec.modelsUrl, timeoutMs, signal);\n\tif (payload !== null) return extractModelIds(payload);\n\tif (spec.tagsUrl) {\n\t\tconst fallback = await fetchJson(spec.tagsUrl, timeoutMs, signal);\n\t\tif (fallback !== null) return extractModelIds(fallback);\n\t}\n\treturn null;\n}\n\n/**\n * ProviderModelConfig defaults for local models: 32k context, zero cost,\n * text-only. Local servers do not advertise per-model limits, so these are\n * conservative fixed values.\n */\nexport function toModelConfig(id: string): ProviderModelConfig {\n\treturn {\n\t\tid,\n\t\tname: id,\n\t\treasoning: false,\n\t\tinput: [\"text\"],\n\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },\n\t\tcontextWindow: 32768,\n\t\tmaxTokens: 8192,\n\t};\n}\n"]}
1
+ {"version":3,"file":"local-servers.d.ts","sourceRoot":"","sources":["../../../src/builtin-extensions/lunr-local-providers/local-servers.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAE3E,MAAM,WAAW,eAAe;IAC/B,4DAA4D;IAC5D,UAAU,EAAE,MAAM,CAAC;IACnB,+CAA+C;IAC/C,WAAW,EAAE,MAAM,CAAC;IACpB,sDAAsD;IACtD,WAAW,EAAE,MAAM,CAAC;IACpB,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,+DAA+D;IAC/D,OAAO,EAAE,MAAM,CAAC;IAChB,gEAAgE;IAChE,SAAS,EAAE,MAAM,CAAC;IAClB,sEAAsE;IACtE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,8DAA8D;IAC9D,QAAQ,EAAE,MAAM,CAAC;CACjB;AAOD,eAAO,MAAM,YAAY,EAAE,eAS1B,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,eAQvB,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,SAAS,eAAe,EAA8B,CAAC;AAEnF;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,EAAE,CA+B1D;AAwBD;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACvC,IAAI,EAAE,eAAe,EACrB,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,WAAW,GAClB,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAQ1B;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,mBAAmB,CAU7D","sourcesContent":["/**\n * Local model server discovery for lunR (Ollama, LM Studio).\n *\n * Pure functions with no runtime imports so the probing and response\n * normalization can be harness-tested directly against a mock HTTP server.\n * The extension factory lives in index.ts.\n */\n\nimport type { ProviderModelConfig } from \"@ashx-j/lunr\";\n\nexport interface LocalServerSpec {\n\t/** Provider id used for registration and auth.json keys. */\n\tproviderId: string;\n\t/** Display name shown in /login and /model. */\n\tdisplayName: string;\n\t/** Bare product name used in probe/login messages. */\n\tproductName: string;\n\t/** localhost port, for failure messages. */\n\tport: number;\n\t/** OpenAI-compatible base URL registered with the provider. */\n\tbaseUrl: string;\n\t/** OpenAI-style model listing endpoint ({ data: [{ id }] }). */\n\tmodelsUrl: string;\n\t/** Ollama-only fallback listing endpoint ({ models: [{ name }] }). */\n\ttagsUrl?: string;\n\t/** Dummy credential value; local servers need no real key. */\n\tdummyKey: string;\n}\n\n// Use IPv4 loopback. `localhost` can prefer ::1 and hang on Windows when the\n// server only listens on 127.0.0.1.\nconst OLLAMA_ORIGIN = \"http://127.0.0.1:11434\";\nconst LM_STUDIO_ORIGIN = \"http://127.0.0.1:1234\";\n\nexport const OLLAMA_LOCAL: LocalServerSpec = {\n\tproviderId: \"ollama-local\",\n\tdisplayName: \"Ollama (local)\",\n\tproductName: \"Ollama\",\n\tport: 11434,\n\tbaseUrl: `${OLLAMA_ORIGIN}/v1`,\n\tmodelsUrl: `${OLLAMA_ORIGIN}/v1/models`,\n\ttagsUrl: `${OLLAMA_ORIGIN}/api/tags`,\n\tdummyKey: \"ollama\",\n};\n\nexport const LM_STUDIO: LocalServerSpec = {\n\tproviderId: \"lm-studio\",\n\tdisplayName: \"LM Studio (local)\",\n\tproductName: \"LM Studio\",\n\tport: 1234,\n\tbaseUrl: `${LM_STUDIO_ORIGIN}/v1`,\n\tmodelsUrl: `${LM_STUDIO_ORIGIN}/v1/models`,\n\tdummyKey: \"local\",\n};\n\nexport const LOCAL_SERVERS: readonly LocalServerSpec[] = [OLLAMA_LOCAL, LM_STUDIO];\n\n/**\n * Normalize the two known listing shapes into a deduped id list:\n * - OpenAI style `{ data: [{ id, ... }] }` (Ollama /v1/models, LM Studio)\n * - Ollama /api/tags `{ models: [{ name, ... }] }`\n * Bare string arrays and `id`/`name`/`model` entry fields are tolerated.\n */\nexport function extractModelIds(payload: unknown): string[] {\n\tconst ids: string[] = [];\n\tconst push = (value: unknown): void => {\n\t\tif (typeof value === \"string\" && value.length > 0 && !ids.includes(value)) {\n\t\t\tids.push(value);\n\t\t}\n\t};\n\tconst fromEntry = (entry: unknown): void => {\n\t\tif (typeof entry === \"string\") {\n\t\t\tpush(entry);\n\t\t\treturn;\n\t\t}\n\t\tif (entry !== null && typeof entry === \"object\") {\n\t\t\tconst record = entry as Record<string, unknown>;\n\t\t\tpush(record.id ?? record.name ?? record.model);\n\t\t}\n\t};\n\tif (Array.isArray(payload)) {\n\t\tfor (const entry of payload) fromEntry(entry);\n\t\treturn ids;\n\t}\n\tif (payload !== null && typeof payload === \"object\") {\n\t\tconst record = payload as Record<string, unknown>;\n\t\tif (Array.isArray(record.data)) {\n\t\t\tfor (const entry of record.data) fromEntry(entry);\n\t\t}\n\t\tif (Array.isArray(record.models)) {\n\t\t\tfor (const entry of record.models) fromEntry(entry);\n\t\t}\n\t}\n\treturn ids;\n}\n\n/** Fetch JSON with a hard timeout; null on any network/HTTP/parse failure. Never throws. */\nasync function fetchJson(url: string, timeoutMs: number, signal?: AbortSignal): Promise<unknown | null> {\n\tif (signal?.aborted) return null;\n\tconst controller = new AbortController();\n\tconst timer = setTimeout(() => controller.abort(), timeoutMs);\n\tconst onAbort = (): void => controller.abort();\n\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\n\ttry {\n\t\tconst response = await fetch(url, {\n\t\t\theaders: { accept: \"application/json\" },\n\t\t\tsignal: controller.signal,\n\t\t});\n\t\tif (!response.ok) return null;\n\t\treturn (await response.json()) as unknown;\n\t} catch {\n\t\treturn null;\n\t} finally {\n\t\tclearTimeout(timer);\n\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t}\n}\n\n/**\n * Probe a local server for its model list.\n * Returns a (possibly empty) id list when the server responded, or null when\n * nothing usable answered — unreachable port, non-JSON, or error status on\n * every known endpoint. Never throws; worst-case delay is ~timeoutMs per\n * endpoint.\n */\nexport async function fetchLocalModelIds(\n\tspec: LocalServerSpec,\n\ttimeoutMs: number,\n\tsignal?: AbortSignal,\n): Promise<string[] | null> {\n\tconst payload = await fetchJson(spec.modelsUrl, timeoutMs, signal);\n\tif (payload !== null) return extractModelIds(payload);\n\tif (spec.tagsUrl && !signal?.aborted) {\n\t\tconst fallback = await fetchJson(spec.tagsUrl, timeoutMs, signal);\n\t\tif (fallback !== null) return extractModelIds(fallback);\n\t}\n\treturn null;\n}\n\n/**\n * ProviderModelConfig defaults for local models: 32k context, zero cost,\n * text-only. Local servers do not advertise per-model limits, so these are\n * conservative fixed values.\n */\nexport function toModelConfig(id: string): ProviderModelConfig {\n\treturn {\n\t\tid,\n\t\tname: id,\n\t\treasoning: false,\n\t\tinput: [\"text\"],\n\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },\n\t\tcontextWindow: 32768,\n\t\tmaxTokens: 8192,\n\t};\n}\n"]}
@@ -72,6 +72,8 @@ export function extractModelIds(payload) {
72
72
  }
73
73
  /** Fetch JSON with a hard timeout; null on any network/HTTP/parse failure. Never throws. */
74
74
  async function fetchJson(url, timeoutMs, signal) {
75
+ if (signal?.aborted)
76
+ return null;
75
77
  const controller = new AbortController();
76
78
  const timer = setTimeout(() => controller.abort(), timeoutMs);
77
79
  const onAbort = () => controller.abort();
@@ -104,7 +106,7 @@ export async function fetchLocalModelIds(spec, timeoutMs, signal) {
104
106
  const payload = await fetchJson(spec.modelsUrl, timeoutMs, signal);
105
107
  if (payload !== null)
106
108
  return extractModelIds(payload);
107
- if (spec.tagsUrl) {
109
+ if (spec.tagsUrl && !signal?.aborted) {
108
110
  const fallback = await fetchJson(spec.tagsUrl, timeoutMs, signal);
109
111
  if (fallback !== null)
110
112
  return extractModelIds(fallback);
@@ -1 +1 @@
1
- {"version":3,"file":"local-servers.js","sourceRoot":"","sources":["../../../src/builtin-extensions/lunr-local-providers/local-servers.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Local model server discovery for lunR (Ollama, LM Studio).\n *\n * Pure functions with no runtime imports so the probing and response\n * normalization can be harness-tested directly against a mock HTTP server.\n * The extension factory lives in index.ts.\n */\n\nimport type { ProviderModelConfig } from \"@ashx-j/lunr\";\n\nexport interface LocalServerSpec {\n\t/** Provider id used for registration and auth.json keys. */\n\tproviderId: string;\n\t/** Display name shown in /login and /model. */\n\tdisplayName: string;\n\t/** Bare product name used in probe/login messages. */\n\tproductName: string;\n\t/** localhost port, for failure messages. */\n\tport: number;\n\t/** OpenAI-compatible base URL registered with the provider. */\n\tbaseUrl: string;\n\t/** OpenAI-style model listing endpoint ({ data: [{ id }] }). */\n\tmodelsUrl: string;\n\t/** Ollama-only fallback listing endpoint ({ models: [{ name }] }). */\n\ttagsUrl?: string;\n\t/** Dummy credential value; local servers need no real key. */\n\tdummyKey: string;\n}\n\n// Use IPv4 loopback. `localhost` can prefer ::1 and hang on Windows when the\n// server only listens on 127.0.0.1.\nconst OLLAMA_ORIGIN = \"http://127.0.0.1:11434\";\nconst LM_STUDIO_ORIGIN = \"http://127.0.0.1:1234\";\n\nexport const OLLAMA_LOCAL: LocalServerSpec = {\n\tproviderId: \"ollama-local\",\n\tdisplayName: \"Ollama (local)\",\n\tproductName: \"Ollama\",\n\tport: 11434,\n\tbaseUrl: `${OLLAMA_ORIGIN}/v1`,\n\tmodelsUrl: `${OLLAMA_ORIGIN}/v1/models`,\n\ttagsUrl: `${OLLAMA_ORIGIN}/api/tags`,\n\tdummyKey: \"ollama\",\n};\n\nexport const LM_STUDIO: LocalServerSpec = {\n\tproviderId: \"lm-studio\",\n\tdisplayName: \"LM Studio (local)\",\n\tproductName: \"LM Studio\",\n\tport: 1234,\n\tbaseUrl: `${LM_STUDIO_ORIGIN}/v1`,\n\tmodelsUrl: `${LM_STUDIO_ORIGIN}/v1/models`,\n\tdummyKey: \"local\",\n};\n\nexport const LOCAL_SERVERS: readonly LocalServerSpec[] = [OLLAMA_LOCAL, LM_STUDIO];\n\n/**\n * Normalize the two known listing shapes into a deduped id list:\n * - OpenAI style `{ data: [{ id, ... }] }` (Ollama /v1/models, LM Studio)\n * - Ollama /api/tags `{ models: [{ name, ... }] }`\n * Bare string arrays and `id`/`name`/`model` entry fields are tolerated.\n */\nexport function extractModelIds(payload: unknown): string[] {\n\tconst ids: string[] = [];\n\tconst push = (value: unknown): void => {\n\t\tif (typeof value === \"string\" && value.length > 0 && !ids.includes(value)) {\n\t\t\tids.push(value);\n\t\t}\n\t};\n\tconst fromEntry = (entry: unknown): void => {\n\t\tif (typeof entry === \"string\") {\n\t\t\tpush(entry);\n\t\t\treturn;\n\t\t}\n\t\tif (entry !== null && typeof entry === \"object\") {\n\t\t\tconst record = entry as Record<string, unknown>;\n\t\t\tpush(record.id ?? record.name ?? record.model);\n\t\t}\n\t};\n\tif (Array.isArray(payload)) {\n\t\tfor (const entry of payload) fromEntry(entry);\n\t\treturn ids;\n\t}\n\tif (payload !== null && typeof payload === \"object\") {\n\t\tconst record = payload as Record<string, unknown>;\n\t\tif (Array.isArray(record.data)) {\n\t\t\tfor (const entry of record.data) fromEntry(entry);\n\t\t}\n\t\tif (Array.isArray(record.models)) {\n\t\t\tfor (const entry of record.models) fromEntry(entry);\n\t\t}\n\t}\n\treturn ids;\n}\n\n/** Fetch JSON with a hard timeout; null on any network/HTTP/parse failure. Never throws. */\nasync function fetchJson(url: string, timeoutMs: number, signal?: AbortSignal): Promise<unknown | null> {\n\tconst controller = new AbortController();\n\tconst timer = setTimeout(() => controller.abort(), timeoutMs);\n\tconst onAbort = (): void => controller.abort();\n\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\n\ttry {\n\t\tconst response = await fetch(url, {\n\t\t\theaders: { accept: \"application/json\" },\n\t\t\tsignal: controller.signal,\n\t\t});\n\t\tif (!response.ok) return null;\n\t\treturn (await response.json()) as unknown;\n\t} catch {\n\t\treturn null;\n\t} finally {\n\t\tclearTimeout(timer);\n\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t}\n}\n\n/**\n * Probe a local server for its model list.\n * Returns a (possibly empty) id list when the server responded, or null when\n * nothing usable answered — unreachable port, non-JSON, or error status on\n * every known endpoint. Never throws; worst-case delay is ~timeoutMs per\n * endpoint.\n */\nexport async function fetchLocalModelIds(\n\tspec: LocalServerSpec,\n\ttimeoutMs: number,\n\tsignal?: AbortSignal,\n): Promise<string[] | null> {\n\tconst payload = await fetchJson(spec.modelsUrl, timeoutMs, signal);\n\tif (payload !== null) return extractModelIds(payload);\n\tif (spec.tagsUrl) {\n\t\tconst fallback = await fetchJson(spec.tagsUrl, timeoutMs, signal);\n\t\tif (fallback !== null) return extractModelIds(fallback);\n\t}\n\treturn null;\n}\n\n/**\n * ProviderModelConfig defaults for local models: 32k context, zero cost,\n * text-only. Local servers do not advertise per-model limits, so these are\n * conservative fixed values.\n */\nexport function toModelConfig(id: string): ProviderModelConfig {\n\treturn {\n\t\tid,\n\t\tname: id,\n\t\treasoning: false,\n\t\tinput: [\"text\"],\n\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },\n\t\tcontextWindow: 32768,\n\t\tmaxTokens: 8192,\n\t};\n}\n"]}
1
+ {"version":3,"file":"local-servers.js","sourceRoot":"","sources":["../../../src/builtin-extensions/lunr-local-providers/local-servers.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Local model server discovery for lunR (Ollama, LM Studio).\n *\n * Pure functions with no runtime imports so the probing and response\n * normalization can be harness-tested directly against a mock HTTP server.\n * The extension factory lives in index.ts.\n */\n\nimport type { ProviderModelConfig } from \"@ashx-j/lunr\";\n\nexport interface LocalServerSpec {\n\t/** Provider id used for registration and auth.json keys. */\n\tproviderId: string;\n\t/** Display name shown in /login and /model. */\n\tdisplayName: string;\n\t/** Bare product name used in probe/login messages. */\n\tproductName: string;\n\t/** localhost port, for failure messages. */\n\tport: number;\n\t/** OpenAI-compatible base URL registered with the provider. */\n\tbaseUrl: string;\n\t/** OpenAI-style model listing endpoint ({ data: [{ id }] }). */\n\tmodelsUrl: string;\n\t/** Ollama-only fallback listing endpoint ({ models: [{ name }] }). */\n\ttagsUrl?: string;\n\t/** Dummy credential value; local servers need no real key. */\n\tdummyKey: string;\n}\n\n// Use IPv4 loopback. `localhost` can prefer ::1 and hang on Windows when the\n// server only listens on 127.0.0.1.\nconst OLLAMA_ORIGIN = \"http://127.0.0.1:11434\";\nconst LM_STUDIO_ORIGIN = \"http://127.0.0.1:1234\";\n\nexport const OLLAMA_LOCAL: LocalServerSpec = {\n\tproviderId: \"ollama-local\",\n\tdisplayName: \"Ollama (local)\",\n\tproductName: \"Ollama\",\n\tport: 11434,\n\tbaseUrl: `${OLLAMA_ORIGIN}/v1`,\n\tmodelsUrl: `${OLLAMA_ORIGIN}/v1/models`,\n\ttagsUrl: `${OLLAMA_ORIGIN}/api/tags`,\n\tdummyKey: \"ollama\",\n};\n\nexport const LM_STUDIO: LocalServerSpec = {\n\tproviderId: \"lm-studio\",\n\tdisplayName: \"LM Studio (local)\",\n\tproductName: \"LM Studio\",\n\tport: 1234,\n\tbaseUrl: `${LM_STUDIO_ORIGIN}/v1`,\n\tmodelsUrl: `${LM_STUDIO_ORIGIN}/v1/models`,\n\tdummyKey: \"local\",\n};\n\nexport const LOCAL_SERVERS: readonly LocalServerSpec[] = [OLLAMA_LOCAL, LM_STUDIO];\n\n/**\n * Normalize the two known listing shapes into a deduped id list:\n * - OpenAI style `{ data: [{ id, ... }] }` (Ollama /v1/models, LM Studio)\n * - Ollama /api/tags `{ models: [{ name, ... }] }`\n * Bare string arrays and `id`/`name`/`model` entry fields are tolerated.\n */\nexport function extractModelIds(payload: unknown): string[] {\n\tconst ids: string[] = [];\n\tconst push = (value: unknown): void => {\n\t\tif (typeof value === \"string\" && value.length > 0 && !ids.includes(value)) {\n\t\t\tids.push(value);\n\t\t}\n\t};\n\tconst fromEntry = (entry: unknown): void => {\n\t\tif (typeof entry === \"string\") {\n\t\t\tpush(entry);\n\t\t\treturn;\n\t\t}\n\t\tif (entry !== null && typeof entry === \"object\") {\n\t\t\tconst record = entry as Record<string, unknown>;\n\t\t\tpush(record.id ?? record.name ?? record.model);\n\t\t}\n\t};\n\tif (Array.isArray(payload)) {\n\t\tfor (const entry of payload) fromEntry(entry);\n\t\treturn ids;\n\t}\n\tif (payload !== null && typeof payload === \"object\") {\n\t\tconst record = payload as Record<string, unknown>;\n\t\tif (Array.isArray(record.data)) {\n\t\t\tfor (const entry of record.data) fromEntry(entry);\n\t\t}\n\t\tif (Array.isArray(record.models)) {\n\t\t\tfor (const entry of record.models) fromEntry(entry);\n\t\t}\n\t}\n\treturn ids;\n}\n\n/** Fetch JSON with a hard timeout; null on any network/HTTP/parse failure. Never throws. */\nasync function fetchJson(url: string, timeoutMs: number, signal?: AbortSignal): Promise<unknown | null> {\n\tif (signal?.aborted) return null;\n\tconst controller = new AbortController();\n\tconst timer = setTimeout(() => controller.abort(), timeoutMs);\n\tconst onAbort = (): void => controller.abort();\n\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\n\ttry {\n\t\tconst response = await fetch(url, {\n\t\t\theaders: { accept: \"application/json\" },\n\t\t\tsignal: controller.signal,\n\t\t});\n\t\tif (!response.ok) return null;\n\t\treturn (await response.json()) as unknown;\n\t} catch {\n\t\treturn null;\n\t} finally {\n\t\tclearTimeout(timer);\n\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t}\n}\n\n/**\n * Probe a local server for its model list.\n * Returns a (possibly empty) id list when the server responded, or null when\n * nothing usable answered — unreachable port, non-JSON, or error status on\n * every known endpoint. Never throws; worst-case delay is ~timeoutMs per\n * endpoint.\n */\nexport async function fetchLocalModelIds(\n\tspec: LocalServerSpec,\n\ttimeoutMs: number,\n\tsignal?: AbortSignal,\n): Promise<string[] | null> {\n\tconst payload = await fetchJson(spec.modelsUrl, timeoutMs, signal);\n\tif (payload !== null) return extractModelIds(payload);\n\tif (spec.tagsUrl && !signal?.aborted) {\n\t\tconst fallback = await fetchJson(spec.tagsUrl, timeoutMs, signal);\n\t\tif (fallback !== null) return extractModelIds(fallback);\n\t}\n\treturn null;\n}\n\n/**\n * ProviderModelConfig defaults for local models: 32k context, zero cost,\n * text-only. Local servers do not advertise per-model limits, so these are\n * conservative fixed values.\n */\nexport function toModelConfig(id: string): ProviderModelConfig {\n\treturn {\n\t\tid,\n\t\tname: id,\n\t\treasoning: false,\n\t\tinput: [\"text\"],\n\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },\n\t\tcontextWindow: 32768,\n\t\tmaxTokens: 8192,\n\t};\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"accounting.d.ts","sourceRoot":"","sources":["../../../../src/builtin-extensions/narumiruna-pi-goal/src/accounting.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,mBAAmB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;CAClB;AAOD,UAAU,YAAY;IACrB,cAAc,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,wBAAgB,wBAAwB,CACvC,IAAI,EAAE,mBAAmB,EACzB,GAAG,EAAE,MAAM,EACX,aAAa,EAAE,OAAO,QAUtB;AAED,wBAAgB,eAAe,CAC9B,IAAI,EAAE,mBAAmB,EACzB,GAAG,EAAE,YAAY,EACjB,aAAa,UAA2B,QAQxC;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,UAO7C;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,UAM7C;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAEzE;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,UAErD;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,sBAIlD;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,UAWlD;AAED,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,OAAO,EAAE,UAU3D;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,CAG3D","sourcesContent":["// @ts-nocheck\nimport type { Usage } from \"@ashx-j/lunr-ai\";\n\nexport interface GoalAccountingState {\n\tstatus: string;\n\tbaselineTokens: number;\n\ttokensUsed: number;\n\ttimeUsedSeconds: number;\n\tactiveStartedAt?: number;\n\tupdatedAt: number;\n}\n\ninterface AssistantUsageEntryLike {\n\ttype?: unknown;\n\tmessage?: unknown;\n}\n\ninterface UsageContext {\n\tsessionManager?: unknown;\n}\n\nexport function checkpointGoalActiveTime(\n\tgoal: GoalAccountingState,\n\tnow: number,\n\tcontinueClock: boolean,\n) {\n\tconst accumulated = nonNegativeFiniteNumber(goal.timeUsedSeconds);\n\tconst startedAt = goal.activeStartedAt;\n\tif (typeof startedAt === \"number\" && Number.isFinite(startedAt)) {\n\t\tgoal.timeUsedSeconds = accumulated + Math.max(0, now - startedAt) / 1000;\n\t} else {\n\t\tgoal.timeUsedSeconds = accumulated;\n\t}\n\tgoal.activeStartedAt = continueClock ? now : undefined;\n}\n\nexport function updateGoalUsage(\n\tgoal: GoalAccountingState,\n\tctx: UsageContext,\n\tcontinueClock = goal.status === \"active\",\n) {\n\tconst now = Date.now();\n\tconst baselineTokens = nonNegativeFiniteNumber(goal.baselineTokens);\n\tgoal.baselineTokens = baselineTokens;\n\tgoal.tokensUsed = Math.max(0, currentTokenTotal(ctx) - baselineTokens);\n\tcheckpointGoalActiveTime(goal, now, continueClock);\n\tgoal.updatedAt = now;\n}\n\nexport function formatDuration(seconds: number) {\n\tconst wholeSeconds = Math.max(0, Math.floor(nonNegativeFiniteNumber(seconds)));\n\tif (wholeSeconds < 60) return `${wholeSeconds}s`;\n\tconst minutes = Math.floor(wholeSeconds / 60);\n\tif (minutes < 60) return `${minutes}m`;\n\tconst hours = Math.floor(minutes / 60);\n\treturn `${hours}h${minutes % 60}m`;\n}\n\nexport function formatTokenCount(value: number) {\n\tif (value < 1_000) return `${value}`;\n\tif (value < 1_000_000) {\n\t\treturn `${Number.isInteger(value / 1_000) ? value / 1_000 : (value / 1_000).toFixed(1)}k`;\n\t}\n\treturn `${Number.isInteger(value / 1_000_000) ? value / 1_000_000 : (value / 1_000_000).toFixed(1)}m`;\n}\n\nexport function isNonNegativeFiniteNumber(value: unknown): value is number {\n\treturn typeof value === \"number\" && Number.isFinite(value) && value >= 0;\n}\n\nexport function nonNegativeFiniteNumber(value: unknown) {\n\treturn isNonNegativeFiniteNumber(value) ? value : 0;\n}\n\nexport function normalizeTokenBudget(value: unknown) {\n\treturn typeof value === \"number\" && Number.isSafeInteger(value) && value > 0\n\t\t? value\n\t\t: undefined;\n}\n\nexport function assistantUsageTokens(value: unknown) {\n\tif (!value || typeof value !== \"object\") return 0;\n\tconst usage = value as Partial<Usage>;\n\tif (isNonNegativeFiniteNumber(usage.totalTokens)) return usage.totalTokens;\n\treturn Math.min(\n\t\tNumber.MAX_SAFE_INTEGER,\n\t\tnonNegativeFiniteNumber(usage.input) +\n\t\t\tnonNegativeFiniteNumber(usage.output) +\n\t\t\tnonNegativeFiniteNumber(usage.cacheRead) +\n\t\t\tnonNegativeFiniteNumber(usage.cacheWrite),\n\t);\n}\n\nexport function cumulativeAssistantTokens(entries: unknown[]) {\n\tlet total = 0;\n\tfor (const entry of entries) {\n\t\tconst candidate = entry as AssistantUsageEntryLike;\n\t\tif (candidate?.type !== \"message\") continue;\n\t\tconst message = candidate.message as { role?: unknown; usage?: unknown } | undefined;\n\t\tif (message?.role !== \"assistant\") continue;\n\t\ttotal = Math.min(Number.MAX_SAFE_INTEGER, total + assistantUsageTokens(message.usage));\n\t}\n\treturn total;\n}\n\nexport function currentTokenTotal(ctx: UsageContext): number {\n\tconst sessionManager = ctx.sessionManager as { getBranch?: () => unknown[] } | undefined;\n\treturn cumulativeAssistantTokens(sessionManager?.getBranch?.() ?? []);\n}\n"]}
1
+ {"version":3,"file":"accounting.d.ts","sourceRoot":"","sources":["../../../../src/builtin-extensions/narumiruna-pi-goal/src/accounting.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,mBAAmB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;CAClB;AAOD,UAAU,YAAY;IACrB,cAAc,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,wBAAgB,wBAAwB,CACvC,IAAI,EAAE,mBAAmB,EACzB,GAAG,EAAE,MAAM,EACX,aAAa,EAAE,OAAO,QAUtB;AAED,wBAAgB,eAAe,CAC9B,IAAI,EAAE,mBAAmB,EACzB,GAAG,EAAE,YAAY,EACjB,aAAa,UAA2B,QAQxC;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,UAO7C;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,UAM7C;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAEzE;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,UAErD;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,sBAIlD;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,UAWlD;AAED,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,OAAO,EAAE,UAU3D;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,CAI3D","sourcesContent":["// @ts-nocheck\nimport { collectUsageRequests, totalRequestUsage, collectChildUsage, totalChildUsage } from \"../../../core/usage-accounting.ts\";\nimport type { Usage } from \"@ashx-j/lunr-ai\";\n\nexport interface GoalAccountingState {\n\tstatus: string;\n\tbaselineTokens: number;\n\ttokensUsed: number;\n\ttimeUsedSeconds: number;\n\tactiveStartedAt?: number;\n\tupdatedAt: number;\n}\n\ninterface AssistantUsageEntryLike {\n\ttype?: unknown;\n\tmessage?: unknown;\n}\n\ninterface UsageContext {\n\tsessionManager?: unknown;\n}\n\nexport function checkpointGoalActiveTime(\n\tgoal: GoalAccountingState,\n\tnow: number,\n\tcontinueClock: boolean,\n) {\n\tconst accumulated = nonNegativeFiniteNumber(goal.timeUsedSeconds);\n\tconst startedAt = goal.activeStartedAt;\n\tif (typeof startedAt === \"number\" && Number.isFinite(startedAt)) {\n\t\tgoal.timeUsedSeconds = accumulated + Math.max(0, now - startedAt) / 1000;\n\t} else {\n\t\tgoal.timeUsedSeconds = accumulated;\n\t}\n\tgoal.activeStartedAt = continueClock ? now : undefined;\n}\n\nexport function updateGoalUsage(\n\tgoal: GoalAccountingState,\n\tctx: UsageContext,\n\tcontinueClock = goal.status === \"active\",\n) {\n\tconst now = Date.now();\n\tconst baselineTokens = nonNegativeFiniteNumber(goal.baselineTokens);\n\tgoal.baselineTokens = baselineTokens;\n\tgoal.tokensUsed = Math.max(nonNegativeFiniteNumber(goal.tokensUsed), currentTokenTotal(ctx) - baselineTokens);\n\tcheckpointGoalActiveTime(goal, now, continueClock);\n\tgoal.updatedAt = now;\n}\n\nexport function formatDuration(seconds: number) {\n\tconst wholeSeconds = Math.max(0, Math.floor(nonNegativeFiniteNumber(seconds)));\n\tif (wholeSeconds < 60) return `${wholeSeconds}s`;\n\tconst minutes = Math.floor(wholeSeconds / 60);\n\tif (minutes < 60) return `${minutes}m`;\n\tconst hours = Math.floor(minutes / 60);\n\treturn `${hours}h${minutes % 60}m`;\n}\n\nexport function formatTokenCount(value: number) {\n\tif (value < 1_000) return `${value}`;\n\tif (value < 1_000_000) {\n\t\treturn `${Number.isInteger(value / 1_000) ? value / 1_000 : (value / 1_000).toFixed(1)}k`;\n\t}\n\treturn `${Number.isInteger(value / 1_000_000) ? value / 1_000_000 : (value / 1_000_000).toFixed(1)}m`;\n}\n\nexport function isNonNegativeFiniteNumber(value: unknown): value is number {\n\treturn typeof value === \"number\" && Number.isFinite(value) && value >= 0;\n}\n\nexport function nonNegativeFiniteNumber(value: unknown) {\n\treturn isNonNegativeFiniteNumber(value) ? value : 0;\n}\n\nexport function normalizeTokenBudget(value: unknown) {\n\treturn typeof value === \"number\" && Number.isSafeInteger(value) && value > 0\n\t\t? value\n\t\t: undefined;\n}\n\nexport function assistantUsageTokens(value: unknown) {\n\tif (!value || typeof value !== \"object\") return 0;\n\tconst usage = value as Partial<Usage>;\n\tif (isNonNegativeFiniteNumber(usage.totalTokens)) return usage.totalTokens;\n\treturn Math.min(\n\t\tNumber.MAX_SAFE_INTEGER,\n\t\tnonNegativeFiniteNumber(usage.input) +\n\t\t\tnonNegativeFiniteNumber(usage.output) +\n\t\t\tnonNegativeFiniteNumber(usage.cacheRead) +\n\t\t\tnonNegativeFiniteNumber(usage.cacheWrite),\n\t);\n}\n\nexport function cumulativeAssistantTokens(entries: unknown[]) {\n\tlet total = 0;\n\tfor (const entry of entries) {\n\t\tconst candidate = entry as AssistantUsageEntryLike;\n\t\tif (candidate?.type !== \"message\") continue;\n\t\tconst message = candidate.message as { role?: unknown; usage?: unknown } | undefined;\n\t\tif (message?.role !== \"assistant\") continue;\n\t\ttotal = Math.min(Number.MAX_SAFE_INTEGER, total + assistantUsageTokens(message.usage));\n\t}\n\treturn total;\n}\n\nexport function currentTokenTotal(ctx: UsageContext): number {\n\tconst sessionManager = ctx.sessionManager as { getEntries?: () => unknown[]; getBranch?: () => unknown[] } | undefined;\n\tconst entries = sessionManager?.getEntries?.() ?? sessionManager?.getBranch?.() ?? [];\n\treturn totalRequestUsage(collectUsageRequests(entries)).total + totalChildUsage(collectChildUsage(entries)).total;\n}\n"]}