pulseed 0.5.3 → 0.5.4

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 (512) hide show
  1. package/dist/base/state/state-manager-goal-state.d.ts +40 -0
  2. package/dist/base/state/state-manager-goal-state.d.ts.map +1 -0
  3. package/dist/base/state/state-manager-goal-state.js +235 -0
  4. package/dist/base/state/state-manager-goal-state.js.map +1 -0
  5. package/dist/base/state/state-manager.d.ts +0 -5
  6. package/dist/base/state/state-manager.d.ts.map +1 -1
  7. package/dist/base/state/state-manager.js +27 -273
  8. package/dist/base/state/state-manager.js.map +1 -1
  9. package/dist/base/types/goal-activation.d.ts +25 -0
  10. package/dist/base/types/goal-activation.d.ts.map +1 -0
  11. package/dist/base/types/goal-activation.js +9 -0
  12. package/dist/base/types/goal-activation.js.map +1 -0
  13. package/dist/interface/chat/chat-history.d.ts +129 -0
  14. package/dist/interface/chat/chat-history.d.ts.map +1 -1
  15. package/dist/interface/chat/chat-history.js +135 -0
  16. package/dist/interface/chat/chat-history.js.map +1 -1
  17. package/dist/interface/chat/chat-runner-command-helpers.d.ts +50 -0
  18. package/dist/interface/chat/chat-runner-command-helpers.d.ts.map +1 -0
  19. package/dist/interface/chat/chat-runner-command-helpers.js +189 -0
  20. package/dist/interface/chat/chat-runner-command-helpers.js.map +1 -0
  21. package/dist/interface/chat/chat-runner-commands.d.ts +76 -0
  22. package/dist/interface/chat/chat-runner-commands.d.ts.map +1 -0
  23. package/dist/interface/chat/chat-runner-commands.js +814 -0
  24. package/dist/interface/chat/chat-runner-commands.js.map +1 -0
  25. package/dist/interface/chat/chat-runner-event-bridge.d.ts +53 -0
  26. package/dist/interface/chat/chat-runner-event-bridge.d.ts.map +1 -0
  27. package/dist/interface/chat/chat-runner-event-bridge.js +311 -0
  28. package/dist/interface/chat/chat-runner-event-bridge.js.map +1 -0
  29. package/dist/interface/chat/chat-runner-routes.d.ts +67 -0
  30. package/dist/interface/chat/chat-runner-routes.d.ts.map +1 -0
  31. package/dist/interface/chat/chat-runner-routes.js +594 -0
  32. package/dist/interface/chat/chat-runner-routes.js.map +1 -0
  33. package/dist/interface/chat/chat-runner-runtime.d.ts +37 -0
  34. package/dist/interface/chat/chat-runner-runtime.d.ts.map +1 -0
  35. package/dist/interface/chat/chat-runner-runtime.js +236 -0
  36. package/dist/interface/chat/chat-runner-runtime.js.map +1 -0
  37. package/dist/interface/chat/chat-runner-state.d.ts +20 -0
  38. package/dist/interface/chat/chat-runner-state.d.ts.map +1 -0
  39. package/dist/interface/chat/chat-runner-state.js +157 -0
  40. package/dist/interface/chat/chat-runner-state.js.map +1 -0
  41. package/dist/interface/chat/chat-runner-support.d.ts +15 -0
  42. package/dist/interface/chat/chat-runner-support.d.ts.map +1 -0
  43. package/dist/interface/chat/chat-runner-support.js +116 -0
  44. package/dist/interface/chat/chat-runner-support.js.map +1 -0
  45. package/dist/interface/chat/chat-runner.d.ts +10 -153
  46. package/dist/interface/chat/chat-runner.d.ts.map +1 -1
  47. package/dist/interface/chat/chat-runner.js +299 -2642
  48. package/dist/interface/chat/chat-runner.js.map +1 -1
  49. package/dist/interface/chat/chat-session-store.d.ts +32 -0
  50. package/dist/interface/chat/chat-session-store.d.ts.map +1 -1
  51. package/dist/interface/chat/chat-session-store.js +100 -10
  52. package/dist/interface/chat/chat-session-store.js.map +1 -1
  53. package/dist/interface/chat/cross-platform-session.d.ts.map +1 -1
  54. package/dist/interface/chat/cross-platform-session.js +2 -5
  55. package/dist/interface/chat/cross-platform-session.js.map +1 -1
  56. package/dist/interface/chat/event-subscriber.d.ts.map +1 -1
  57. package/dist/interface/chat/event-subscriber.js +41 -0
  58. package/dist/interface/chat/event-subscriber.js.map +1 -1
  59. package/dist/interface/chat/ingress-router.d.ts +0 -25
  60. package/dist/interface/chat/ingress-router.d.ts.map +1 -1
  61. package/dist/interface/chat/ingress-router.js +12 -85
  62. package/dist/interface/chat/ingress-router.js.map +1 -1
  63. package/dist/interface/chat/tend-command.d.ts.map +1 -1
  64. package/dist/interface/chat/tend-command.js +2 -0
  65. package/dist/interface/chat/tend-command.js.map +1 -1
  66. package/dist/interface/cli/commands/daemon-shared.d.ts +32 -0
  67. package/dist/interface/cli/commands/daemon-shared.d.ts.map +1 -0
  68. package/dist/interface/cli/commands/daemon-shared.js +120 -0
  69. package/dist/interface/cli/commands/daemon-shared.js.map +1 -0
  70. package/dist/interface/cli/commands/daemon.d.ts +2 -2
  71. package/dist/interface/cli/commands/daemon.d.ts.map +1 -1
  72. package/dist/interface/cli/commands/daemon.js +4 -120
  73. package/dist/interface/cli/commands/daemon.js.map +1 -1
  74. package/dist/interface/cli/commands/schedule/history.d.ts.map +1 -1
  75. package/dist/interface/cli/commands/schedule/history.js +5 -1
  76. package/dist/interface/cli/commands/schedule/history.js.map +1 -1
  77. package/dist/interface/cli/commands/schedule.js +34 -4
  78. package/dist/interface/cli/commands/schedule.js.map +1 -1
  79. package/dist/interface/tui/app.d.ts.map +1 -1
  80. package/dist/interface/tui/app.js +14 -1
  81. package/dist/interface/tui/app.js.map +1 -1
  82. package/dist/interface/tui/chat/suggestions.d.ts.map +1 -1
  83. package/dist/interface/tui/chat/suggestions.js +118 -4
  84. package/dist/interface/tui/chat/suggestions.js.map +1 -1
  85. package/dist/interface/tui/entry-approval.d.ts +8 -0
  86. package/dist/interface/tui/entry-approval.d.ts.map +1 -0
  87. package/dist/interface/tui/entry-approval.js +59 -0
  88. package/dist/interface/tui/entry-approval.js.map +1 -0
  89. package/dist/interface/tui/entry-daemon.d.ts +12 -0
  90. package/dist/interface/tui/entry-daemon.d.ts.map +1 -0
  91. package/dist/interface/tui/entry-daemon.js +74 -0
  92. package/dist/interface/tui/entry-daemon.js.map +1 -0
  93. package/dist/interface/tui/entry-deps.d.ts +22 -0
  94. package/dist/interface/tui/entry-deps.d.ts.map +1 -0
  95. package/dist/interface/tui/entry-deps.js +409 -0
  96. package/dist/interface/tui/entry-deps.js.map +1 -0
  97. package/dist/interface/tui/entry.d.ts +2 -4
  98. package/dist/interface/tui/entry.d.ts.map +1 -1
  99. package/dist/interface/tui/entry.js +10 -557
  100. package/dist/interface/tui/entry.js.map +1 -1
  101. package/dist/interface/tui/fullscreen-chat-render.d.ts +127 -0
  102. package/dist/interface/tui/fullscreen-chat-render.d.ts.map +1 -0
  103. package/dist/interface/tui/fullscreen-chat-render.js +667 -0
  104. package/dist/interface/tui/fullscreen-chat-render.js.map +1 -0
  105. package/dist/interface/tui/fullscreen-chat.d.ts +2 -111
  106. package/dist/interface/tui/fullscreen-chat.d.ts.map +1 -1
  107. package/dist/interface/tui/fullscreen-chat.js +4 -663
  108. package/dist/interface/tui/fullscreen-chat.js.map +1 -1
  109. package/dist/interface/tui/help-overlay.d.ts.map +1 -1
  110. package/dist/interface/tui/help-overlay.js +1 -1
  111. package/dist/interface/tui/help-overlay.js.map +1 -1
  112. package/dist/interface/tui/intent-recognizer.js +2 -2
  113. package/dist/interface/tui/intent-recognizer.js.map +1 -1
  114. package/dist/orchestrator/execution/agent-loop/agent-loop-default-profile.d.ts.map +1 -1
  115. package/dist/orchestrator/execution/agent-loop/agent-loop-default-profile.js +8 -0
  116. package/dist/orchestrator/execution/agent-loop/agent-loop-default-profile.js.map +1 -1
  117. package/dist/orchestrator/execution/agent-loop/agent-loop-tool-router.d.ts.map +1 -1
  118. package/dist/orchestrator/execution/agent-loop/agent-loop-tool-router.js +2 -1
  119. package/dist/orchestrator/execution/agent-loop/agent-loop-tool-router.js.map +1 -1
  120. package/dist/orchestrator/execution/agent-loop/agent-loop-tool-runtime.d.ts +2 -0
  121. package/dist/orchestrator/execution/agent-loop/agent-loop-tool-runtime.d.ts.map +1 -1
  122. package/dist/orchestrator/execution/agent-loop/agent-loop-tool-runtime.js +31 -0
  123. package/dist/orchestrator/execution/agent-loop/agent-loop-tool-runtime.js.map +1 -1
  124. package/dist/orchestrator/execution/agent-loop/agent-loop-turn-context.d.ts +1 -0
  125. package/dist/orchestrator/execution/agent-loop/agent-loop-turn-context.d.ts.map +1 -1
  126. package/dist/orchestrator/execution/agent-loop/agent-loop-turn-context.js.map +1 -1
  127. package/dist/orchestrator/execution/agent-loop/bounded-agent-loop-runner.d.ts +1 -0
  128. package/dist/orchestrator/execution/agent-loop/bounded-agent-loop-runner.d.ts.map +1 -1
  129. package/dist/orchestrator/execution/agent-loop/bounded-agent-loop-runner.js +36 -2
  130. package/dist/orchestrator/execution/agent-loop/bounded-agent-loop-runner.js.map +1 -1
  131. package/dist/orchestrator/execution/agent-loop/chat-agent-loop-runner.d.ts.map +1 -1
  132. package/dist/orchestrator/execution/agent-loop/chat-agent-loop-runner.js +2 -1
  133. package/dist/orchestrator/execution/agent-loop/chat-agent-loop-runner.js.map +1 -1
  134. package/dist/orchestrator/execution/agent-loop/core-loop-control-tools.d.ts +19 -0
  135. package/dist/orchestrator/execution/agent-loop/core-loop-control-tools.d.ts.map +1 -1
  136. package/dist/orchestrator/execution/agent-loop/core-loop-control-tools.js +164 -14
  137. package/dist/orchestrator/execution/agent-loop/core-loop-control-tools.js.map +1 -1
  138. package/dist/orchestrator/execution/reflection-generator.d.ts +1 -0
  139. package/dist/orchestrator/execution/reflection-generator.d.ts.map +1 -1
  140. package/dist/orchestrator/execution/reflection-generator.js +10 -1
  141. package/dist/orchestrator/execution/reflection-generator.js.map +1 -1
  142. package/dist/orchestrator/execution/task/task-context-enricher.d.ts +2 -0
  143. package/dist/orchestrator/execution/task/task-context-enricher.d.ts.map +1 -1
  144. package/dist/orchestrator/execution/task/task-context-enricher.js +9 -4
  145. package/dist/orchestrator/execution/task/task-context-enricher.js.map +1 -1
  146. package/dist/orchestrator/execution/task/task-execution-helpers-internal.d.ts +5 -0
  147. package/dist/orchestrator/execution/task/task-execution-helpers-internal.d.ts.map +1 -0
  148. package/dist/orchestrator/execution/task/task-execution-helpers-internal.js +6 -0
  149. package/dist/orchestrator/execution/task/task-execution-helpers-internal.js.map +1 -0
  150. package/dist/orchestrator/execution/task/task-generation.d.ts.map +1 -1
  151. package/dist/orchestrator/execution/task/task-generation.js +8 -3
  152. package/dist/orchestrator/execution/task/task-generation.js.map +1 -1
  153. package/dist/orchestrator/execution/task/task-lifecycle-runner.d.ts +73 -0
  154. package/dist/orchestrator/execution/task/task-lifecycle-runner.d.ts.map +1 -0
  155. package/dist/orchestrator/execution/task/task-lifecycle-runner.js +184 -0
  156. package/dist/orchestrator/execution/task/task-lifecycle-runner.js.map +1 -0
  157. package/dist/orchestrator/execution/task/task-lifecycle.d.ts +7 -7
  158. package/dist/orchestrator/execution/task/task-lifecycle.d.ts.map +1 -1
  159. package/dist/orchestrator/execution/task/task-lifecycle.js +37 -181
  160. package/dist/orchestrator/execution/task/task-lifecycle.js.map +1 -1
  161. package/dist/orchestrator/execution/task/task-verifier-internal.d.ts +2 -0
  162. package/dist/orchestrator/execution/task/task-verifier-internal.d.ts.map +1 -0
  163. package/dist/orchestrator/execution/task/task-verifier-internal.js +2 -0
  164. package/dist/orchestrator/execution/task/task-verifier-internal.js.map +1 -0
  165. package/dist/orchestrator/goal/goal-negotiator.d.ts.map +1 -1
  166. package/dist/orchestrator/goal/goal-negotiator.js +23 -3
  167. package/dist/orchestrator/goal/goal-negotiator.js.map +1 -1
  168. package/dist/orchestrator/loop/core-loop/contracts.d.ts +1 -0
  169. package/dist/orchestrator/loop/core-loop/contracts.d.ts.map +1 -1
  170. package/dist/orchestrator/loop/core-loop/contracts.js.map +1 -1
  171. package/dist/orchestrator/loop/core-loop/iteration-kernel-knowledge.d.ts +7 -0
  172. package/dist/orchestrator/loop/core-loop/iteration-kernel-knowledge.d.ts.map +1 -0
  173. package/dist/orchestrator/loop/core-loop/iteration-kernel-knowledge.js +43 -0
  174. package/dist/orchestrator/loop/core-loop/iteration-kernel-knowledge.js.map +1 -0
  175. package/dist/orchestrator/loop/core-loop/iteration-kernel-wait.d.ts +14 -0
  176. package/dist/orchestrator/loop/core-loop/iteration-kernel-wait.d.ts.map +1 -0
  177. package/dist/orchestrator/loop/core-loop/iteration-kernel-wait.js +41 -0
  178. package/dist/orchestrator/loop/core-loop/iteration-kernel-wait.js.map +1 -0
  179. package/dist/orchestrator/loop/core-loop/iteration-kernel.d.ts +3 -2
  180. package/dist/orchestrator/loop/core-loop/iteration-kernel.d.ts.map +1 -1
  181. package/dist/orchestrator/loop/core-loop/iteration-kernel.js +16 -87
  182. package/dist/orchestrator/loop/core-loop/iteration-kernel.js.map +1 -1
  183. package/dist/orchestrator/loop/core-loop/phase-policy.js +5 -5
  184. package/dist/orchestrator/loop/core-loop/task-cycle-stall.d.ts +9 -0
  185. package/dist/orchestrator/loop/core-loop/task-cycle-stall.d.ts.map +1 -0
  186. package/dist/orchestrator/loop/core-loop/task-cycle-stall.js +297 -0
  187. package/dist/orchestrator/loop/core-loop/task-cycle-stall.js.map +1 -0
  188. package/dist/orchestrator/loop/core-loop/task-cycle-wait.d.ts +11 -0
  189. package/dist/orchestrator/loop/core-loop/task-cycle-wait.d.ts.map +1 -0
  190. package/dist/orchestrator/loop/core-loop/task-cycle-wait.js +176 -0
  191. package/dist/orchestrator/loop/core-loop/task-cycle-wait.js.map +1 -0
  192. package/dist/orchestrator/loop/core-loop/task-cycle.d.ts +3 -15
  193. package/dist/orchestrator/loop/core-loop/task-cycle.d.ts.map +1 -1
  194. package/dist/orchestrator/loop/core-loop/task-cycle.js +10 -444
  195. package/dist/orchestrator/loop/core-loop/task-cycle.js.map +1 -1
  196. package/dist/orchestrator/loop/core-loop.d.ts +3 -0
  197. package/dist/orchestrator/loop/core-loop.d.ts.map +1 -1
  198. package/dist/orchestrator/loop/core-loop.js +4 -0
  199. package/dist/orchestrator/loop/core-loop.js.map +1 -1
  200. package/dist/orchestrator/strategy/portfolio-manager.d.ts +3 -2
  201. package/dist/orchestrator/strategy/portfolio-manager.d.ts.map +1 -1
  202. package/dist/orchestrator/strategy/portfolio-manager.js +16 -11
  203. package/dist/orchestrator/strategy/portfolio-manager.js.map +1 -1
  204. package/dist/orchestrator/strategy/portfolio-rebalance.d.ts +1 -1
  205. package/dist/orchestrator/strategy/portfolio-rebalance.d.ts.map +1 -1
  206. package/dist/orchestrator/strategy/portfolio-rebalance.js +31 -9
  207. package/dist/orchestrator/strategy/portfolio-rebalance.js.map +1 -1
  208. package/dist/orchestrator/strategy/strategy-manager-base.d.ts +12 -2
  209. package/dist/orchestrator/strategy/strategy-manager-base.d.ts.map +1 -1
  210. package/dist/orchestrator/strategy/strategy-manager-base.js +23 -7
  211. package/dist/orchestrator/strategy/strategy-manager-base.js.map +1 -1
  212. package/dist/orchestrator/strategy/strategy-manager.d.ts +1 -11
  213. package/dist/orchestrator/strategy/strategy-manager.d.ts.map +1 -1
  214. package/dist/orchestrator/strategy/strategy-manager.js +78 -19
  215. package/dist/orchestrator/strategy/strategy-manager.js.map +1 -1
  216. package/dist/platform/dream/dream-consolidator/fs-metrics.d.ts +18 -0
  217. package/dist/platform/dream/dream-consolidator/fs-metrics.d.ts.map +1 -0
  218. package/dist/platform/dream/dream-consolidator/fs-metrics.js +130 -0
  219. package/dist/platform/dream/dream-consolidator/fs-metrics.js.map +1 -0
  220. package/dist/platform/dream/dream-consolidator.d.ts +4 -14
  221. package/dist/platform/dream/dream-consolidator.d.ts.map +1 -1
  222. package/dist/platform/dream/dream-consolidator.js +46 -166
  223. package/dist/platform/dream/dream-consolidator.js.map +1 -1
  224. package/dist/platform/dream/dream-soil-sync.d.ts +1 -0
  225. package/dist/platform/dream/dream-soil-sync.d.ts.map +1 -1
  226. package/dist/platform/dream/dream-soil-sync.js +8 -1
  227. package/dist/platform/dream/dream-soil-sync.js.map +1 -1
  228. package/dist/platform/dream/dream-types.d.ts +5 -0
  229. package/dist/platform/dream/dream-types.d.ts.map +1 -1
  230. package/dist/platform/dream/dream-types.js +1 -0
  231. package/dist/platform/dream/dream-types.js.map +1 -1
  232. package/dist/platform/dream/playbook-memory.d.ts +4 -4
  233. package/dist/platform/drive/stall-detector/analysis.d.ts +5 -0
  234. package/dist/platform/drive/stall-detector/analysis.d.ts.map +1 -0
  235. package/dist/platform/drive/stall-detector/analysis.js +55 -0
  236. package/dist/platform/drive/stall-detector/analysis.js.map +1 -0
  237. package/dist/platform/drive/stall-detector/repetitive.d.ts +3 -0
  238. package/dist/platform/drive/stall-detector/repetitive.d.ts.map +1 -0
  239. package/dist/platform/drive/stall-detector/repetitive.js +72 -0
  240. package/dist/platform/drive/stall-detector/repetitive.js.map +1 -0
  241. package/dist/platform/drive/stall-detector/thresholds.d.ts +10 -0
  242. package/dist/platform/drive/stall-detector/thresholds.d.ts.map +1 -0
  243. package/dist/platform/drive/stall-detector/thresholds.js +61 -0
  244. package/dist/platform/drive/stall-detector/thresholds.js.map +1 -0
  245. package/dist/platform/drive/stall-detector.d.ts +2 -20
  246. package/dist/platform/drive/stall-detector.d.ts.map +1 -1
  247. package/dist/platform/drive/stall-detector.js +9 -202
  248. package/dist/platform/drive/stall-detector.js.map +1 -1
  249. package/dist/platform/knowledge/knowledge-manager-agent-memory.d.ts +55 -0
  250. package/dist/platform/knowledge/knowledge-manager-agent-memory.d.ts.map +1 -0
  251. package/dist/platform/knowledge/knowledge-manager-agent-memory.js +232 -0
  252. package/dist/platform/knowledge/knowledge-manager-agent-memory.js.map +1 -0
  253. package/dist/platform/knowledge/knowledge-manager-internals.d.ts +10 -0
  254. package/dist/platform/knowledge/knowledge-manager-internals.d.ts.map +1 -0
  255. package/dist/platform/knowledge/knowledge-manager-internals.js +43 -0
  256. package/dist/platform/knowledge/knowledge-manager-internals.js.map +1 -0
  257. package/dist/platform/knowledge/knowledge-manager-store.d.ts +13 -0
  258. package/dist/platform/knowledge/knowledge-manager-store.d.ts.map +1 -0
  259. package/dist/platform/knowledge/knowledge-manager-store.js +67 -0
  260. package/dist/platform/knowledge/knowledge-manager-store.js.map +1 -0
  261. package/dist/platform/knowledge/knowledge-manager.d.ts +6 -2
  262. package/dist/platform/knowledge/knowledge-manager.d.ts.map +1 -1
  263. package/dist/platform/knowledge/knowledge-manager.js +43 -344
  264. package/dist/platform/knowledge/knowledge-manager.js.map +1 -1
  265. package/dist/platform/knowledge/memory/memory-lifecycle-storage.d.ts +4 -0
  266. package/dist/platform/knowledge/memory/memory-lifecycle-storage.d.ts.map +1 -0
  267. package/dist/platform/knowledge/memory/memory-lifecycle-storage.js +106 -0
  268. package/dist/platform/knowledge/memory/memory-lifecycle-storage.js.map +1 -0
  269. package/dist/platform/knowledge/memory/memory-lifecycle.d.ts.map +1 -1
  270. package/dist/platform/knowledge/memory/memory-lifecycle.js +6 -112
  271. package/dist/platform/knowledge/memory/memory-lifecycle.js.map +1 -1
  272. package/dist/platform/observation/capability-detector/prompts.d.ts +18 -0
  273. package/dist/platform/observation/capability-detector/prompts.d.ts.map +1 -0
  274. package/dist/platform/observation/capability-detector/prompts.js +80 -0
  275. package/dist/platform/observation/capability-detector/prompts.js.map +1 -0
  276. package/dist/platform/observation/capability-detector/recommendations.d.ts +5 -0
  277. package/dist/platform/observation/capability-detector/recommendations.d.ts.map +1 -0
  278. package/dist/platform/observation/capability-detector/recommendations.js +76 -0
  279. package/dist/platform/observation/capability-detector/recommendations.js.map +1 -0
  280. package/dist/platform/observation/capability-detector/types.d.ts +112 -0
  281. package/dist/platform/observation/capability-detector/types.d.ts.map +1 -0
  282. package/dist/platform/observation/capability-detector/types.js +75 -0
  283. package/dist/platform/observation/capability-detector/types.js.map +1 -0
  284. package/dist/platform/observation/capability-detector.d.ts +4 -9
  285. package/dist/platform/observation/capability-detector.d.ts.map +1 -1
  286. package/dist/platform/observation/capability-detector.js +12 -212
  287. package/dist/platform/observation/capability-detector.js.map +1 -1
  288. package/dist/platform/observation/context-provider/collector.d.ts +13 -0
  289. package/dist/platform/observation/context-provider/collector.d.ts.map +1 -0
  290. package/dist/platform/observation/context-provider/collector.js +259 -0
  291. package/dist/platform/observation/context-provider/collector.js.map +1 -0
  292. package/dist/platform/observation/context-provider/search-terms.d.ts +2 -0
  293. package/dist/platform/observation/context-provider/search-terms.d.ts.map +1 -0
  294. package/dist/platform/observation/context-provider/search-terms.js +24 -0
  295. package/dist/platform/observation/context-provider/search-terms.js.map +1 -0
  296. package/dist/platform/observation/context-provider/shared.d.ts +17 -0
  297. package/dist/platform/observation/context-provider/shared.d.ts.map +1 -0
  298. package/dist/platform/observation/context-provider/shared.js +87 -0
  299. package/dist/platform/observation/context-provider/shared.js.map +1 -0
  300. package/dist/platform/observation/context-provider.d.ts +3 -28
  301. package/dist/platform/observation/context-provider.d.ts.map +1 -1
  302. package/dist/platform/observation/context-provider.js +7 -395
  303. package/dist/platform/observation/context-provider.js.map +1 -1
  304. package/dist/platform/soil/compiled-memory-projections.d.ts +2 -0
  305. package/dist/platform/soil/compiled-memory-projections.d.ts.map +1 -1
  306. package/dist/platform/soil/compiled-memory-projections.js +59 -0
  307. package/dist/platform/soil/compiled-memory-projections.js.map +1 -1
  308. package/dist/platform/soil/contracts.d.ts +2 -2
  309. package/dist/platform/soil/retriever.d.ts +25 -0
  310. package/dist/platform/soil/retriever.d.ts.map +1 -1
  311. package/dist/platform/soil/retriever.js +94 -5
  312. package/dist/platform/soil/retriever.js.map +1 -1
  313. package/dist/platform/soil/sqlite-repository-helpers.d.ts +80 -0
  314. package/dist/platform/soil/sqlite-repository-helpers.d.ts.map +1 -0
  315. package/dist/platform/soil/sqlite-repository-helpers.js +143 -0
  316. package/dist/platform/soil/sqlite-repository-helpers.js.map +1 -0
  317. package/dist/platform/soil/sqlite-repository-search.d.ts +8 -0
  318. package/dist/platform/soil/sqlite-repository-search.d.ts.map +1 -0
  319. package/dist/platform/soil/sqlite-repository-search.js +367 -0
  320. package/dist/platform/soil/sqlite-repository-search.js.map +1 -0
  321. package/dist/platform/soil/sqlite-repository-storage.d.ts +8 -0
  322. package/dist/platform/soil/sqlite-repository-storage.d.ts.map +1 -0
  323. package/dist/platform/soil/sqlite-repository-storage.js +278 -0
  324. package/dist/platform/soil/sqlite-repository-storage.js.map +1 -0
  325. package/dist/platform/soil/sqlite-repository.d.ts +1 -4
  326. package/dist/platform/soil/sqlite-repository.d.ts.map +1 -1
  327. package/dist/platform/soil/sqlite-repository.js +26 -820
  328. package/dist/platform/soil/sqlite-repository.js.map +1 -1
  329. package/dist/runtime/daemon/index.d.ts +1 -1
  330. package/dist/runtime/daemon/index.d.ts.map +1 -1
  331. package/dist/runtime/daemon/index.js +1 -1
  332. package/dist/runtime/daemon/index.js.map +1 -1
  333. package/dist/runtime/daemon/maintenance.d.ts +2 -10
  334. package/dist/runtime/daemon/maintenance.d.ts.map +1 -1
  335. package/dist/runtime/daemon/maintenance.js +14 -45
  336. package/dist/runtime/daemon/maintenance.js.map +1 -1
  337. package/dist/runtime/daemon/runner-bootstrap.d.ts +25 -0
  338. package/dist/runtime/daemon/runner-bootstrap.d.ts.map +1 -0
  339. package/dist/runtime/daemon/runner-bootstrap.js +77 -0
  340. package/dist/runtime/daemon/runner-bootstrap.js.map +1 -0
  341. package/dist/runtime/daemon/runner-commands.d.ts +7 -7
  342. package/dist/runtime/daemon/runner-commands.d.ts.map +1 -1
  343. package/dist/runtime/daemon/runner-commands.js +35 -20
  344. package/dist/runtime/daemon/runner-commands.js.map +1 -1
  345. package/dist/runtime/daemon/runner-goal-cycle.d.ts.map +1 -1
  346. package/dist/runtime/daemon/runner-goal-cycle.js +3 -5
  347. package/dist/runtime/daemon/runner-goal-cycle.js.map +1 -1
  348. package/dist/runtime/daemon/runner-resident-curiosity.d.ts +12 -0
  349. package/dist/runtime/daemon/runner-resident-curiosity.d.ts.map +1 -0
  350. package/dist/runtime/daemon/runner-resident-curiosity.js +155 -0
  351. package/dist/runtime/daemon/runner-resident-curiosity.js.map +1 -0
  352. package/dist/runtime/daemon/runner-resident-dream.d.ts +20 -0
  353. package/dist/runtime/daemon/runner-resident-dream.d.ts.map +1 -0
  354. package/dist/runtime/daemon/runner-resident-dream.js +148 -0
  355. package/dist/runtime/daemon/runner-resident-dream.js.map +1 -0
  356. package/dist/runtime/daemon/runner-resident-proactive.d.ts +4 -0
  357. package/dist/runtime/daemon/runner-resident-proactive.d.ts.map +1 -0
  358. package/dist/runtime/daemon/runner-resident-proactive.js +113 -0
  359. package/dist/runtime/daemon/runner-resident-proactive.js.map +1 -0
  360. package/dist/runtime/daemon/runner-resident-shared.d.ts +40 -0
  361. package/dist/runtime/daemon/runner-resident-shared.d.ts.map +1 -0
  362. package/dist/runtime/daemon/runner-resident-shared.js +101 -0
  363. package/dist/runtime/daemon/runner-resident-shared.js.map +1 -0
  364. package/dist/runtime/daemon/runner-resident.d.ts +4 -68
  365. package/dist/runtime/daemon/runner-resident.d.ts.map +1 -1
  366. package/dist/runtime/daemon/runner-resident.js +4 -506
  367. package/dist/runtime/daemon/runner-resident.js.map +1 -1
  368. package/dist/runtime/daemon/runner-runtime.d.ts +12 -0
  369. package/dist/runtime/daemon/runner-runtime.d.ts.map +1 -0
  370. package/dist/runtime/daemon/runner-runtime.js +43 -0
  371. package/dist/runtime/daemon/runner-runtime.js.map +1 -0
  372. package/dist/runtime/daemon/runner-startup.js +3 -4
  373. package/dist/runtime/daemon/runner-startup.js.map +1 -1
  374. package/dist/runtime/daemon/runner.d.ts +10 -23
  375. package/dist/runtime/daemon/runner.d.ts.map +1 -1
  376. package/dist/runtime/daemon/runner.js +27 -110
  377. package/dist/runtime/daemon/runner.js.map +1 -1
  378. package/dist/runtime/daemon/wait-deadline-resolver.d.ts +5 -2
  379. package/dist/runtime/daemon/wait-deadline-resolver.d.ts.map +1 -1
  380. package/dist/runtime/daemon/wait-deadline-resolver.js +55 -35
  381. package/dist/runtime/daemon/wait-deadline-resolver.js.map +1 -1
  382. package/dist/runtime/event/dispatcher.d.ts +0 -2
  383. package/dist/runtime/event/dispatcher.d.ts.map +1 -1
  384. package/dist/runtime/event/dispatcher.js +0 -4
  385. package/dist/runtime/event/dispatcher.js.map +1 -1
  386. package/dist/runtime/executor/goal-worker.d.ts +2 -1
  387. package/dist/runtime/executor/goal-worker.d.ts.map +1 -1
  388. package/dist/runtime/executor/goal-worker.js +2 -1
  389. package/dist/runtime/executor/goal-worker.js.map +1 -1
  390. package/dist/runtime/executor/loop-supervisor.d.ts +3 -0
  391. package/dist/runtime/executor/loop-supervisor.d.ts.map +1 -1
  392. package/dist/runtime/executor/loop-supervisor.js +37 -11
  393. package/dist/runtime/executor/loop-supervisor.js.map +1 -1
  394. package/dist/runtime/schedule/engine-cron-reflection.d.ts +31 -0
  395. package/dist/runtime/schedule/engine-cron-reflection.d.ts.map +1 -0
  396. package/dist/runtime/schedule/engine-cron-reflection.js +229 -0
  397. package/dist/runtime/schedule/engine-cron-reflection.js.map +1 -0
  398. package/dist/runtime/schedule/engine-execution.d.ts +47 -0
  399. package/dist/runtime/schedule/engine-execution.d.ts.map +1 -0
  400. package/dist/runtime/schedule/engine-execution.js +424 -0
  401. package/dist/runtime/schedule/engine-execution.js.map +1 -0
  402. package/dist/runtime/schedule/engine-heartbeat.d.ts +5 -0
  403. package/dist/runtime/schedule/engine-heartbeat.d.ts.map +1 -0
  404. package/dist/runtime/schedule/engine-heartbeat.js +104 -0
  405. package/dist/runtime/schedule/engine-heartbeat.js.map +1 -0
  406. package/dist/runtime/schedule/engine-layers.d.ts +2 -0
  407. package/dist/runtime/schedule/engine-layers.d.ts.map +1 -1
  408. package/dist/runtime/schedule/engine-layers.js +12 -228
  409. package/dist/runtime/schedule/engine-layers.js.map +1 -1
  410. package/dist/runtime/schedule/engine-mutations.d.ts +37 -0
  411. package/dist/runtime/schedule/engine-mutations.d.ts.map +1 -0
  412. package/dist/runtime/schedule/engine-mutations.js +263 -0
  413. package/dist/runtime/schedule/engine-mutations.js.map +1 -0
  414. package/dist/runtime/schedule/engine.d.ts +11 -38
  415. package/dist/runtime/schedule/engine.d.ts.map +1 -1
  416. package/dist/runtime/schedule/engine.js +65 -810
  417. package/dist/runtime/schedule/engine.js.map +1 -1
  418. package/dist/runtime/schedule/history.d.ts +16 -0
  419. package/dist/runtime/schedule/history.d.ts.map +1 -1
  420. package/dist/runtime/schedule/history.js +8 -0
  421. package/dist/runtime/schedule/history.js.map +1 -1
  422. package/dist/runtime/schedule/index.d.ts +1 -0
  423. package/dist/runtime/schedule/index.d.ts.map +1 -1
  424. package/dist/runtime/schedule/index.js +1 -0
  425. package/dist/runtime/schedule/index.js.map +1 -1
  426. package/dist/runtime/schedule/legacy-cron-migration.d.ts +9 -0
  427. package/dist/runtime/schedule/legacy-cron-migration.d.ts.map +1 -0
  428. package/dist/runtime/schedule/legacy-cron-migration.js +89 -0
  429. package/dist/runtime/schedule/legacy-cron-migration.js.map +1 -0
  430. package/dist/runtime/schedule/wait-projection.d.ts +6 -0
  431. package/dist/runtime/schedule/wait-projection.d.ts.map +1 -0
  432. package/dist/runtime/schedule/wait-projection.js +102 -0
  433. package/dist/runtime/schedule/wait-projection.js.map +1 -0
  434. package/dist/runtime/session-registry/registry-helpers.d.ts +34 -0
  435. package/dist/runtime/session-registry/registry-helpers.d.ts.map +1 -0
  436. package/dist/runtime/session-registry/registry-helpers.js +241 -0
  437. package/dist/runtime/session-registry/registry-helpers.js.map +1 -0
  438. package/dist/runtime/session-registry/registry.d.ts.map +1 -1
  439. package/dist/runtime/session-registry/registry.js +14 -243
  440. package/dist/runtime/session-registry/registry.js.map +1 -1
  441. package/dist/runtime/session-registry/types.d.ts +36 -36
  442. package/dist/runtime/store/runtime-operation-schemas.d.ts +36 -36
  443. package/dist/runtime/store/runtime-schemas.d.ts +2 -2
  444. package/dist/runtime/types/daemon.d.ts +10 -0
  445. package/dist/runtime/types/daemon.d.ts.map +1 -1
  446. package/dist/runtime/types/daemon.js +2 -0
  447. package/dist/runtime/types/daemon.js.map +1 -1
  448. package/dist/runtime/types/schedule.d.ts +65 -0
  449. package/dist/runtime/types/schedule.d.ts.map +1 -1
  450. package/dist/runtime/types/schedule.js +5 -0
  451. package/dist/runtime/types/schedule.js.map +1 -1
  452. package/dist/tools/builtin/exports.d.ts +1 -0
  453. package/dist/tools/builtin/exports.d.ts.map +1 -1
  454. package/dist/tools/builtin/exports.js +1 -0
  455. package/dist/tools/builtin/exports.js.map +1 -1
  456. package/dist/tools/builtin/factory.d.ts +2 -0
  457. package/dist/tools/builtin/factory.d.ts.map +1 -1
  458. package/dist/tools/builtin/factory.js +8 -1
  459. package/dist/tools/builtin/factory.js.map +1 -1
  460. package/dist/tools/fs/FileValidationTool/protected-path-policy.d.ts +1 -0
  461. package/dist/tools/fs/FileValidationTool/protected-path-policy.d.ts.map +1 -1
  462. package/dist/tools/fs/FileValidationTool/protected-path-policy.js +17 -4
  463. package/dist/tools/fs/FileValidationTool/protected-path-policy.js.map +1 -1
  464. package/dist/tools/fs/ListDirTool/ListDirTool.js +1 -1
  465. package/dist/tools/fs/ListDirTool/ListDirTool.js.map +1 -1
  466. package/dist/tools/kaggle/paths.d.ts.map +1 -1
  467. package/dist/tools/kaggle/paths.js +6 -0
  468. package/dist/tools/kaggle/paths.js.map +1 -1
  469. package/dist/tools/query/CodeSearchRepairTool/CodeSearchRepairTool.d.ts.map +1 -1
  470. package/dist/tools/query/CodeSearchRepairTool/CodeSearchRepairTool.js +23 -2
  471. package/dist/tools/query/CodeSearchRepairTool/CodeSearchRepairTool.js.map +1 -1
  472. package/dist/tools/query/CodeSearchTool/CodeSearchTool.d.ts.map +1 -1
  473. package/dist/tools/query/CodeSearchTool/CodeSearchTool.js +24 -2
  474. package/dist/tools/query/CodeSearchTool/CodeSearchTool.js.map +1 -1
  475. package/dist/tools/query/SoilQueryTool/SoilQueryTool.d.ts.map +1 -1
  476. package/dist/tools/query/SoilQueryTool/SoilQueryTool.js +43 -9
  477. package/dist/tools/query/SoilQueryTool/SoilQueryTool.js.map +1 -1
  478. package/dist/tools/query/code-search-root.d.ts +8 -0
  479. package/dist/tools/query/code-search-root.d.ts.map +1 -0
  480. package/dist/tools/query/code-search-root.js +41 -0
  481. package/dist/tools/query/code-search-root.js.map +1 -0
  482. package/dist/tools/query/runtime-session-tools.d.ts +560 -0
  483. package/dist/tools/query/runtime-session-tools.d.ts.map +1 -0
  484. package/dist/tools/query/runtime-session-tools.js +1015 -0
  485. package/dist/tools/query/runtime-session-tools.js.map +1 -0
  486. package/dist/tools/runtime/LongRunningRuntimeTools.d.ts +821 -0
  487. package/dist/tools/runtime/LongRunningRuntimeTools.d.ts.map +1 -0
  488. package/dist/tools/runtime/LongRunningRuntimeTools.js +845 -0
  489. package/dist/tools/runtime/LongRunningRuntimeTools.js.map +1 -0
  490. package/dist/tools/system/ProcessSessionTool/ProcessSessionTool.d.ts +1 -0
  491. package/dist/tools/system/ProcessSessionTool/ProcessSessionTool.d.ts.map +1 -1
  492. package/dist/tools/system/ProcessSessionTool/ProcessSessionTool.js +11 -0
  493. package/dist/tools/system/ProcessSessionTool/ProcessSessionTool.js.map +1 -1
  494. package/dist/tools/system/ShellTool/ShellTool.d.ts.map +1 -1
  495. package/dist/tools/system/ShellTool/ShellTool.js +2 -1
  496. package/dist/tools/system/ShellTool/ShellTool.js.map +1 -1
  497. package/dist/tools/types.d.ts +2 -0
  498. package/dist/tools/types.d.ts.map +1 -1
  499. package/dist/tools/types.js.map +1 -1
  500. package/package.json +1 -1
  501. package/dist/base/types/cron.d.ts +0 -2
  502. package/dist/base/types/cron.d.ts.map +0 -1
  503. package/dist/base/types/cron.js +0 -3
  504. package/dist/base/types/cron.js.map +0 -1
  505. package/dist/runtime/cron-scheduler.d.ts +0 -13
  506. package/dist/runtime/cron-scheduler.d.ts.map +0 -1
  507. package/dist/runtime/cron-scheduler.js +0 -90
  508. package/dist/runtime/cron-scheduler.js.map +0 -1
  509. package/dist/runtime/types/cron.d.ts +0 -59
  510. package/dist/runtime/types/cron.d.ts.map +0 -1
  511. package/dist/runtime/types/cron.js +0 -13
  512. package/dist/runtime/types/cron.js.map +0 -1
@@ -1,27 +1,13 @@
1
- import { CronExpressionParser } from "cron-parser";
2
1
  import * as path from "node:path";
3
- import * as net from "node:net";
4
- import { randomUUID } from "node:crypto";
5
- import { exec } from "node:child_process";
6
- import { ScheduleEntrySchema, ScheduleResultSchema, } from "../types/schedule.js";
7
- import { CronConfigSchema, GoalTriggerConfigSchema, HeartbeatConfigSchema, ProbeConfigSchema, } from "../types/schedule.js";
8
2
  import { executeCron, executeGoalTrigger, executeProbe } from "./engine-layers.js";
9
3
  import { ScheduleHistoryStore, } from "./history.js";
10
4
  import { projectSchedulesToSoil, rebuildSoilIndex } from "../../platform/soil/index.js";
11
5
  import { hasConfiguredSoilPublishProvider } from "../../platform/soil/publish/index.js";
12
6
  import { buildSchedulePresetEntry } from "./presets.js";
13
- import { ExternalScheduleEntrySchema } from "./source.js";
14
7
  import { ScheduleEntryStore } from "./entry-store.js";
15
- const DEFAULT_RETRY_POLICY = {
16
- enabled: true,
17
- initial_delay_ms: 30_000,
18
- max_delay_ms: 15 * 60 * 1000,
19
- multiplier: 2,
20
- jitter_factor: 0.2,
21
- max_attempts: 3,
22
- max_retry_window_ms: 24 * 60 * 60 * 1000,
23
- retryable_failure_kinds: ["transient"],
24
- };
8
+ import { migrateLegacyCronTasksIfNeeded } from "./legacy-cron-migration.js";
9
+ import { addEntryForEngine, addEntryInMemory, removeEntryForEngine, syncExternalSourcesForEngine, updateEntryForEngine, } from "./engine-mutations.js";
10
+ import { checkEscalationForEngine, executeEntryForEngine, executeEscalationTargetEntryForEngine, executeEscalationTargetGoalForEngine, getDueEntriesFromEngine, runEntryNowForEngine, tickEngine, } from "./engine-execution.js";
25
11
  const noopLogger = {
26
12
  info: (_msg, _ctx) => { },
27
13
  warn: (_msg, _ctx) => { },
@@ -62,7 +48,10 @@ export class ScheduleEngine {
62
48
  }
63
49
  // ─── Persistence ───
64
50
  async loadEntries() {
65
- this.entries = await this.readEntriesFromDisk();
51
+ this.entries = await this.entryStore.withLock(async () => {
52
+ await migrateLegacyCronTasksIfNeeded({ baseDir: this.baseDir, logger: this.logger });
53
+ return this.readEntriesFromDisk();
54
+ });
66
55
  await this.projectCurrentSchedulesToSoil();
67
56
  return this.entries;
68
57
  }
@@ -143,218 +132,24 @@ export class ScheduleEngine {
143
132
  return this.baseDir;
144
133
  }
145
134
  async syncExternalSources(sources) {
146
- return this.withScheduleMutation(async () => {
147
- const seenKeys = new Set();
148
- const reconciledSourceIds = new Set();
149
- const errors = [];
150
- let added = 0;
151
- let updated = 0;
152
- let skipped = 0;
153
- for (const source of sources) {
154
- try {
155
- const health = await source.healthCheck();
156
- if (!health.healthy) {
157
- errors.push({ source_id: source.id, message: health.error ?? "source is unhealthy" });
158
- continue;
159
- }
160
- const rawEntries = await source.fetchEntries();
161
- const sourceIdsFromFetchedEntries = new Set([source.id]);
162
- let sourceHadEntryErrors = false;
163
- for (const raw of rawEntries) {
164
- const parsed = ExternalScheduleEntrySchema.safeParse(raw);
165
- if (!parsed.success) {
166
- sourceHadEntryErrors = true;
167
- skipped++;
168
- errors.push({ source_id: source.id, message: parsed.error.message });
169
- continue;
170
- }
171
- const external = parsed.data;
172
- sourceIdsFromFetchedEntries.add(external.source_id);
173
- const entryInput = this.buildExternalScheduleEntryInput(external);
174
- if (!entryInput) {
175
- sourceHadEntryErrors = true;
176
- skipped++;
177
- errors.push({ source_id: external.source_id, message: `missing ${external.layer} config for ${external.external_id}` });
178
- continue;
179
- }
180
- const key = this.externalEntryKey(external.source_id, external.external_id);
181
- seenKeys.add(key);
182
- const existingIndex = this.entries.findIndex((entry) => entry.metadata?.source === "external" &&
183
- entry.metadata.external_source_id === external.source_id &&
184
- entry.metadata.external_id === external.external_id);
185
- if (existingIndex === -1) {
186
- this.entries.push(ScheduleEntrySchema.parse({
187
- ...entryInput,
188
- id: randomUUID(),
189
- created_at: new Date().toISOString(),
190
- updated_at: new Date().toISOString(),
191
- last_fired_at: null,
192
- next_fire_at: this.computeNextFireAt(entryInput.trigger),
193
- consecutive_failures: 0,
194
- last_escalation_at: null,
195
- baseline_results: [],
196
- total_executions: 0,
197
- total_tokens_used: 0,
198
- }));
199
- added++;
200
- continue;
201
- }
202
- const existing = this.entries[existingIndex];
203
- const candidate = ScheduleEntrySchema.parse({
204
- ...existing,
205
- ...entryInput,
206
- id: existing.id,
207
- created_at: existing.created_at,
208
- updated_at: existing.updated_at,
209
- next_fire_at: JSON.stringify(existing.trigger) === JSON.stringify(entryInput.trigger)
210
- ? existing.next_fire_at
211
- : this.computeNextFireAt(entryInput.trigger),
212
- });
213
- if (JSON.stringify(existing) !== JSON.stringify(candidate)) {
214
- this.entries[existingIndex] = ScheduleEntrySchema.parse({
215
- ...candidate,
216
- updated_at: new Date().toISOString(),
217
- });
218
- updated++;
219
- }
220
- }
221
- if (!sourceHadEntryErrors) {
222
- for (const sourceId of sourceIdsFromFetchedEntries) {
223
- reconciledSourceIds.add(sourceId);
224
- }
225
- }
226
- }
227
- catch (error) {
228
- errors.push({ source_id: source.id, message: error instanceof Error ? error.message : String(error) });
229
- }
230
- }
231
- let disabled = 0;
232
- this.entries = this.entries.map((entry) => {
233
- if (entry.metadata?.source !== "external" ||
234
- !entry.enabled ||
235
- !entry.metadata.external_source_id ||
236
- !reconciledSourceIds.has(entry.metadata.external_source_id)) {
237
- return entry;
238
- }
239
- const key = this.externalEntryKey(entry.metadata.external_source_id, entry.metadata.external_id ?? "");
240
- if (seenKeys.has(key)) {
241
- return entry;
242
- }
243
- disabled++;
244
- return ScheduleEntrySchema.parse({
245
- ...entry,
246
- enabled: false,
247
- updated_at: new Date().toISOString(),
248
- });
249
- });
250
- if (added > 0 || updated > 0 || disabled > 0) {
251
- await this.saveEntries();
252
- }
253
- return { added, updated, disabled, skipped, errors };
254
- });
135
+ return syncExternalSourcesForEngine(this.mutationHost(), sources);
255
136
  }
256
137
  // ─── Entry management ───
257
138
  async addEntry(input) {
258
- return this.withScheduleMutation(async () => this.addEntryInMemory(input));
139
+ return addEntryForEngine(this.mutationHost(), input);
259
140
  }
260
141
  addEntryInMemory(input) {
261
- const now = new Date().toISOString();
262
- const entry = ScheduleEntrySchema.parse({
263
- ...input,
264
- id: randomUUID(),
265
- created_at: now,
266
- updated_at: now,
267
- last_fired_at: null,
268
- next_fire_at: this.computeNextFireAt(input.trigger),
269
- consecutive_failures: 0,
270
- last_escalation_at: null,
271
- baseline_results: [],
272
- total_executions: 0,
273
- total_tokens_used: 0,
274
- });
275
- this.entries.push(entry);
276
- return entry;
142
+ return addEntryInMemory(this.mutationHost(), input);
277
143
  }
278
144
  async removeEntry(id) {
279
- return this.withScheduleMutation(async () => {
280
- const before = this.entries.length;
281
- this.entries = this.entries.filter((e) => e.id !== id);
282
- if (this.entries.length === before)
283
- return false;
284
- return true;
285
- });
145
+ return removeEntryForEngine(this.mutationHost(), id);
286
146
  }
287
147
  async updateEntry(id, patch) {
288
- return this.withScheduleMutation(async () => {
289
- const idx = this.entries.findIndex((entry) => entry.id === id);
290
- if (idx === -1)
291
- return null;
292
- const hasUpdatableFields = patch.name !== undefined ||
293
- patch.enabled !== undefined ||
294
- patch.trigger !== undefined ||
295
- patch.heartbeat !== undefined ||
296
- patch.probe !== undefined ||
297
- patch.cron !== undefined ||
298
- patch.goal_trigger !== undefined ||
299
- patch.escalation !== undefined ||
300
- patch.retry_policy !== undefined;
301
- if (!hasUpdatableFields) {
302
- throw new Error("No updatable fields provided");
303
- }
304
- const current = this.entries[idx];
305
- const layerConfigFields = [
306
- ["heartbeat", patch.heartbeat],
307
- ["probe", patch.probe],
308
- ["cron", patch.cron],
309
- ["goal_trigger", patch.goal_trigger],
310
- ];
311
- for (const [field, value] of layerConfigFields) {
312
- if (value === undefined)
313
- continue;
314
- if (current.layer !== field) {
315
- throw new Error(`Cannot update ${field} config for ${current.layer} entry`);
316
- }
317
- }
318
- const nextEntry = { ...current };
319
- if (patch.name !== undefined)
320
- nextEntry.name = patch.name;
321
- if (patch.enabled !== undefined)
322
- nextEntry.enabled = patch.enabled;
323
- if (patch.trigger !== undefined)
324
- nextEntry.trigger = patch.trigger;
325
- if (patch.heartbeat !== undefined)
326
- nextEntry.heartbeat = patch.heartbeat;
327
- if (patch.probe !== undefined)
328
- nextEntry.probe = patch.probe;
329
- if (patch.cron !== undefined)
330
- nextEntry.cron = patch.cron;
331
- if (patch.goal_trigger !== undefined)
332
- nextEntry.goal_trigger = patch.goal_trigger;
333
- if (patch.retry_policy !== undefined)
334
- nextEntry.retry_policy = patch.retry_policy;
335
- if (patch.escalation !== undefined) {
336
- if (patch.escalation === null) {
337
- delete nextEntry.escalation;
338
- }
339
- else {
340
- nextEntry.escalation = patch.escalation;
341
- }
342
- }
343
- if (patch.trigger !== undefined || (current.enabled === false && patch.enabled === true)) {
344
- nextEntry.next_fire_at = this.computeNextFireAt(nextEntry.trigger);
345
- nextEntry.retry_state = null;
346
- }
347
- nextEntry.updated_at = new Date().toISOString();
348
- const parsedEntry = ScheduleEntrySchema.parse(nextEntry);
349
- const nextEntries = [...this.entries];
350
- nextEntries[idx] = parsedEntry;
351
- this.entries = nextEntries;
352
- return parsedEntry;
353
- });
148
+ return updateEntryForEngine(this.mutationHost(), id, patch);
354
149
  }
355
150
  // ─── Scheduling ───
356
151
  async getDueEntries() {
357
- return (await this.getDueEntryDescriptors()).map((descriptor) => descriptor.entry);
152
+ return getDueEntriesFromEngine(this.entries);
358
153
  }
359
154
  async getRecentHistory(limit = 20, entryId) {
360
155
  const history = await this.historyStore.load();
@@ -362,147 +157,10 @@ export class ScheduleEngine {
362
157
  return filtered.slice(-limit);
363
158
  }
364
159
  async runEntryNow(entryId, options = {}) {
365
- const entry = await this.withScheduleFileLock(async () => {
366
- await this.refreshEntriesForMutation();
367
- return this.entries.find((candidate) => candidate.id === entryId) ?? null;
368
- });
369
- if (!entry) {
370
- return null;
371
- }
372
- const scheduledFor = new Date().toISOString();
373
- const immediateEntry = {
374
- ...entry,
375
- enabled: true,
376
- next_fire_at: scheduledFor,
377
- };
378
- const executedResult = await this.executeEntry(immediateEntry);
379
- const sideEffects = entry.layer === "probe"
380
- ? this.captureExecutionSideEffects(entry.id)
381
- : null;
382
- const applied = await this.withScheduleFileLock(async () => {
383
- await this.refreshEntriesForMutation();
384
- const outcome = await this.applyExecutionOutcome(entry.id, executedResult, "manual_run", scheduledFor, { preserveEnabled: options.preserveEnabled ?? true });
385
- if (outcome) {
386
- this.applyExecutionSideEffects(entry.id, sideEffects);
387
- await this.writeEntriesAndProject();
388
- }
389
- return outcome;
390
- });
391
- let finalResult = executedResult;
392
- if (options.allowEscalation && applied?.entry) {
393
- const escalationResult = await this.checkEscalation(applied.entry, executedResult);
394
- if (escalationResult !== null) {
395
- finalResult = escalationResult;
396
- }
397
- }
398
- if (applied) {
399
- await this.recordHistory({
400
- entry_id: applied.entry?.id ?? entry.id,
401
- entry_name: applied.entry?.name ?? entry.name,
402
- layer: entry.layer,
403
- result: {
404
- ...finalResult,
405
- failure_kind: applied.failureKind,
406
- },
407
- reason: "manual_run",
408
- attempt: applied.attempt,
409
- scheduled_for: scheduledFor,
410
- started_at: applied.startedAt,
411
- finished_at: applied.finishedAt,
412
- retry_at: applied.retryAt,
413
- failure_kind: applied.failureKind,
414
- });
415
- }
416
- return {
417
- entry: applied?.entry ?? null,
418
- result: finalResult,
419
- reason: "manual_run",
420
- };
421
- }
422
- async getDueEntryDescriptors() {
423
- const now = Date.now();
424
- return this.entries.flatMap((entry) => {
425
- if (!entry.enabled) {
426
- return [];
427
- }
428
- const retryState = entry.retry_state ?? null;
429
- if (retryState?.next_retry_at) {
430
- return new Date(retryState.next_retry_at).getTime() <= now
431
- ? [{ entry, reason: "retry", scheduledFor: retryState.next_retry_at }]
432
- : [];
433
- }
434
- return new Date(entry.next_fire_at).getTime() <= now
435
- ? [{ entry, reason: "cadence", scheduledFor: entry.next_fire_at }]
436
- : [];
437
- });
160
+ return runEntryNowForEngine(this.executionHost(), entryId, options);
438
161
  }
439
162
  async tick() {
440
- const due = await this.withScheduleFileLock(async () => {
441
- await this.refreshEntriesForMutation();
442
- // Reset daily budget for entries whose budget_reset_at is null or in the past
443
- const nowMs = Date.now();
444
- let budgetReset = false;
445
- for (let i = 0; i < this.entries.length; i++) {
446
- const e = this.entries[i];
447
- if (!e.budget_reset_at || new Date(e.budget_reset_at).getTime() <= nowMs) {
448
- this.entries[i] = {
449
- ...e,
450
- tokens_used_today: 0,
451
- budget_reset_at: new Date(nowMs + 24 * 60 * 60 * 1000).toISOString(),
452
- };
453
- budgetReset = true;
454
- }
455
- }
456
- if (budgetReset) {
457
- await this.writeEntriesAndProject();
458
- }
459
- return this.getDueEntryDescriptors();
460
- });
461
- const results = [];
462
- for (const descriptor of due) {
463
- const executedResult = await this.executeEntry(descriptor.entry);
464
- const sideEffects = descriptor.entry.layer === "probe"
465
- ? this.captureExecutionSideEffects(descriptor.entry.id)
466
- : null;
467
- const applied = await this.withScheduleFileLock(async () => {
468
- await this.refreshEntriesForMutation();
469
- const outcome = await this.applyExecutionOutcome(descriptor.entry.id, executedResult, descriptor.reason, descriptor.scheduledFor);
470
- if (outcome) {
471
- this.applyExecutionSideEffects(descriptor.entry.id, sideEffects);
472
- // Persist cadence/retry advancement before history side effects so a crash
473
- // cannot replay an already-fired entry from stale schedule state.
474
- await this.writeEntriesAndProject();
475
- }
476
- return outcome;
477
- });
478
- let finalResult = executedResult;
479
- if (applied?.entry) {
480
- const escalationResult = await this.checkEscalation(applied.entry, executedResult);
481
- if (escalationResult !== null) {
482
- finalResult = escalationResult;
483
- }
484
- }
485
- if (applied) {
486
- await this.recordHistory({
487
- entry_id: applied.entry?.id ?? descriptor.entry.id,
488
- entry_name: applied.entry?.name ?? descriptor.entry.name,
489
- layer: descriptor.entry.layer,
490
- result: {
491
- ...finalResult,
492
- failure_kind: applied.failureKind,
493
- },
494
- reason: descriptor.reason,
495
- attempt: applied.attempt,
496
- scheduled_for: descriptor.scheduledFor,
497
- started_at: applied.startedAt,
498
- finished_at: applied.finishedAt,
499
- retry_at: applied.retryAt,
500
- failure_kind: applied.failureKind,
501
- });
502
- }
503
- results.push(finalResult);
504
- }
505
- return results;
163
+ return tickEngine(this.executionHost());
506
164
  }
507
165
  // ─── Probe execution (Phase 2) ───
508
166
  async executeProbe(entry) {
@@ -543,188 +201,8 @@ export class ScheduleEngine {
543
201
  logger: this.logger,
544
202
  };
545
203
  }
546
- externalEntryKey(sourceId, externalId) {
547
- return `${sourceId}:${externalId}`;
548
- }
549
- buildExternalScheduleEntryInput(external) {
550
- const base = {
551
- name: external.name,
552
- layer: external.layer,
553
- trigger: external.trigger.type === "cron"
554
- ? { type: "cron", expression: external.trigger.expression, timezone: "UTC" }
555
- : { type: "interval", seconds: external.trigger.seconds, jitter_factor: 0 },
556
- enabled: external.enabled,
557
- metadata: {
558
- source: "external",
559
- external_source_id: external.source_id,
560
- external_id: external.external_id,
561
- dependency_hints: [],
562
- note: typeof external.metadata["note"] === "string" ? external.metadata["note"] : undefined,
563
- },
564
- };
565
- if (external.layer === "heartbeat") {
566
- const parsed = HeartbeatConfigSchema.safeParse(external.heartbeat ?? external.metadata["heartbeat"]);
567
- return parsed.success ? { ...base, heartbeat: parsed.data } : null;
568
- }
569
- if (external.layer === "probe") {
570
- const parsed = ProbeConfigSchema.safeParse(external.probe ?? external.metadata["probe"]);
571
- return parsed.success ? { ...base, probe: parsed.data } : null;
572
- }
573
- if (external.layer === "cron") {
574
- const parsed = CronConfigSchema.safeParse(external.cron ?? external.metadata["cron"]);
575
- return parsed.success ? { ...base, cron: parsed.data } : null;
576
- }
577
- const parsed = GoalTriggerConfigSchema.safeParse(external.goal_trigger ?? external.metadata["goal_trigger"]);
578
- return parsed.success ? { ...base, goal_trigger: parsed.data } : null;
579
- }
580
204
  async executeEntry(entry) {
581
- if (entry.layer === "heartbeat") {
582
- return this.executeHeartbeat(entry);
583
- }
584
- if (entry.layer === "probe") {
585
- return this.executeProbe(entry);
586
- }
587
- if (entry.layer === "cron") {
588
- return this.executeCron(entry);
589
- }
590
- if (entry.layer === "goal_trigger") {
591
- return this.executeGoalTrigger(entry);
592
- }
593
- this.logger.info(`Skipping unknown layer entry: ${entry.name} (layer=${entry.layer})`);
594
- return ScheduleResultSchema.parse({
595
- entry_id: entry.id,
596
- status: "skipped",
597
- duration_ms: 0,
598
- fired_at: new Date().toISOString(),
599
- });
600
- }
601
- normalizeRetryPolicy(entry) {
602
- return {
603
- ...DEFAULT_RETRY_POLICY,
604
- ...(entry.retry_policy ?? {}),
605
- };
606
- }
607
- classifyFailureKind(entry, result) {
608
- if (result.failure_kind) {
609
- return result.failure_kind;
610
- }
611
- const message = `${result.error_message ?? ""}`.toLowerCase();
612
- const permanentHints = [
613
- "no cron config",
614
- "no heartbeat config",
615
- "no probe config",
616
- "no coreloop",
617
- "not found",
618
- "missing",
619
- "invalid",
620
- "unsupported",
621
- "cannot",
622
- "schema",
623
- "permission denied",
624
- ];
625
- if (permanentHints.some((hint) => message.includes(hint))) {
626
- return "permanent";
627
- }
628
- const transientHints = [
629
- "timeout",
630
- "timed out",
631
- "econnrefused",
632
- "econnreset",
633
- "etimedout",
634
- "eai_again",
635
- "enotfound",
636
- "network",
637
- "temporar",
638
- "unavailable",
639
- "rate limit",
640
- "busy",
641
- "abort",
642
- ];
643
- if (transientHints.some((hint) => message.includes(hint))) {
644
- return "transient";
645
- }
646
- return entry.layer === "goal_trigger" ? "permanent" : "transient";
647
- }
648
- computeRetryDelay(policy, attempt) {
649
- const baseDelay = policy.initial_delay_ms * Math.pow(policy.multiplier, Math.max(0, attempt - 1));
650
- const cappedDelay = Math.min(baseDelay, policy.max_delay_ms);
651
- if (policy.jitter_factor <= 0) {
652
- return cappedDelay;
653
- }
654
- const jitter = cappedDelay * policy.jitter_factor * (Math.random() * 2 - 1);
655
- return Math.max(0, Math.round(cappedDelay + jitter));
656
- }
657
- async applyExecutionOutcome(entryId, result, _reason, scheduledFor, options = {}) {
658
- const idx = this.entries.findIndex((candidate) => candidate.id === entryId);
659
- if (idx === -1) {
660
- return null;
661
- }
662
- const entry = this.entries[idx];
663
- const startedAt = scheduledFor ?? result.fired_at;
664
- const finishedAt = new Date().toISOString();
665
- const failureKind = this.classifyFailureKind(entry, result);
666
- const isFailure = result.status === "error" || result.status === "down";
667
- const retryPolicy = this.normalizeRetryPolicy(entry);
668
- const currentRetryState = entry.retry_state ?? null;
669
- let retryAt = null;
670
- let retryState = null;
671
- if (isFailure && retryPolicy.enabled && retryPolicy.retryable_failure_kinds.includes(failureKind)) {
672
- const attempts = (currentRetryState?.attempts ?? 0) + 1;
673
- const firstFailureAt = currentRetryState?.first_failure_at ?? result.fired_at;
674
- const windowElapsed = new Date(result.fired_at).getTime() - new Date(firstFailureAt).getTime();
675
- if (attempts <= retryPolicy.max_attempts && windowElapsed <= retryPolicy.max_retry_window_ms) {
676
- retryAt = new Date(Date.now() + this.computeRetryDelay(retryPolicy, attempts)).toISOString();
677
- retryState = {
678
- attempts,
679
- next_retry_at: retryAt,
680
- last_attempt_at: result.fired_at,
681
- first_failure_at: firstFailureAt,
682
- last_failure_kind: failureKind,
683
- last_error_message: result.error_message ?? null,
684
- };
685
- }
686
- }
687
- this.entries[idx] = {
688
- ...entry,
689
- enabled: options.preserveEnabled ? entry.enabled : true,
690
- last_fired_at: result.fired_at,
691
- next_fire_at: this.computeNextFireAt(entry.trigger),
692
- updated_at: new Date().toISOString(),
693
- total_executions: entry.total_executions + 1,
694
- total_tokens_used: entry.total_tokens_used + (result.tokens_used ?? 0),
695
- tokens_used_today: (entry.tokens_used_today ?? 0) + (result.tokens_used ?? 0),
696
- consecutive_failures: isFailure ? entry.consecutive_failures + 1 : 0,
697
- retry_state: retryState,
698
- };
699
- const updated = this.entries[idx];
700
- if (updated.escalation?.circuit_breaker_threshold &&
701
- updated.consecutive_failures >= updated.escalation.circuit_breaker_threshold) {
702
- updated.enabled = false;
703
- this.logger.warn(`Entry "${updated.name}" disabled by circuit breaker (${updated.consecutive_failures}/${updated.escalation.circuit_breaker_threshold})`);
704
- }
705
- if (result.status === "down" &&
706
- updated.heartbeat &&
707
- updated.consecutive_failures >= updated.heartbeat.failure_threshold) {
708
- this.logger.warn(`Entry "${updated.name}" reached failure threshold (${updated.consecutive_failures}/${updated.heartbeat.failure_threshold})`);
709
- if (updated.consecutive_failures === updated.heartbeat.failure_threshold) {
710
- await this.dispatchNotification({
711
- report_type: "schedule_heartbeat_failure",
712
- entry_id: updated.id,
713
- entry_name: updated.name,
714
- failure_threshold: updated.heartbeat.failure_threshold,
715
- consecutive_failures: updated.consecutive_failures,
716
- layer: updated.layer,
717
- });
718
- }
719
- }
720
- return {
721
- entry: updated,
722
- attempt: retryState?.attempts ?? 0,
723
- startedAt,
724
- finishedAt,
725
- retryAt,
726
- failureKind,
727
- };
205
+ return executeEntryForEngine(this.executionHost(), entry);
728
206
  }
729
207
  async recordHistory(input) {
730
208
  await this.historyStore.append({
@@ -733,7 +211,7 @@ export class ScheduleEngine {
733
211
  layer: input.layer,
734
212
  result: {
735
213
  ...input.result,
736
- failure_kind: input.failure_kind,
214
+ failure_kind: input.failure_kind ?? input.result.failure_kind ?? undefined,
737
215
  },
738
216
  reason: input.reason,
739
217
  attempt: input.attempt,
@@ -741,168 +219,19 @@ export class ScheduleEngine {
741
219
  started_at: input.started_at,
742
220
  finished_at: input.finished_at,
743
221
  retry_at: input.retry_at,
744
- failure_kind: input.failure_kind,
222
+ failure_kind: input.failure_kind ?? input.result.failure_kind,
745
223
  });
746
224
  }
747
225
  async executeEscalationTargetEntry(targetEntryId) {
748
- const targetEntry = await this.withScheduleFileLock(async () => {
749
- await this.refreshEntriesForMutation();
750
- return this.entries.find((candidate) => candidate.id === targetEntryId) ?? null;
751
- });
752
- if (!targetEntry) {
753
- this.logger.warn(`Escalation target entry not found: ${targetEntryId}`);
754
- return null;
755
- }
756
- const immediateEntry = {
757
- ...targetEntry,
758
- enabled: true,
759
- next_fire_at: new Date().toISOString(),
760
- };
761
- const result = await this.executeEntry(immediateEntry);
762
- const sideEffects = targetEntry.layer === "probe"
763
- ? this.captureExecutionSideEffects(targetEntry.id)
764
- : null;
765
- const applied = await this.withScheduleFileLock(async () => {
766
- await this.refreshEntriesForMutation();
767
- const outcome = await this.applyExecutionOutcome(targetEntryId, result, "escalation_target", immediateEntry.next_fire_at);
768
- if (outcome) {
769
- this.applyExecutionSideEffects(targetEntryId, sideEffects);
770
- await this.writeEntriesAndProject();
771
- }
772
- return outcome;
773
- });
774
- if (applied) {
775
- await this.recordHistory({
776
- entry_id: targetEntry.id,
777
- entry_name: targetEntry.name,
778
- layer: targetEntry.layer,
779
- result: {
780
- ...result,
781
- failure_kind: applied.failureKind,
782
- },
783
- reason: "escalation_target",
784
- attempt: applied.attempt,
785
- scheduled_for: immediateEntry.next_fire_at,
786
- started_at: applied.startedAt,
787
- finished_at: applied.finishedAt,
788
- retry_at: applied.retryAt,
789
- failure_kind: applied.failureKind,
790
- });
791
- }
792
- return result;
226
+ return executeEscalationTargetEntryForEngine(this.executionHost(), targetEntryId);
793
227
  }
794
228
  async executeEscalationTargetGoal(goalId) {
795
- const now = new Date().toISOString();
796
- if (!this.coreLoop) {
797
- return ScheduleResultSchema.parse({
798
- entry_id: randomUUID(),
799
- status: "error",
800
- duration_ms: 0,
801
- fired_at: now,
802
- goal_id: goalId,
803
- error_message: "No coreLoop provided for escalation target goal",
804
- failure_kind: "permanent",
805
- });
806
- }
807
- const startedAt = Date.now();
808
- try {
809
- const result = await this.coreLoop.run(goalId);
810
- return ScheduleResultSchema.parse({
811
- entry_id: randomUUID(),
812
- status: "ok",
813
- duration_ms: Date.now() - startedAt,
814
- fired_at: now,
815
- goal_id: goalId,
816
- tokens_used: result?.tokensUsed ?? 0,
817
- });
818
- }
819
- catch (error) {
820
- const message = error instanceof Error ? error.message : String(error);
821
- this.logger.error(`Escalation target goal "${goalId}" failed: ${message}`);
822
- return ScheduleResultSchema.parse({
823
- entry_id: randomUUID(),
824
- status: "error",
825
- duration_ms: Date.now() - startedAt,
826
- fired_at: now,
827
- goal_id: goalId,
828
- error_message: message,
829
- failure_kind: "transient",
830
- });
831
- }
229
+ return executeEscalationTargetGoalForEngine({ logger: this.logger, coreLoop: this.coreLoop }, goalId);
832
230
  }
833
231
  // ─── Escalation logic ───
834
232
  async checkEscalation(entry, result) {
835
- const isFailure = result.status === "error" || result.status === "down";
836
- if (!isFailure)
837
- return null;
838
- const escalationEntry = await this.withScheduleFileLock(async () => {
839
- await this.refreshEntriesForMutation();
840
- const idx = this.entries.findIndex((e) => e.id === entry.id);
841
- if (idx === -1) {
842
- return null;
843
- }
844
- const current = this.entries[idx];
845
- const esc = current.escalation;
846
- if (!esc?.enabled)
847
- return null;
848
- const now = Date.now();
849
- // Check cooldown
850
- if (current.last_escalation_at) {
851
- const lastEsc = new Date(current.last_escalation_at).getTime();
852
- if (now - lastEsc < esc.cooldown_minutes * 60 * 1000) {
853
- this.logger.info(`Escalation for "${current.name}" suppressed (cooldown)`);
854
- return null;
855
- }
856
- }
857
- // Rolling-window rate-limit: check escalation_timestamps within the last hour
858
- const hourAgo = now - 60 * 60 * 1000;
859
- const recentTimestamps = (current.escalation_timestamps ?? []).filter((ts) => new Date(ts).getTime() > hourAgo);
860
- if (recentTimestamps.length >= esc.max_per_hour) {
861
- this.logger.info(`Escalation for "${current.name}" suppressed (max_per_hour=${esc.max_per_hour} reached)`);
862
- return null;
863
- }
864
- // Update last_escalation_at and rolling-window escalation_timestamps.
865
- const nowIso = new Date(now).toISOString();
866
- const prunedTimestamps = [
867
- ...(current.escalation_timestamps ?? []).filter((ts) => new Date(ts).getTime() > hourAgo),
868
- nowIso,
869
- ];
870
- this.entries[idx] = {
871
- ...current,
872
- last_escalation_at: nowIso,
873
- escalation_timestamps: prunedTimestamps,
874
- };
875
- await this.writeEntriesAndProject();
876
- return this.entries[idx];
877
- });
878
- if (!escalationEntry?.escalation)
879
- return null;
880
- const esc = escalationEntry.escalation;
881
- // Dispatch escalation notification
882
- await this.dispatchNotification({
883
- report_type: "schedule_escalation",
884
- entry_id: escalationEntry.id,
885
- entry_name: escalationEntry.name,
886
- target_layer: esc.target_layer,
887
- target_entry_id: esc.target_entry_id,
888
- target_goal_id: esc.target_goal_id,
889
- consecutive_failures: escalationEntry.consecutive_failures,
890
- });
891
- this.logger.warn(`Escalating "${escalationEntry.name}" to ${esc.target_layer ?? "unknown"} (failures=${escalationEntry.consecutive_failures})`);
892
- // Execute target goal or target entry immediately so escalations take effect in the same tick.
893
- if (esc.target_goal_id) {
894
- await this.executeEscalationTargetGoal(esc.target_goal_id);
895
- }
896
- if (esc.target_entry_id) {
897
- await this.executeEscalationTargetEntry(esc.target_entry_id);
898
- }
899
- return ScheduleResultSchema.parse({
900
- ...result,
901
- status: "escalated",
902
- escalated_to: esc.target_goal_id ?? esc.target_entry_id ?? esc.target_layer ?? null,
903
- });
233
+ return checkEscalationForEngine(this.executionHost(), entry, result);
904
234
  }
905
- // ─── Notification dispatch ───
906
235
  async dispatchNotification(payload) {
907
236
  if (!this.notificationDispatcher)
908
237
  return;
@@ -913,125 +242,51 @@ export class ScheduleEngine {
913
242
  this.logger.warn(`Notification dispatch failed: ${err instanceof Error ? err.message : String(err)}`);
914
243
  }
915
244
  }
916
- // ─── Heartbeat execution (Phase 1) ───
917
- async executeHeartbeat(entry) {
918
- const firedAt = new Date().toISOString();
919
- const start = Date.now();
920
- const cfg = entry.heartbeat;
921
- if (!cfg) {
922
- return ScheduleResultSchema.parse({
923
- entry_id: entry.id,
924
- status: "error",
925
- duration_ms: 0,
926
- error_message: "No heartbeat config",
927
- fired_at: firedAt,
928
- failure_kind: "permanent",
929
- });
930
- }
931
- try {
932
- const timeoutMs = cfg.timeout_ms;
933
- const config = cfg.check_config;
934
- switch (cfg.check_type) {
935
- case "http":
936
- await this.checkHttp(config.url, timeoutMs);
937
- break;
938
- case "tcp":
939
- await this.checkTcp(config.host, config.port, timeoutMs);
940
- break;
941
- case "process":
942
- this.checkProcess(config.pid);
943
- break;
944
- case "disk":
945
- await this.checkDisk(config.path);
946
- break;
947
- case "custom":
948
- await this.checkCustom(config.command, timeoutMs);
949
- break;
950
- }
951
- return ScheduleResultSchema.parse({
952
- entry_id: entry.id,
953
- status: "ok",
954
- duration_ms: Date.now() - start,
955
- fired_at: firedAt,
956
- });
957
- }
958
- catch (err) {
959
- const msg = err instanceof Error ? err.message : String(err);
960
- this.logger.error(`Heartbeat "${entry.name}" failed: ${msg}`);
961
- return ScheduleResultSchema.parse({
962
- entry_id: entry.id,
963
- status: "down",
964
- duration_ms: Date.now() - start,
965
- error_message: msg,
966
- fired_at: firedAt,
967
- failure_kind: "transient",
968
- });
969
- }
970
- }
971
- // ─── Check implementations ───
972
- async checkHttp(url, timeoutMs) {
973
- const controller = new AbortController();
974
- const timer = setTimeout(() => controller.abort(), timeoutMs);
975
- try {
976
- const res = await fetch(url, { signal: controller.signal });
977
- if (!res.ok)
978
- throw new Error(`HTTP ${res.status}`);
979
- }
980
- finally {
981
- clearTimeout(timer);
982
- }
983
- }
984
- checkTcp(host, port, timeoutMs) {
985
- return new Promise((resolve, reject) => {
986
- const socket = net.createConnection({ host, port }, () => {
987
- socket.destroy();
988
- resolve();
989
- });
990
- socket.setTimeout(timeoutMs);
991
- socket.on("timeout", () => {
992
- socket.destroy();
993
- reject(new Error(`TCP timeout after ${timeoutMs}ms`));
994
- });
995
- socket.on("error", (err) => {
996
- socket.destroy();
997
- reject(err);
998
- });
999
- });
1000
- }
1001
- checkProcess(pid) {
1002
- process.kill(pid, 0); // throws if process doesn't exist
1003
- }
1004
- checkCustom(command, timeoutMs) {
1005
- return new Promise((resolve, reject) => {
1006
- exec(command, { timeout: timeoutMs }, (err) => {
1007
- if (err)
1008
- reject(err);
1009
- else
1010
- resolve();
1011
- });
1012
- });
1013
- }
1014
- async checkDisk(diskPath) {
1015
- const { statfs } = await import("node:fs/promises");
1016
- await statfs(diskPath); // throws if path doesn't exist
245
+ mutationHost() {
246
+ const thisEngine = this;
247
+ return {
248
+ get entries() {
249
+ return thisEngine.entries;
250
+ },
251
+ set entries(value) {
252
+ thisEngine.entries = value;
253
+ },
254
+ saveEntries: () => this.saveEntries(),
255
+ refreshEntriesForMutation: () => this.refreshEntriesForMutation(),
256
+ withScheduleMutation: (mutate) => this.withScheduleMutation(mutate),
257
+ };
1017
258
  }
1018
- // ─── Schedule computation ───
1019
- computeNextFireAt(trigger) {
1020
- if (trigger.type === "cron") {
1021
- const next = CronExpressionParser.parse(trigger.expression, { tz: trigger.timezone || "UTC" }).next();
1022
- return next.toISOString() ?? new Date().toISOString();
1023
- }
1024
- let nextTime = new Date(Date.now() + trigger.seconds * 1000);
1025
- if (trigger.jitter_factor && trigger.jitter_factor > 0) {
1026
- const jitterMs = trigger.seconds * 1000 * trigger.jitter_factor * (Math.random() * 2 - 1);
1027
- nextTime = new Date(nextTime.getTime() + jitterMs);
1028
- }
1029
- // Clamp to at least now + 1s to avoid past-scheduling from negative jitter
1030
- const minTime = Date.now() + 1000;
1031
- if (nextTime.getTime() < minTime) {
1032
- nextTime = new Date(minTime);
1033
- }
1034
- return nextTime.toISOString();
259
+ executionHost() {
260
+ const thisEngine = this;
261
+ return {
262
+ get entries() {
263
+ return thisEngine.entries;
264
+ },
265
+ set entries(value) {
266
+ thisEngine.entries = value;
267
+ },
268
+ logger: this.logger,
269
+ withScheduleFileLock: (work) => this.withScheduleFileLock(work),
270
+ refreshEntriesForMutation: () => this.refreshEntriesForMutation(),
271
+ writeEntriesAndProject: () => this.writeEntriesAndProject(),
272
+ captureExecutionSideEffects: (entryId) => this.captureExecutionSideEffects(entryId),
273
+ applyExecutionSideEffects: (entryId, sideEffects) => this.applyExecutionSideEffects(entryId, sideEffects),
274
+ recordHistory: (record) => this.recordHistory({
275
+ ...record,
276
+ attempt: record.attempt ?? 0,
277
+ scheduled_for: record.scheduled_for ?? null,
278
+ retry_at: record.retry_at ?? null,
279
+ failure_kind: record.failure_kind ?? null,
280
+ }),
281
+ executeEntry: (entry) => this.executeEntry(entry),
282
+ executeProbe: (entry) => this.executeProbe(entry),
283
+ executeCron: (entry) => this.executeCron(entry),
284
+ executeGoalTrigger: (entry) => this.executeGoalTrigger(entry),
285
+ checkEscalation: (entry, result) => this.checkEscalation(entry, result),
286
+ executeEscalationTargetGoal: (goalId) => this.executeEscalationTargetGoal(goalId),
287
+ executeEscalationTargetEntry: (entryId) => this.executeEscalationTargetEntry(entryId),
288
+ dispatchNotification: (payload) => this.dispatchNotification(payload),
289
+ };
1035
290
  }
1036
291
  }
1037
292
  //# sourceMappingURL=engine.js.map