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
@@ -1,699 +1,2 @@
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
- export class EventServer {
11
- server = null;
12
- driveSystem;
13
- host;
14
- port;
15
- eventsDir;
16
- fileWatcher = null;
17
- processingFiles = new Set();
18
- logger;
19
- stateManager;
20
- triggerMapper;
21
- triggerMappingsCache = null;
22
- sseClients = new Set();
23
- eventIdCounter = 0;
24
- approvalQueue = new Map();
25
- approvalBroker;
26
- envelopeHook;
27
- commandEnvelopeHook;
28
- constructor(driveSystem, config, logger) {
29
- this.driveSystem = driveSystem;
30
- this.host = config?.host ?? "127.0.0.1";
31
- this.port = config?.port ?? DEFAULT_PORT;
32
- // Default events directory: ~/.pulseed/events/
33
- this.eventsDir = config?.eventsDir ?? getEventsDir();
34
- this.logger = logger;
35
- this.stateManager = config?.stateManager;
36
- this.triggerMapper = config?.triggerMapper;
37
- this.approvalBroker = config?.approvalBroker;
38
- }
39
- /** Start HTTP server, auto-retrying on EADDRINUSE up to MAX_PORT_ATTEMPTS times */
40
- async start() {
41
- if (this.server) {
42
- return; // Already running
43
- }
44
- await fsp.mkdir(this.eventsDir, { recursive: true });
45
- await this.approvalBroker?.start();
46
- // If a specific non-zero port was requested, find the first available port
47
- // starting from it. Port 0 means OS-assigned — skip auto-detection.
48
- const startPort = this.port === 0 ? 0 : await findAvailablePort(this.port);
49
- return new Promise((resolve, reject) => {
50
- this.server = http.createServer((req, res) => this.handleRequest(req, res));
51
- const server = this.server;
52
- server.listen(startPort, this.host, () => {
53
- // Capture the actual bound port (important for port 0 and auto-retry cases)
54
- const addr = server.address();
55
- if (addr && typeof addr === "object") {
56
- this.port = addr.port;
57
- }
58
- this.logger?.info(`EventServer listening on ${this.host}:${this.port}`);
59
- resolve();
60
- });
61
- this.server.on("error", (err) => {
62
- // EADDRINUSE should not reach here since findAvailablePort pre-checks,
63
- // but guard against a race condition.
64
- if (err.code === "EADDRINUSE" && startPort !== 0) {
65
- const fallbackStart = startPort + MAX_PORT_ATTEMPTS;
66
- findAvailablePort(fallbackStart).then((fallback) => {
67
- server.listen(fallback, this.host, () => {
68
- const addr = server.address();
69
- if (addr && typeof addr === "object") {
70
- this.port = addr.port;
71
- }
72
- this.logger?.info(`EventServer listening on ${this.host}:${this.port} (fallback)`);
73
- resolve();
74
- });
75
- }).catch(reject);
76
- }
77
- else {
78
- reject(err);
79
- }
80
- });
81
- });
82
- }
83
- /** Stop HTTP server */
84
- async stop() {
85
- this.stopFileWatcher();
86
- await this.approvalBroker?.stop();
87
- // Close all SSE connections
88
- for (const client of this.sseClients) {
89
- try {
90
- client.end();
91
- }
92
- catch { /* ignore */ }
93
- }
94
- this.sseClients.clear();
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
- broadcast(eventType, data) {
205
- this.eventIdCounter++;
206
- const id = String(this.eventIdCounter);
207
- const payload = `id: ${id}\nevent: ${eventType}\ndata: ${JSON.stringify(data)}\n\n`;
208
- for (const client of this.sseClients) {
209
- try {
210
- client.write(payload);
211
- }
212
- catch {
213
- this.sseClients.delete(client);
214
- }
215
- }
216
- }
217
- /** Request human approval and wait for response (5 min timeout) */
218
- async requestApproval(goalId, task) {
219
- if (this.approvalBroker) {
220
- return this.approvalBroker.requestApproval(goalId, task);
221
- }
222
- const requestId = `approval-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
223
- return new Promise((resolve) => {
224
- const timer = setTimeout(() => {
225
- this.approvalQueue.delete(requestId);
226
- this.broadcast("approval_resolved", { requestId, approved: false, reason: "timeout" });
227
- resolve(false);
228
- }, 5 * 60 * 1000);
229
- this.approvalQueue.set(requestId, { resolve, timer });
230
- this.broadcast("approval_required", { requestId, goalId, task });
231
- });
232
- }
233
- /** Resolve a pending approval request */
234
- async resolveApproval(requestId, approved) {
235
- if (this.approvalBroker) {
236
- return this.approvalBroker.resolveApproval(requestId, approved, "http");
237
- }
238
- const entry = this.approvalQueue.get(requestId);
239
- if (!entry)
240
- return false;
241
- clearTimeout(entry.timer);
242
- this.approvalQueue.delete(requestId);
243
- entry.resolve(approved);
244
- this.broadcast("approval_resolved", { requestId, approved });
245
- return true;
246
- }
247
- /** Handle incoming HTTP request */
248
- /** Set a hook to intercept incoming events as Envelopes (used by HttpChannelAdapter). */
249
- setEnvelopeHook(hook) {
250
- this.envelopeHook = hook;
251
- }
252
- /** Set a hook to intercept command-style HTTP actions as Envelopes. */
253
- setCommandEnvelopeHook(hook) {
254
- this.commandEnvelopeHook = hook;
255
- }
256
- setApprovalBroker(broker) {
257
- this.approvalBroker = broker;
258
- }
259
- handleRequest(req, res) {
260
- const urlPath = req.url?.split("?")[0] ?? "/";
261
- // GET /health
262
- if (req.method === "GET" && urlPath === "/health") {
263
- res.writeHead(200, { "Content-Type": "application/json" });
264
- res.end(JSON.stringify({ status: "ok", uptime: process.uptime() }));
265
- return;
266
- }
267
- // POST /events
268
- if (req.method === "POST" && urlPath === "/events") {
269
- this.handlePostEvents(req, res);
270
- return;
271
- }
272
- // POST /triggers
273
- if (req.method === "POST" && urlPath === "/triggers") {
274
- this.handlePostTriggers(req, res);
275
- return;
276
- }
277
- // GET /goals
278
- if (req.method === "GET" && urlPath === "/goals") {
279
- void this.handleGetGoals(res);
280
- return;
281
- }
282
- // GET /goals/:id
283
- const goalsMatch = /^\/goals\/([^/]+)$/.exec(urlPath);
284
- if (req.method === "GET" && goalsMatch) {
285
- void this.handleGetGoalById(res, goalsMatch[1]);
286
- return;
287
- }
288
- // GET /stream — SSE event stream
289
- if (req.method === "GET" && urlPath === "/stream") {
290
- res.writeHead(200, {
291
- "Content-Type": "text/event-stream",
292
- "Cache-Control": "no-cache",
293
- Connection: "keep-alive",
294
- "Access-Control-Allow-Origin": "*",
295
- });
296
- res.write(`event: connected\ndata: ${JSON.stringify({ timestamp: new Date().toISOString() })}\n\n`);
297
- this.sseClients.add(res);
298
- for (const pending of this.approvalBroker?.getPendingApprovalEvents() ?? []) {
299
- this.writeSseEvent(res, "approval_required", pending);
300
- }
301
- req.on("close", () => { this.sseClients.delete(res); });
302
- const keepAlive = setInterval(() => {
303
- try {
304
- res.write(": keepalive\n\n");
305
- }
306
- catch {
307
- clearInterval(keepAlive);
308
- this.sseClients.delete(res);
309
- }
310
- }, 30_000);
311
- req.on("close", () => clearInterval(keepAlive));
312
- return;
313
- }
314
- // GET /daemon/status
315
- if (req.method === "GET" && urlPath === "/daemon/status") {
316
- void (async () => {
317
- const statePath = path.join(this.eventsDir.replace("/events", ""), "daemon-state.json");
318
- try {
319
- const raw = await fsp.readFile(statePath, "utf-8");
320
- res.writeHead(200, { "Content-Type": "application/json" });
321
- res.end(raw);
322
- }
323
- catch {
324
- res.writeHead(404, { "Content-Type": "application/json" });
325
- res.end(JSON.stringify({ error: "daemon state not found" }));
326
- }
327
- })();
328
- return;
329
- }
330
- // POST /goals/:id/start|stop|approve|chat
331
- const goalActionMatch = /^\/goals\/([^/]+)\/([^/]+)$/.exec(urlPath);
332
- if (req.method === "POST" && goalActionMatch) {
333
- const goalId = goalActionMatch[1];
334
- const action = goalActionMatch[2];
335
- void (async () => {
336
- if (action === "start") {
337
- try {
338
- await this.dispatchCommandEnvelope({
339
- name: "goal_start",
340
- goalId,
341
- payload: { goalId },
342
- });
343
- this.broadcast("goal_start_requested", { goalId });
344
- res.writeHead(200, { "Content-Type": "application/json" });
345
- res.end(JSON.stringify({ ok: true, goalId }));
346
- }
347
- catch (err) {
348
- res.writeHead(500, { "Content-Type": "application/json" });
349
- res.end(JSON.stringify({ error: "Command accept failed", details: String(err) }));
350
- }
351
- }
352
- else if (action === "stop") {
353
- try {
354
- await this.dispatchCommandEnvelope({
355
- name: "goal_stop",
356
- goalId,
357
- payload: { goalId },
358
- });
359
- this.broadcast("goal_stop_requested", { goalId });
360
- res.writeHead(200, { "Content-Type": "application/json" });
361
- res.end(JSON.stringify({ ok: true, goalId }));
362
- }
363
- catch (err) {
364
- res.writeHead(500, { "Content-Type": "application/json" });
365
- res.end(JSON.stringify({ error: "Command accept failed", details: String(err) }));
366
- }
367
- }
368
- else if (action === "approve") {
369
- try {
370
- const body = await readBody(req);
371
- const { requestId, approved } = JSON.parse(body);
372
- if (!this.approvalBroker && !this.approvalQueue.has(requestId)) {
373
- res.writeHead(404, { "Content-Type": "application/json" });
374
- res.end(JSON.stringify({ ok: false }));
375
- return;
376
- }
377
- await this.dispatchCommandEnvelope({
378
- name: "approval_response",
379
- goalId,
380
- priority: "high",
381
- dedupeKey: `approval_response:${requestId}`,
382
- payload: { goalId, requestId, approved },
383
- });
384
- const resolved = await this.resolveApproval(requestId, approved);
385
- res.writeHead(resolved ? 200 : 404, { "Content-Type": "application/json" });
386
- res.end(JSON.stringify({ ok: resolved }));
387
- }
388
- catch (err) {
389
- res.writeHead(400, { "Content-Type": "application/json" });
390
- res.end(JSON.stringify({ error: "Invalid approval response", details: String(err) }));
391
- }
392
- }
393
- else if (action === "chat") {
394
- try {
395
- const body = await readBody(req);
396
- const { message } = JSON.parse(body);
397
- await this.dispatchCommandEnvelope({
398
- name: "chat_message",
399
- goalId,
400
- payload: { goalId, message },
401
- });
402
- this.broadcast("chat_message_received", { goalId, message });
403
- res.writeHead(200, { "Content-Type": "application/json" });
404
- res.end(JSON.stringify({ ok: true }));
405
- }
406
- catch (err) {
407
- res.writeHead(400, { "Content-Type": "application/json" });
408
- res.end(JSON.stringify({ error: "Invalid chat message", details: String(err) }));
409
- }
410
- }
411
- else {
412
- res.writeHead(404, { "Content-Type": "application/json" });
413
- res.end(JSON.stringify({ error: "Not found" }));
414
- }
415
- })();
416
- return;
417
- }
418
- res.writeHead(404, { "Content-Type": "application/json" });
419
- res.end(JSON.stringify({ error: "Not found" }));
420
- }
421
- handlePostEvents(req, res) {
422
- const MAX_BODY_SIZE = 1_048_576; // 1 MB
423
- let body = "";
424
- let bytesReceived = 0;
425
- req.on("data", (chunk) => {
426
- bytesReceived += chunk.length;
427
- if (bytesReceived > MAX_BODY_SIZE) {
428
- res.writeHead(413, { "Content-Type": "application/json" });
429
- res.end(JSON.stringify({ error: "Payload too large" }));
430
- req.destroy();
431
- return;
432
- }
433
- body += chunk;
434
- });
435
- req.on("end", () => {
436
- void (async () => {
437
- try {
438
- const data = JSON.parse(body);
439
- const event = PulSeedEventSchema.parse(data);
440
- if (this.envelopeHook) {
441
- // Route through Gateway Envelope path and wait for durable accept.
442
- await this.envelopeHook(event);
443
- }
444
- else {
445
- await this.driveSystem.writeEvent(event);
446
- }
447
- res.writeHead(200, { "Content-Type": "application/json" });
448
- res.end(JSON.stringify({ status: "accepted", event_type: event.type }));
449
- }
450
- catch (err) {
451
- res.writeHead(400, { "Content-Type": "application/json" });
452
- res.end(JSON.stringify({ error: "Invalid event", details: String(err) }));
453
- }
454
- })();
455
- });
456
- }
457
- handlePostTriggers(req, res) {
458
- const MAX_BODY_SIZE = 1_048_576;
459
- let body = "";
460
- let bytesReceived = 0;
461
- req.on("data", (chunk) => {
462
- bytesReceived += chunk.length;
463
- if (bytesReceived > MAX_BODY_SIZE) {
464
- res.writeHead(413, { "Content-Type": "application/json" });
465
- res.end(JSON.stringify({ error: "Payload too large" }));
466
- req.destroy();
467
- return;
468
- }
469
- body += chunk;
470
- });
471
- req.on("end", () => {
472
- void (async () => {
473
- try {
474
- const data = JSON.parse(body);
475
- const trigger = TriggerEventSchema.parse(data);
476
- let action;
477
- let goalId;
478
- if (this.triggerMapper) {
479
- const resolved = await this.triggerMapper.resolve(trigger, []);
480
- if (resolved.action === "none") {
481
- res.writeHead(200, { "Content-Type": "application/json" });
482
- res.end(JSON.stringify({ status: "no_mapping" }));
483
- return;
484
- }
485
- action = resolved.action;
486
- goalId = resolved.goal_id ?? undefined;
487
- }
488
- else {
489
- const mappingsConfig = await this.loadTriggerMappings();
490
- const mapping = mappingsConfig.mappings.find((m) => m.source === trigger.source && m.event_type === trigger.event_type);
491
- goalId = mapping?.goal_id ?? trigger.goal_id;
492
- if (!mapping) {
493
- if (!trigger.goal_id) {
494
- res.writeHead(200, { "Content-Type": "application/json" });
495
- res.end(JSON.stringify({ status: "no_mapping" }));
496
- return;
497
- }
498
- action = "observe";
499
- }
500
- else {
501
- action = mapping.action;
502
- }
503
- }
504
- await this.executeTriggerAction(action, trigger, goalId ?? undefined);
505
- res.writeHead(200, { "Content-Type": "application/json" });
506
- res.end(JSON.stringify({ status: "ok", action, goal_id: goalId ?? null }));
507
- }
508
- catch (err) {
509
- res.writeHead(400, { "Content-Type": "application/json" });
510
- res.end(JSON.stringify({ error: "Invalid trigger", details: String(err) }));
511
- }
512
- })();
513
- });
514
- }
515
- async executeTriggerAction(action, trigger, goalId) {
516
- if (action === "observe") {
517
- const event = PulSeedEventSchema.parse({
518
- type: "external",
519
- source: trigger.source,
520
- timestamp: new Date().toISOString(),
521
- data: { ...trigger.data, event_type: trigger.event_type, goal_id: goalId },
522
- });
523
- try {
524
- if (this.envelopeHook) {
525
- await this.envelopeHook(event);
526
- }
527
- else {
528
- await this.driveSystem.writeEvent(event);
529
- }
530
- }
531
- catch (err) {
532
- this.logger?.error(`EventServer: trigger observe failed: ${String(err)}`);
533
- throw err;
534
- }
535
- }
536
- else if (action === "create_task") {
537
- const filename = `trigger_${Date.now()}_${Math.random().toString(36).slice(2)}.json`;
538
- const filePath = path.join(this.eventsDir, filename);
539
- const payload = {
540
- type: "external",
541
- source: trigger.source,
542
- timestamp: new Date().toISOString(),
543
- data: { ...trigger.data, event_type: trigger.event_type, action: "create_task", goal_id: goalId },
544
- };
545
- await fsp.writeFile(filePath, JSON.stringify(payload), "utf-8");
546
- }
547
- else if (action === "notify") {
548
- this.logger?.warn(`EventServer: trigger notify — source=${trigger.source} event_type=${trigger.event_type} goal_id=${goalId ?? "none"}`);
549
- }
550
- else if (action === "wake") {
551
- this.logger?.warn(`EventServer: trigger wake — source=${trigger.source} event_type=${trigger.event_type}`);
552
- }
553
- }
554
- async loadTriggerMappings() {
555
- if (this.triggerMappingsCache !== null)
556
- return this.triggerMappingsCache;
557
- const mappingsPath = path.join(this.eventsDir, "..", "trigger-mappings.json");
558
- try {
559
- const content = await fsp.readFile(mappingsPath, "utf-8");
560
- const raw = JSON.parse(content);
561
- this.triggerMappingsCache = TriggerMappingsConfigSchema.parse(raw);
562
- }
563
- catch (err) {
564
- const code = err.code;
565
- if (code !== "ENOENT") {
566
- this.logger?.warn(`EventServer: failed to load trigger-mappings.json: ${String(err)}`);
567
- }
568
- this.triggerMappingsCache = { mappings: [] };
569
- }
570
- return this.triggerMappingsCache;
571
- }
572
- /** Invalidate the trigger mappings cache (for testing or hot-reload). */
573
- invalidateTriggerMappingsCache() {
574
- this.triggerMappingsCache = null;
575
- }
576
- async handleGetGoals(res) {
577
- try {
578
- const goalsDir = path.join(path.dirname(this.eventsDir), "goals");
579
- let entries;
580
- try {
581
- entries = await fsp.readdir(goalsDir);
582
- }
583
- catch {
584
- res.writeHead(200, { "Content-Type": "application/json" });
585
- res.end(JSON.stringify([]));
586
- return;
587
- }
588
- const goals = [];
589
- for (const entry of entries) {
590
- const goalFile = path.join(goalsDir, entry, "goal.json");
591
- try {
592
- const content = await fsp.readFile(goalFile, "utf-8");
593
- const raw = JSON.parse(content);
594
- goals.push({
595
- id: String(raw["id"] ?? entry),
596
- title: String(raw["title"] ?? ""),
597
- status: String(raw["status"] ?? "active"),
598
- loop_status: String(raw["loop_status"] ?? "idle"),
599
- });
600
- }
601
- catch {
602
- // Skip unreadable entries
603
- }
604
- }
605
- res.writeHead(200, { "Content-Type": "application/json" });
606
- res.end(JSON.stringify(goals));
607
- }
608
- catch (err) {
609
- res.writeHead(500, { "Content-Type": "application/json" });
610
- res.end(JSON.stringify({ error: "Internal error", details: String(err) }));
611
- }
612
- }
613
- async handleGetGoalById(res, goalId) {
614
- try {
615
- const goalFile = path.join(path.dirname(this.eventsDir), "goals", goalId, "goal.json");
616
- let goalRaw;
617
- try {
618
- const content = await fsp.readFile(goalFile, "utf-8");
619
- goalRaw = JSON.parse(content);
620
- }
621
- catch {
622
- res.writeHead(404, { "Content-Type": "application/json" });
623
- res.end(JSON.stringify({ error: "Goal not found" }));
624
- return;
625
- }
626
- const gapFile = path.join(path.dirname(this.eventsDir), "goals", goalId, "gap-history.json");
627
- let currentGap = null;
628
- try {
629
- const gapContent = await fsp.readFile(gapFile, "utf-8");
630
- const gapHistory = JSON.parse(gapContent);
631
- currentGap = gapHistory.at(-1) ?? null;
632
- }
633
- catch {
634
- // Gap file may not exist
635
- }
636
- res.writeHead(200, { "Content-Type": "application/json" });
637
- res.end(JSON.stringify({ ...goalRaw, current_gap: currentGap }));
638
- }
639
- catch (err) {
640
- res.writeHead(500, { "Content-Type": "application/json" });
641
- res.end(JSON.stringify({ error: "Internal error", details: String(err) }));
642
- }
643
- }
644
- /** Check if server is running */
645
- isRunning() {
646
- return this.server !== null && this.server.listening;
647
- }
648
- /** Check if file watcher is active (internal use) */
649
- isWatching() {
650
- return this.fileWatcher !== null;
651
- }
652
- getPort() {
653
- return this.port;
654
- }
655
- getHost() {
656
- return this.host;
657
- }
658
- getEventsDir() {
659
- return this.eventsDir;
660
- }
661
- async dispatchCommandEnvelope(input) {
662
- if (!this.commandEnvelopeHook)
663
- return;
664
- await this.commandEnvelopeHook(createEnvelope({
665
- type: "command",
666
- name: input.name,
667
- source: "http",
668
- goal_id: input.goalId,
669
- priority: input.priority,
670
- dedupe_key: input.dedupeKey,
671
- payload: input.payload,
672
- }));
673
- }
674
- writeSseEvent(res, eventType, data) {
675
- this.eventIdCounter++;
676
- const id = String(this.eventIdCounter);
677
- res.write(`id: ${id}\nevent: ${eventType}\ndata: ${JSON.stringify(data)}\n\n`);
678
- }
679
- }
680
- /** Read the full request body as a string (max 1 MB). */
681
- function readBody(req) {
682
- return new Promise((resolve, reject) => {
683
- const MAX = 1_048_576;
684
- let body = "";
685
- let bytes = 0;
686
- req.on("data", (chunk) => {
687
- bytes += chunk.length;
688
- if (bytes > MAX) {
689
- reject(new Error("Payload too large"));
690
- req.destroy();
691
- return;
692
- }
693
- body += chunk;
694
- });
695
- req.on("end", () => resolve(body));
696
- req.on("error", reject);
697
- });
698
- }
1
+ export * from "./event/server.js";
699
2
  //# sourceMappingURL=event-server.js.map