pulseed 0.4.0 → 0.4.1

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 (335) hide show
  1. package/dist/base/state/state-manager-goal-write.d.ts +22 -0
  2. package/dist/base/state/state-manager-goal-write.d.ts.map +1 -0
  3. package/dist/base/state/state-manager-goal-write.js +74 -0
  4. package/dist/base/state/state-manager-goal-write.js.map +1 -0
  5. package/dist/base/state/state-manager-wal.d.ts +11 -0
  6. package/dist/base/state/state-manager-wal.d.ts.map +1 -0
  7. package/dist/base/state/state-manager-wal.js +89 -0
  8. package/dist/base/state/state-manager-wal.js.map +1 -0
  9. package/dist/base/state/state-manager.d.ts +1 -4
  10. package/dist/base/state/state-manager.d.ts.map +1 -1
  11. package/dist/base/state/state-manager.js +18 -127
  12. package/dist/base/state/state-manager.js.map +1 -1
  13. package/dist/interface/chat/chat-runner.d.ts +1 -1
  14. package/dist/interface/chat/event-subscriber.d.ts +4 -0
  15. package/dist/interface/chat/event-subscriber.d.ts.map +1 -1
  16. package/dist/interface/chat/event-subscriber.js +49 -2
  17. package/dist/interface/chat/event-subscriber.js.map +1 -1
  18. package/dist/interface/chat/tend-command.d.ts +1 -1
  19. package/dist/interface/cli/cli-command-registry.js +1 -1
  20. package/dist/interface/cli/cli-command-registry.js.map +1 -1
  21. package/dist/interface/cli/commands/chat.js +2 -2
  22. package/dist/interface/cli/commands/daemon.d.ts.map +1 -1
  23. package/dist/interface/cli/commands/daemon.js +87 -44
  24. package/dist/interface/cli/commands/daemon.js.map +1 -1
  25. package/dist/interface/cli/commands/schedule.js +2 -2
  26. package/dist/interface/cli/commands/setup/steps-runtime.js +1 -1
  27. package/dist/interface/cli/ensure-api-key.d.ts +4 -1
  28. package/dist/interface/cli/ensure-api-key.d.ts.map +1 -1
  29. package/dist/interface/cli/ensure-api-key.js +52 -15
  30. package/dist/interface/cli/ensure-api-key.js.map +1 -1
  31. package/dist/interface/tui/app.d.ts +1 -1
  32. package/dist/interface/tui/chat/scroll.d.ts +14 -0
  33. package/dist/interface/tui/chat/scroll.d.ts.map +1 -0
  34. package/dist/interface/tui/chat/scroll.js +46 -0
  35. package/dist/interface/tui/chat/scroll.js.map +1 -0
  36. package/dist/interface/tui/chat/suggestions.d.ts +8 -0
  37. package/dist/interface/tui/chat/suggestions.d.ts.map +1 -0
  38. package/dist/interface/tui/chat/suggestions.js +112 -0
  39. package/dist/interface/tui/chat/suggestions.js.map +1 -0
  40. package/dist/interface/tui/chat/types.d.ts +31 -0
  41. package/dist/interface/tui/chat/types.d.ts.map +1 -0
  42. package/dist/interface/tui/chat/types.js +2 -0
  43. package/dist/interface/tui/chat/types.js.map +1 -0
  44. package/dist/interface/tui/chat/viewport.d.ts +3 -0
  45. package/dist/interface/tui/chat/viewport.d.ts.map +1 -0
  46. package/dist/interface/tui/chat/viewport.js +78 -0
  47. package/dist/interface/tui/chat/viewport.js.map +1 -0
  48. package/dist/interface/tui/chat.d.ts +5 -49
  49. package/dist/interface/tui/chat.d.ts.map +1 -1
  50. package/dist/interface/tui/chat.js +7 -236
  51. package/dist/interface/tui/chat.js.map +1 -1
  52. package/dist/interface/tui/entry.js +3 -3
  53. package/dist/interface/tui/use-loop.d.ts +1 -1
  54. package/dist/orchestrator/execution/task/task-lifecycle.d.ts +3 -0
  55. package/dist/orchestrator/execution/task/task-lifecycle.d.ts.map +1 -1
  56. package/dist/orchestrator/execution/task/task-lifecycle.js +3 -0
  57. package/dist/orchestrator/execution/task/task-lifecycle.js.map +1 -1
  58. package/dist/orchestrator/execution/task/task-verifier-rules.d.ts.map +1 -1
  59. package/dist/orchestrator/execution/task/task-verifier-rules.js +34 -2
  60. package/dist/orchestrator/execution/task/task-verifier-rules.js.map +1 -1
  61. package/dist/orchestrator/execution/task/task-verifier-types.d.ts +2 -0
  62. package/dist/orchestrator/execution/task/task-verifier-types.d.ts.map +1 -1
  63. package/dist/orchestrator/loop/checkpoint-manager-loop.d.ts +1 -1
  64. package/dist/orchestrator/loop/checkpoint-manager-loop.d.ts.map +1 -1
  65. package/dist/orchestrator/loop/core-loop/capability.d.ts +22 -0
  66. package/dist/orchestrator/loop/core-loop/capability.d.ts.map +1 -0
  67. package/dist/orchestrator/loop/core-loop/capability.js +151 -0
  68. package/dist/orchestrator/loop/core-loop/capability.js.map +1 -0
  69. package/dist/orchestrator/loop/core-loop/contracts.d.ts +245 -0
  70. package/dist/orchestrator/loop/core-loop/contracts.d.ts.map +1 -0
  71. package/dist/orchestrator/loop/core-loop/contracts.js +40 -0
  72. package/dist/orchestrator/loop/core-loop/contracts.js.map +1 -0
  73. package/dist/orchestrator/loop/core-loop/control.d.ts +27 -0
  74. package/dist/orchestrator/loop/core-loop/control.d.ts.map +1 -0
  75. package/dist/orchestrator/loop/core-loop/control.js +72 -0
  76. package/dist/orchestrator/loop/core-loop/control.js.map +1 -0
  77. package/dist/orchestrator/loop/core-loop/learning.d.ts +31 -0
  78. package/dist/orchestrator/loop/core-loop/learning.d.ts.map +1 -0
  79. package/dist/orchestrator/loop/core-loop/learning.js +92 -0
  80. package/dist/orchestrator/loop/core-loop/learning.js.map +1 -0
  81. package/dist/orchestrator/loop/core-loop/preparation.d.ts +63 -0
  82. package/dist/orchestrator/loop/core-loop/preparation.d.ts.map +1 -0
  83. package/dist/orchestrator/loop/core-loop/preparation.js +362 -0
  84. package/dist/orchestrator/loop/core-loop/preparation.js.map +1 -0
  85. package/dist/orchestrator/loop/core-loop/task-cycle.d.ts +29 -0
  86. package/dist/orchestrator/loop/core-loop/task-cycle.d.ts.map +1 -0
  87. package/dist/orchestrator/loop/core-loop/task-cycle.js +674 -0
  88. package/dist/orchestrator/loop/core-loop/task-cycle.js.map +1 -0
  89. package/dist/orchestrator/loop/core-loop-capability.d.ts +1 -24
  90. package/dist/orchestrator/loop/core-loop-capability.d.ts.map +1 -1
  91. package/dist/orchestrator/loop/core-loop-capability.js +1 -153
  92. package/dist/orchestrator/loop/core-loop-capability.js.map +1 -1
  93. package/dist/orchestrator/loop/core-loop-learning.d.ts +1 -34
  94. package/dist/orchestrator/loop/core-loop-learning.d.ts.map +1 -1
  95. package/dist/orchestrator/loop/core-loop-learning.js +1 -95
  96. package/dist/orchestrator/loop/core-loop-learning.js.map +1 -1
  97. package/dist/orchestrator/loop/core-loop-phases-b.d.ts +1 -31
  98. package/dist/orchestrator/loop/core-loop-phases-b.d.ts.map +1 -1
  99. package/dist/orchestrator/loop/core-loop-phases-b.js +1 -669
  100. package/dist/orchestrator/loop/core-loop-phases-b.js.map +1 -1
  101. package/dist/orchestrator/loop/core-loop-phases-c.d.ts +1 -26
  102. package/dist/orchestrator/loop/core-loop-phases-c.d.ts.map +1 -1
  103. package/dist/orchestrator/loop/core-loop-phases-c.js +1 -71
  104. package/dist/orchestrator/loop/core-loop-phases-c.js.map +1 -1
  105. package/dist/orchestrator/loop/core-loop-phases.d.ts +1 -68
  106. package/dist/orchestrator/loop/core-loop-phases.d.ts.map +1 -1
  107. package/dist/orchestrator/loop/core-loop-phases.js +1 -367
  108. package/dist/orchestrator/loop/core-loop-phases.js.map +1 -1
  109. package/dist/orchestrator/loop/core-loop-types.d.ts +1 -244
  110. package/dist/orchestrator/loop/core-loop-types.d.ts.map +1 -1
  111. package/dist/orchestrator/loop/core-loop-types.js +1 -39
  112. package/dist/orchestrator/loop/core-loop-types.js.map +1 -1
  113. package/dist/orchestrator/loop/core-loop.d.ts +3 -3
  114. package/dist/orchestrator/loop/core-loop.d.ts.map +1 -1
  115. package/dist/orchestrator/loop/core-loop.js +6 -6
  116. package/dist/orchestrator/loop/core-loop.js.map +1 -1
  117. package/dist/orchestrator/loop/loop-report-helper.d.ts +1 -1
  118. package/dist/orchestrator/loop/loop-report-helper.d.ts.map +1 -1
  119. package/dist/orchestrator/loop/parallel-dispatch.d.ts +2 -2
  120. package/dist/orchestrator/loop/parallel-dispatch.d.ts.map +1 -1
  121. package/dist/orchestrator/loop/post-loop-hooks.d.ts +1 -1
  122. package/dist/orchestrator/loop/post-loop-hooks.d.ts.map +1 -1
  123. package/dist/orchestrator/loop/tree-loop-runner.d.ts +1 -1
  124. package/dist/orchestrator/loop/tree-loop-runner.d.ts.map +1 -1
  125. package/dist/orchestrator/loop/tree-loop-runner.js +1 -1
  126. package/dist/orchestrator/loop/tree-loop-runner.js.map +1 -1
  127. package/dist/platform/dream/dream-schedule-suggestions.d.ts +1 -1
  128. package/dist/platform/drive/drive-system.d.ts +8 -0
  129. package/dist/platform/drive/drive-system.d.ts.map +1 -1
  130. package/dist/platform/drive/drive-system.js +39 -22
  131. package/dist/platform/drive/drive-system.js.map +1 -1
  132. package/dist/platform/observation/engine/observe-context.d.ts +4 -0
  133. package/dist/platform/observation/engine/observe-context.d.ts.map +1 -0
  134. package/dist/platform/observation/engine/observe-context.js +26 -0
  135. package/dist/platform/observation/engine/observe-context.js.map +1 -0
  136. package/dist/platform/observation/engine/observe-datasource-stage.d.ts +33 -0
  137. package/dist/platform/observation/engine/observe-datasource-stage.d.ts.map +1 -0
  138. package/dist/platform/observation/engine/observe-datasource-stage.js +66 -0
  139. package/dist/platform/observation/engine/observe-datasource-stage.js.map +1 -0
  140. package/dist/platform/observation/engine/observe-llm-stage.d.ts +25 -0
  141. package/dist/platform/observation/engine/observe-llm-stage.d.ts.map +1 -0
  142. package/dist/platform/observation/engine/observe-llm-stage.js +79 -0
  143. package/dist/platform/observation/engine/observe-llm-stage.js.map +1 -0
  144. package/dist/platform/observation/engine/observe-precheck.d.ts +21 -0
  145. package/dist/platform/observation/engine/observe-precheck.d.ts.map +1 -0
  146. package/dist/platform/observation/engine/observe-precheck.js +51 -0
  147. package/dist/platform/observation/engine/observe-precheck.js.map +1 -0
  148. package/dist/platform/observation/engine/observe-self-report.d.ts +18 -0
  149. package/dist/platform/observation/engine/observe-self-report.d.ts.map +1 -0
  150. package/dist/platform/observation/engine/observe-self-report.js +26 -0
  151. package/dist/platform/observation/engine/observe-self-report.js.map +1 -0
  152. package/dist/platform/observation/engine/observe-tool-stage.d.ts +21 -0
  153. package/dist/platform/observation/engine/observe-tool-stage.d.ts.map +1 -0
  154. package/dist/platform/observation/engine/observe-tool-stage.js +49 -0
  155. package/dist/platform/observation/engine/observe-tool-stage.js.map +1 -0
  156. package/dist/platform/observation/observation-engine.d.ts.map +1 -1
  157. package/dist/platform/observation/observation-engine.js +67 -246
  158. package/dist/platform/observation/observation-engine.js.map +1 -1
  159. package/dist/prompt/context-assembler.d.ts +61 -13
  160. package/dist/prompt/context-assembler.d.ts.map +1 -1
  161. package/dist/prompt/context-assembler.js +18 -3
  162. package/dist/prompt/context-assembler.js.map +1 -1
  163. package/dist/runtime/approval-broker.d.ts.map +1 -1
  164. package/dist/runtime/approval-broker.js +1 -0
  165. package/dist/runtime/approval-broker.js.map +1 -1
  166. package/dist/runtime/command-dispatcher.d.ts +35 -0
  167. package/dist/runtime/command-dispatcher.d.ts.map +1 -0
  168. package/dist/runtime/command-dispatcher.js +145 -0
  169. package/dist/runtime/command-dispatcher.js.map +1 -0
  170. package/dist/runtime/daemon/client.d.ts +67 -0
  171. package/dist/runtime/daemon/client.d.ts.map +1 -0
  172. package/dist/runtime/daemon/client.js +330 -0
  173. package/dist/runtime/daemon/client.js.map +1 -0
  174. package/dist/runtime/daemon/health.d.ts +31 -0
  175. package/dist/runtime/daemon/health.d.ts.map +1 -0
  176. package/dist/runtime/daemon/health.js +113 -0
  177. package/dist/runtime/daemon/health.js.map +1 -0
  178. package/dist/runtime/daemon/index.d.ts +9 -0
  179. package/dist/runtime/daemon/index.d.ts.map +1 -0
  180. package/dist/runtime/daemon/index.js +8 -0
  181. package/dist/runtime/daemon/index.js.map +1 -0
  182. package/dist/runtime/daemon/maintenance.d.ts +47 -0
  183. package/dist/runtime/daemon/maintenance.d.ts.map +1 -0
  184. package/dist/runtime/daemon/maintenance.js +230 -0
  185. package/dist/runtime/daemon/maintenance.js.map +1 -0
  186. package/dist/runtime/daemon/persistence.d.ts +20 -0
  187. package/dist/runtime/daemon/persistence.d.ts.map +1 -0
  188. package/dist/runtime/daemon/persistence.js +112 -0
  189. package/dist/runtime/daemon/persistence.js.map +1 -0
  190. package/dist/runtime/daemon/runner-lifecycle.d.ts +29 -0
  191. package/dist/runtime/daemon/runner-lifecycle.d.ts.map +1 -0
  192. package/dist/runtime/daemon/runner-lifecycle.js +56 -0
  193. package/dist/runtime/daemon/runner-lifecycle.js.map +1 -0
  194. package/dist/runtime/daemon/runner.d.ts +229 -0
  195. package/dist/runtime/daemon/runner.d.ts.map +1 -0
  196. package/dist/runtime/daemon/runner.js +875 -0
  197. package/dist/runtime/daemon/runner.js.map +1 -0
  198. package/dist/runtime/daemon/runtime-ownership.d.ts +30 -0
  199. package/dist/runtime/daemon/runtime-ownership.d.ts.map +1 -0
  200. package/dist/runtime/daemon/runtime-ownership.js +132 -0
  201. package/dist/runtime/daemon/runtime-ownership.js.map +1 -0
  202. package/dist/runtime/daemon/signals.d.ts +17 -0
  203. package/dist/runtime/daemon/signals.d.ts.map +1 -0
  204. package/dist/runtime/daemon/signals.js +31 -0
  205. package/dist/runtime/daemon/signals.js.map +1 -0
  206. package/dist/runtime/daemon/types.d.ts +8 -0
  207. package/dist/runtime/daemon/types.d.ts.map +1 -0
  208. package/dist/runtime/daemon/types.js +2 -0
  209. package/dist/runtime/daemon/types.js.map +1 -0
  210. package/dist/runtime/daemon-client.d.ts +1 -55
  211. package/dist/runtime/daemon-client.d.ts.map +1 -1
  212. package/dist/runtime/daemon-client.js +1 -297
  213. package/dist/runtime/daemon-client.js.map +1 -1
  214. package/dist/runtime/daemon-health.d.ts +1 -30
  215. package/dist/runtime/daemon-health.d.ts.map +1 -1
  216. package/dist/runtime/daemon-health.js +1 -112
  217. package/dist/runtime/daemon-health.js.map +1 -1
  218. package/dist/runtime/daemon-runner-lifecycle.d.ts +2 -0
  219. package/dist/runtime/daemon-runner-lifecycle.d.ts.map +1 -0
  220. package/dist/runtime/daemon-runner-lifecycle.js +2 -0
  221. package/dist/runtime/daemon-runner-lifecycle.js.map +1 -0
  222. package/dist/runtime/daemon-runner.d.ts +1 -231
  223. package/dist/runtime/daemon-runner.d.ts.map +1 -1
  224. package/dist/runtime/daemon-runner.js +1 -1042
  225. package/dist/runtime/daemon-runner.js.map +1 -1
  226. package/dist/runtime/daemon-runtime-ownership.d.ts +2 -0
  227. package/dist/runtime/daemon-runtime-ownership.d.ts.map +1 -0
  228. package/dist/runtime/daemon-runtime-ownership.js +2 -0
  229. package/dist/runtime/daemon-runtime-ownership.js.map +1 -0
  230. package/dist/runtime/daemon-signals.d.ts +1 -16
  231. package/dist/runtime/daemon-signals.d.ts.map +1 -1
  232. package/dist/runtime/daemon-signals.js +1 -30
  233. package/dist/runtime/daemon-signals.js.map +1 -1
  234. package/dist/runtime/event/dispatcher.d.ts +34 -0
  235. package/dist/runtime/event/dispatcher.d.ts.map +1 -0
  236. package/dist/runtime/event/dispatcher.js +124 -0
  237. package/dist/runtime/event/dispatcher.js.map +1 -0
  238. package/dist/runtime/event/index.d.ts +5 -0
  239. package/dist/runtime/event/index.d.ts.map +1 -0
  240. package/dist/runtime/event/index.js +5 -0
  241. package/dist/runtime/event/index.js.map +1 -0
  242. package/dist/runtime/event/server-snapshot-reader.d.ts +31 -0
  243. package/dist/runtime/event/server-snapshot-reader.d.ts.map +1 -0
  244. package/dist/runtime/event/server-snapshot-reader.js +94 -0
  245. package/dist/runtime/event/server-snapshot-reader.js.map +1 -0
  246. package/dist/runtime/event/server-sse.d.ts +25 -0
  247. package/dist/runtime/event/server-sse.d.ts.map +1 -0
  248. package/dist/runtime/event/server-sse.js +149 -0
  249. package/dist/runtime/event/server-sse.js.map +1 -0
  250. package/dist/runtime/event/server.d.ts +114 -0
  251. package/dist/runtime/event/server.d.ts.map +1 -0
  252. package/dist/runtime/event/server.js +651 -0
  253. package/dist/runtime/event/server.js.map +1 -0
  254. package/dist/runtime/event-dispatcher.d.ts +2 -0
  255. package/dist/runtime/event-dispatcher.d.ts.map +1 -0
  256. package/dist/runtime/event-dispatcher.js +2 -0
  257. package/dist/runtime/event-dispatcher.js.map +1 -0
  258. package/dist/runtime/event-server-snapshot-reader.d.ts +2 -0
  259. package/dist/runtime/event-server-snapshot-reader.d.ts.map +1 -0
  260. package/dist/runtime/event-server-snapshot-reader.js +2 -0
  261. package/dist/runtime/event-server-snapshot-reader.js.map +1 -0
  262. package/dist/runtime/event-server-sse.d.ts +2 -0
  263. package/dist/runtime/event-server-sse.d.ts.map +1 -0
  264. package/dist/runtime/event-server-sse.js +2 -0
  265. package/dist/runtime/event-server-sse.js.map +1 -0
  266. package/dist/runtime/event-server.d.ts +1 -91
  267. package/dist/runtime/event-server.d.ts.map +1 -1
  268. package/dist/runtime/event-server.js +1 -698
  269. package/dist/runtime/event-server.js.map +1 -1
  270. package/dist/runtime/executor/loop-supervisor.d.ts +9 -5
  271. package/dist/runtime/executor/loop-supervisor.d.ts.map +1 -1
  272. package/dist/runtime/executor/loop-supervisor.js +59 -76
  273. package/dist/runtime/executor/loop-supervisor.js.map +1 -1
  274. package/dist/runtime/gateway/http-channel-adapter.d.ts +1 -1
  275. package/dist/runtime/plugin-loader.d.ts +1 -1
  276. package/dist/runtime/queue/index.d.ts +0 -4
  277. package/dist/runtime/queue/index.d.ts.map +1 -1
  278. package/dist/runtime/queue/index.js +0 -2
  279. package/dist/runtime/queue/index.js.map +1 -1
  280. package/dist/runtime/queue/journal-backed-queue.d.ts.map +1 -1
  281. package/dist/runtime/queue/journal-backed-queue.js +2 -0
  282. package/dist/runtime/queue/journal-backed-queue.js.map +1 -1
  283. package/dist/runtime/schedule/engine-layers.d.ts +44 -0
  284. package/dist/runtime/schedule/engine-layers.d.ts.map +1 -0
  285. package/dist/runtime/schedule/engine-layers.js +433 -0
  286. package/dist/runtime/schedule/engine-layers.js.map +1 -0
  287. package/dist/runtime/schedule/engine.d.ts +82 -0
  288. package/dist/runtime/schedule/engine.d.ts.map +1 -0
  289. package/dist/runtime/schedule/engine.js +480 -0
  290. package/dist/runtime/schedule/engine.js.map +1 -0
  291. package/dist/runtime/schedule/index.d.ts +5 -0
  292. package/dist/runtime/schedule/index.d.ts.map +1 -0
  293. package/dist/runtime/schedule/index.js +5 -0
  294. package/dist/runtime/schedule/index.js.map +1 -0
  295. package/dist/runtime/schedule/presets.d.ts +536 -0
  296. package/dist/runtime/schedule/presets.d.ts.map +1 -0
  297. package/dist/runtime/schedule/presets.js +166 -0
  298. package/dist/runtime/schedule/presets.js.map +1 -0
  299. package/dist/runtime/schedule/source.d.ts +65 -0
  300. package/dist/runtime/schedule/source.d.ts.map +1 -0
  301. package/dist/runtime/schedule/source.js +16 -0
  302. package/dist/runtime/schedule/source.js.map +1 -0
  303. package/dist/runtime/schedule-engine-layers.d.ts +1 -43
  304. package/dist/runtime/schedule-engine-layers.d.ts.map +1 -1
  305. package/dist/runtime/schedule-engine-layers.js +1 -432
  306. package/dist/runtime/schedule-engine-layers.js.map +1 -1
  307. package/dist/runtime/schedule-engine.d.ts +1 -81
  308. package/dist/runtime/schedule-engine.d.ts.map +1 -1
  309. package/dist/runtime/schedule-engine.js +1 -479
  310. package/dist/runtime/schedule-engine.js.map +1 -1
  311. package/dist/runtime/schedule-presets.d.ts +1 -535
  312. package/dist/runtime/schedule-presets.d.ts.map +1 -1
  313. package/dist/runtime/schedule-presets.js +1 -165
  314. package/dist/runtime/schedule-presets.js.map +1 -1
  315. package/dist/runtime/schedule-source.d.ts +1 -64
  316. package/dist/runtime/schedule-source.d.ts.map +1 -1
  317. package/dist/runtime/schedule-source.js +1 -15
  318. package/dist/runtime/schedule-source.js.map +1 -1
  319. package/dist/runtime/types/daemon.d.ts.map +1 -1
  320. package/dist/runtime/types/daemon.js +2 -1
  321. package/dist/runtime/types/daemon.js.map +1 -1
  322. package/dist/runtime/watchdog.d.ts +44 -0
  323. package/dist/runtime/watchdog.d.ts.map +1 -0
  324. package/dist/runtime/watchdog.js +185 -0
  325. package/dist/runtime/watchdog.js.map +1 -0
  326. package/dist/tools/builtin/index.d.ts +1 -1
  327. package/dist/tools/schedule/CreateScheduleTool/CreateScheduleTool.d.ts +1 -1
  328. package/dist/tools/schedule/CreateScheduleTool/CreateScheduleTool.js +1 -1
  329. package/dist/tools/schedule/GetScheduleTool/GetScheduleTool.d.ts +1 -1
  330. package/dist/tools/schedule/ListSchedulesTool/ListSchedulesTool.d.ts +1 -1
  331. package/dist/tools/schedule/PauseScheduleTool/PauseScheduleTool.d.ts +1 -1
  332. package/dist/tools/schedule/RemoveScheduleTool/RemoveScheduleTool.d.ts +1 -1
  333. package/dist/tools/schedule/ResumeScheduleTool/ResumeScheduleTool.d.ts +1 -1
  334. package/dist/tools/schedule/UpdateScheduleTool/UpdateScheduleTool.d.ts +1 -1
  335. package/package.json +1 -1
@@ -0,0 +1,651 @@
1
+ import * as fs from "node:fs";
2
+ import * as fsp from "node:fs/promises";
3
+ import * as path from "node:path";
4
+ import * as http from "node:http";
5
+ import { PulSeedEventSchema } from "../../base/types/drive.js";
6
+ import { TriggerEventSchema, TriggerMappingsConfigSchema } from "../../base/types/trigger.js";
7
+ import { getEventsDir } from "../../base/utils/paths.js";
8
+ import { findAvailablePort, DEFAULT_PORT, MAX_PORT_ATTEMPTS } from "../port-utils.js";
9
+ import { createEnvelope } from "../types/envelope.js";
10
+ import { EventServerSnapshotReader } from "./server-snapshot-reader.js";
11
+ import { EventServerSseManager } from "./server-sse.js";
12
+ export class EventServer {
13
+ server = null;
14
+ driveSystem;
15
+ host;
16
+ port;
17
+ eventsDir;
18
+ fileWatcher = null;
19
+ processingFiles = new Set();
20
+ logger;
21
+ stateManager;
22
+ triggerMapper;
23
+ snapshotReader;
24
+ sseManager;
25
+ triggerMappingsCache = null;
26
+ approvalQueue = new Map();
27
+ approvalBroker;
28
+ outboxStore;
29
+ envelopeHook;
30
+ commandEnvelopeHook;
31
+ activeWorkersProvider;
32
+ constructor(driveSystem, config, logger) {
33
+ this.driveSystem = driveSystem;
34
+ this.host = config?.host ?? "127.0.0.1";
35
+ this.port = config?.port ?? DEFAULT_PORT;
36
+ // Default events directory: ~/.pulseed/events/
37
+ this.eventsDir = config?.eventsDir ?? getEventsDir();
38
+ this.logger = logger;
39
+ this.stateManager = config?.stateManager;
40
+ this.triggerMapper = config?.triggerMapper;
41
+ this.approvalBroker = config?.approvalBroker;
42
+ this.outboxStore = config?.outboxStore;
43
+ this.snapshotReader = new EventServerSnapshotReader(this.eventsDir);
44
+ this.sseManager = new EventServerSseManager(this.logger, this.approvalBroker, this.outboxStore);
45
+ }
46
+ /** Start HTTP server, auto-retrying on EADDRINUSE up to MAX_PORT_ATTEMPTS times */
47
+ async start() {
48
+ if (this.server) {
49
+ return; // Already running
50
+ }
51
+ await fsp.mkdir(this.eventsDir, { recursive: true });
52
+ await this.approvalBroker?.start();
53
+ // If a specific non-zero port was requested, find the first available port
54
+ // starting from it. Port 0 means OS-assigned — skip auto-detection.
55
+ const startPort = this.port === 0 ? 0 : await findAvailablePort(this.port);
56
+ return new Promise((resolve, reject) => {
57
+ this.server = http.createServer((req, res) => this.handleRequest(req, res));
58
+ const server = this.server;
59
+ server.listen(startPort, this.host, () => {
60
+ // Capture the actual bound port (important for port 0 and auto-retry cases)
61
+ const addr = server.address();
62
+ if (addr && typeof addr === "object") {
63
+ this.port = addr.port;
64
+ }
65
+ this.logger?.info(`EventServer listening on ${this.host}:${this.port}`);
66
+ resolve();
67
+ });
68
+ this.server.on("error", (err) => {
69
+ // EADDRINUSE should not reach here since findAvailablePort pre-checks,
70
+ // but guard against a race condition.
71
+ if (err.code === "EADDRINUSE" && startPort !== 0) {
72
+ const fallbackStart = startPort + MAX_PORT_ATTEMPTS;
73
+ findAvailablePort(fallbackStart).then((fallback) => {
74
+ server.listen(fallback, this.host, () => {
75
+ const addr = server.address();
76
+ if (addr && typeof addr === "object") {
77
+ this.port = addr.port;
78
+ }
79
+ this.logger?.info(`EventServer listening on ${this.host}:${this.port} (fallback)`);
80
+ resolve();
81
+ });
82
+ }).catch(reject);
83
+ }
84
+ else {
85
+ reject(err);
86
+ }
87
+ });
88
+ });
89
+ }
90
+ /** Stop HTTP server */
91
+ async stop() {
92
+ this.stopFileWatcher();
93
+ await this.approvalBroker?.stop();
94
+ this.sseManager.closeAllClients();
95
+ return new Promise((resolve) => {
96
+ if (!this.server) {
97
+ resolve();
98
+ return;
99
+ }
100
+ this.server.close(() => resolve());
101
+ });
102
+ }
103
+ /**
104
+ * Start watching the events directory for new `.json` files.
105
+ * When a file appears:
106
+ * 1. Read and parse it
107
+ * 2. Validate via PulSeedEventSchema
108
+ * 3. Dispatch to DriveSystem (writeEvent)
109
+ * 4. Move to events/processed/ subdirectory
110
+ * 5. Log errors for malformed files but don't crash
111
+ *
112
+ * Creates the events directory if it doesn't exist.
113
+ */
114
+ startFileWatcher() {
115
+ if (this.fileWatcher)
116
+ return; // already watching
117
+ fs.mkdirSync(this.eventsDir, { recursive: true });
118
+ this.fileWatcher = fs.watch(this.eventsDir, (eventType, filename) => {
119
+ if ((eventType !== "rename" && eventType !== "change") || !filename)
120
+ return;
121
+ if (!filename.endsWith(".json") || filename.endsWith(".tmp"))
122
+ return;
123
+ const filePath = path.join(this.eventsDir, filename);
124
+ if (this.processingFiles.has(filename))
125
+ return;
126
+ this.processingFiles.add(filename);
127
+ void (async () => {
128
+ try {
129
+ await this.processEventFile(filePath, filename);
130
+ }
131
+ catch (err) {
132
+ this.logger?.error(`EventServer: unhandled error processing event file "${filename}": ${String(err)}`);
133
+ }
134
+ finally {
135
+ this.processingFiles.delete(filename);
136
+ }
137
+ })();
138
+ });
139
+ }
140
+ /** Stop the file watcher and clean up the handle. */
141
+ stopFileWatcher() {
142
+ if (this.fileWatcher) {
143
+ this.fileWatcher.close();
144
+ this.fileWatcher = null;
145
+ }
146
+ }
147
+ /**
148
+ * Read, validate, dispatch, and move a single event file.
149
+ * Errors are logged but never propagated (caller must not crash).
150
+ */
151
+ async processEventFile(filePath, filename) {
152
+ try {
153
+ let stat;
154
+ try {
155
+ // Retry on ENOENT: on macOS, fs.watch fires 'rename' before the file
156
+ // is visible to fsp.stat, so retry up to 3 times with 20ms delay.
157
+ let lastErr;
158
+ for (let attempt = 0; attempt < 3; attempt++) {
159
+ try {
160
+ stat = await fsp.stat(filePath);
161
+ break;
162
+ }
163
+ catch (err) {
164
+ const code = err.code;
165
+ if (code !== "ENOENT")
166
+ throw err;
167
+ lastErr = err;
168
+ await new Promise((r) => setTimeout(r, 20));
169
+ }
170
+ }
171
+ if (!stat) {
172
+ // File never appeared — already removed
173
+ void lastErr; // suppress unused warning
174
+ return;
175
+ }
176
+ }
177
+ catch {
178
+ return; // non-ENOENT error — file already removed or inaccessible
179
+ }
180
+ if (!stat.isFile())
181
+ return;
182
+ const content = await fsp.readFile(filePath, "utf-8");
183
+ const raw = JSON.parse(content);
184
+ const event = PulSeedEventSchema.parse(raw);
185
+ // Dispatch through Gateway Envelope path or direct
186
+ if (this.envelopeHook) {
187
+ await this.envelopeHook(event);
188
+ }
189
+ else {
190
+ await this.driveSystem.writeEvent(event);
191
+ }
192
+ // Move to processed/
193
+ const processedDir = path.join(this.eventsDir, "processed");
194
+ await fsp.mkdir(processedDir, { recursive: true });
195
+ const dstPath = path.join(processedDir, filename);
196
+ await fsp.rename(filePath, dstPath);
197
+ }
198
+ catch (err) {
199
+ this.logger?.error(`EventServer: failed to process event file "${filename}": ${String(err)}`);
200
+ // Do not re-throw — watcher must keep running
201
+ }
202
+ }
203
+ /** Broadcast an SSE event to all connected clients */
204
+ async broadcast(eventType, data) {
205
+ await this.sseManager.broadcast(eventType, data);
206
+ }
207
+ /** Request human approval and wait for response (5 min timeout) */
208
+ async requestApproval(goalId, task) {
209
+ if (this.approvalBroker) {
210
+ return this.approvalBroker.requestApproval(goalId, task);
211
+ }
212
+ const requestId = `approval-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
213
+ return new Promise((resolve) => {
214
+ const timer = setTimeout(() => {
215
+ this.approvalQueue.delete(requestId);
216
+ void this.broadcast("approval_resolved", { requestId, goalId, approved: false, reason: "timeout" });
217
+ resolve(false);
218
+ }, 5 * 60 * 1000);
219
+ this.approvalQueue.set(requestId, { resolve, timer });
220
+ void this.broadcast("approval_required", { requestId, goalId, task });
221
+ });
222
+ }
223
+ /** Resolve a pending approval request */
224
+ async resolveApproval(requestId, approved) {
225
+ if (this.approvalBroker) {
226
+ return this.approvalBroker.resolveApproval(requestId, approved, "http");
227
+ }
228
+ const entry = this.approvalQueue.get(requestId);
229
+ if (!entry)
230
+ return false;
231
+ clearTimeout(entry.timer);
232
+ this.approvalQueue.delete(requestId);
233
+ entry.resolve(approved);
234
+ void this.broadcast("approval_resolved", { requestId, approved });
235
+ return true;
236
+ }
237
+ /** Handle incoming HTTP request */
238
+ /** Set a hook to intercept incoming events as Envelopes (used by HttpChannelAdapter). */
239
+ setEnvelopeHook(hook) {
240
+ this.envelopeHook = hook;
241
+ }
242
+ /** Set a hook to intercept command-style HTTP actions as Envelopes. */
243
+ setCommandEnvelopeHook(hook) {
244
+ this.commandEnvelopeHook = hook;
245
+ }
246
+ setApprovalBroker(broker) {
247
+ this.approvalBroker = broker;
248
+ this.sseManager.setApprovalBroker(broker);
249
+ }
250
+ setOutboxStore(store) {
251
+ this.outboxStore = store;
252
+ this.sseManager.setOutboxStore(store);
253
+ }
254
+ setActiveWorkersProvider(provider) {
255
+ this.activeWorkersProvider = provider;
256
+ }
257
+ handleRequest(req, res) {
258
+ const requestUrl = new URL(req.url ?? "/", "http://127.0.0.1");
259
+ const urlPath = requestUrl.pathname;
260
+ // GET /health
261
+ if (req.method === "GET" && urlPath === "/health") {
262
+ res.writeHead(200, { "Content-Type": "application/json" });
263
+ res.end(JSON.stringify({ status: "ok", uptime: process.uptime() }));
264
+ return;
265
+ }
266
+ // POST /events
267
+ if (req.method === "POST" && urlPath === "/events") {
268
+ this.handlePostEvents(req, res);
269
+ return;
270
+ }
271
+ // POST /triggers
272
+ if (req.method === "POST" && urlPath === "/triggers") {
273
+ this.handlePostTriggers(req, res);
274
+ return;
275
+ }
276
+ // GET /goals
277
+ if (req.method === "GET" && urlPath === "/goals") {
278
+ void this.handleGetGoals(res);
279
+ return;
280
+ }
281
+ if (req.method === "GET" && urlPath === "/snapshot") {
282
+ void this.handleGetSnapshot(res);
283
+ return;
284
+ }
285
+ // GET /goals/:id
286
+ const goalsMatch = /^\/goals\/([^/]+)$/.exec(urlPath);
287
+ if (req.method === "GET" && goalsMatch) {
288
+ void this.handleGetGoalById(res, goalsMatch[1]);
289
+ return;
290
+ }
291
+ // GET /stream — SSE event stream
292
+ if (req.method === "GET" && urlPath === "/stream") {
293
+ void this.handleStream(req, res, requestUrl);
294
+ return;
295
+ }
296
+ // GET /daemon/status
297
+ if (req.method === "GET" && urlPath === "/daemon/status") {
298
+ void (async () => {
299
+ const raw = await this.snapshotReader.readDaemonStateRaw();
300
+ if (raw !== null) {
301
+ res.writeHead(200, { "Content-Type": "application/json" });
302
+ res.end(raw);
303
+ }
304
+ else {
305
+ res.writeHead(404, { "Content-Type": "application/json" });
306
+ res.end(JSON.stringify({ error: "daemon state not found" }));
307
+ }
308
+ })();
309
+ return;
310
+ }
311
+ // POST /goals/:id/start|stop|approve|chat
312
+ const goalActionMatch = /^\/goals\/([^/]+)\/([^/]+)$/.exec(urlPath);
313
+ if (req.method === "POST" && goalActionMatch) {
314
+ const goalId = goalActionMatch[1];
315
+ const action = goalActionMatch[2];
316
+ void (async () => {
317
+ if (action === "start") {
318
+ try {
319
+ await this.dispatchCommandEnvelope({
320
+ name: "goal_start",
321
+ goalId,
322
+ payload: { goalId },
323
+ });
324
+ await this.broadcast("goal_start_requested", { goalId });
325
+ res.writeHead(200, { "Content-Type": "application/json" });
326
+ res.end(JSON.stringify({ ok: true, goalId }));
327
+ }
328
+ catch (err) {
329
+ res.writeHead(500, { "Content-Type": "application/json" });
330
+ res.end(JSON.stringify({ error: "Command accept failed", details: String(err) }));
331
+ }
332
+ }
333
+ else if (action === "stop") {
334
+ try {
335
+ await this.dispatchCommandEnvelope({
336
+ name: "goal_stop",
337
+ goalId,
338
+ payload: { goalId },
339
+ });
340
+ await this.broadcast("goal_stop_requested", { goalId });
341
+ res.writeHead(200, { "Content-Type": "application/json" });
342
+ res.end(JSON.stringify({ ok: true, goalId }));
343
+ }
344
+ catch (err) {
345
+ res.writeHead(500, { "Content-Type": "application/json" });
346
+ res.end(JSON.stringify({ error: "Command accept failed", details: String(err) }));
347
+ }
348
+ }
349
+ else if (action === "approve") {
350
+ try {
351
+ const body = await readBody(req);
352
+ const { requestId, approved } = JSON.parse(body);
353
+ if (!this.approvalBroker && !this.approvalQueue.has(requestId)) {
354
+ res.writeHead(404, { "Content-Type": "application/json" });
355
+ res.end(JSON.stringify({ ok: false }));
356
+ return;
357
+ }
358
+ await this.dispatchCommandEnvelope({
359
+ name: "approval_response",
360
+ goalId,
361
+ priority: "high",
362
+ dedupeKey: `approval_response:${requestId}`,
363
+ payload: { goalId, requestId, approved },
364
+ });
365
+ const resolved = await this.resolveApproval(requestId, approved);
366
+ res.writeHead(resolved ? 200 : 404, { "Content-Type": "application/json" });
367
+ res.end(JSON.stringify({ ok: resolved }));
368
+ }
369
+ catch (err) {
370
+ res.writeHead(400, { "Content-Type": "application/json" });
371
+ res.end(JSON.stringify({ error: "Invalid approval response", details: String(err) }));
372
+ }
373
+ }
374
+ else if (action === "chat") {
375
+ try {
376
+ const body = await readBody(req);
377
+ const { message } = JSON.parse(body);
378
+ await this.dispatchCommandEnvelope({
379
+ name: "chat_message",
380
+ goalId,
381
+ payload: { goalId, message },
382
+ });
383
+ await this.broadcast("chat_message_received", { goalId, message });
384
+ res.writeHead(200, { "Content-Type": "application/json" });
385
+ res.end(JSON.stringify({ ok: true }));
386
+ }
387
+ catch (err) {
388
+ res.writeHead(400, { "Content-Type": "application/json" });
389
+ res.end(JSON.stringify({ error: "Invalid chat message", details: String(err) }));
390
+ }
391
+ }
392
+ else {
393
+ res.writeHead(404, { "Content-Type": "application/json" });
394
+ res.end(JSON.stringify({ error: "Not found" }));
395
+ }
396
+ })();
397
+ return;
398
+ }
399
+ res.writeHead(404, { "Content-Type": "application/json" });
400
+ res.end(JSON.stringify({ error: "Not found" }));
401
+ }
402
+ handlePostEvents(req, res) {
403
+ const MAX_BODY_SIZE = 1_048_576; // 1 MB
404
+ let body = "";
405
+ let bytesReceived = 0;
406
+ req.on("data", (chunk) => {
407
+ bytesReceived += chunk.length;
408
+ if (bytesReceived > MAX_BODY_SIZE) {
409
+ res.writeHead(413, { "Content-Type": "application/json" });
410
+ res.end(JSON.stringify({ error: "Payload too large" }));
411
+ req.destroy();
412
+ return;
413
+ }
414
+ body += chunk;
415
+ });
416
+ req.on("end", () => {
417
+ void (async () => {
418
+ try {
419
+ const data = JSON.parse(body);
420
+ const event = PulSeedEventSchema.parse(data);
421
+ if (this.envelopeHook) {
422
+ // Route through Gateway Envelope path and wait for durable accept.
423
+ await this.envelopeHook(event);
424
+ }
425
+ else {
426
+ await this.driveSystem.writeEvent(event);
427
+ }
428
+ res.writeHead(200, { "Content-Type": "application/json" });
429
+ res.end(JSON.stringify({ status: "accepted", event_type: event.type }));
430
+ }
431
+ catch (err) {
432
+ res.writeHead(400, { "Content-Type": "application/json" });
433
+ res.end(JSON.stringify({ error: "Invalid event", details: String(err) }));
434
+ }
435
+ })();
436
+ });
437
+ }
438
+ handlePostTriggers(req, res) {
439
+ const MAX_BODY_SIZE = 1_048_576;
440
+ let body = "";
441
+ let bytesReceived = 0;
442
+ req.on("data", (chunk) => {
443
+ bytesReceived += chunk.length;
444
+ if (bytesReceived > MAX_BODY_SIZE) {
445
+ res.writeHead(413, { "Content-Type": "application/json" });
446
+ res.end(JSON.stringify({ error: "Payload too large" }));
447
+ req.destroy();
448
+ return;
449
+ }
450
+ body += chunk;
451
+ });
452
+ req.on("end", () => {
453
+ void (async () => {
454
+ try {
455
+ const data = JSON.parse(body);
456
+ const trigger = TriggerEventSchema.parse(data);
457
+ let action;
458
+ let goalId;
459
+ if (this.triggerMapper) {
460
+ const resolved = await this.triggerMapper.resolve(trigger, []);
461
+ if (resolved.action === "none") {
462
+ res.writeHead(200, { "Content-Type": "application/json" });
463
+ res.end(JSON.stringify({ status: "no_mapping" }));
464
+ return;
465
+ }
466
+ action = resolved.action;
467
+ goalId = resolved.goal_id ?? undefined;
468
+ }
469
+ else {
470
+ const mappingsConfig = await this.loadTriggerMappings();
471
+ const mapping = mappingsConfig.mappings.find((m) => m.source === trigger.source && m.event_type === trigger.event_type);
472
+ goalId = mapping?.goal_id ?? trigger.goal_id;
473
+ if (!mapping) {
474
+ if (!trigger.goal_id) {
475
+ res.writeHead(200, { "Content-Type": "application/json" });
476
+ res.end(JSON.stringify({ status: "no_mapping" }));
477
+ return;
478
+ }
479
+ action = "observe";
480
+ }
481
+ else {
482
+ action = mapping.action;
483
+ }
484
+ }
485
+ await this.executeTriggerAction(action, trigger, goalId ?? undefined);
486
+ res.writeHead(200, { "Content-Type": "application/json" });
487
+ res.end(JSON.stringify({ status: "ok", action, goal_id: goalId ?? null }));
488
+ }
489
+ catch (err) {
490
+ res.writeHead(400, { "Content-Type": "application/json" });
491
+ res.end(JSON.stringify({ error: "Invalid trigger", details: String(err) }));
492
+ }
493
+ })();
494
+ });
495
+ }
496
+ async executeTriggerAction(action, trigger, goalId) {
497
+ if (action === "observe") {
498
+ const event = PulSeedEventSchema.parse({
499
+ type: "external",
500
+ source: trigger.source,
501
+ timestamp: new Date().toISOString(),
502
+ data: { ...trigger.data, event_type: trigger.event_type, goal_id: goalId },
503
+ });
504
+ try {
505
+ if (this.envelopeHook) {
506
+ await this.envelopeHook(event);
507
+ }
508
+ else {
509
+ await this.driveSystem.writeEvent(event);
510
+ }
511
+ }
512
+ catch (err) {
513
+ this.logger?.error(`EventServer: trigger observe failed: ${String(err)}`);
514
+ throw err;
515
+ }
516
+ }
517
+ else if (action === "create_task") {
518
+ const filename = `trigger_${Date.now()}_${Math.random().toString(36).slice(2)}.json`;
519
+ const filePath = path.join(this.eventsDir, filename);
520
+ const payload = {
521
+ type: "external",
522
+ source: trigger.source,
523
+ timestamp: new Date().toISOString(),
524
+ data: { ...trigger.data, event_type: trigger.event_type, action: "create_task", goal_id: goalId },
525
+ };
526
+ await fsp.writeFile(filePath, JSON.stringify(payload), "utf-8");
527
+ }
528
+ else if (action === "notify") {
529
+ this.logger?.warn(`EventServer: trigger notify — source=${trigger.source} event_type=${trigger.event_type} goal_id=${goalId ?? "none"}`);
530
+ }
531
+ else if (action === "wake") {
532
+ this.logger?.warn(`EventServer: trigger wake — source=${trigger.source} event_type=${trigger.event_type}`);
533
+ }
534
+ }
535
+ async loadTriggerMappings() {
536
+ if (this.triggerMappingsCache !== null)
537
+ return this.triggerMappingsCache;
538
+ const mappingsPath = path.join(this.eventsDir, "..", "trigger-mappings.json");
539
+ try {
540
+ const content = await fsp.readFile(mappingsPath, "utf-8");
541
+ const raw = JSON.parse(content);
542
+ this.triggerMappingsCache = TriggerMappingsConfigSchema.parse(raw);
543
+ }
544
+ catch (err) {
545
+ const code = err.code;
546
+ if (code !== "ENOENT") {
547
+ this.logger?.warn(`EventServer: failed to load trigger-mappings.json: ${String(err)}`);
548
+ }
549
+ this.triggerMappingsCache = { mappings: [] };
550
+ }
551
+ return this.triggerMappingsCache;
552
+ }
553
+ /** Invalidate the trigger mappings cache (for testing or hot-reload). */
554
+ invalidateTriggerMappingsCache() {
555
+ this.triggerMappingsCache = null;
556
+ }
557
+ async handleGetGoals(res) {
558
+ try {
559
+ const goals = await this.snapshotReader.readGoalSummaries();
560
+ res.writeHead(200, { "Content-Type": "application/json" });
561
+ res.end(JSON.stringify(goals));
562
+ }
563
+ catch (err) {
564
+ res.writeHead(500, { "Content-Type": "application/json" });
565
+ res.end(JSON.stringify({ error: "Internal error", details: String(err) }));
566
+ }
567
+ }
568
+ async handleGetGoalById(res, goalId) {
569
+ try {
570
+ const goal = await this.snapshotReader.readGoalDetail(goalId);
571
+ if (goal === null) {
572
+ res.writeHead(404, { "Content-Type": "application/json" });
573
+ res.end(JSON.stringify({ error: "Goal not found" }));
574
+ return;
575
+ }
576
+ res.writeHead(200, { "Content-Type": "application/json" });
577
+ res.end(JSON.stringify(goal));
578
+ }
579
+ catch (err) {
580
+ res.writeHead(500, { "Content-Type": "application/json" });
581
+ res.end(JSON.stringify({ error: "Internal error", details: String(err) }));
582
+ }
583
+ }
584
+ /** Check if server is running */
585
+ isRunning() {
586
+ return this.server !== null && this.server.listening;
587
+ }
588
+ /** Check if file watcher is active (internal use) */
589
+ isWatching() {
590
+ return this.fileWatcher !== null;
591
+ }
592
+ getPort() {
593
+ return this.port;
594
+ }
595
+ getHost() {
596
+ return this.host;
597
+ }
598
+ getEventsDir() {
599
+ return this.eventsDir;
600
+ }
601
+ async handleGetSnapshot(res) {
602
+ try {
603
+ const snapshot = await this.buildSnapshot();
604
+ res.writeHead(200, { "Content-Type": "application/json" });
605
+ res.end(JSON.stringify(snapshot));
606
+ }
607
+ catch (err) {
608
+ res.writeHead(500, { "Content-Type": "application/json" });
609
+ res.end(JSON.stringify({ error: "Internal error", details: String(err) }));
610
+ }
611
+ }
612
+ async handleStream(req, res, requestUrl) {
613
+ await this.sseManager.handleStream(req, res, requestUrl);
614
+ }
615
+ async dispatchCommandEnvelope(input) {
616
+ if (!this.commandEnvelopeHook)
617
+ return;
618
+ await this.commandEnvelopeHook(createEnvelope({
619
+ type: "command",
620
+ name: input.name,
621
+ source: "http",
622
+ goal_id: input.goalId,
623
+ priority: input.priority,
624
+ dedupe_key: input.dedupeKey,
625
+ payload: input.payload,
626
+ }));
627
+ }
628
+ async buildSnapshot() {
629
+ return this.snapshotReader.buildSnapshot(this.approvalBroker?.getPendingApprovalEvents() ?? [], this.outboxStore, this.activeWorkersProvider);
630
+ }
631
+ }
632
+ /** Read the full request body as a string (max 1 MB). */
633
+ function readBody(req) {
634
+ return new Promise((resolve, reject) => {
635
+ const MAX = 1_048_576;
636
+ let body = "";
637
+ let bytes = 0;
638
+ req.on("data", (chunk) => {
639
+ bytes += chunk.length;
640
+ if (bytes > MAX) {
641
+ reject(new Error("Payload too large"));
642
+ req.destroy();
643
+ return;
644
+ }
645
+ body += chunk;
646
+ });
647
+ req.on("end", () => resolve(body));
648
+ req.on("error", reject);
649
+ });
650
+ }
651
+ //# sourceMappingURL=server.js.map