@getpaseo/server 0.1.37 → 0.1.38

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 (295) hide show
  1. package/dist/scripts/dev-runner.js +1 -1
  2. package/dist/scripts/dev-runner.js.map +1 -1
  3. package/dist/scripts/{daemon-runner.js → supervisor-entrypoint.js} +7 -9
  4. package/dist/scripts/supervisor-entrypoint.js.map +1 -0
  5. package/dist/scripts/supervisor.js +17 -1
  6. package/dist/scripts/supervisor.js.map +1 -1
  7. package/dist/server/server/bootstrap.d.ts +0 -4
  8. package/dist/server/server/bootstrap.d.ts.map +1 -1
  9. package/dist/server/server/bootstrap.js +8 -22
  10. package/dist/server/server/bootstrap.js.map +1 -1
  11. package/dist/server/server/index.js +0 -4
  12. package/dist/server/server/index.js.map +1 -1
  13. package/dist/server/server/pid-lock.d.ts +7 -2
  14. package/dist/server/server/pid-lock.d.ts.map +1 -1
  15. package/dist/server/server/pid-lock.js +21 -0
  16. package/dist/server/server/pid-lock.js.map +1 -1
  17. package/dist/server/server/session.d.ts.map +1 -1
  18. package/dist/server/server/session.js +2 -2
  19. package/dist/server/server/session.js.map +1 -1
  20. package/dist/src/server/pid-lock.js +21 -0
  21. package/dist/src/server/pid-lock.js.map +1 -1
  22. package/package.json +3 -3
  23. package/dist/scripts/daemon-runner.js.map +0 -1
  24. package/dist/src/server/agent/activity-curator.js +0 -243
  25. package/dist/src/server/agent/activity-curator.js.map +0 -1
  26. package/dist/src/server/agent/agent-manager.js +0 -1855
  27. package/dist/src/server/agent/agent-manager.js.map +0 -1
  28. package/dist/src/server/agent/agent-metadata-generator.js +0 -161
  29. package/dist/src/server/agent/agent-metadata-generator.js.map +0 -1
  30. package/dist/src/server/agent/agent-projections.js +0 -254
  31. package/dist/src/server/agent/agent-projections.js.map +0 -1
  32. package/dist/src/server/agent/agent-response-loop.js +0 -304
  33. package/dist/src/server/agent/agent-response-loop.js.map +0 -1
  34. package/dist/src/server/agent/agent-sdk-types.js +0 -12
  35. package/dist/src/server/agent/agent-sdk-types.js.map +0 -1
  36. package/dist/src/server/agent/agent-storage.js +0 -302
  37. package/dist/src/server/agent/agent-storage.js.map +0 -1
  38. package/dist/src/server/agent/agent-title-limits.js +0 -3
  39. package/dist/src/server/agent/agent-title-limits.js.map +0 -1
  40. package/dist/src/server/agent/audio-utils.js +0 -19
  41. package/dist/src/server/agent/audio-utils.js.map +0 -1
  42. package/dist/src/server/agent/dictation-debug.js +0 -50
  43. package/dist/src/server/agent/dictation-debug.js.map +0 -1
  44. package/dist/src/server/agent/mcp-server.js +0 -754
  45. package/dist/src/server/agent/mcp-server.js.map +0 -1
  46. package/dist/src/server/agent/orchestrator-instructions.js +0 -51
  47. package/dist/src/server/agent/orchestrator-instructions.js.map +0 -1
  48. package/dist/src/server/agent/pcm16-resampler.js +0 -63
  49. package/dist/src/server/agent/pcm16-resampler.js.map +0 -1
  50. package/dist/src/server/agent/provider-launch-config.js +0 -213
  51. package/dist/src/server/agent/provider-launch-config.js.map +0 -1
  52. package/dist/src/server/agent/provider-manifest.js +0 -127
  53. package/dist/src/server/agent/provider-manifest.js.map +0 -1
  54. package/dist/src/server/agent/provider-registry.js +0 -45
  55. package/dist/src/server/agent/provider-registry.js.map +0 -1
  56. package/dist/src/server/agent/providers/claude/partial-json.js +0 -306
  57. package/dist/src/server/agent/providers/claude/partial-json.js.map +0 -1
  58. package/dist/src/server/agent/providers/claude/sdk-model-resolver.js +0 -104
  59. package/dist/src/server/agent/providers/claude/sdk-model-resolver.js.map +0 -1
  60. package/dist/src/server/agent/providers/claude/sidechain-tracker.js +0 -230
  61. package/dist/src/server/agent/providers/claude/sidechain-tracker.js.map +0 -1
  62. package/dist/src/server/agent/providers/claude/task-notification-tool-call.js +0 -267
  63. package/dist/src/server/agent/providers/claude/task-notification-tool-call.js.map +0 -1
  64. package/dist/src/server/agent/providers/claude/tool-call-detail-parser.js +0 -121
  65. package/dist/src/server/agent/providers/claude/tool-call-detail-parser.js.map +0 -1
  66. package/dist/src/server/agent/providers/claude/tool-call-mapper.js +0 -252
  67. package/dist/src/server/agent/providers/claude/tool-call-mapper.js.map +0 -1
  68. package/dist/src/server/agent/providers/claude-agent.js +0 -3166
  69. package/dist/src/server/agent/providers/claude-agent.js.map +0 -1
  70. package/dist/src/server/agent/providers/codex/tool-call-detail-parser.js +0 -104
  71. package/dist/src/server/agent/providers/codex/tool-call-detail-parser.js.map +0 -1
  72. package/dist/src/server/agent/providers/codex/tool-call-mapper.js +0 -758
  73. package/dist/src/server/agent/providers/codex/tool-call-mapper.js.map +0 -1
  74. package/dist/src/server/agent/providers/codex-app-server-agent.js +0 -2949
  75. package/dist/src/server/agent/providers/codex-app-server-agent.js.map +0 -1
  76. package/dist/src/server/agent/providers/codex-rollout-timeline.js +0 -544
  77. package/dist/src/server/agent/providers/codex-rollout-timeline.js.map +0 -1
  78. package/dist/src/server/agent/providers/opencode/tool-call-detail-parser.js +0 -39
  79. package/dist/src/server/agent/providers/opencode/tool-call-detail-parser.js.map +0 -1
  80. package/dist/src/server/agent/providers/opencode/tool-call-mapper.js +0 -144
  81. package/dist/src/server/agent/providers/opencode/tool-call-mapper.js.map +0 -1
  82. package/dist/src/server/agent/providers/opencode-agent.js +0 -1193
  83. package/dist/src/server/agent/providers/opencode-agent.js.map +0 -1
  84. package/dist/src/server/agent/providers/tool-call-detail-primitives.js +0 -686
  85. package/dist/src/server/agent/providers/tool-call-detail-primitives.js.map +0 -1
  86. package/dist/src/server/agent/providers/tool-call-mapper-utils.js +0 -115
  87. package/dist/src/server/agent/providers/tool-call-mapper-utils.js.map +0 -1
  88. package/dist/src/server/agent/recordings-debug.js +0 -19
  89. package/dist/src/server/agent/recordings-debug.js.map +0 -1
  90. package/dist/src/server/agent/stt-debug.js +0 -33
  91. package/dist/src/server/agent/stt-debug.js.map +0 -1
  92. package/dist/src/server/agent/stt-manager.js +0 -232
  93. package/dist/src/server/agent/stt-manager.js.map +0 -1
  94. package/dist/src/server/agent/timeline-append.js +0 -27
  95. package/dist/src/server/agent/timeline-append.js.map +0 -1
  96. package/dist/src/server/agent/timeline-projection.js +0 -215
  97. package/dist/src/server/agent/timeline-projection.js.map +0 -1
  98. package/dist/src/server/agent/tool-name-normalization.js +0 -45
  99. package/dist/src/server/agent/tool-name-normalization.js.map +0 -1
  100. package/dist/src/server/agent/tts-debug.js +0 -24
  101. package/dist/src/server/agent/tts-debug.js.map +0 -1
  102. package/dist/src/server/agent/tts-manager.js +0 -374
  103. package/dist/src/server/agent/tts-manager.js.map +0 -1
  104. package/dist/src/server/agent/wait-for-agent-tracker.js +0 -53
  105. package/dist/src/server/agent/wait-for-agent-tracker.js.map +0 -1
  106. package/dist/src/server/agent-attention-policy.js +0 -40
  107. package/dist/src/server/agent-attention-policy.js.map +0 -1
  108. package/dist/src/server/allowed-hosts.js +0 -94
  109. package/dist/src/server/allowed-hosts.js.map +0 -1
  110. package/dist/src/server/bootstrap.js +0 -620
  111. package/dist/src/server/bootstrap.js.map +0 -1
  112. package/dist/src/server/chat/chat-mentions.js +0 -71
  113. package/dist/src/server/chat/chat-mentions.js.map +0 -1
  114. package/dist/src/server/chat/chat-rpc-schemas.js +0 -103
  115. package/dist/src/server/chat/chat-rpc-schemas.js.map +0 -1
  116. package/dist/src/server/chat/chat-service.js +0 -330
  117. package/dist/src/server/chat/chat-service.js.map +0 -1
  118. package/dist/src/server/chat/chat-types.js +0 -22
  119. package/dist/src/server/chat/chat-types.js.map +0 -1
  120. package/dist/src/server/checkout-diff-manager.js +0 -272
  121. package/dist/src/server/checkout-diff-manager.js.map +0 -1
  122. package/dist/src/server/checkout-git-utils.js +0 -37
  123. package/dist/src/server/checkout-git-utils.js.map +0 -1
  124. package/dist/src/server/client-message-id.js +0 -12
  125. package/dist/src/server/client-message-id.js.map +0 -1
  126. package/dist/src/server/config.js +0 -73
  127. package/dist/src/server/config.js.map +0 -1
  128. package/dist/src/server/connection-offer.js +0 -59
  129. package/dist/src/server/connection-offer.js.map +0 -1
  130. package/dist/src/server/daemon-keypair.js +0 -40
  131. package/dist/src/server/daemon-keypair.js.map +0 -1
  132. package/dist/src/server/daemon-version.js +0 -22
  133. package/dist/src/server/daemon-version.js.map +0 -1
  134. package/dist/src/server/dictation/dictation-stream-manager.js +0 -571
  135. package/dist/src/server/dictation/dictation-stream-manager.js.map +0 -1
  136. package/dist/src/server/file-download/token-store.js +0 -40
  137. package/dist/src/server/file-download/token-store.js.map +0 -1
  138. package/dist/src/server/file-explorer/service.js +0 -180
  139. package/dist/src/server/file-explorer/service.js.map +0 -1
  140. package/dist/src/server/json-utils.js +0 -45
  141. package/dist/src/server/json-utils.js.map +0 -1
  142. package/dist/src/server/loop/rpc-schemas.js +0 -159
  143. package/dist/src/server/loop/rpc-schemas.js.map +0 -1
  144. package/dist/src/server/loop-service.js +0 -741
  145. package/dist/src/server/loop-service.js.map +0 -1
  146. package/dist/src/server/messages.js +0 -29
  147. package/dist/src/server/messages.js.map +0 -1
  148. package/dist/src/server/package-version.js +0 -46
  149. package/dist/src/server/package-version.js.map +0 -1
  150. package/dist/src/server/pairing-offer.js +0 -45
  151. package/dist/src/server/pairing-offer.js.map +0 -1
  152. package/dist/src/server/pairing-qr.js +0 -45
  153. package/dist/src/server/pairing-qr.js.map +0 -1
  154. package/dist/src/server/path-utils.js +0 -20
  155. package/dist/src/server/path-utils.js.map +0 -1
  156. package/dist/src/server/persisted-config.js +0 -265
  157. package/dist/src/server/persisted-config.js.map +0 -1
  158. package/dist/src/server/persistence-hooks.js +0 -60
  159. package/dist/src/server/persistence-hooks.js.map +0 -1
  160. package/dist/src/server/push/push-service.js +0 -68
  161. package/dist/src/server/push/push-service.js.map +0 -1
  162. package/dist/src/server/push/token-store.js +0 -70
  163. package/dist/src/server/push/token-store.js.map +0 -1
  164. package/dist/src/server/relay-transport.js +0 -461
  165. package/dist/src/server/relay-transport.js.map +0 -1
  166. package/dist/src/server/schedule/cron.js +0 -103
  167. package/dist/src/server/schedule/cron.js.map +0 -1
  168. package/dist/src/server/schedule/rpc-schemas.js +0 -112
  169. package/dist/src/server/schedule/rpc-schemas.js.map +0 -1
  170. package/dist/src/server/schedule/service.js +0 -397
  171. package/dist/src/server/schedule/service.js.map +0 -1
  172. package/dist/src/server/schedule/store.js +0 -56
  173. package/dist/src/server/schedule/store.js.map +0 -1
  174. package/dist/src/server/schedule/types.js +0 -73
  175. package/dist/src/server/schedule/types.js.map +0 -1
  176. package/dist/src/server/server-id.js +0 -63
  177. package/dist/src/server/server-id.js.map +0 -1
  178. package/dist/src/server/session.js +0 -6381
  179. package/dist/src/server/session.js.map +0 -1
  180. package/dist/src/server/speech/audio.js +0 -101
  181. package/dist/src/server/speech/audio.js.map +0 -1
  182. package/dist/src/server/speech/provider-resolver.js +0 -7
  183. package/dist/src/server/speech/provider-resolver.js.map +0 -1
  184. package/dist/src/server/speech/providers/local/config.js +0 -74
  185. package/dist/src/server/speech/providers/local/config.js.map +0 -1
  186. package/dist/src/server/speech/providers/local/models.js +0 -17
  187. package/dist/src/server/speech/providers/local/models.js.map +0 -1
  188. package/dist/src/server/speech/providers/local/pocket/pocket-tts-onnx.js +0 -436
  189. package/dist/src/server/speech/providers/local/pocket/pocket-tts-onnx.js.map +0 -1
  190. package/dist/src/server/speech/providers/local/runtime.js +0 -238
  191. package/dist/src/server/speech/providers/local/runtime.js.map +0 -1
  192. package/dist/src/server/speech/providers/local/sherpa/model-catalog.js +0 -166
  193. package/dist/src/server/speech/providers/local/sherpa/model-catalog.js.map +0 -1
  194. package/dist/src/server/speech/providers/local/sherpa/model-downloader.js +0 -165
  195. package/dist/src/server/speech/providers/local/sherpa/model-downloader.js.map +0 -1
  196. package/dist/src/server/speech/providers/local/sherpa/sherpa-offline-recognizer.js +0 -73
  197. package/dist/src/server/speech/providers/local/sherpa/sherpa-offline-recognizer.js.map +0 -1
  198. package/dist/src/server/speech/providers/local/sherpa/sherpa-online-recognizer.js +0 -84
  199. package/dist/src/server/speech/providers/local/sherpa/sherpa-online-recognizer.js.map +0 -1
  200. package/dist/src/server/speech/providers/local/sherpa/sherpa-onnx-loader.js +0 -11
  201. package/dist/src/server/speech/providers/local/sherpa/sherpa-onnx-loader.js.map +0 -1
  202. package/dist/src/server/speech/providers/local/sherpa/sherpa-onnx-node-loader.js +0 -102
  203. package/dist/src/server/speech/providers/local/sherpa/sherpa-onnx-node-loader.js.map +0 -1
  204. package/dist/src/server/speech/providers/local/sherpa/sherpa-parakeet-realtime-session.js +0 -135
  205. package/dist/src/server/speech/providers/local/sherpa/sherpa-parakeet-realtime-session.js.map +0 -1
  206. package/dist/src/server/speech/providers/local/sherpa/sherpa-parakeet-stt.js +0 -130
  207. package/dist/src/server/speech/providers/local/sherpa/sherpa-parakeet-stt.js.map +0 -1
  208. package/dist/src/server/speech/providers/local/sherpa/sherpa-realtime-session.js +0 -110
  209. package/dist/src/server/speech/providers/local/sherpa/sherpa-realtime-session.js.map +0 -1
  210. package/dist/src/server/speech/providers/local/sherpa/sherpa-stt.js +0 -138
  211. package/dist/src/server/speech/providers/local/sherpa/sherpa-stt.js.map +0 -1
  212. package/dist/src/server/speech/providers/local/sherpa/sherpa-tts.js +0 -98
  213. package/dist/src/server/speech/providers/local/sherpa/sherpa-tts.js.map +0 -1
  214. package/dist/src/server/speech/providers/local/sherpa/silero-vad-provider.js +0 -23
  215. package/dist/src/server/speech/providers/local/sherpa/silero-vad-provider.js.map +0 -1
  216. package/dist/src/server/speech/providers/local/sherpa/silero-vad-session.js +0 -107
  217. package/dist/src/server/speech/providers/local/sherpa/silero-vad-session.js.map +0 -1
  218. package/dist/src/server/speech/providers/openai/config.js +0 -80
  219. package/dist/src/server/speech/providers/openai/config.js.map +0 -1
  220. package/dist/src/server/speech/providers/openai/realtime-transcription-session.js +0 -168
  221. package/dist/src/server/speech/providers/openai/realtime-transcription-session.js.map +0 -1
  222. package/dist/src/server/speech/providers/openai/runtime.js +0 -112
  223. package/dist/src/server/speech/providers/openai/runtime.js.map +0 -1
  224. package/dist/src/server/speech/providers/openai/stt.js +0 -206
  225. package/dist/src/server/speech/providers/openai/stt.js.map +0 -1
  226. package/dist/src/server/speech/providers/openai/tts.js +0 -46
  227. package/dist/src/server/speech/providers/openai/tts.js.map +0 -1
  228. package/dist/src/server/speech/speech-config-resolver.js +0 -102
  229. package/dist/src/server/speech/speech-config-resolver.js.map +0 -1
  230. package/dist/src/server/speech/speech-provider.js +0 -2
  231. package/dist/src/server/speech/speech-provider.js.map +0 -1
  232. package/dist/src/server/speech/speech-runtime.js +0 -530
  233. package/dist/src/server/speech/speech-runtime.js.map +0 -1
  234. package/dist/src/server/speech/speech-types.js +0 -8
  235. package/dist/src/server/speech/speech-types.js.map +0 -1
  236. package/dist/src/server/speech/turn-detection-provider.js +0 -2
  237. package/dist/src/server/speech/turn-detection-provider.js.map +0 -1
  238. package/dist/src/server/utils/diff-highlighter.js +0 -257
  239. package/dist/src/server/utils/diff-highlighter.js.map +0 -1
  240. package/dist/src/server/voice/fixed-duration-pcm-ring-buffer.js +0 -35
  241. package/dist/src/server/voice/fixed-duration-pcm-ring-buffer.js.map +0 -1
  242. package/dist/src/server/voice/voice-turn-controller.js +0 -159
  243. package/dist/src/server/voice/voice-turn-controller.js.map +0 -1
  244. package/dist/src/server/voice-config.js +0 -51
  245. package/dist/src/server/voice-config.js.map +0 -1
  246. package/dist/src/server/voice-mcp-bridge-command.js +0 -31
  247. package/dist/src/server/voice-mcp-bridge-command.js.map +0 -1
  248. package/dist/src/server/voice-mcp-bridge.js +0 -109
  249. package/dist/src/server/voice-mcp-bridge.js.map +0 -1
  250. package/dist/src/server/voice-permission-policy.js +0 -13
  251. package/dist/src/server/voice-permission-policy.js.map +0 -1
  252. package/dist/src/server/voice-types.js +0 -2
  253. package/dist/src/server/voice-types.js.map +0 -1
  254. package/dist/src/server/websocket-server.js +0 -1048
  255. package/dist/src/server/websocket-server.js.map +0 -1
  256. package/dist/src/server/workspace-registry-bootstrap.js +0 -98
  257. package/dist/src/server/workspace-registry-bootstrap.js.map +0 -1
  258. package/dist/src/server/workspace-registry-model.js +0 -175
  259. package/dist/src/server/workspace-registry-model.js.map +0 -1
  260. package/dist/src/server/workspace-registry.js +0 -151
  261. package/dist/src/server/workspace-registry.js.map +0 -1
  262. package/dist/src/server/worktree-bootstrap.js +0 -508
  263. package/dist/src/server/worktree-bootstrap.js.map +0 -1
  264. package/dist/src/shared/agent-attention-notification.js +0 -130
  265. package/dist/src/shared/agent-attention-notification.js.map +0 -1
  266. package/dist/src/shared/agent-lifecycle.js +0 -8
  267. package/dist/src/shared/agent-lifecycle.js.map +0 -1
  268. package/dist/src/shared/connection-offer.js +0 -17
  269. package/dist/src/shared/connection-offer.js.map +0 -1
  270. package/dist/src/shared/daemon-endpoints.js +0 -122
  271. package/dist/src/shared/daemon-endpoints.js.map +0 -1
  272. package/dist/src/shared/messages.js +0 -2107
  273. package/dist/src/shared/messages.js.map +0 -1
  274. package/dist/src/shared/path-utils.js +0 -16
  275. package/dist/src/shared/path-utils.js.map +0 -1
  276. package/dist/src/shared/terminal-stream-protocol.js +0 -99
  277. package/dist/src/shared/terminal-stream-protocol.js.map +0 -1
  278. package/dist/src/shared/tool-call-display.js +0 -122
  279. package/dist/src/shared/tool-call-display.js.map +0 -1
  280. package/dist/src/terminal/terminal-manager.js +0 -136
  281. package/dist/src/terminal/terminal-manager.js.map +0 -1
  282. package/dist/src/terminal/terminal.js +0 -333
  283. package/dist/src/terminal/terminal.js.map +0 -1
  284. package/dist/src/utils/checkout-git.js +0 -1518
  285. package/dist/src/utils/checkout-git.js.map +0 -1
  286. package/dist/src/utils/directory-suggestions.js +0 -671
  287. package/dist/src/utils/directory-suggestions.js.map +0 -1
  288. package/dist/src/utils/path.js +0 -15
  289. package/dist/src/utils/path.js.map +0 -1
  290. package/dist/src/utils/project-icon.js +0 -389
  291. package/dist/src/utils/project-icon.js.map +0 -1
  292. package/dist/src/utils/worktree-metadata.js +0 -116
  293. package/dist/src/utils/worktree-metadata.js.map +0 -1
  294. package/dist/src/utils/worktree.js +0 -744
  295. package/dist/src/utils/worktree.js.map +0 -1
@@ -1,741 +0,0 @@
1
- import { randomUUID } from "node:crypto";
2
- import { execFile } from "node:child_process";
3
- import { promises as fs } from "node:fs";
4
- import path from "node:path";
5
- import { promisify } from "node:util";
6
- import { z } from "zod";
7
- import { curateAgentActivity } from "./agent/activity-curator.js";
8
- import { getStructuredAgentResponse } from "./agent/agent-response-loop.js";
9
- const execFileAsync = promisify(execFile);
10
- const LOOP_ID_LENGTH = 8;
11
- const DEFAULT_LOOP_PROVIDER = "claude";
12
- const MAX_VERIFY_OUTPUT_BYTES = 64 * 1024;
13
- const LoopVerifyPromptSchema = z.object({
14
- passed: z.boolean(),
15
- reason: z.string().min(1),
16
- });
17
- const LoopLogEntrySchema = z.object({
18
- seq: z.number().int().positive(),
19
- timestamp: z.string(),
20
- iteration: z.number().int().positive().nullable(),
21
- source: z.enum(["loop", "worker", "verifier", "verify-check"]),
22
- level: z.enum(["info", "error"]),
23
- text: z.string(),
24
- });
25
- const LoopVerifyCheckResultSchema = z.object({
26
- command: z.string(),
27
- exitCode: z.number().int(),
28
- passed: z.boolean(),
29
- stdout: z.string(),
30
- stderr: z.string(),
31
- startedAt: z.string(),
32
- completedAt: z.string(),
33
- });
34
- const LoopVerifyPromptResultSchema = z.object({
35
- passed: z.boolean(),
36
- reason: z.string(),
37
- verifierAgentId: z.string().nullable(),
38
- startedAt: z.string(),
39
- completedAt: z.string(),
40
- });
41
- const LoopIterationRecordSchema = z.object({
42
- index: z.number().int().positive(),
43
- workerAgentId: z.string().nullable(),
44
- workerStartedAt: z.string(),
45
- workerCompletedAt: z.string().nullable(),
46
- verifierAgentId: z.string().nullable(),
47
- status: z.enum(["running", "succeeded", "failed", "stopped"]),
48
- workerOutcome: z.enum(["completed", "failed", "canceled"]).nullable(),
49
- failureReason: z.string().nullable(),
50
- verifyChecks: z.array(LoopVerifyCheckResultSchema),
51
- verifyPrompt: LoopVerifyPromptResultSchema.nullable(),
52
- });
53
- const LoopRecordSchema = z.object({
54
- id: z.string(),
55
- name: z.string().nullable(),
56
- prompt: z.string(),
57
- cwd: z.string(),
58
- provider: z.enum(["claude", "codex", "opencode"]),
59
- model: z.string().nullable(),
60
- workerProvider: z.enum(["claude", "codex", "opencode"]).nullable(),
61
- workerModel: z.string().nullable(),
62
- verifierProvider: z.enum(["claude", "codex", "opencode"]).nullable(),
63
- verifierModel: z.string().nullable(),
64
- verifyPrompt: z.string().nullable(),
65
- verifyChecks: z.array(z.string()),
66
- archive: z.boolean(),
67
- sleepMs: z.number().int().nonnegative(),
68
- maxIterations: z.number().int().positive().nullable(),
69
- maxTimeMs: z.number().int().positive().nullable(),
70
- status: z.enum(["running", "succeeded", "failed", "stopped"]),
71
- createdAt: z.string(),
72
- updatedAt: z.string(),
73
- startedAt: z.string(),
74
- completedAt: z.string().nullable(),
75
- stopRequestedAt: z.string().nullable(),
76
- iterations: z.array(LoopIterationRecordSchema),
77
- logs: z.array(LoopLogEntrySchema),
78
- nextLogSeq: z.number().int().positive(),
79
- activeIteration: z.number().int().positive().nullable(),
80
- activeWorkerAgentId: z.string().nullable(),
81
- activeVerifierAgentId: z.string().nullable(),
82
- });
83
- const StoredLoopsSchema = z.array(LoopRecordSchema);
84
- function nowIso() {
85
- return new Date().toISOString();
86
- }
87
- function cloneLoop(record) {
88
- return LoopRecordSchema.parse(record);
89
- }
90
- function createLoopId() {
91
- return randomUUID().replace(/-/g, "").slice(0, LOOP_ID_LENGTH);
92
- }
93
- function normalizeName(name) {
94
- const trimmed = name?.trim();
95
- return trimmed ? trimmed : null;
96
- }
97
- function normalizePrompt(value, field) {
98
- if (value === undefined) {
99
- return null;
100
- }
101
- const trimmed = value.trim();
102
- if (!trimmed) {
103
- throw new Error(`${field} cannot be empty`);
104
- }
105
- return trimmed;
106
- }
107
- function ensurePositiveInteger(value, field) {
108
- if (value === undefined) {
109
- return null;
110
- }
111
- if (!Number.isInteger(value) || value <= 0) {
112
- throw new Error(`${field} must be a positive integer`);
113
- }
114
- return value;
115
- }
116
- function ensureNonNegativeInteger(value, field) {
117
- if (value === undefined) {
118
- return 0;
119
- }
120
- if (!Number.isInteger(value) || value < 0) {
121
- throw new Error(`${field} must be a non-negative integer`);
122
- }
123
- return value;
124
- }
125
- function buildWorkerTitle(loop, iterationIndex) {
126
- const prefix = loop.name ?? loop.id;
127
- return `${prefix} [loop ${iterationIndex} worker]`;
128
- }
129
- function buildVerifierTitle(loop, iterationIndex) {
130
- const prefix = loop.name ?? loop.id;
131
- return `${prefix} [loop ${iterationIndex} verifier]`;
132
- }
133
- function formatStreamLog(event) {
134
- switch (event.type) {
135
- case "timeline": {
136
- const rendered = curateAgentActivity([event.item]);
137
- return rendered === "No activity to display." ? null : rendered;
138
- }
139
- case "turn_failed":
140
- return `[Turn Failed] ${event.error}`;
141
- case "turn_canceled":
142
- return `[Turn Canceled] ${event.reason}`;
143
- case "permission_requested":
144
- return `[Permission Requested] ${event.request.name}`;
145
- case "permission_resolved":
146
- return `[Permission Resolved] ${event.requestId}`;
147
- default:
148
- return null;
149
- }
150
- }
151
- async function sleepWithAbort(ms, signal) {
152
- if (ms <= 0) {
153
- return;
154
- }
155
- await new Promise((resolve, reject) => {
156
- const timer = setTimeout(() => {
157
- cleanup();
158
- resolve();
159
- }, ms);
160
- const onAbort = () => {
161
- cleanup();
162
- reject(signal.reason instanceof Error ? signal.reason : new Error("Loop aborted"));
163
- };
164
- const cleanup = () => {
165
- clearTimeout(timer);
166
- signal.removeEventListener("abort", onAbort);
167
- };
168
- signal.addEventListener("abort", onAbort, { once: true });
169
- });
170
- }
171
- function isAbortError(error) {
172
- if (error instanceof Error && error.message === "Loop aborted") {
173
- return true;
174
- }
175
- return false;
176
- }
177
- async function runVerifyCheck(options) {
178
- const startedAt = nowIso();
179
- try {
180
- const result = await execFileAsync("/bin/zsh", ["-lc", options.command], {
181
- cwd: options.cwd,
182
- maxBuffer: MAX_VERIFY_OUTPUT_BYTES,
183
- });
184
- return {
185
- command: options.command,
186
- exitCode: 0,
187
- passed: true,
188
- stdout: result.stdout ?? "",
189
- stderr: result.stderr ?? "",
190
- startedAt,
191
- completedAt: nowIso(),
192
- };
193
- }
194
- catch (error) {
195
- const childError = error;
196
- return {
197
- command: options.command,
198
- exitCode: typeof childError.code === "number" ? childError.code : 1,
199
- passed: false,
200
- stdout: childError.stdout ?? "",
201
- stderr: childError.stderr ?? "",
202
- startedAt,
203
- completedAt: nowIso(),
204
- };
205
- }
206
- }
207
- export class LoopService {
208
- constructor(options) {
209
- this.options = options;
210
- this.loaded = false;
211
- this.loops = new Map();
212
- this.persistQueue = Promise.resolve();
213
- this.running = new Map();
214
- this.storePath = path.join(options.paseoHome, "loops", "loops.json");
215
- this.logger = options.logger.child({ module: "loop-service" });
216
- }
217
- async initialize() {
218
- if (this.loaded) {
219
- return;
220
- }
221
- this.loops.clear();
222
- try {
223
- const raw = await fs.readFile(this.storePath, "utf8");
224
- const parsed = StoredLoopsSchema.parse(JSON.parse(raw));
225
- for (const record of parsed) {
226
- if (record.status === "running") {
227
- const recovered = cloneLoop(record);
228
- recovered.status = "stopped";
229
- recovered.updatedAt = nowIso();
230
- recovered.completedAt = recovered.updatedAt;
231
- recovered.stopRequestedAt = recovered.updatedAt;
232
- recovered.activeIteration = null;
233
- recovered.activeWorkerAgentId = null;
234
- recovered.activeVerifierAgentId = null;
235
- this.appendLog(recovered, {
236
- iteration: null,
237
- source: "loop",
238
- level: "error",
239
- text: "Loop was interrupted by daemon restart.",
240
- });
241
- const lastIteration = recovered.iterations.at(-1);
242
- if (lastIteration && lastIteration.status === "running") {
243
- lastIteration.status = "stopped";
244
- lastIteration.failureReason = "Daemon restarted";
245
- lastIteration.workerCompletedAt = recovered.updatedAt;
246
- }
247
- this.loops.set(recovered.id, recovered);
248
- continue;
249
- }
250
- this.loops.set(record.id, record);
251
- }
252
- }
253
- catch (error) {
254
- const code = error.code;
255
- if (code !== "ENOENT") {
256
- this.logger.error({ err: error, storePath: this.storePath }, "Failed to load loops");
257
- }
258
- }
259
- this.loaded = true;
260
- await this.persist();
261
- }
262
- async runLoop(input) {
263
- await this.initialize();
264
- const prompt = normalizePrompt(input.prompt, "prompt");
265
- if (!prompt) {
266
- throw new Error("prompt cannot be empty");
267
- }
268
- const verifyPrompt = normalizePrompt(input.verifyPrompt, "verifyPrompt");
269
- const verifyChecks = (input.verifyChecks ?? []).map((command) => {
270
- const trimmed = command.trim();
271
- if (!trimmed) {
272
- throw new Error("verifyChecks cannot contain empty commands");
273
- }
274
- return trimmed;
275
- });
276
- if (!verifyPrompt && verifyChecks.length === 0) {
277
- throw new Error("Loop requires --verify or at least one --verify-check");
278
- }
279
- const createdAt = nowIso();
280
- const record = LoopRecordSchema.parse({
281
- id: createLoopId(),
282
- name: normalizeName(input.name),
283
- prompt,
284
- cwd: path.resolve(input.cwd),
285
- provider: input.provider ?? DEFAULT_LOOP_PROVIDER,
286
- model: normalizePrompt(input.model, "model"),
287
- workerProvider: input.workerProvider ?? null,
288
- workerModel: normalizePrompt(input.workerModel, "workerModel"),
289
- verifierProvider: input.verifierProvider ?? null,
290
- verifierModel: normalizePrompt(input.verifierModel, "verifierModel"),
291
- verifyPrompt,
292
- verifyChecks,
293
- archive: input.archive ?? false,
294
- sleepMs: ensureNonNegativeInteger(input.sleepMs, "sleepMs"),
295
- maxIterations: ensurePositiveInteger(input.maxIterations, "maxIterations"),
296
- maxTimeMs: ensurePositiveInteger(input.maxTimeMs, "maxTimeMs"),
297
- status: "running",
298
- createdAt,
299
- updatedAt: createdAt,
300
- startedAt: createdAt,
301
- completedAt: null,
302
- stopRequestedAt: null,
303
- iterations: [],
304
- logs: [],
305
- nextLogSeq: 1,
306
- activeIteration: null,
307
- activeWorkerAgentId: null,
308
- activeVerifierAgentId: null,
309
- });
310
- this.loops.set(record.id, record);
311
- this.appendLog(record, {
312
- iteration: null,
313
- source: "loop",
314
- level: "info",
315
- text: `Loop created in ${record.cwd}`,
316
- });
317
- await this.persist();
318
- const abortController = new AbortController();
319
- const promise = this.executeLoop(record.id, abortController.signal).finally(() => {
320
- this.running.delete(record.id);
321
- });
322
- this.running.set(record.id, { abortController, promise });
323
- return cloneLoop(record);
324
- }
325
- async listLoops() {
326
- await this.initialize();
327
- return Array.from(this.loops.values())
328
- .sort((left, right) => right.createdAt.localeCompare(left.createdAt))
329
- .map((record) => ({
330
- id: record.id,
331
- name: record.name,
332
- status: record.status,
333
- cwd: record.cwd,
334
- createdAt: record.createdAt,
335
- updatedAt: record.updatedAt,
336
- activeIteration: record.activeIteration,
337
- }));
338
- }
339
- async inspectLoop(idOrPrefix) {
340
- await this.initialize();
341
- const loop = this.requireLoop(idOrPrefix);
342
- return cloneLoop(loop);
343
- }
344
- async getLoopLogs(idOrPrefix, afterSeq = 0) {
345
- await this.initialize();
346
- const loop = this.requireLoop(idOrPrefix);
347
- const entries = loop.logs.filter((entry) => entry.seq > afterSeq);
348
- return {
349
- loop: cloneLoop(loop),
350
- entries: entries.map((entry) => LoopLogEntrySchema.parse(entry)),
351
- nextCursor: loop.nextLogSeq - 1,
352
- };
353
- }
354
- async stopLoop(idOrPrefix) {
355
- await this.initialize();
356
- const loop = this.requireLoop(idOrPrefix);
357
- if (loop.status !== "running") {
358
- return cloneLoop(loop);
359
- }
360
- const running = this.running.get(loop.id);
361
- loop.stopRequestedAt = loop.stopRequestedAt ?? nowIso();
362
- loop.updatedAt = loop.stopRequestedAt;
363
- this.appendLog(loop, {
364
- iteration: loop.activeIteration,
365
- source: "loop",
366
- level: "info",
367
- text: "Stop requested.",
368
- });
369
- await this.persist();
370
- if (running) {
371
- running.abortController.abort(new Error("Loop aborted"));
372
- if (loop.activeWorkerAgentId) {
373
- await this.options.agentManager.cancelAgentRun(loop.activeWorkerAgentId).catch(() => { });
374
- }
375
- if (loop.activeVerifierAgentId) {
376
- await this.options.agentManager.cancelAgentRun(loop.activeVerifierAgentId).catch(() => { });
377
- }
378
- await running.promise.catch(() => { });
379
- }
380
- else {
381
- loop.status = "stopped";
382
- loop.completedAt = nowIso();
383
- loop.updatedAt = loop.completedAt;
384
- await this.persist();
385
- }
386
- return cloneLoop(loop);
387
- }
388
- async executeLoop(loopId, signal) {
389
- const loop = this.requireLoop(loopId);
390
- const deadline = loop.maxTimeMs ? Date.now() + loop.maxTimeMs : null;
391
- try {
392
- for (let index = 1;; index += 1) {
393
- if (signal.aborted) {
394
- throw new Error("Loop aborted");
395
- }
396
- if (loop.maxIterations && index > loop.maxIterations) {
397
- this.finishLoop(loop, "failed", `Reached max iterations (${loop.maxIterations}).`);
398
- return;
399
- }
400
- if (deadline !== null && Date.now() > deadline) {
401
- this.finishLoop(loop, "failed", `Reached max time (${loop.maxTimeMs}ms).`);
402
- return;
403
- }
404
- const iteration = LoopIterationRecordSchema.parse({
405
- index,
406
- workerAgentId: null,
407
- workerStartedAt: nowIso(),
408
- workerCompletedAt: null,
409
- verifierAgentId: null,
410
- status: "running",
411
- workerOutcome: null,
412
- failureReason: null,
413
- verifyChecks: [],
414
- verifyPrompt: null,
415
- });
416
- loop.iterations.push(iteration);
417
- loop.activeIteration = index;
418
- loop.updatedAt = nowIso();
419
- this.appendLog(loop, {
420
- iteration: index,
421
- source: "loop",
422
- level: "info",
423
- text: `Starting iteration ${index}.`,
424
- });
425
- await this.persist();
426
- const workerPassed = await this.runWorkerIteration(loop, iteration, signal);
427
- if (signal.aborted) {
428
- throw new Error("Loop aborted");
429
- }
430
- if (!workerPassed) {
431
- iteration.status = iteration.status === "stopped" ? "stopped" : "failed";
432
- }
433
- else {
434
- const verificationPassed = await this.runVerification(loop, iteration, signal);
435
- if (verificationPassed) {
436
- iteration.status = "succeeded";
437
- this.finishLoop(loop, "succeeded", `Iteration ${index} passed verification.`);
438
- return;
439
- }
440
- if (iteration.status === "running") {
441
- iteration.status = "failed";
442
- }
443
- }
444
- loop.activeIteration = null;
445
- loop.activeWorkerAgentId = null;
446
- loop.activeVerifierAgentId = null;
447
- loop.updatedAt = nowIso();
448
- await this.persist();
449
- if (loop.sleepMs > 0) {
450
- this.appendLog(loop, {
451
- iteration: index,
452
- source: "loop",
453
- level: "info",
454
- text: `Sleeping ${loop.sleepMs}ms before next iteration.`,
455
- });
456
- await this.persist();
457
- await sleepWithAbort(loop.sleepMs, signal);
458
- }
459
- }
460
- }
461
- catch (error) {
462
- if (isAbortError(error)) {
463
- this.finishLoop(loop, "stopped", "Loop stopped.");
464
- const iteration = loop.activeIteration
465
- ? loop.iterations.find((candidate) => candidate.index === loop.activeIteration)
466
- : null;
467
- if (iteration && iteration.status === "running") {
468
- iteration.status = "stopped";
469
- iteration.failureReason = "Loop stopped";
470
- iteration.workerCompletedAt = nowIso();
471
- }
472
- await this.persist();
473
- return;
474
- }
475
- const message = error instanceof Error ? error.message : String(error);
476
- this.logger.error({ err: error, loopId }, "Loop execution failed");
477
- this.finishLoop(loop, "failed", message);
478
- const iteration = loop.activeIteration
479
- ? loop.iterations.find((candidate) => candidate.index === loop.activeIteration)
480
- : null;
481
- if (iteration && iteration.status === "running") {
482
- iteration.status = "failed";
483
- iteration.failureReason = message;
484
- iteration.workerCompletedAt = nowIso();
485
- }
486
- await this.persist();
487
- }
488
- }
489
- async runWorkerIteration(loop, iteration, signal) {
490
- const agent = await this.options.agentManager.createAgent(this.buildWorkerConfig(loop, iteration));
491
- iteration.workerAgentId = agent.id;
492
- loop.activeWorkerAgentId = agent.id;
493
- loop.updatedAt = nowIso();
494
- await this.persist();
495
- const unsubscribe = this.options.agentManager.subscribe((event) => {
496
- if (event.type !== "agent_stream") {
497
- return;
498
- }
499
- const text = formatStreamLog(event.event);
500
- if (!text) {
501
- return;
502
- }
503
- this.appendLog(loop, {
504
- iteration: iteration.index,
505
- source: "worker",
506
- level: event.event.type === "turn_failed" ? "error" : "info",
507
- text,
508
- });
509
- void this.persist();
510
- }, { agentId: agent.id, replayState: false });
511
- try {
512
- const prompt = this.toPrompt(loop.prompt);
513
- const result = await this.options.agentManager.runAgent(agent.id, prompt);
514
- iteration.workerCompletedAt = nowIso();
515
- iteration.workerOutcome = result.canceled ? "canceled" : "completed";
516
- if (result.canceled) {
517
- iteration.failureReason = "Worker run was canceled.";
518
- iteration.status = "stopped";
519
- return false;
520
- }
521
- return true;
522
- }
523
- catch (error) {
524
- iteration.workerCompletedAt = nowIso();
525
- iteration.workerOutcome = "failed";
526
- iteration.failureReason = error instanceof Error ? error.message : String(error);
527
- this.appendLog(loop, {
528
- iteration: iteration.index,
529
- source: "loop",
530
- level: "error",
531
- text: `Worker failed: ${iteration.failureReason}`,
532
- });
533
- return false;
534
- }
535
- finally {
536
- unsubscribe();
537
- loop.activeWorkerAgentId = null;
538
- loop.updatedAt = nowIso();
539
- await this.persist();
540
- try {
541
- if (loop.archive) {
542
- await this.options.agentManager.archiveAgent(agent.id);
543
- }
544
- else {
545
- await this.options.agentManager.closeAgent(agent.id);
546
- }
547
- }
548
- catch {
549
- // Ignore cleanup errors for internal loop workers.
550
- }
551
- if (signal.aborted && iteration.status === "running") {
552
- iteration.status = "stopped";
553
- }
554
- }
555
- }
556
- async runVerification(loop, iteration, signal) {
557
- for (const command of loop.verifyChecks) {
558
- if (signal.aborted) {
559
- throw new Error("Loop aborted");
560
- }
561
- this.appendLog(loop, {
562
- iteration: iteration.index,
563
- source: "verify-check",
564
- level: "info",
565
- text: `$ ${command}`,
566
- });
567
- const result = await runVerifyCheck({ cwd: loop.cwd, command });
568
- iteration.verifyChecks.push(result);
569
- const output = [result.stdout.trim(), result.stderr.trim()].filter(Boolean).join("\n");
570
- this.appendLog(loop, {
571
- iteration: iteration.index,
572
- source: "verify-check",
573
- level: result.passed ? "info" : "error",
574
- text: output
575
- ? `exit ${result.exitCode}\n${output}`
576
- : `exit ${result.exitCode}`,
577
- });
578
- loop.updatedAt = nowIso();
579
- await this.persist();
580
- if (!result.passed) {
581
- iteration.failureReason = `Verify check failed: ${command}`;
582
- return false;
583
- }
584
- }
585
- if (!loop.verifyPrompt) {
586
- return true;
587
- }
588
- const startedAt = nowIso();
589
- const verifierAgent = await this.options.agentManager.createAgent(this.buildVerifierConfig(loop, iteration));
590
- iteration.verifierAgentId = verifierAgent.id;
591
- loop.activeVerifierAgentId = verifierAgent.id;
592
- loop.updatedAt = nowIso();
593
- await this.persist();
594
- const unsubscribe = this.options.agentManager.subscribe((event) => {
595
- if (event.type !== "agent_stream") {
596
- return;
597
- }
598
- const text = formatStreamLog(event.event);
599
- if (!text) {
600
- return;
601
- }
602
- this.appendLog(loop, {
603
- iteration: iteration.index,
604
- source: "verifier",
605
- level: event.event.type === "turn_failed" ? "error" : "info",
606
- text,
607
- });
608
- void this.persist();
609
- }, { agentId: verifierAgent.id, replayState: false });
610
- try {
611
- const result = await getStructuredAgentResponse({
612
- caller: async (nextPrompt) => {
613
- const run = await this.options.agentManager.runAgent(verifierAgent.id, this.toPrompt(nextPrompt));
614
- return this.resolveFinalText(run.timeline, run.finalText);
615
- },
616
- prompt: loop.verifyPrompt,
617
- schema: LoopVerifyPromptSchema,
618
- maxRetries: 2,
619
- schemaName: "LoopVerifierResult",
620
- });
621
- iteration.verifyPrompt = {
622
- passed: result.passed,
623
- reason: result.reason,
624
- verifierAgentId: verifierAgent.id,
625
- startedAt,
626
- completedAt: nowIso(),
627
- };
628
- this.appendLog(loop, {
629
- iteration: iteration.index,
630
- source: "loop",
631
- level: result.passed ? "info" : "error",
632
- text: `Verifier result: ${result.reason}`,
633
- });
634
- if (!result.passed) {
635
- iteration.failureReason = result.reason;
636
- }
637
- return result.passed;
638
- }
639
- finally {
640
- unsubscribe();
641
- loop.activeVerifierAgentId = null;
642
- loop.updatedAt = nowIso();
643
- await this.persist();
644
- try {
645
- if (loop.archive) {
646
- await this.options.agentManager.archiveAgent(verifierAgent.id);
647
- }
648
- else {
649
- await this.options.agentManager.closeAgent(verifierAgent.id);
650
- }
651
- }
652
- catch {
653
- // Ignore cleanup errors for internal loop verifiers.
654
- }
655
- }
656
- }
657
- buildWorkerConfig(loop, iteration) {
658
- return {
659
- provider: loop.workerProvider ?? loop.provider,
660
- cwd: loop.cwd,
661
- model: loop.workerModel ?? loop.model ?? undefined,
662
- title: buildWorkerTitle(loop, iteration.index),
663
- internal: true,
664
- };
665
- }
666
- buildVerifierConfig(loop, iteration) {
667
- return {
668
- provider: loop.verifierProvider ?? loop.provider,
669
- cwd: loop.cwd,
670
- model: loop.verifierModel ?? loop.model ?? undefined,
671
- title: buildVerifierTitle(loop, iteration.index),
672
- internal: true,
673
- };
674
- }
675
- resolveFinalText(timeline, finalText) {
676
- if (finalText.trim()) {
677
- return finalText;
678
- }
679
- for (let index = timeline.length - 1; index >= 0; index -= 1) {
680
- const item = timeline[index];
681
- if (item?.type === "assistant_message" && item.text.trim()) {
682
- return item.text;
683
- }
684
- }
685
- return "";
686
- }
687
- toPrompt(text) {
688
- return text;
689
- }
690
- finishLoop(loop, status, message) {
691
- loop.status = status;
692
- loop.completedAt = nowIso();
693
- loop.updatedAt = loop.completedAt;
694
- loop.activeIteration = null;
695
- loop.activeWorkerAgentId = null;
696
- loop.activeVerifierAgentId = null;
697
- this.appendLog(loop, {
698
- iteration: null,
699
- source: "loop",
700
- level: status === "succeeded" ? "info" : "error",
701
- text: message,
702
- });
703
- }
704
- appendLog(loop, entry) {
705
- loop.logs.push({
706
- seq: loop.nextLogSeq,
707
- timestamp: nowIso(),
708
- ...entry,
709
- });
710
- loop.nextLogSeq += 1;
711
- loop.updatedAt = nowIso();
712
- }
713
- requireLoop(idOrPrefix) {
714
- const trimmed = idOrPrefix.trim();
715
- if (!trimmed) {
716
- throw new Error("Loop id is required");
717
- }
718
- const exact = this.loops.get(trimmed);
719
- if (exact) {
720
- return exact;
721
- }
722
- const matches = Array.from(this.loops.values()).filter((record) => record.id.startsWith(trimmed));
723
- if (matches.length === 1) {
724
- return matches[0];
725
- }
726
- if (matches.length > 1) {
727
- throw new Error(`Loop id prefix is ambiguous: ${trimmed}`);
728
- }
729
- throw new Error(`Loop not found: ${trimmed}`);
730
- }
731
- async persist() {
732
- const nextPersist = this.persistQueue.then(async () => {
733
- await fs.mkdir(path.dirname(this.storePath), { recursive: true });
734
- const records = Array.from(this.loops.values()).sort((left, right) => left.createdAt.localeCompare(right.createdAt));
735
- await fs.writeFile(this.storePath, JSON.stringify(records, null, 2), "utf8");
736
- });
737
- this.persistQueue = nextPersist.catch(() => { });
738
- await nextPersist;
739
- }
740
- }
741
- //# sourceMappingURL=loop-service.js.map