lorenz 0.1.4 → 0.1.6

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 (249) hide show
  1. package/README.md +83 -20
  2. package/RELEASE-MANIFEST.json +6 -1
  3. package/node_modules/@lorenz/agent-sdk/dist/index.d.ts +1 -0
  4. package/node_modules/@lorenz/agent-sdk/dist/index.d.ts.map +1 -1
  5. package/node_modules/@lorenz/agent-sdk/dist/index.js +1 -0
  6. package/node_modules/@lorenz/agent-sdk/dist/index.js.map +1 -1
  7. package/node_modules/@lorenz/agent-sdk/dist/module.d.ts +38 -0
  8. package/node_modules/@lorenz/agent-sdk/dist/module.d.ts.map +1 -0
  9. package/node_modules/@lorenz/agent-sdk/dist/module.js +41 -0
  10. package/node_modules/@lorenz/agent-sdk/dist/module.js.map +1 -0
  11. package/node_modules/@lorenz/cli/dist/agentExecutorLoader.d.ts +30 -0
  12. package/node_modules/@lorenz/cli/dist/agentExecutorLoader.d.ts.map +1 -0
  13. package/node_modules/@lorenz/cli/dist/agentExecutorLoader.js +63 -0
  14. package/node_modules/@lorenz/cli/dist/agentExecutorLoader.js.map +1 -0
  15. package/node_modules/@lorenz/cli/dist/daemon.d.ts +42 -19
  16. package/node_modules/@lorenz/cli/dist/daemon.d.ts.map +1 -1
  17. package/node_modules/@lorenz/cli/dist/daemon.js +72 -23
  18. package/node_modules/@lorenz/cli/dist/daemon.js.map +1 -1
  19. package/node_modules/@lorenz/cli/dist/daemonLock.d.ts +59 -0
  20. package/node_modules/@lorenz/cli/dist/daemonLock.d.ts.map +1 -0
  21. package/node_modules/@lorenz/cli/dist/daemonLock.js +304 -0
  22. package/node_modules/@lorenz/cli/dist/daemonLock.js.map +1 -0
  23. package/node_modules/@lorenz/cli/dist/daemonStatus.d.ts +16 -0
  24. package/node_modules/@lorenz/cli/dist/daemonStatus.d.ts.map +1 -0
  25. package/node_modules/@lorenz/cli/dist/daemonStatus.js +21 -0
  26. package/node_modules/@lorenz/cli/dist/daemonStatus.js.map +1 -0
  27. package/node_modules/@lorenz/cli/dist/doctor.d.ts +6 -0
  28. package/node_modules/@lorenz/cli/dist/doctor.d.ts.map +1 -1
  29. package/node_modules/@lorenz/cli/dist/doctor.js +39 -2
  30. package/node_modules/@lorenz/cli/dist/doctor.js.map +1 -1
  31. package/node_modules/@lorenz/cli/dist/extensionLoader.d.ts +126 -0
  32. package/node_modules/@lorenz/cli/dist/extensionLoader.d.ts.map +1 -0
  33. package/node_modules/@lorenz/cli/dist/extensionLoader.js +187 -0
  34. package/node_modules/@lorenz/cli/dist/extensionLoader.js.map +1 -0
  35. package/node_modules/@lorenz/cli/dist/flags-manifest.d.ts +42 -0
  36. package/node_modules/@lorenz/cli/dist/flags-manifest.d.ts.map +1 -0
  37. package/node_modules/@lorenz/cli/dist/flags-manifest.js +67 -0
  38. package/node_modules/@lorenz/cli/dist/flags-manifest.js.map +1 -0
  39. package/node_modules/@lorenz/cli/dist/index.d.ts +6 -0
  40. package/node_modules/@lorenz/cli/dist/index.d.ts.map +1 -1
  41. package/node_modules/@lorenz/cli/dist/index.js +4 -0
  42. package/node_modules/@lorenz/cli/dist/index.js.map +1 -1
  43. package/node_modules/@lorenz/cli/dist/leadershipStore.d.ts +42 -0
  44. package/node_modules/@lorenz/cli/dist/leadershipStore.d.ts.map +1 -0
  45. package/node_modules/@lorenz/cli/dist/leadershipStore.js +2 -0
  46. package/node_modules/@lorenz/cli/dist/leadershipStore.js.map +1 -0
  47. package/node_modules/@lorenz/cli/dist/main.d.ts +11 -7
  48. package/node_modules/@lorenz/cli/dist/main.d.ts.map +1 -1
  49. package/node_modules/@lorenz/cli/dist/main.js +58 -8
  50. package/node_modules/@lorenz/cli/dist/main.js.map +1 -1
  51. package/node_modules/@lorenz/cli/dist/toolLoader.d.ts +28 -0
  52. package/node_modules/@lorenz/cli/dist/toolLoader.d.ts.map +1 -0
  53. package/node_modules/@lorenz/cli/dist/toolLoader.js +62 -0
  54. package/node_modules/@lorenz/cli/dist/toolLoader.js.map +1 -0
  55. package/node_modules/@lorenz/cli/dist/trackerLoader.d.ts +24 -0
  56. package/node_modules/@lorenz/cli/dist/trackerLoader.d.ts.map +1 -0
  57. package/node_modules/@lorenz/cli/dist/trackerLoader.js +34 -0
  58. package/node_modules/@lorenz/cli/dist/trackerLoader.js.map +1 -0
  59. package/node_modules/@lorenz/cli/dist/workerDriverLoader.d.ts +15 -55
  60. package/node_modules/@lorenz/cli/dist/workerDriverLoader.d.ts.map +1 -1
  61. package/node_modules/@lorenz/cli/dist/workerDriverLoader.js +26 -203
  62. package/node_modules/@lorenz/cli/dist/workerDriverLoader.js.map +1 -1
  63. package/node_modules/@lorenz/cli/package.json +1 -0
  64. package/node_modules/@lorenz/config/dist/index.d.ts +1 -1
  65. package/node_modules/@lorenz/config/dist/index.d.ts.map +1 -1
  66. package/node_modules/@lorenz/config/dist/index.js +1 -1
  67. package/node_modules/@lorenz/config/dist/index.js.map +1 -1
  68. package/node_modules/@lorenz/config/dist/parse.d.ts +17 -0
  69. package/node_modules/@lorenz/config/dist/parse.d.ts.map +1 -1
  70. package/node_modules/@lorenz/config/dist/parse.js +107 -11
  71. package/node_modules/@lorenz/config/dist/parse.js.map +1 -1
  72. package/node_modules/@lorenz/config/dist/schemas.d.ts +0 -2
  73. package/node_modules/@lorenz/config/dist/schemas.d.ts.map +1 -1
  74. package/node_modules/@lorenz/config/dist/schemas.js +5 -1
  75. package/node_modules/@lorenz/config/dist/schemas.js.map +1 -1
  76. package/node_modules/@lorenz/dispatch-coordinator/dist/coordinator.d.ts +55 -21
  77. package/node_modules/@lorenz/dispatch-coordinator/dist/coordinator.d.ts.map +1 -1
  78. package/node_modules/@lorenz/dispatch-coordinator/dist/coordinator.js +187 -82
  79. package/node_modules/@lorenz/dispatch-coordinator/dist/coordinator.js.map +1 -1
  80. package/node_modules/@lorenz/dispatch-coordinator/dist/gate.d.ts +6 -4
  81. package/node_modules/@lorenz/dispatch-coordinator/dist/gate.d.ts.map +1 -1
  82. package/node_modules/@lorenz/dispatch-coordinator/dist/gate.js +9 -6
  83. package/node_modules/@lorenz/dispatch-coordinator/dist/gate.js.map +1 -1
  84. package/node_modules/@lorenz/dispatch-coordinator/dist/index.d.ts +1 -1
  85. package/node_modules/@lorenz/dispatch-coordinator/dist/index.d.ts.map +1 -1
  86. package/node_modules/@lorenz/dispatch-coordinator/dist/index.js +5 -6
  87. package/node_modules/@lorenz/dispatch-coordinator/dist/index.js.map +1 -1
  88. package/node_modules/@lorenz/dispatch-coordinator/dist/mcpEndpointManager.d.ts +7 -5
  89. package/node_modules/@lorenz/dispatch-coordinator/dist/mcpEndpointManager.d.ts.map +1 -1
  90. package/node_modules/@lorenz/dispatch-coordinator/dist/mcpEndpointManager.js +12 -10
  91. package/node_modules/@lorenz/dispatch-coordinator/dist/mcpEndpointManager.js.map +1 -1
  92. package/node_modules/@lorenz/dispatch-coordinator/dist/nullEndpointManager.d.ts +11 -10
  93. package/node_modules/@lorenz/dispatch-coordinator/dist/nullEndpointManager.d.ts.map +1 -1
  94. package/node_modules/@lorenz/dispatch-coordinator/dist/nullEndpointManager.js +15 -22
  95. package/node_modules/@lorenz/dispatch-coordinator/dist/nullEndpointManager.js.map +1 -1
  96. package/node_modules/@lorenz/dispatch-coordinator/dist/types.d.ts +16 -15
  97. package/node_modules/@lorenz/dispatch-coordinator/dist/types.d.ts.map +1 -1
  98. package/node_modules/@lorenz/dispatch-coordinator/dist/types.js +6 -7
  99. package/node_modules/@lorenz/dispatch-coordinator/dist/types.js.map +1 -1
  100. package/node_modules/@lorenz/domain/dist/index.d.ts +75 -9
  101. package/node_modules/@lorenz/domain/dist/index.d.ts.map +1 -1
  102. package/node_modules/@lorenz/domain/dist/index.js +40 -0
  103. package/node_modules/@lorenz/domain/dist/index.js.map +1 -1
  104. package/node_modules/@lorenz/flags/dist/coerce.d.ts +12 -0
  105. package/node_modules/@lorenz/flags/dist/coerce.d.ts.map +1 -0
  106. package/node_modules/@lorenz/flags/dist/coerce.js +44 -0
  107. package/node_modules/@lorenz/flags/dist/coerce.js.map +1 -0
  108. package/node_modules/@lorenz/flags/dist/default.d.ts +6 -0
  109. package/node_modules/@lorenz/flags/dist/default.d.ts.map +1 -0
  110. package/node_modules/@lorenz/flags/dist/default.js +22 -0
  111. package/node_modules/@lorenz/flags/dist/default.js.map +1 -0
  112. package/node_modules/@lorenz/flags/dist/deprecations.d.ts +20 -0
  113. package/node_modules/@lorenz/flags/dist/deprecations.d.ts.map +1 -0
  114. package/node_modules/@lorenz/flags/dist/deprecations.js +42 -0
  115. package/node_modules/@lorenz/flags/dist/deprecations.js.map +1 -0
  116. package/node_modules/@lorenz/flags/dist/env.d.ts +17 -0
  117. package/node_modules/@lorenz/flags/dist/env.d.ts.map +1 -0
  118. package/node_modules/@lorenz/flags/dist/env.js +90 -0
  119. package/node_modules/@lorenz/flags/dist/env.js.map +1 -0
  120. package/node_modules/@lorenz/flags/dist/errors.d.ts +22 -0
  121. package/node_modules/@lorenz/flags/dist/errors.d.ts.map +1 -0
  122. package/node_modules/@lorenz/flags/dist/errors.js +61 -0
  123. package/node_modules/@lorenz/flags/dist/errors.js.map +1 -0
  124. package/node_modules/@lorenz/flags/dist/index.d.ts +8 -0
  125. package/node_modules/@lorenz/flags/dist/index.d.ts.map +1 -0
  126. package/node_modules/@lorenz/flags/dist/index.js +11 -0
  127. package/node_modules/@lorenz/flags/dist/index.js.map +1 -0
  128. package/node_modules/@lorenz/flags/dist/keys.d.ts +6 -0
  129. package/node_modules/@lorenz/flags/dist/keys.d.ts.map +1 -0
  130. package/node_modules/@lorenz/flags/dist/keys.js +15 -0
  131. package/node_modules/@lorenz/flags/dist/keys.js.map +1 -0
  132. package/node_modules/@lorenz/flags/dist/layers.d.ts +14 -0
  133. package/node_modules/@lorenz/flags/dist/layers.d.ts.map +1 -0
  134. package/node_modules/@lorenz/flags/dist/layers.js +107 -0
  135. package/node_modules/@lorenz/flags/dist/layers.js.map +1 -0
  136. package/node_modules/@lorenz/flags/dist/manifest.d.ts +71 -0
  137. package/node_modules/@lorenz/flags/dist/manifest.d.ts.map +1 -0
  138. package/node_modules/@lorenz/flags/dist/manifest.js +137 -0
  139. package/node_modules/@lorenz/flags/dist/manifest.js.map +1 -0
  140. package/node_modules/@lorenz/flags/dist/resolve.d.ts +8 -0
  141. package/node_modules/@lorenz/flags/dist/resolve.d.ts.map +1 -0
  142. package/node_modules/@lorenz/flags/dist/resolve.js +178 -0
  143. package/node_modules/@lorenz/flags/dist/resolve.js.map +1 -0
  144. package/node_modules/@lorenz/flags/dist/testing.d.ts +19 -0
  145. package/node_modules/@lorenz/flags/dist/testing.d.ts.map +1 -0
  146. package/node_modules/@lorenz/flags/dist/testing.js +68 -0
  147. package/node_modules/@lorenz/flags/dist/testing.js.map +1 -0
  148. package/node_modules/@lorenz/flags/dist/types.d.ts +93 -0
  149. package/node_modules/@lorenz/flags/dist/types.d.ts.map +1 -0
  150. package/node_modules/@lorenz/flags/dist/types.js +2 -0
  151. package/node_modules/@lorenz/flags/dist/types.js.map +1 -0
  152. package/node_modules/@lorenz/flags/package.json +16 -0
  153. package/node_modules/@lorenz/mcp/dist/agentEndpoint.d.ts +16 -3
  154. package/node_modules/@lorenz/mcp/dist/agentEndpoint.d.ts.map +1 -1
  155. package/node_modules/@lorenz/mcp/dist/agentEndpoint.js +105 -17
  156. package/node_modules/@lorenz/mcp/dist/agentEndpoint.js.map +1 -1
  157. package/node_modules/@lorenz/mcp/dist/auth.d.ts +88 -0
  158. package/node_modules/@lorenz/mcp/dist/auth.d.ts.map +1 -1
  159. package/node_modules/@lorenz/mcp/dist/auth.js +53 -0
  160. package/node_modules/@lorenz/mcp/dist/auth.js.map +1 -1
  161. package/node_modules/@lorenz/mcp/dist/index.d.ts +3 -2
  162. package/node_modules/@lorenz/mcp/dist/index.d.ts.map +1 -1
  163. package/node_modules/@lorenz/mcp/dist/index.js +1 -1
  164. package/node_modules/@lorenz/mcp/dist/index.js.map +1 -1
  165. package/node_modules/@lorenz/mcp/dist/server.d.ts +22 -0
  166. package/node_modules/@lorenz/mcp/dist/server.d.ts.map +1 -1
  167. package/node_modules/@lorenz/mcp/dist/server.js +85 -12
  168. package/node_modules/@lorenz/mcp/dist/server.js.map +1 -1
  169. package/node_modules/@lorenz/orchestrator/dist/claimStore.d.ts +157 -0
  170. package/node_modules/@lorenz/orchestrator/dist/claimStore.d.ts.map +1 -0
  171. package/node_modules/@lorenz/orchestrator/dist/claimStore.js +621 -0
  172. package/node_modules/@lorenz/orchestrator/dist/claimStore.js.map +1 -0
  173. package/node_modules/@lorenz/orchestrator/dist/codec.d.ts +38 -0
  174. package/node_modules/@lorenz/orchestrator/dist/codec.d.ts.map +1 -0
  175. package/node_modules/@lorenz/orchestrator/dist/codec.js +176 -0
  176. package/node_modules/@lorenz/orchestrator/dist/codec.js.map +1 -0
  177. package/node_modules/@lorenz/orchestrator/dist/index.d.ts +55 -51
  178. package/node_modules/@lorenz/orchestrator/dist/index.d.ts.map +1 -1
  179. package/node_modules/@lorenz/orchestrator/dist/index.js +285 -45
  180. package/node_modules/@lorenz/orchestrator/dist/index.js.map +1 -1
  181. package/node_modules/@lorenz/orchestrator/dist/sqlite.d.ts +34 -0
  182. package/node_modules/@lorenz/orchestrator/dist/sqlite.d.ts.map +1 -0
  183. package/node_modules/@lorenz/orchestrator/dist/sqlite.js +142 -0
  184. package/node_modules/@lorenz/orchestrator/dist/sqlite.js.map +1 -0
  185. package/node_modules/@lorenz/orchestrator/dist/state.d.ts +47 -0
  186. package/node_modules/@lorenz/orchestrator/dist/state.d.ts.map +1 -0
  187. package/node_modules/@lorenz/orchestrator/dist/state.js +15 -0
  188. package/node_modules/@lorenz/orchestrator/dist/state.js.map +1 -0
  189. package/node_modules/@lorenz/orchestrator/dist/turso.d.ts +28 -0
  190. package/node_modules/@lorenz/orchestrator/dist/turso.d.ts.map +1 -0
  191. package/node_modules/@lorenz/orchestrator/dist/turso.js +125 -0
  192. package/node_modules/@lorenz/orchestrator/dist/turso.js.map +1 -0
  193. package/node_modules/@lorenz/orchestrator/package.json +6 -2
  194. package/node_modules/@lorenz/presenter/dist/index.d.ts +14 -0
  195. package/node_modules/@lorenz/presenter/dist/index.d.ts.map +1 -1
  196. package/node_modules/@lorenz/presenter/dist/index.js +18 -0
  197. package/node_modules/@lorenz/presenter/dist/index.js.map +1 -1
  198. package/node_modules/@lorenz/projections/dist/index.d.ts.map +1 -1
  199. package/node_modules/@lorenz/projections/dist/index.js +1 -0
  200. package/node_modules/@lorenz/projections/dist/index.js.map +1 -1
  201. package/node_modules/@lorenz/runtime/dist/index.d.ts +27 -8
  202. package/node_modules/@lorenz/runtime/dist/index.d.ts.map +1 -1
  203. package/node_modules/@lorenz/runtime/dist/index.js +422 -98
  204. package/node_modules/@lorenz/runtime/dist/index.js.map +1 -1
  205. package/node_modules/@lorenz/runtime-events/dist/index.d.ts +14 -0
  206. package/node_modules/@lorenz/runtime-events/dist/index.d.ts.map +1 -1
  207. package/node_modules/@lorenz/server/dist/index.js +1 -1
  208. package/node_modules/@lorenz/server/dist/index.js.map +1 -1
  209. package/node_modules/@lorenz/ssh/dist/index.d.ts +2 -0
  210. package/node_modules/@lorenz/ssh/dist/index.d.ts.map +1 -1
  211. package/node_modules/@lorenz/ssh/dist/index.js +2 -1
  212. package/node_modules/@lorenz/ssh/dist/index.js.map +1 -1
  213. package/node_modules/@lorenz/tool-sdk/dist/index.d.ts +1 -0
  214. package/node_modules/@lorenz/tool-sdk/dist/index.d.ts.map +1 -1
  215. package/node_modules/@lorenz/tool-sdk/dist/index.js +1 -0
  216. package/node_modules/@lorenz/tool-sdk/dist/index.js.map +1 -1
  217. package/node_modules/@lorenz/tool-sdk/dist/module.d.ts +38 -0
  218. package/node_modules/@lorenz/tool-sdk/dist/module.d.ts.map +1 -0
  219. package/node_modules/@lorenz/tool-sdk/dist/module.js +42 -0
  220. package/node_modules/@lorenz/tool-sdk/dist/module.js.map +1 -0
  221. package/node_modules/@lorenz/tracker-sdk/dist/index.d.ts +1 -0
  222. package/node_modules/@lorenz/tracker-sdk/dist/index.d.ts.map +1 -1
  223. package/node_modules/@lorenz/tracker-sdk/dist/index.js +1 -0
  224. package/node_modules/@lorenz/tracker-sdk/dist/index.js.map +1 -1
  225. package/node_modules/@lorenz/tracker-sdk/dist/module.d.ts +37 -0
  226. package/node_modules/@lorenz/tracker-sdk/dist/module.d.ts.map +1 -0
  227. package/node_modules/@lorenz/tracker-sdk/dist/module.js +38 -0
  228. package/node_modules/@lorenz/tracker-sdk/dist/module.js.map +1 -0
  229. package/node_modules/@lorenz/worker-host-pool/dist/index.d.ts +34 -6
  230. package/node_modules/@lorenz/worker-host-pool/dist/index.d.ts.map +1 -1
  231. package/node_modules/@lorenz/worker-host-pool/dist/index.js +110 -143
  232. package/node_modules/@lorenz/worker-host-pool/dist/index.js.map +1 -1
  233. package/node_modules/@lorenz/worker-sdk/dist/index.d.ts +1 -0
  234. package/node_modules/@lorenz/worker-sdk/dist/index.d.ts.map +1 -1
  235. package/node_modules/@lorenz/worker-sdk/dist/index.js +1 -0
  236. package/node_modules/@lorenz/worker-sdk/dist/index.js.map +1 -1
  237. package/node_modules/@lorenz/worker-sdk/dist/local.d.ts +74 -0
  238. package/node_modules/@lorenz/worker-sdk/dist/local.d.ts.map +1 -0
  239. package/node_modules/@lorenz/worker-sdk/dist/local.js +112 -0
  240. package/node_modules/@lorenz/worker-sdk/dist/local.js.map +1 -0
  241. package/node_modules/@lorenz/worker-sdk/dist/module.d.ts +8 -16
  242. package/node_modules/@lorenz/worker-sdk/dist/module.d.ts.map +1 -1
  243. package/node_modules/@lorenz/worker-sdk/dist/module.js +15 -35
  244. package/node_modules/@lorenz/worker-sdk/dist/module.js.map +1 -1
  245. package/node_modules/@lorenz/workflow/dist/index.d.ts +11 -0
  246. package/node_modules/@lorenz/workflow/dist/index.d.ts.map +1 -1
  247. package/node_modules/@lorenz/workflow/dist/index.js +3 -0
  248. package/node_modules/@lorenz/workflow/dist/index.js.map +1 -1
  249. package/package.json +4 -1
@@ -3,7 +3,8 @@ import path from "node:path";
3
3
  import { acpExecutorProvider } from "@lorenz/acp";
4
4
  import { defaultAgentExecutorRegistry } from "@lorenz/agent-sdk";
5
5
  import { runAgentAttempt as runAgentAttemptCore, } from "@lorenz/agent-runner";
6
- import { defaultWorkerDriverRegistry, registerFakeWorkerDriver, } from "@lorenz/worker-sdk";
6
+ import { defaultWorkerDriverRegistry, registerFakeWorkerDriver, registerLocalWorkerDriver, } from "@lorenz/worker-sdk";
7
+ import { trackerSpecifierFromConfig } from "@lorenz/config";
7
8
  import { registerDockerWorkerDriver } from "@lorenz/docker-worker";
8
9
  import { systemClock } from "@lorenz/domain";
9
10
  import { registerJiraTrackers } from "@lorenz/jira-tracker";
@@ -22,6 +23,7 @@ import { appendLogEvent } from "@lorenz/log-file";
22
23
  import { defaultToolRegistry } from "@lorenz/tool-sdk";
23
24
  import { createTrackerToolProvider, defaultTrackerRegistry, } from "@lorenz/tracker-sdk";
24
25
  import { ensureWorkerDriverLoaded } from "./workerDriverLoader.js";
26
+ import { ensureTrackerProviderLoaded } from "./trackerLoader.js";
25
27
  /**
26
28
  * Composition root: the CLI decides which extensions and agent executors this binary
27
29
  * supports. Each extension registers itself; the CLI only lists them here. Everything
@@ -46,26 +48,58 @@ export function registerBuiltinBackends(registries = {}) {
46
48
  }
47
49
  const workerDrivers = registries.workerDrivers ?? defaultWorkerDriverRegistry;
48
50
  registerFakeWorkerDriver({ workerDrivers });
51
+ registerLocalWorkerDriver({ workerDrivers });
49
52
  registerStaticSshWorkerDriver({ workerDrivers });
50
53
  registerDockerWorkerDriver({ workerDrivers });
51
54
  }
52
55
  export function runtimeDefaultSettingsOptions() {
53
56
  return { tmpdir: os.tmpdir() };
54
57
  }
58
+ /**
59
+ * `loadWorkflow` pre-parse hook: dynamic-import any out-of-tree tracker named by
60
+ * `tracker.kind` (a module specifier rather than a registered kind) and register
61
+ * it into `trackers` under that exact string, BEFORE the config parser resolves
62
+ * the tracker provider. Mirrors {@link buildWorkerPool}'s driver-loading step:
63
+ * the loader is a no-op for a built-in kind, dynamic-imports on a miss, and
64
+ * fail-loud on an unresolvable specifier / SDK mismatch at the same startup point
65
+ * as an unregistered kind. Re-running it on a reload re-encounters an
66
+ * already-loaded specifier and emits `tracker_provider_module_pinned`; a config
67
+ * that switches `tracker.kind` to a NEW specifier hot-loads it.
68
+ *
69
+ * `baseDir` anchors `./relative` specifiers to the workflow file's directory (the
70
+ * most predictable anchor for operators), and `logEvent` routes the
71
+ * `tracker_provider_loaded`/`_module_pinned` audit events to the configured log
72
+ * file when one is known.
73
+ */
74
+ export async function prepareTrackerExtensions(rawConfig, context) {
75
+ const specifier = trackerSpecifierFromConfig(rawConfig);
76
+ if (specifier === undefined)
77
+ return;
78
+ const trackers = context.trackers ?? defaultTrackerRegistry;
79
+ const logEvent = context.logFile === undefined
80
+ ? undefined
81
+ : (event) => void appendLogEvent(context.logFile, event);
82
+ await ensureTrackerProviderLoaded(specifier, trackers, {
83
+ baseDir: context.baseDir,
84
+ logEvent,
85
+ });
86
+ }
55
87
  export function createTrackerClient(settings, env = process.env) {
56
88
  return defaultTrackerRegistry.require(settings.tracker.kind).createClient(settings, { env });
57
89
  }
58
90
  /**
59
- * Constructs the warm worker pool when `worker.worker_pool.enabled` is set, and
60
- * returns `undefined` otherwise so the disabled path stays byte-identical to the
61
- * pre-pool daemon. The pool resolves the configured `driver` against the
62
- * worker-driver registry populated by {@link registerBuiltinBackends}; a driver
63
- * string that is NOT a registered kind is treated as a module specifier and
64
- * dynamic-imported into the registry first (see {@link ensureWorkerDriverLoaded}),
65
- * so third-party drivers load at the same fail-loud startup point - an
66
- * unresolvable driver throws `worker_pool_driver_unavailable` before the pool, the
67
- * runtime, or any provision exists. The write-ahead ledger (only consulted by
68
- * cloud drivers) lives under `<workspace.root>/.lorenz/worker-pool/`.
91
+ * Constructs the warm worker pool for the parsed worker-pool settings. The pool is the single
92
+ * dispatch path, so a parsed config always carries an enabled pool (an absent `worker_pool`
93
+ * defaults to an enabled `local` pool that provisions nothing eagerly). The internal `enabled`
94
+ * field is only flipped off by the reload-drain (a removed pool reconciled to drain to zero); this
95
+ * guard returns `undefined` for such an internally disabled / absent settings object so nothing is
96
+ * rebuilt. The pool resolves the configured `driver` against the worker-driver registry populated
97
+ * by {@link registerBuiltinBackends}; a driver string that is NOT a registered kind is treated as a
98
+ * module specifier and dynamic-imported into the registry first (see
99
+ * {@link ensureWorkerDriverLoaded}), so third-party drivers load at the same fail-loud startup
100
+ * point - an unresolvable driver throws `worker_pool_driver_unavailable` before the pool, the
101
+ * runtime, or any provision exists. The write-ahead ledger (only consulted by cloud drivers) lives
102
+ * under `<workspace.root>/.lorenz/worker-pool/`.
69
103
  */
70
104
  export async function buildWorkerPool(settings, _env = process.env, options = {}) {
71
105
  const workerPoolSettings = settings.worker.workerPool;
@@ -84,19 +118,19 @@ export async function buildWorkerPool(settings, _env = process.env, options = {}
84
118
  });
85
119
  }
86
120
  /**
87
- * Constructs the runtime-facing {@link DispatchCoordinator} when
88
- * `worker.worker_pool.enabled` is set, wrapping the same {@link WorkerPool} that
89
- * {@link buildWorkerPool} builds and the injected {@link McpEndpointManager}. Returns
90
- * `undefined` when the pool is disabled so the disabled path stays byte-identical
91
- * to the pre-pool daemon.
121
+ * Constructs the runtime-facing {@link DispatchCoordinator}, wrapping the same
122
+ * {@link WorkerPool} that {@link buildWorkerPool} builds and the injected
123
+ * {@link McpEndpointManager}. The pool is the single dispatch path, so a parsed config always
124
+ * yields a coordinator. Returns `undefined` only for an internally disabled / absent settings
125
+ * object (the reload-drain's drained-to-zero shape), mirroring {@link buildWorkerPool}.
92
126
  *
93
- * The CONCRETE per-run {@link McpEndpointManager} (`perRunEndpoint=true`) is wired
127
+ * The CONCRETE per-run {@link McpEndpointManager} (`perRunClaimEnforcement=true`) is wired
94
128
  * here: it OWNS the whole per-run MCP endpoint lease (auth token + refcounted local
95
129
  * mcp server + reverse tunnel) via the injected `acquireAgentMcpEndpointForRun`. The
96
130
  * daemon is the right ownership boundary because it already depends on
97
131
  * `@lorenz/mcp`, keeping `@lorenz/worker-pool` and
98
- * `@lorenz/dispatch-coordinator` free of any mcp/tunnel runtime dependency
99
- * (invariant #8). At the default `slotsPerMachine=1` this opens exactly ONE endpoint
132
+ * `@lorenz/dispatch-coordinator` free of any mcp/tunnel runtime dependency.
133
+ * At the default `slotsPerMachine=1` this opens exactly ONE endpoint
100
134
  * per run (just coordinator-owned), and the manager returns `null` for an empty
101
135
  * (local) worker host so the local path keeps using acp's own endpoint -
102
136
  * byte-identical to the single-tenant path. `buildWorkerPool` stays for the worker-pool
@@ -111,7 +145,16 @@ export async function buildDispatchCoordinator(settings, env = process.env, opti
111
145
  return undefined;
112
146
  const baseDir = options.baseDir ?? process.cwd();
113
147
  const logEvent = (event) => void appendLogEvent(settings.logging.logFile, event);
114
- return createDispatchCoordinator({
148
+ // Forward reference so the per-run endpoint manager's `acquireForRun` can inject
149
+ // the coordinator's own `isRunLive` oracle into `@lorenz/mcp`. The coordinator
150
+ // is the live-slot authority the gateway owner re-check reads; the daemon is the
151
+ // only place that holds both `@lorenz/mcp` and the coordinator, so it closes the
152
+ // loop here WITHOUT either package importing the other. `acquireForRun` is only
153
+ // ever called AFTER `createDispatchCoordinator` returns (during an
154
+ // `acquireRunSlot`), so `ref.coordinator` is always bound by then.
155
+ const ref = { coordinator: undefined };
156
+ const isRunLive = (runKey, workerHost, generation) => ref.coordinator?.isRunLive(runKey, workerHost, generation) ?? false;
157
+ const coordinator = createDispatchCoordinator({
115
158
  pool,
116
159
  // The concrete manager OWNS each run's whole endpoint lease; it calls the
117
160
  // injected `acquireAgentMcpEndpointForRun` (signature-compatible) for an
@@ -119,9 +162,13 @@ export async function buildDispatchCoordinator(settings, env = process.env, opti
119
162
  // local path keeps using acp's own endpoint.
120
163
  mcpEndpointManager: createPerRunEndpointManager({
121
164
  // The composition root binds the concrete tunnel transport (the shared
122
- // worker-host pool), keeping `@lorenz/mcp` free of any worker-host-pool
123
- // import (invariant #8) while the coordinator stays on the 3-arg acquirer.
124
- acquireForRun: async (runSettings, workerHost, runKey) => acquireAgentMcpEndpointForRun(runSettings, workerHost, runKey, workerHostPool),
165
+ // worker-host pool) AND the coordinator-backed `isRunLive` oracle, keeping
166
+ // `@lorenz/mcp` free of any worker-host-pool / coordinator import while the
167
+ // coordinator stays on the manager seam. The per-run MCP server mounts
168
+ // `isRunLive` so its Token B middleware enforces the per-request owner
169
+ // re-check + generation fence over live coordinator slots; the
170
+ // capture-before-await fence is what makes that window safe.
171
+ acquireForRun: async (runSettings, workerHost, runKey) => acquireAgentMcpEndpointForRun(runSettings, workerHost, runKey, workerHostPool, isRunLive),
125
172
  }),
126
173
  // Same structured-event sink as the pool so coordinator faults (e.g.
127
174
  // worker_pool_endpoint_release_failed) reach the log file instead of being
@@ -134,6 +181,8 @@ export async function buildDispatchCoordinator(settings, env = process.env, opti
134
181
  // and transactional. A registered-but-unused module is inert.
135
182
  driverLoader: async (driver) => ensureWorkerDriverLoaded(driver, defaultWorkerDriverRegistry, { baseDir, logEvent }),
136
183
  });
184
+ ref.coordinator = coordinator;
185
+ return coordinator;
137
186
  }
138
187
  /**
139
188
  * Skill overlay for a prepared workspace: the configured `agent.skills` unioned with the skills
@@ -1 +1 @@
1
- {"version":3,"file":"daemon.js","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"daemon.js","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ import type { LeadershipAcquireResult, LeadershipEndpoint, LeadershipIdentity, LeadershipLease, LeadershipLeaseRecord, LeadershipStore } from "./leadershipStore.js";
2
+ /** @beta */
3
+ export declare const DAEMON_LOCK_VERSION = 1;
4
+ /** @beta */
5
+ export type DaemonEndpoint = LeadershipEndpoint;
6
+ export type DaemonIdentity = LeadershipIdentity;
7
+ export interface DaemonLockRecord extends DaemonIdentity, LeadershipLeaseRecord {
8
+ version: typeof DAEMON_LOCK_VERSION;
9
+ lockPath: string;
10
+ endpoint: DaemonEndpoint;
11
+ heartbeatAt: string;
12
+ }
13
+ export interface CreateDaemonIdentityOptions {
14
+ workflowPath: string;
15
+ workspaceRoot: string;
16
+ now?: Date | undefined;
17
+ ownerId?: string | undefined;
18
+ pid?: number | undefined;
19
+ hostname?: string | undefined;
20
+ }
21
+ export interface AcquireDaemonLockOptions {
22
+ lockPath: string;
23
+ identity: DaemonIdentity;
24
+ endpoint: DaemonEndpoint;
25
+ now?: Date | undefined;
26
+ staleAfterMs?: number | undefined;
27
+ }
28
+ export type AcquireDaemonLockResult = {
29
+ status: "acquired";
30
+ lock: DaemonLock;
31
+ } | {
32
+ status: "conflict";
33
+ record: DaemonLockRecord | null;
34
+ stale: boolean;
35
+ };
36
+ export type AcquireLocalFileDaemonLeadershipResult = LeadershipAcquireResult<DaemonLock, DaemonLockRecord>;
37
+ export declare function createDaemonIdentity(options: CreateDaemonIdentityOptions): DaemonIdentity;
38
+ export declare function daemonLockPath(workspaceRoot: string, workflowPath: string): string;
39
+ export declare function acquireDaemonLock(options: AcquireDaemonLockOptions): Promise<AcquireDaemonLockResult>;
40
+ export declare function readDaemonLock(lockPath: string): Promise<DaemonLockRecord | null>;
41
+ export declare function daemonLockIsStale(record: DaemonLockRecord, now?: Date, staleAfterMs?: number): boolean;
42
+ /** @beta */
43
+ export declare class DaemonLock implements LeadershipLease<DaemonLockRecord> {
44
+ readonly lockPath: string;
45
+ private record;
46
+ private readonly operationMutex;
47
+ constructor(lockPath: string, record: DaemonLockRecord);
48
+ snapshot(): DaemonLockRecord;
49
+ heartbeat(now?: Date): Promise<DaemonLockRecord>;
50
+ release(): Promise<boolean>;
51
+ }
52
+ /** @beta */
53
+ export declare class LocalFileDaemonLeadershipStore implements LeadershipStore<AcquireDaemonLockOptions, string, DaemonLockRecord, DaemonLock> {
54
+ readonly kind = "local-file";
55
+ acquire(options: AcquireDaemonLockOptions): Promise<AcquireLocalFileDaemonLeadershipResult>;
56
+ read(lockPath: string): Promise<DaemonLockRecord | null>;
57
+ isStale(record: DaemonLockRecord, now?: Date, staleAfterMs?: number): boolean;
58
+ }
59
+ //# sourceMappingURL=daemonLock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemonLock.d.ts","sourceRoot":"","sources":["../src/daemonLock.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACV,uBAAuB,EACvB,kBAAkB,EAClB,kBAAkB,EAClB,eAAe,EACf,qBAAqB,EACrB,eAAe,EAChB,MAAM,sBAAsB,CAAC;AAE9B,YAAY;AACZ,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAOrC,YAAY;AACZ,MAAM,MAAM,cAAc,GAAG,kBAAkB,CAAC;AAEhD,MAAM,MAAM,cAAc,GAAG,kBAAkB,CAAC;AAEhD,MAAM,WAAW,gBAAiB,SAAQ,cAAc,EAAE,qBAAqB;IAC7E,OAAO,EAAE,OAAO,mBAAmB,CAAC;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,cAAc,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,2BAA2B;IAC1C,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,GAAG,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC/B;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,cAAc,CAAC;IACzB,QAAQ,EAAE,cAAc,CAAC;IACzB,GAAG,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACnC;AAED,MAAM,MAAM,uBAAuB,GAC/B;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,UAAU,CAAA;CAAE,GACxC;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC;AAE5E,MAAM,MAAM,sCAAsC,GAAG,uBAAuB,CAC1E,UAAU,EACV,gBAAgB,CACjB,CAAC;AAEF,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,2BAA2B,GAAG,cAAc,CAUzF;AAED,wBAAgB,cAAc,CAAC,aAAa,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAIlF;AAED,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,wBAAwB,GAChC,OAAO,CAAC,uBAAuB,CAAC,CAGlC;AAED,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAQvF;AAED,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,gBAAgB,EACxB,GAAG,OAAa,EAChB,YAAY,SAAS,GACpB,OAAO,CAIT;AAED,YAAY;AACZ,qBAAa,UAAW,YAAW,eAAe,CAAC,gBAAgB,CAAC;IAIhE,QAAQ,CAAC,QAAQ,EAAE,MAAM;IACzB,OAAO,CAAC,MAAM;IAJhB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAwB;gBAG5C,QAAQ,EAAE,MAAM,EACjB,MAAM,EAAE,gBAAgB;IAGlC,QAAQ,IAAI,gBAAgB;IAItB,SAAS,CAAC,GAAG,OAAa,GAAG,OAAO,CAAC,gBAAgB,CAAC;IActD,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC;CAUlC;AAED,YAAY;AACZ,qBAAa,8BAA+B,YAAW,eAAe,CACpE,wBAAwB,EACxB,MAAM,EACN,gBAAgB,EAChB,UAAU,CACX;IACC,QAAQ,CAAC,IAAI,gBAAgB;IAEvB,OAAO,CACX,OAAO,EAAE,wBAAwB,GAChC,OAAO,CAAC,sCAAsC,CAAC;IAkB5C,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAI9D,OAAO,CAAC,MAAM,EAAE,gBAAgB,EAAE,GAAG,OAAa,EAAE,YAAY,SAAS,GAAG,OAAO;CAGpF"}
@@ -0,0 +1,304 @@
1
+ import { constants, realpathSync } from "node:fs";
2
+ import fs from "node:fs/promises";
3
+ import os from "node:os";
4
+ import path from "node:path";
5
+ import { createHash, randomUUID } from "node:crypto";
6
+ import { setTimeout as sleep } from "node:timers/promises";
7
+ import { isOneOf, isRecord } from "@lorenz/domain";
8
+ import { createMutex } from "@lorenz/worker-pool";
9
+ /** @beta */
10
+ export const DAEMON_LOCK_VERSION = 1;
11
+ const MUTATION_LOCK_RETRY_MS = 10;
12
+ const MUTATION_LOCK_MAX_RETRY_MS = 250;
13
+ const MUTATION_LOCK_STALE_MS = 30_000;
14
+ const MUTATION_LOCK_TIMEOUT_MS = 120_000;
15
+ const DAEMON_ENDPOINT_KINDS = ["http", "socket"];
16
+ export function createDaemonIdentity(options) {
17
+ const now = options.now ?? new Date();
18
+ return {
19
+ ownerId: options.ownerId ?? randomUUID(),
20
+ pid: options.pid ?? process.pid,
21
+ hostname: options.hostname ?? os.hostname(),
22
+ startedAt: now.toISOString(),
23
+ workflowPath: canonicalPath(options.workflowPath),
24
+ workspaceRoot: canonicalPath(options.workspaceRoot),
25
+ };
26
+ }
27
+ export function daemonLockPath(workspaceRoot, workflowPath) {
28
+ const normalizedWorkflow = canonicalPath(workflowPath);
29
+ const suffix = createHash("sha256").update(normalizedWorkflow).digest("hex");
30
+ return path.join(canonicalPath(workspaceRoot), ".lorenz", "daemon", `${suffix}.lock.json`);
31
+ }
32
+ export async function acquireDaemonLock(options) {
33
+ const result = await new LocalFileDaemonLeadershipStore().acquire(options);
34
+ return result.status === "acquired" ? { status: "acquired", lock: result.lease } : result;
35
+ }
36
+ export async function readDaemonLock(lockPath) {
37
+ try {
38
+ const raw = await fs.readFile(lockPath, "utf8");
39
+ return parseDaemonLockRecord(raw, lockPath);
40
+ }
41
+ catch (error) {
42
+ if (isNodeError(error) && error.code === "ENOENT")
43
+ return null;
44
+ throw error;
45
+ }
46
+ }
47
+ export function daemonLockIsStale(record, now = new Date(), staleAfterMs = 60_000) {
48
+ const heartbeatMs = Date.parse(record.heartbeatAt);
49
+ if (!Number.isFinite(heartbeatMs))
50
+ return true;
51
+ return now.getTime() - heartbeatMs > staleAfterMs;
52
+ }
53
+ /** @beta */
54
+ export class DaemonLock {
55
+ lockPath;
56
+ record;
57
+ operationMutex = createMutex();
58
+ constructor(lockPath, record) {
59
+ this.lockPath = lockPath;
60
+ this.record = record;
61
+ }
62
+ snapshot() {
63
+ return { ...this.record, endpoint: { ...this.record.endpoint } };
64
+ }
65
+ async heartbeat(now = new Date()) {
66
+ return this.operationMutex.runExclusive(async () => {
67
+ return withDaemonLockMutation(this.lockPath, async () => {
68
+ const current = await readDaemonLock(this.lockPath);
69
+ if (!current || current.ownerId !== this.record.ownerId) {
70
+ throw new Error("daemon_lock_lost");
71
+ }
72
+ this.record = { ...current, heartbeatAt: now.toISOString() };
73
+ await writeDaemonLockRecord(this.lockPath, this.record);
74
+ return this.snapshot();
75
+ });
76
+ });
77
+ }
78
+ async release() {
79
+ return this.operationMutex.runExclusive(async () => {
80
+ return withDaemonLockMutation(this.lockPath, async () => {
81
+ const current = await readDaemonLock(this.lockPath);
82
+ if (!current || current.ownerId !== this.record.ownerId)
83
+ return false;
84
+ await fs.rm(this.lockPath, { force: true });
85
+ return true;
86
+ });
87
+ });
88
+ }
89
+ }
90
+ /** @beta */
91
+ export class LocalFileDaemonLeadershipStore {
92
+ kind = "local-file";
93
+ async acquire(options) {
94
+ const now = options.now ?? new Date();
95
+ const record = daemonLockRecord(options.lockPath, options.identity, options.endpoint, now);
96
+ await fs.mkdir(path.dirname(options.lockPath), { recursive: true, mode: 0o700 });
97
+ return withDaemonLockMutation(options.lockPath, async () => {
98
+ const created = await writeExclusiveJsonFile(options.lockPath, record);
99
+ if (created) {
100
+ return { status: "acquired", lease: new DaemonLock(options.lockPath, record) };
101
+ }
102
+ const existing = await readDaemonLock(options.lockPath);
103
+ return {
104
+ status: "conflict",
105
+ record: existing,
106
+ stale: existing ? this.isStale(existing, now, options.staleAfterMs ?? 60_000) : true,
107
+ };
108
+ });
109
+ }
110
+ async read(lockPath) {
111
+ return readDaemonLock(lockPath);
112
+ }
113
+ isStale(record, now = new Date(), staleAfterMs = 60_000) {
114
+ return daemonLockIsStale(record, now, staleAfterMs);
115
+ }
116
+ }
117
+ function daemonLockRecord(lockPath, identity, endpoint, now) {
118
+ return {
119
+ version: DAEMON_LOCK_VERSION,
120
+ ...identity,
121
+ lockPath,
122
+ endpoint,
123
+ heartbeatAt: now.toISOString(),
124
+ };
125
+ }
126
+ async function writeDaemonLockRecord(lockPath, record) {
127
+ const tempPath = `${lockPath}.${record.ownerId}.${randomUUID()}.tmp`;
128
+ try {
129
+ await fs.writeFile(tempPath, `${JSON.stringify(record, null, 2)}\n`, {
130
+ encoding: "utf8",
131
+ mode: 0o600,
132
+ });
133
+ await fs.rename(tempPath, lockPath);
134
+ }
135
+ catch (error) {
136
+ await fs.rm(tempPath, { force: true });
137
+ throw error;
138
+ }
139
+ }
140
+ async function writeExclusiveJsonFile(filePath, value) {
141
+ let handle;
142
+ try {
143
+ handle = await fs.open(filePath, constants.O_CREAT | constants.O_EXCL | constants.O_WRONLY, 0o600);
144
+ }
145
+ catch (error) {
146
+ if (isNodeError(error) && error.code === "EEXIST")
147
+ return false;
148
+ throw error;
149
+ }
150
+ try {
151
+ await handle.writeFile(`${JSON.stringify(value, null, 2)}\n`, "utf8");
152
+ await handle.close();
153
+ return true;
154
+ }
155
+ catch (error) {
156
+ try {
157
+ await handle.close();
158
+ }
159
+ catch {
160
+ // Ignore secondary close errors so the original write or close failure remains visible.
161
+ }
162
+ await fs.rm(filePath, { force: true });
163
+ throw error;
164
+ }
165
+ }
166
+ function parseDaemonLockRecord(raw, lockPath) {
167
+ let parsed;
168
+ try {
169
+ parsed = JSON.parse(raw);
170
+ }
171
+ catch {
172
+ return null;
173
+ }
174
+ if (!isRecord(parsed))
175
+ return null;
176
+ const record = parsed;
177
+ if (record.version !== DAEMON_LOCK_VERSION ||
178
+ typeof record.ownerId !== "string" ||
179
+ typeof record.pid !== "number" ||
180
+ typeof record.hostname !== "string" ||
181
+ typeof record.startedAt !== "string" ||
182
+ typeof record.workflowPath !== "string" ||
183
+ typeof record.workspaceRoot !== "string" ||
184
+ typeof record.heartbeatAt !== "string" ||
185
+ !isRecord(record.endpoint) ||
186
+ typeof record.endpoint.kind !== "string" ||
187
+ !isOneOf(record.endpoint.kind, DAEMON_ENDPOINT_KINDS) ||
188
+ typeof record.endpoint.address !== "string") {
189
+ return null;
190
+ }
191
+ return {
192
+ version: DAEMON_LOCK_VERSION,
193
+ ownerId: record.ownerId,
194
+ pid: record.pid,
195
+ hostname: record.hostname,
196
+ startedAt: record.startedAt,
197
+ workflowPath: record.workflowPath,
198
+ workspaceRoot: record.workspaceRoot,
199
+ lockPath,
200
+ endpoint: { kind: record.endpoint.kind, address: record.endpoint.address },
201
+ heartbeatAt: record.heartbeatAt,
202
+ };
203
+ }
204
+ function isNodeError(error) {
205
+ return error instanceof Error && "code" in error;
206
+ }
207
+ function canonicalPath(input) {
208
+ const resolved = path.resolve(input);
209
+ try {
210
+ return realpathSync.native(resolved);
211
+ }
212
+ catch (error) {
213
+ if (isNodeError(error) && error.code === "ENOENT")
214
+ return resolved;
215
+ throw error;
216
+ }
217
+ }
218
+ async function withDaemonLockMutation(lockPath, operation) {
219
+ const mutationPath = `${lockPath}.mutation`;
220
+ const token = randomUUID();
221
+ const startedAt = Date.now();
222
+ let retryDelayMs = MUTATION_LOCK_RETRY_MS;
223
+ await fs.mkdir(path.dirname(lockPath), { recursive: true, mode: 0o700 });
224
+ while (!(await tryAcquireMutationLock(mutationPath, token))) {
225
+ if (await removeStaleMutationLock(mutationPath)) {
226
+ retryDelayMs = MUTATION_LOCK_RETRY_MS;
227
+ continue;
228
+ }
229
+ if (Date.now() - startedAt > MUTATION_LOCK_TIMEOUT_MS) {
230
+ throw new Error("daemon_lock_mutation_timeout");
231
+ }
232
+ await sleep(retryDelayMs);
233
+ retryDelayMs = Math.min(retryDelayMs * 2, MUTATION_LOCK_MAX_RETRY_MS);
234
+ }
235
+ try {
236
+ return await operation();
237
+ }
238
+ finally {
239
+ await releaseMutationLock(mutationPath, token);
240
+ }
241
+ }
242
+ async function tryAcquireMutationLock(mutationPath, token) {
243
+ return writeExclusiveJsonFile(mutationPath, {
244
+ token,
245
+ pid: process.pid,
246
+ createdAt: new Date().toISOString(),
247
+ });
248
+ }
249
+ async function releaseMutationLock(mutationPath, token) {
250
+ const record = await readMutationLock(mutationPath);
251
+ if (record?.token !== token)
252
+ return false;
253
+ await fs.rm(mutationPath, { force: true });
254
+ return true;
255
+ }
256
+ async function removeStaleMutationLock(mutationPath, now = new Date()) {
257
+ const record = await readMutationLock(mutationPath);
258
+ if (!record)
259
+ return removeMalformedMutationLockIfStale(mutationPath, now);
260
+ if (!mutationLockRecordIsStale(record, now))
261
+ return false;
262
+ return releaseMutationLock(mutationPath, record.token);
263
+ }
264
+ async function removeMalformedMutationLockIfStale(mutationPath, now = new Date()) {
265
+ try {
266
+ const stat = await fs.stat(mutationPath);
267
+ if (now.getTime() - stat.mtimeMs <= MUTATION_LOCK_STALE_MS)
268
+ return false;
269
+ if (await readMutationLock(mutationPath))
270
+ return false;
271
+ throw new Error("daemon_lock_mutation_guard_malformed");
272
+ }
273
+ catch (error) {
274
+ if (isNodeError(error) && error.code === "ENOENT")
275
+ return true;
276
+ throw error;
277
+ }
278
+ }
279
+ function mutationLockRecordIsStale(record, now = new Date()) {
280
+ const createdAtMs = Date.parse(record.createdAt);
281
+ if (!Number.isFinite(createdAtMs))
282
+ return true;
283
+ return now.getTime() - createdAtMs > MUTATION_LOCK_STALE_MS;
284
+ }
285
+ async function readMutationLock(mutationPath) {
286
+ try {
287
+ const raw = await fs.readFile(mutationPath, "utf8");
288
+ const parsed = JSON.parse(raw);
289
+ if (!isRecord(parsed))
290
+ return null;
291
+ const record = parsed;
292
+ if (typeof record.token !== "string" || typeof record.createdAt !== "string")
293
+ return null;
294
+ return { token: record.token, createdAt: record.createdAt };
295
+ }
296
+ catch (error) {
297
+ if (isNodeError(error) && error.code === "ENOENT")
298
+ return null;
299
+ if (error instanceof SyntaxError)
300
+ return null;
301
+ throw error;
302
+ }
303
+ }
304
+ //# sourceMappingURL=daemonLock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemonLock.js","sourceRoot":"","sources":["../src/daemonLock.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { type DaemonEndpoint, type DaemonLockRecord } from "./daemonLock.js";
2
+ export interface DaemonStatusPayload {
3
+ owner_id: string;
4
+ pid: number;
5
+ hostname: string;
6
+ started_at: string;
7
+ workflow_path: string;
8
+ workspace_root: string;
9
+ lock_path: string;
10
+ endpoint: DaemonEndpoint;
11
+ heartbeat_at: string;
12
+ heartbeat_age_ms: number | null;
13
+ stale: boolean;
14
+ }
15
+ export declare function daemonStatusPayload(record: DaemonLockRecord, now?: Date, staleAfterMs?: number): DaemonStatusPayload;
16
+ //# sourceMappingURL=daemonStatus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemonStatus.d.ts","sourceRoot":"","sources":["../src/daemonStatus.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,cAAc,EAAE,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEhG,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,cAAc,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,gBAAgB,EACxB,GAAG,OAAa,EAChB,YAAY,SAAS,GACpB,mBAAmB,CAkBrB"}
@@ -0,0 +1,21 @@
1
+ import { daemonLockIsStale } from "./daemonLock.js";
2
+ export function daemonStatusPayload(record, now = new Date(), staleAfterMs = 60_000) {
3
+ const heartbeatMs = Date.parse(record.heartbeatAt);
4
+ const heartbeatAgeMs = Number.isFinite(heartbeatMs)
5
+ ? Math.max(0, now.getTime() - heartbeatMs)
6
+ : null;
7
+ return {
8
+ owner_id: record.ownerId,
9
+ pid: record.pid,
10
+ hostname: record.hostname,
11
+ started_at: record.startedAt,
12
+ workflow_path: record.workflowPath,
13
+ workspace_root: record.workspaceRoot,
14
+ lock_path: record.lockPath,
15
+ endpoint: { ...record.endpoint },
16
+ heartbeat_at: record.heartbeatAt,
17
+ heartbeat_age_ms: heartbeatAgeMs,
18
+ stale: daemonLockIsStale(record, now, staleAfterMs),
19
+ };
20
+ }
21
+ //# sourceMappingURL=daemonStatus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemonStatus.js","sourceRoot":"","sources":["../src/daemonStatus.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAA8C,MAAM,iBAAiB,CAAC;AAgBhG,MAAM,UAAU,mBAAmB,CACjC,MAAwB,EACxB,GAAG,GAAG,IAAI,IAAI,EAAE,EAChB,YAAY,GAAG,MAAM;IAErB,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IACnD,MAAM,cAAc,GAAG,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC;QACjD,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,OAAO,EAAE,GAAG,WAAW,CAAC;QAC1C,CAAC,CAAC,IAAI,CAAC;IACT,OAAO;QACL,QAAQ,EAAE,MAAM,CAAC,OAAO;QACxB,GAAG,EAAE,MAAM,CAAC,GAAG;QACf,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,UAAU,EAAE,MAAM,CAAC,SAAS;QAC5B,aAAa,EAAE,MAAM,CAAC,YAAY;QAClC,cAAc,EAAE,MAAM,CAAC,aAAa;QACpC,SAAS,EAAE,MAAM,CAAC,QAAQ;QAC1B,QAAQ,EAAE,EAAE,GAAG,MAAM,CAAC,QAAQ,EAAE;QAChC,YAAY,EAAE,MAAM,CAAC,WAAW;QAChC,gBAAgB,EAAE,cAAc;QAChC,KAAK,EAAE,iBAAiB,CAAC,MAAM,EAAE,GAAG,EAAE,YAAY,CAAC;KACpD,CAAC;AACJ,CAAC"}
@@ -16,14 +16,20 @@ export interface DoctorCommandOptions {
16
16
  workflowPath: string | null;
17
17
  dashboard: boolean;
18
18
  logsRoot: string | null;
19
+ flagTokens?: string[];
20
+ featureTokens?: string[];
19
21
  }
20
22
  export interface DoctorCommanderOptions {
21
23
  dashboard?: boolean;
22
24
  logsRoot?: string;
25
+ flag?: string[];
26
+ feature?: string[];
23
27
  }
24
28
  export interface DoctorInheritedOptions {
25
29
  dashboard?: boolean | undefined;
26
30
  logsRoot?: string | undefined;
31
+ flag?: string[] | undefined;
32
+ feature?: string[] | undefined;
27
33
  }
28
34
  interface DoctorRunContext {
29
35
  cwd?: string | undefined;