@exaudeus/workrail 0.8.5 → 0.9.0

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 (424) hide show
  1. package/README.md +157 -403
  2. package/dist/application/services/enhanced-loop-validator.d.ts +2 -2
  3. package/dist/application/services/enhanced-loop-validator.js +12 -2
  4. package/dist/application/services/validation-engine.d.ts +8 -29
  5. package/dist/application/services/validation-engine.js +38 -21
  6. package/dist/application/services/workflow-compiler.d.ts +18 -0
  7. package/dist/application/services/workflow-compiler.js +79 -0
  8. package/dist/application/services/workflow-interpreter.d.ts +31 -0
  9. package/dist/application/services/workflow-interpreter.js +280 -0
  10. package/dist/application/services/workflow-service.d.ts +34 -32
  11. package/dist/application/services/workflow-service.js +93 -425
  12. package/dist/application/use-cases/get-next-step.d.ts +6 -10
  13. package/dist/application/use-cases/get-next-step.js +2 -6
  14. package/dist/application/use-cases/get-workflow.d.ts +8 -6
  15. package/dist/application/use-cases/get-workflow.js +42 -33
  16. package/dist/application/use-cases/list-workflows.d.ts +3 -3
  17. package/dist/application/use-cases/validate-step-output.d.ts +4 -4
  18. package/dist/application/use-cases/validate-workflow-file.d.ts +46 -0
  19. package/dist/application/use-cases/validate-workflow-file.js +57 -0
  20. package/dist/cli/commands/cleanup.d.ts +8 -0
  21. package/dist/cli/commands/cleanup.js +20 -0
  22. package/dist/cli/commands/index.d.ts +7 -0
  23. package/dist/cli/commands/index.js +21 -0
  24. package/dist/cli/commands/init.d.ts +11 -0
  25. package/dist/cli/commands/init.js +49 -0
  26. package/dist/cli/commands/list.d.ts +9 -0
  27. package/dist/cli/commands/list.js +34 -0
  28. package/dist/cli/commands/migrate.d.ts +78 -0
  29. package/dist/cli/commands/migrate.js +248 -0
  30. package/dist/cli/commands/sources.d.ts +21 -0
  31. package/dist/cli/commands/sources.js +87 -0
  32. package/dist/cli/commands/start.d.ts +8 -0
  33. package/dist/cli/commands/start.js +16 -0
  34. package/dist/cli/commands/validate.d.ts +6 -0
  35. package/dist/cli/commands/validate.js +55 -0
  36. package/dist/cli/interpret-result.d.ts +4 -0
  37. package/dist/cli/interpret-result.js +24 -0
  38. package/dist/cli/output-formatter.d.ts +10 -0
  39. package/dist/cli/output-formatter.js +97 -0
  40. package/dist/cli/types/cli-result.d.ts +23 -0
  41. package/dist/cli/types/cli-result.js +30 -0
  42. package/dist/cli/types/exit-code.d.ts +13 -0
  43. package/dist/cli/types/exit-code.js +23 -0
  44. package/dist/cli/types/index.d.ts +4 -0
  45. package/dist/cli/types/index.js +11 -0
  46. package/dist/cli.js +84 -278
  47. package/dist/config/app-config.d.ts +40 -0
  48. package/dist/config/app-config.js +58 -0
  49. package/dist/config/feature-flags.d.ts +10 -2
  50. package/dist/config/feature-flags.js +74 -12
  51. package/dist/core/error-handler.d.ts +18 -27
  52. package/dist/core/error-handler.js +24 -218
  53. package/dist/di/container.d.ts +12 -0
  54. package/dist/di/container.js +244 -0
  55. package/dist/di/tokens.d.ts +40 -0
  56. package/dist/di/tokens.js +42 -0
  57. package/dist/domain/execution/error.d.ts +32 -0
  58. package/dist/domain/execution/error.js +24 -0
  59. package/dist/domain/execution/event.d.ts +7 -0
  60. package/dist/domain/execution/event.js +11 -0
  61. package/dist/domain/execution/ids.d.ts +9 -0
  62. package/dist/domain/execution/ids.js +9 -0
  63. package/dist/domain/execution/result.d.ts +3 -0
  64. package/dist/domain/execution/result.js +10 -0
  65. package/dist/domain/execution/state.d.ts +57 -0
  66. package/dist/domain/execution/state.js +28 -0
  67. package/dist/errors/app-error.d.ts +23 -0
  68. package/dist/errors/factories.d.ts +6 -0
  69. package/dist/errors/factories.js +21 -0
  70. package/dist/errors/formatter.d.ts +2 -0
  71. package/dist/errors/formatter.js +32 -0
  72. package/dist/errors/index.d.ts +3 -0
  73. package/dist/errors/index.js +7 -0
  74. package/dist/index.d.ts +6 -1
  75. package/dist/index.js +10 -25
  76. package/dist/infrastructure/index.d.ts +0 -1
  77. package/dist/infrastructure/index.js +0 -1
  78. package/dist/infrastructure/session/DashboardHeartbeat.d.ts +8 -0
  79. package/dist/infrastructure/session/DashboardHeartbeat.js +39 -0
  80. package/dist/infrastructure/session/DashboardLockRelease.d.ts +2 -0
  81. package/dist/infrastructure/session/DashboardLockRelease.js +29 -0
  82. package/dist/infrastructure/session/HttpServer.d.ts +25 -6
  83. package/dist/infrastructure/session/HttpServer.js +245 -90
  84. package/dist/infrastructure/session/SessionDataNormalizer.js +12 -2
  85. package/dist/infrastructure/session/SessionDataValidator.js +12 -2
  86. package/dist/infrastructure/session/SessionManager.d.ts +5 -3
  87. package/dist/infrastructure/session/SessionManager.js +52 -6
  88. package/dist/infrastructure/storage/caching-workflow-storage.d.ts +30 -6
  89. package/dist/infrastructure/storage/caching-workflow-storage.js +105 -23
  90. package/dist/infrastructure/storage/enhanced-multi-source-workflow-storage.d.ts +13 -9
  91. package/dist/infrastructure/storage/enhanced-multi-source-workflow-storage.js +80 -54
  92. package/dist/infrastructure/storage/file-workflow-storage.d.ts +10 -8
  93. package/dist/infrastructure/storage/file-workflow-storage.js +48 -56
  94. package/dist/infrastructure/storage/git-workflow-storage.d.ts +7 -22
  95. package/dist/infrastructure/storage/git-workflow-storage.js +48 -103
  96. package/dist/infrastructure/storage/in-memory-storage.d.ts +10 -6
  97. package/dist/infrastructure/storage/in-memory-storage.js +18 -13
  98. package/dist/infrastructure/storage/plugin-workflow-storage.d.ts +6 -18
  99. package/dist/infrastructure/storage/plugin-workflow-storage.js +29 -51
  100. package/dist/infrastructure/storage/remote-workflow-storage.d.ts +8 -17
  101. package/dist/infrastructure/storage/remote-workflow-storage.js +33 -156
  102. package/dist/infrastructure/storage/schema-validating-workflow-storage.d.ts +21 -13
  103. package/dist/infrastructure/storage/schema-validating-workflow-storage.js +86 -24
  104. package/dist/infrastructure/storage/storage.d.ts +7 -5
  105. package/dist/infrastructure/storage/storage.js +7 -6
  106. package/dist/manifest.json +1093 -0
  107. package/dist/mcp/error-mapper.d.ts +9 -0
  108. package/dist/mcp/error-mapper.js +66 -0
  109. package/dist/mcp/handlers/session.d.ts +34 -0
  110. package/dist/mcp/handlers/session.js +135 -0
  111. package/dist/mcp/handlers/v2-workflow.d.ts +4 -0
  112. package/dist/mcp/handlers/v2-workflow.js +112 -0
  113. package/dist/mcp/handlers/workflow.d.ts +45 -0
  114. package/dist/mcp/handlers/workflow.js +167 -0
  115. package/dist/mcp/index.d.ts +16 -0
  116. package/dist/mcp/index.js +51 -0
  117. package/dist/mcp/output-schemas.d.ts +317 -0
  118. package/dist/mcp/output-schemas.js +91 -0
  119. package/dist/mcp/server.d.ts +3 -0
  120. package/dist/mcp/server.js +258 -0
  121. package/dist/mcp/tool-description-provider.d.ts +16 -0
  122. package/dist/mcp/tool-description-provider.js +43 -0
  123. package/dist/mcp/tool-descriptions.d.ts +2 -0
  124. package/dist/mcp/tool-descriptions.js +109 -0
  125. package/dist/mcp/tool-factory.d.ts +23 -0
  126. package/dist/mcp/tool-factory.js +14 -0
  127. package/dist/mcp/tools.d.ts +156 -0
  128. package/dist/mcp/tools.js +196 -0
  129. package/dist/mcp/types/tool-description-types.d.ts +8 -0
  130. package/dist/mcp/types/tool-description-types.js +24 -0
  131. package/dist/mcp/types.d.ts +25 -0
  132. package/dist/mcp/types.js +15 -0
  133. package/dist/mcp/v2/tool-registry.d.ts +11 -0
  134. package/dist/mcp/v2/tool-registry.js +26 -0
  135. package/dist/mcp/v2/tools.d.ts +20 -0
  136. package/dist/mcp/v2/tools.js +17 -0
  137. package/dist/mcp/validation/bounded-json.d.ts +3 -0
  138. package/dist/mcp/validation/bounded-json.js +22 -0
  139. package/dist/mcp/validation/workflow-next-prevalidate.d.ts +9 -0
  140. package/dist/mcp/validation/workflow-next-prevalidate.js +83 -0
  141. package/dist/mcp/zod-to-json-schema.d.ts +17 -0
  142. package/dist/mcp/zod-to-json-schema.js +134 -0
  143. package/dist/mcp-server.d.ts +1 -1
  144. package/dist/mcp-server.js +6 -424
  145. package/dist/runtime/adapters/in-memory-shutdown-events.d.ts +6 -0
  146. package/dist/runtime/adapters/in-memory-shutdown-events.js +20 -0
  147. package/dist/runtime/adapters/node-process-signals.d.ts +4 -0
  148. package/dist/runtime/adapters/node-process-signals.js +11 -0
  149. package/dist/runtime/adapters/node-process-terminator.d.ts +4 -0
  150. package/dist/runtime/adapters/node-process-terminator.js +17 -0
  151. package/dist/runtime/adapters/noop-process-signals.d.ts +4 -0
  152. package/dist/runtime/adapters/noop-process-signals.js +8 -0
  153. package/dist/runtime/adapters/throwing-process-terminator.d.ts +4 -0
  154. package/dist/runtime/adapters/throwing-process-terminator.js +9 -0
  155. package/dist/runtime/assert-never.d.ts +1 -0
  156. package/dist/runtime/assert-never.js +6 -0
  157. package/dist/runtime/brand.d.ts +5 -0
  158. package/dist/runtime/ports/process-signals.d.ts +4 -0
  159. package/dist/runtime/ports/process-signals.js +2 -0
  160. package/dist/runtime/ports/process-terminator.d.ts +8 -0
  161. package/dist/runtime/ports/process-terminator.js +2 -0
  162. package/dist/runtime/ports/shutdown-events.d.ts +11 -0
  163. package/dist/runtime/ports/shutdown-events.js +2 -0
  164. package/dist/runtime/process-lifecycle-policy.d.ts +5 -0
  165. package/dist/runtime/process-lifecycle-policy.js +2 -0
  166. package/dist/runtime/result.d.ts +17 -0
  167. package/dist/runtime/result.js +31 -0
  168. package/dist/runtime/runtime-mode.d.ts +9 -0
  169. package/dist/runtime/runtime-mode.js +2 -0
  170. package/dist/types/storage.d.ts +16 -5
  171. package/dist/types/storage.js +8 -0
  172. package/dist/types/validation.d.ts +27 -0
  173. package/dist/types/validation.js +10 -0
  174. package/dist/types/workflow-definition.d.ts +63 -0
  175. package/dist/types/workflow-definition.js +33 -0
  176. package/dist/types/workflow-source.d.ts +51 -0
  177. package/dist/types/workflow-source.js +128 -0
  178. package/dist/types/workflow.d.ts +28 -0
  179. package/dist/types/workflow.js +96 -0
  180. package/dist/utils/workflow-init.d.ts +1 -0
  181. package/dist/utils/workflow-init.js +38 -0
  182. package/dist/v2/durable-core/canonical/hashing.d.ts +11 -0
  183. package/dist/v2/durable-core/canonical/hashing.js +13 -0
  184. package/dist/v2/durable-core/canonical/jcs.d.ts +11 -0
  185. package/dist/v2/durable-core/canonical/jcs.js +65 -0
  186. package/dist/v2/durable-core/canonical/json-types.d.ts +6 -0
  187. package/dist/v2/durable-core/canonical/json-types.js +2 -0
  188. package/dist/v2/durable-core/canonical/json-zod.d.ts +2 -0
  189. package/dist/v2/durable-core/canonical/json-zod.js +7 -0
  190. package/dist/v2/durable-core/canonical/jsonl.d.ts +4 -0
  191. package/dist/v2/durable-core/canonical/jsonl.js +13 -0
  192. package/dist/v2/durable-core/ids/index.d.ts +23 -0
  193. package/dist/v2/durable-core/ids/index.js +46 -0
  194. package/dist/v2/durable-core/schemas/compiled-workflow/index.d.ts +47 -0
  195. package/dist/v2/durable-core/schemas/compiled-workflow/index.js +17 -0
  196. package/dist/v2/durable-core/schemas/session/events.d.ts +1812 -0
  197. package/dist/v2/durable-core/schemas/session/events.js +328 -0
  198. package/dist/v2/durable-core/schemas/session/index.d.ts +2 -0
  199. package/dist/v2/durable-core/schemas/session/index.js +8 -0
  200. package/dist/v2/durable-core/schemas/session/manifest.d.ts +57 -0
  201. package/dist/v2/durable-core/schemas/session/manifest.js +30 -0
  202. package/dist/v2/infra/local/crypto/index.d.ts +5 -0
  203. package/dist/v2/infra/local/crypto/index.js +12 -0
  204. package/dist/v2/infra/local/data-dir/index.d.ts +13 -0
  205. package/dist/v2/infra/local/data-dir/index.js +69 -0
  206. package/dist/v2/infra/local/fs/index.d.ts +26 -0
  207. package/dist/v2/infra/local/fs/index.js +156 -0
  208. package/dist/v2/infra/local/pinned-workflow-store/index.d.ts +11 -0
  209. package/dist/v2/infra/local/pinned-workflow-store/index.js +85 -0
  210. package/dist/v2/infra/local/session-lock/index.d.ts +12 -0
  211. package/dist/v2/infra/local/session-lock/index.js +44 -0
  212. package/dist/v2/infra/local/session-store/index.d.ts +22 -0
  213. package/dist/v2/infra/local/session-store/index.js +358 -0
  214. package/dist/v2/infra/local/sha256/index.d.ts +5 -0
  215. package/dist/v2/infra/local/sha256/index.js +12 -0
  216. package/dist/v2/ports/data-dir.port.d.ts +9 -0
  217. package/dist/v2/ports/data-dir.port.js +2 -0
  218. package/dist/v2/ports/fs.port.d.ts +41 -0
  219. package/dist/v2/ports/fs.port.js +2 -0
  220. package/dist/v2/ports/pinned-workflow-store.port.d.ts +11 -0
  221. package/dist/v2/ports/pinned-workflow-store.port.js +2 -0
  222. package/dist/v2/ports/session-event-log-store.port.d.ts +37 -0
  223. package/dist/v2/ports/session-event-log-store.port.js +2 -0
  224. package/dist/v2/ports/session-lock.port.d.ts +23 -0
  225. package/dist/v2/ports/session-lock.port.js +2 -0
  226. package/dist/v2/ports/sha256.port.d.ts +4 -0
  227. package/dist/v2/ports/sha256.port.js +2 -0
  228. package/dist/v2/projections/advance-outcomes.d.ts +23 -0
  229. package/dist/v2/projections/advance-outcomes.js +23 -0
  230. package/dist/v2/projections/capabilities.d.ts +27 -0
  231. package/dist/v2/projections/capabilities.js +33 -0
  232. package/dist/v2/projections/gaps.d.ts +29 -0
  233. package/dist/v2/projections/gaps.js +49 -0
  234. package/dist/v2/projections/node-outputs.d.ts +34 -0
  235. package/dist/v2/projections/node-outputs.js +73 -0
  236. package/dist/v2/projections/preferences.d.ts +28 -0
  237. package/dist/v2/projections/preferences.js +50 -0
  238. package/dist/v2/projections/run-dag.d.ts +42 -0
  239. package/dist/v2/projections/run-dag.js +186 -0
  240. package/dist/v2/projections/run-status-signals.d.ts +26 -0
  241. package/dist/v2/projections/run-status-signals.js +49 -0
  242. package/dist/v2/projections/session-health.d.ts +18 -0
  243. package/dist/v2/projections/session-health.js +15 -0
  244. package/dist/v2/read-only/v1-to-v2-shim.d.ts +3 -0
  245. package/dist/v2/read-only/v1-to-v2-shim.js +38 -0
  246. package/package.json +35 -10
  247. package/spec/mcp-api-v1.0.md +5 -5
  248. package/web/assets/services/data-normalizer.js +17 -2
  249. package/web/assets/services/pattern-recognizer.js +3 -1
  250. package/web/assets/services/session-data.js +13 -8
  251. package/web/assets/utils/formatters.js +34 -23
  252. package/workflows/CHANGELOG-bug-investigation.md +4 -4
  253. package/workflows/bug-investigation.agentic.json +156 -56
  254. package/workflows/coding-task-workflow-agentic.json +262 -0
  255. package/workflows/design-thinking-workflow-autonomous.agentic.json +215 -0
  256. package/workflows/design-thinking-workflow.json +198 -0
  257. package/workflows/mr-review-workflow.agentic.json +538 -0
  258. package/workflows/routines/context-gathering.json +0 -4
  259. package/workflows/routines/ideation.json +73 -0
  260. package/dist/application/app.d.ts +0 -29
  261. package/dist/application/app.d.ts.map +0 -1
  262. package/dist/application/app.js +0 -114
  263. package/dist/application/app.js.map +0 -1
  264. package/dist/application/decorators/simple-output-decorator.d.ts +0 -8
  265. package/dist/application/decorators/simple-output-decorator.js +0 -89
  266. package/dist/application/services/classification-engine.d.ts +0 -33
  267. package/dist/application/services/classification-engine.js +0 -258
  268. package/dist/application/services/compression-service.d.ts +0 -20
  269. package/dist/application/services/compression-service.js +0 -312
  270. package/dist/application/services/context-management-service.d.ts +0 -38
  271. package/dist/application/services/context-management-service.js +0 -301
  272. package/dist/application/services/context-optimizer.d.ts +0 -11
  273. package/dist/application/services/context-optimizer.js +0 -62
  274. package/dist/application/services/context-persistence-service.d.ts +0 -45
  275. package/dist/application/services/context-persistence-service.js +0 -273
  276. package/dist/application/services/documentation-service.d.ts +0 -20
  277. package/dist/application/services/documentation-service.js +0 -155
  278. package/dist/application/services/enhanced-error-service.d.ts.map +0 -1
  279. package/dist/application/services/enhanced-error-service.js.map +0 -1
  280. package/dist/application/services/loop-context-optimizer.d.ts +0 -8
  281. package/dist/application/services/loop-context-optimizer.js +0 -114
  282. package/dist/application/services/loop-execution-context.d.ts +0 -23
  283. package/dist/application/services/loop-execution-context.js +0 -188
  284. package/dist/application/services/loop-step-resolver.d.ts +0 -11
  285. package/dist/application/services/loop-step-resolver.js +0 -70
  286. package/dist/application/services/validation-engine.d.ts.map +0 -1
  287. package/dist/application/services/validation-engine.js.map +0 -1
  288. package/dist/application/services/workflow-service.d.ts.map +0 -1
  289. package/dist/application/services/workflow-service.js.map +0 -1
  290. package/dist/application/use-cases/get-next-step.d.ts.map +0 -1
  291. package/dist/application/use-cases/get-next-step.js.map +0 -1
  292. package/dist/application/use-cases/get-workflow-docs.d.ts +0 -4
  293. package/dist/application/use-cases/get-workflow-docs.js +0 -12
  294. package/dist/application/use-cases/get-workflow.d.ts.map +0 -1
  295. package/dist/application/use-cases/get-workflow.js.map +0 -1
  296. package/dist/application/use-cases/get-workrail-help.d.ts +0 -4
  297. package/dist/application/use-cases/get-workrail-help.js +0 -12
  298. package/dist/application/use-cases/list-workflows.d.ts.map +0 -1
  299. package/dist/application/use-cases/list-workflows.js.map +0 -1
  300. package/dist/application/use-cases/validate-step-output.d.ts.map +0 -1
  301. package/dist/application/use-cases/validate-step-output.js.map +0 -1
  302. package/dist/application/use-cases/validate-workflow-json.d.ts.map +0 -1
  303. package/dist/application/use-cases/validate-workflow-json.js.map +0 -1
  304. package/dist/application/validation.d.ts.map +0 -1
  305. package/dist/application/validation.js.map +0 -1
  306. package/dist/cli/migrate-workflow.d.ts +0 -22
  307. package/dist/cli/migrate-workflow.js +0 -196
  308. package/dist/cli.d.ts.map +0 -1
  309. package/dist/cli.js.map +0 -1
  310. package/dist/container.d.ts +0 -15
  311. package/dist/container.d.ts.map +0 -1
  312. package/dist/container.js +0 -25
  313. package/dist/container.js.map +0 -1
  314. package/dist/core/error-handler.d.ts.map +0 -1
  315. package/dist/core/error-handler.js.map +0 -1
  316. package/dist/domain/index.d.ts +0 -2
  317. package/dist/domain/index.d.ts.map +0 -1
  318. package/dist/domain/index.js +0 -18
  319. package/dist/domain/index.js.map +0 -1
  320. package/dist/index.d.ts.map +0 -1
  321. package/dist/index.js.map +0 -1
  322. package/dist/infrastructure/index.d.ts.map +0 -1
  323. package/dist/infrastructure/index.js.map +0 -1
  324. package/dist/infrastructure/rpc/handler.d.ts +0 -17
  325. package/dist/infrastructure/rpc/handler.d.ts.map +0 -1
  326. package/dist/infrastructure/rpc/handler.js +0 -78
  327. package/dist/infrastructure/rpc/handler.js.map +0 -1
  328. package/dist/infrastructure/rpc/index.d.ts +0 -1
  329. package/dist/infrastructure/rpc/index.d.ts.map +0 -1
  330. package/dist/infrastructure/rpc/index.js +0 -17
  331. package/dist/infrastructure/rpc/index.js.map +0 -1
  332. package/dist/infrastructure/rpc/server.d.ts +0 -3
  333. package/dist/infrastructure/rpc/server.d.ts.map +0 -1
  334. package/dist/infrastructure/rpc/server.js +0 -37
  335. package/dist/infrastructure/rpc/server.js.map +0 -1
  336. package/dist/infrastructure/storage/caching-workflow-storage.d.ts.map +0 -1
  337. package/dist/infrastructure/storage/caching-workflow-storage.js.map +0 -1
  338. package/dist/infrastructure/storage/context-storage.d.ts +0 -150
  339. package/dist/infrastructure/storage/context-storage.js +0 -40
  340. package/dist/infrastructure/storage/file-workflow-storage.d.ts.map +0 -1
  341. package/dist/infrastructure/storage/file-workflow-storage.js.map +0 -1
  342. package/dist/infrastructure/storage/filesystem-blob-storage.d.ts +0 -27
  343. package/dist/infrastructure/storage/filesystem-blob-storage.js +0 -363
  344. package/dist/infrastructure/storage/git-workflow-storage.d.ts.map +0 -1
  345. package/dist/infrastructure/storage/git-workflow-storage.js.map +0 -1
  346. package/dist/infrastructure/storage/hybrid-context-storage.d.ts +0 -29
  347. package/dist/infrastructure/storage/hybrid-context-storage.js +0 -400
  348. package/dist/infrastructure/storage/in-memory-storage.d.ts.map +0 -1
  349. package/dist/infrastructure/storage/in-memory-storage.js.map +0 -1
  350. package/dist/infrastructure/storage/index.d.ts.map +0 -1
  351. package/dist/infrastructure/storage/index.js.map +0 -1
  352. package/dist/infrastructure/storage/migrations/001_initial_schema.sql +0 -38
  353. package/dist/infrastructure/storage/migrations/002_context_concurrency_enhancements.sql +0 -234
  354. package/dist/infrastructure/storage/migrations/003_classification_overrides.sql +0 -20
  355. package/dist/infrastructure/storage/multi-directory-workflow-storage.d.ts +0 -32
  356. package/dist/infrastructure/storage/multi-directory-workflow-storage.d.ts.map +0 -1
  357. package/dist/infrastructure/storage/multi-directory-workflow-storage.js +0 -184
  358. package/dist/infrastructure/storage/multi-directory-workflow-storage.js.map +0 -1
  359. package/dist/infrastructure/storage/plugin-workflow-storage.d.ts.map +0 -1
  360. package/dist/infrastructure/storage/plugin-workflow-storage.js.map +0 -1
  361. package/dist/infrastructure/storage/remote-workflow-storage.d.ts.map +0 -1
  362. package/dist/infrastructure/storage/remote-workflow-storage.js.map +0 -1
  363. package/dist/infrastructure/storage/schema-validating-workflow-storage.d.ts.map +0 -1
  364. package/dist/infrastructure/storage/schema-validating-workflow-storage.js.map +0 -1
  365. package/dist/infrastructure/storage/sqlite-metadata-storage.d.ts +0 -35
  366. package/dist/infrastructure/storage/sqlite-metadata-storage.js +0 -410
  367. package/dist/infrastructure/storage/sqlite-migrator.d.ts +0 -46
  368. package/dist/infrastructure/storage/sqlite-migrator.js +0 -293
  369. package/dist/infrastructure/storage/storage.d.ts.map +0 -1
  370. package/dist/infrastructure/storage/storage.js.map +0 -1
  371. package/dist/mcp-server.d.ts.map +0 -1
  372. package/dist/mcp-server.js.map +0 -1
  373. package/dist/tools/mcp_initialize.d.ts +0 -2
  374. package/dist/tools/mcp_initialize.d.ts.map +0 -1
  375. package/dist/tools/mcp_initialize.js +0 -45
  376. package/dist/tools/mcp_initialize.js.map +0 -1
  377. package/dist/tools/mcp_shutdown.d.ts +0 -2
  378. package/dist/tools/mcp_shutdown.d.ts.map +0 -1
  379. package/dist/tools/mcp_shutdown.js +0 -10
  380. package/dist/tools/mcp_shutdown.js.map +0 -1
  381. package/dist/tools/mcp_tools_list.d.ts +0 -2
  382. package/dist/tools/mcp_tools_list.d.ts.map +0 -1
  383. package/dist/tools/mcp_tools_list.js +0 -60
  384. package/dist/tools/mcp_tools_list.js.map +0 -1
  385. package/dist/tools/session-tools.d.ts +0 -5
  386. package/dist/tools/session-tools.js +0 -270
  387. package/dist/types/context-types.d.ts +0 -236
  388. package/dist/types/context-types.js +0 -10
  389. package/dist/types/documentation-types.d.ts +0 -37
  390. package/dist/types/loop-context-optimizer.d.ts +0 -7
  391. package/dist/types/mcp-types.d.ts +0 -273
  392. package/dist/types/mcp-types.d.ts.map +0 -1
  393. package/dist/types/mcp-types.js +0 -19
  394. package/dist/types/mcp-types.js.map +0 -1
  395. package/dist/types/server.d.ts.map +0 -1
  396. package/dist/types/server.js.map +0 -1
  397. package/dist/types/storage.d.ts.map +0 -1
  398. package/dist/types/storage.js.map +0 -1
  399. package/dist/types/workflow-types.d.ts +0 -336
  400. package/dist/types/workflow-types.d.ts.map +0 -1
  401. package/dist/types/workflow-types.js +0 -20
  402. package/dist/types/workflow-types.js.map +0 -1
  403. package/dist/utils/condition-evaluator.d.ts.map +0 -1
  404. package/dist/utils/condition-evaluator.js.map +0 -1
  405. package/dist/utils/config.d.ts +0 -149
  406. package/dist/utils/config.d.ts.map +0 -1
  407. package/dist/utils/config.js +0 -251
  408. package/dist/utils/config.js.map +0 -1
  409. package/dist/utils/storage-security.d.ts.map +0 -1
  410. package/dist/utils/storage-security.js.map +0 -1
  411. package/dist/validation/request-validator.d.ts +0 -8
  412. package/dist/validation/request-validator.d.ts.map +0 -1
  413. package/dist/validation/request-validator.js +0 -32
  414. package/dist/validation/request-validator.js.map +0 -1
  415. package/dist/validation/response-validator.d.ts +0 -8
  416. package/dist/validation/response-validator.d.ts.map +0 -1
  417. package/dist/validation/response-validator.js +0 -110
  418. package/dist/validation/response-validator.js.map +0 -1
  419. package/dist/validation/schemas.d.ts +0 -1
  420. package/dist/validation/schemas.d.ts.map +0 -1
  421. package/dist/validation/schemas.js +0 -53
  422. package/dist/validation/schemas.js.map +0 -1
  423. /package/dist/{types/documentation-types.js → errors/app-error.js} +0 -0
  424. /package/dist/{types/loop-context-optimizer.js → runtime/brand.js} +0 -0
package/dist/index.js CHANGED
@@ -1,28 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict";
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.createWorkflowLookupServer = void 0;
5
- const container_1 = require("./container");
6
- async function main() {
7
- try {
8
- const { server } = (0, container_1.createAppContainer)();
9
- await server.start();
10
- console.log('Workflow Lookup MCP Server started successfully');
11
- const shutdown = async (signal) => {
12
- console.log(`Received ${signal}, shutting down...`);
13
- await server.stop();
14
- process.exit(0);
15
- };
16
- process.on('SIGINT', () => shutdown('SIGINT'));
17
- process.on('SIGTERM', () => shutdown('SIGTERM'));
18
- }
19
- catch (error) {
20
- console.error('Failed to start server:', error);
21
- process.exit(1);
22
- }
23
- }
24
- if (require.main === module) {
25
- main();
26
- }
27
- var server_1 = require("./infrastructure/rpc/server");
28
- Object.defineProperty(exports, "createWorkflowLookupServer", { enumerable: true, get: function () { return server_1.createWorkflowLookupServer; } });
4
+ exports.startServer = exports.DI = exports.resetContainer = exports.container = exports.initializeContainer = exports.bootstrap = void 0;
5
+ var container_js_1 = require("./di/container.js");
6
+ Object.defineProperty(exports, "bootstrap", { enumerable: true, get: function () { return container_js_1.bootstrap; } });
7
+ Object.defineProperty(exports, "initializeContainer", { enumerable: true, get: function () { return container_js_1.initializeContainer; } });
8
+ Object.defineProperty(exports, "container", { enumerable: true, get: function () { return container_js_1.container; } });
9
+ Object.defineProperty(exports, "resetContainer", { enumerable: true, get: function () { return container_js_1.resetContainer; } });
10
+ var tokens_js_1 = require("./di/tokens.js");
11
+ Object.defineProperty(exports, "DI", { enumerable: true, get: function () { return tokens_js_1.DI; } });
12
+ var server_js_1 = require("./mcp/server.js");
13
+ Object.defineProperty(exports, "startServer", { enumerable: true, get: function () { return server_js_1.startServer; } });
@@ -1,2 +1 @@
1
1
  export * from './storage';
2
- export * from './rpc';
@@ -15,4 +15,3 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./storage"), exports);
18
- __exportStar(require("./rpc"), exports);
@@ -0,0 +1,8 @@
1
+ export declare class DashboardHeartbeat {
2
+ private readonly lockFile;
3
+ private readonly isPrimary;
4
+ private timer;
5
+ constructor(lockFile: string, isPrimary: () => boolean);
6
+ start(): void;
7
+ stop(): void;
8
+ }
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.DashboardHeartbeat = void 0;
7
+ const promises_1 = __importDefault(require("fs/promises"));
8
+ class DashboardHeartbeat {
9
+ constructor(lockFile, isPrimary) {
10
+ this.lockFile = lockFile;
11
+ this.isPrimary = isPrimary;
12
+ this.timer = null;
13
+ }
14
+ start() {
15
+ this.stop();
16
+ this.timer = setInterval(async () => {
17
+ if (!this.isPrimary())
18
+ return;
19
+ try {
20
+ const lockContent = await promises_1.default.readFile(this.lockFile, 'utf-8');
21
+ const lockData = JSON.parse(lockContent);
22
+ lockData.lastHeartbeat = new Date().toISOString();
23
+ await promises_1.default.writeFile(this.lockFile, JSON.stringify(lockData, null, 2));
24
+ }
25
+ catch {
26
+ }
27
+ }, 30000);
28
+ if (this.timer.unref) {
29
+ this.timer.unref();
30
+ }
31
+ }
32
+ stop() {
33
+ if (!this.timer)
34
+ return;
35
+ clearInterval(this.timer);
36
+ this.timer = null;
37
+ }
38
+ }
39
+ exports.DashboardHeartbeat = DashboardHeartbeat;
@@ -0,0 +1,2 @@
1
+ export declare function releaseLockFileSync(lockFile: string): void;
2
+ export declare function releaseLockFile(lockFile: string): Promise<void>;
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.releaseLockFileSync = releaseLockFileSync;
7
+ exports.releaseLockFile = releaseLockFile;
8
+ const promises_1 = __importDefault(require("fs/promises"));
9
+ function releaseLockFileSync(lockFile) {
10
+ try {
11
+ const fsSync = require('fs');
12
+ fsSync.unlinkSync(lockFile);
13
+ }
14
+ catch (error) {
15
+ if (error?.code !== 'ENOENT') {
16
+ throw error;
17
+ }
18
+ }
19
+ }
20
+ async function releaseLockFile(lockFile) {
21
+ try {
22
+ await promises_1.default.unlink(lockFile);
23
+ }
24
+ catch (error) {
25
+ if (error?.code !== 'ENOENT') {
26
+ throw error;
27
+ }
28
+ }
29
+ }
@@ -1,24 +1,44 @@
1
1
  import { SessionManager } from './SessionManager.js';
2
+ import type { ProcessLifecyclePolicy } from '../../runtime/process-lifecycle-policy.js';
3
+ import type { ProcessSignals } from '../../runtime/ports/process-signals.js';
4
+ import type { ShutdownEvents } from '../../runtime/ports/shutdown-events.js';
5
+ export type DashboardMode = {
6
+ kind: 'unified';
7
+ } | {
8
+ kind: 'legacy';
9
+ };
10
+ export type BrowserBehavior = {
11
+ kind: 'auto_open';
12
+ } | {
13
+ kind: 'manual';
14
+ };
2
15
  export interface ServerConfig {
3
16
  port?: number;
4
- autoOpen?: boolean;
5
- disableUnifiedDashboard?: boolean;
17
+ browserBehavior?: BrowserBehavior;
18
+ dashboardMode?: DashboardMode;
6
19
  }
7
20
  export declare class HttpServer {
8
21
  private sessionManager;
9
- private config;
22
+ private readonly processLifecyclePolicy;
23
+ private readonly processSignals;
24
+ private readonly shutdownEvents;
25
+ private readonly dashboardMode;
26
+ private readonly browserBehavior;
10
27
  private app;
11
28
  private server;
12
29
  private port;
13
30
  private baseUrl;
14
31
  private isPrimary;
15
32
  private lockFile;
16
- private heartbeatInterval;
17
- constructor(sessionManager: SessionManager, config?: ServerConfig);
33
+ private readonly heartbeat;
34
+ constructor(sessionManager: SessionManager, processLifecyclePolicy: ProcessLifecyclePolicy, processSignals: ProcessSignals, shutdownEvents: ShutdownEvents, dashboardMode: DashboardMode, browserBehavior: BrowserBehavior);
35
+ private config;
36
+ setConfig(config: ServerConfig): this;
18
37
  private setupMiddleware;
19
38
  private setupRoutes;
20
39
  start(): Promise<string | null>;
21
40
  private tryBecomePrimary;
41
+ private shouldReclaimLock;
22
42
  private reclaimStaleLock;
23
43
  private checkHealth;
24
44
  private setupPrimaryCleanup;
@@ -29,7 +49,6 @@ export declare class HttpServer {
29
49
  stop(): Promise<void>;
30
50
  getBaseUrl(): string;
31
51
  getPort(): number;
32
- private startHeartbeat;
33
52
  private quickCleanup;
34
53
  private getWorkrailPorts;
35
54
  fullCleanup(): Promise<number>;
@@ -1,4 +1,16 @@
1
1
  "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
2
14
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
15
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
16
  };
@@ -9,23 +21,40 @@ const http_1 = require("http");
9
21
  const path_1 = __importDefault(require("path"));
10
22
  const promises_1 = __importDefault(require("fs/promises"));
11
23
  const os_1 = __importDefault(require("os"));
24
+ const tsyringe_1 = require("tsyringe");
25
+ const tokens_js_1 = require("../../di/tokens.js");
26
+ const SessionManager_js_1 = require("./SessionManager.js");
27
+ const DashboardHeartbeat_js_1 = require("./DashboardHeartbeat.js");
28
+ const DashboardLockRelease_js_1 = require("./DashboardLockRelease.js");
12
29
  const cors_1 = __importDefault(require("cors"));
13
30
  const open_1 = __importDefault(require("open"));
14
31
  const child_process_1 = require("child_process");
15
- class HttpServer {
16
- constructor(sessionManager, config = {}) {
32
+ let HttpServer = class HttpServer {
33
+ constructor(sessionManager, processLifecyclePolicy, processSignals, shutdownEvents, dashboardMode, browserBehavior) {
17
34
  this.sessionManager = sessionManager;
18
- this.config = config;
35
+ this.processLifecyclePolicy = processLifecyclePolicy;
36
+ this.processSignals = processSignals;
37
+ this.shutdownEvents = shutdownEvents;
38
+ this.dashboardMode = dashboardMode;
39
+ this.browserBehavior = browserBehavior;
19
40
  this.server = null;
20
41
  this.baseUrl = '';
21
42
  this.isPrimary = false;
22
- this.heartbeatInterval = null;
23
- this.port = config.port || 3456;
43
+ this.config = {};
44
+ this.port = 3456;
24
45
  this.lockFile = path_1.default.join(os_1.default.homedir(), '.workrail', 'dashboard.lock');
46
+ this.heartbeat = new DashboardHeartbeat_js_1.DashboardHeartbeat(this.lockFile, () => this.isPrimary);
25
47
  this.app = (0, express_1.default)();
26
48
  this.setupMiddleware();
27
49
  this.setupRoutes();
28
50
  }
51
+ setConfig(config) {
52
+ this.config = config;
53
+ if (config.port) {
54
+ this.port = config.port;
55
+ }
56
+ return this;
57
+ }
29
58
  setupMiddleware() {
30
59
  this.app.use((0, cors_1.default)({
31
60
  origin: '*',
@@ -150,34 +179,102 @@ class HttpServer {
150
179
  });
151
180
  this.app.get('/api/sessions/:workflow/:id/stream', async (req, res) => {
152
181
  const { workflow, id } = req.params;
182
+ let isCleanedUp = false;
183
+ let keepaliveInterval = null;
184
+ let maxConnectionTimeout = null;
185
+ const cleanup = () => {
186
+ if (isCleanedUp)
187
+ return;
188
+ isCleanedUp = true;
189
+ if (keepaliveInterval) {
190
+ clearInterval(keepaliveInterval);
191
+ keepaliveInterval = null;
192
+ }
193
+ if (maxConnectionTimeout) {
194
+ clearTimeout(maxConnectionTimeout);
195
+ maxConnectionTimeout = null;
196
+ }
197
+ try {
198
+ this.sessionManager.off('session:updated', onUpdate);
199
+ }
200
+ catch { }
201
+ try {
202
+ this.sessionManager.unwatchSession(workflow, id);
203
+ }
204
+ catch { }
205
+ try {
206
+ if (!res.writableEnded) {
207
+ res.end();
208
+ }
209
+ }
210
+ catch { }
211
+ };
212
+ const onUpdate = (event) => {
213
+ if (isCleanedUp || event.workflowId !== workflow || event.sessionId !== id) {
214
+ return;
215
+ }
216
+ if (res.writableEnded) {
217
+ cleanup();
218
+ return;
219
+ }
220
+ try {
221
+ res.write(`data: ${JSON.stringify({ type: 'update', session: event.session })}\n\n`);
222
+ }
223
+ catch (error) {
224
+ console.error(`[SSE] Write error for ${workflow}/${id}:`, error);
225
+ cleanup();
226
+ }
227
+ };
228
+ const safeWrite = (data) => {
229
+ if (isCleanedUp || res.writableEnded) {
230
+ cleanup();
231
+ return false;
232
+ }
233
+ try {
234
+ res.write(data);
235
+ return true;
236
+ }
237
+ catch (error) {
238
+ console.error(`[SSE] Write error for ${workflow}/${id}:`, error);
239
+ cleanup();
240
+ return false;
241
+ }
242
+ };
153
243
  res.setHeader('Content-Type', 'text/event-stream');
154
244
  res.setHeader('Cache-Control', 'no-cache');
155
245
  res.setHeader('Connection', 'keep-alive');
156
246
  res.setHeader('X-Accel-Buffering', 'no');
157
- res.write(`data: ${JSON.stringify({ type: 'connected', workflowId: workflow, sessionId: id })}\n\n`);
247
+ maxConnectionTimeout = setTimeout(() => {
248
+ console.error(`[SSE] Max connection time reached for ${workflow}/${id}, closing`);
249
+ cleanup();
250
+ }, 30 * 60 * 1000);
251
+ if (!safeWrite(`data: ${JSON.stringify({ type: 'connected', workflowId: workflow, sessionId: id })}\n\n`)) {
252
+ return;
253
+ }
158
254
  try {
159
255
  const session = await this.sessionManager.getSession(workflow, id);
160
- if (session) {
161
- res.write(`data: ${JSON.stringify({ type: 'update', session })}\n\n`);
256
+ if (session && !isCleanedUp) {
257
+ safeWrite(`data: ${JSON.stringify({ type: 'update', session })}\n\n`);
162
258
  }
163
259
  }
164
260
  catch (error) {
165
261
  }
166
- const onUpdate = (event) => {
167
- if (event.workflowId === workflow && event.sessionId === id) {
168
- res.write(`data: ${JSON.stringify({ type: 'update', session: event.session })}\n\n`);
169
- }
170
- };
171
262
  this.sessionManager.on('session:updated', onUpdate);
172
263
  this.sessionManager.watchSession(workflow, id);
173
- const keepalive = setInterval(() => {
174
- res.write(`:keepalive\n\n`);
264
+ keepaliveInterval = setInterval(() => {
265
+ if (!safeWrite(`:keepalive\n\n`)) {
266
+ }
175
267
  }, 30000);
176
- req.on('close', () => {
177
- this.sessionManager.off('session:updated', onUpdate);
178
- clearInterval(keepalive);
179
- res.end();
268
+ req.on('close', cleanup);
269
+ req.on('error', (error) => {
270
+ console.error(`[SSE] Request error for ${workflow}/${id}:`, error);
271
+ cleanup();
272
+ });
273
+ res.on('error', (error) => {
274
+ console.error(`[SSE] Response error for ${workflow}/${id}:`, error);
275
+ cleanup();
180
276
  });
277
+ res.on('finish', cleanup);
181
278
  });
182
279
  this.app.delete('/api/sessions/:workflow/:id', async (req, res) => {
183
280
  try {
@@ -241,7 +338,8 @@ class HttpServer {
241
338
  }
242
339
  async start() {
243
340
  await this.quickCleanup();
244
- if (this.config.disableUnifiedDashboard || process.env.WORKRAIL_DISABLE_UNIFIED_DASHBOARD === '1') {
341
+ const mode = this.config.dashboardMode ?? this.dashboardMode;
342
+ if (mode.kind === 'legacy') {
245
343
  console.error('[Dashboard] Unified dashboard disabled, using legacy mode');
246
344
  return await this.startLegacyMode();
247
345
  }
@@ -279,7 +377,7 @@ class HttpServer {
279
377
  console.error('[Dashboard] Primary elected');
280
378
  this.isPrimary = true;
281
379
  this.setupPrimaryCleanup();
282
- this.startHeartbeat();
380
+ this.heartbeat.start();
283
381
  return true;
284
382
  }
285
383
  catch (error) {
@@ -293,50 +391,80 @@ class HttpServer {
293
391
  throw error;
294
392
  }
295
393
  }
394
+ shouldReclaimLock(lockData) {
395
+ if (!lockData.pid || !lockData.port || !lockData.startedAt) {
396
+ return { reclaim: true, reason: 'invalid lock structure' };
397
+ }
398
+ const lastHeartbeat = new Date(lockData.lastHeartbeat || lockData.startedAt);
399
+ const ageMinutes = (Date.now() - lastHeartbeat.getTime()) / 60000;
400
+ if (ageMinutes > 2) {
401
+ return { reclaim: true, reason: `stale (${ageMinutes.toFixed(1)}min old)` };
402
+ }
403
+ try {
404
+ process.kill(lockData.pid, 0);
405
+ }
406
+ catch {
407
+ return { reclaim: true, reason: `PID ${lockData.pid} dead` };
408
+ }
409
+ return { reclaim: false, reason: 'valid' };
410
+ }
296
411
  async reclaimStaleLock() {
297
412
  try {
298
413
  const lockContent = await promises_1.default.readFile(this.lockFile, 'utf-8');
299
414
  const lockData = JSON.parse(lockContent);
300
- if (!lockData.pid || !lockData.port || !lockData.startedAt) {
301
- console.error('[Dashboard] Invalid lock file, reclaiming');
302
- await promises_1.default.unlink(this.lockFile);
303
- return await this.tryBecomePrimary();
304
- }
305
- const lastHeartbeat = new Date(lockData.lastHeartbeat || lockData.startedAt);
306
- const ageMinutes = (Date.now() - lastHeartbeat.getTime()) / 60000;
307
- if (ageMinutes > 2) {
308
- console.error(`[Dashboard] Stale lock detected (${ageMinutes.toFixed(1)}min old), reclaiming`);
309
- await promises_1.default.unlink(this.lockFile);
310
- return await this.tryBecomePrimary();
311
- }
312
- let processExists = false;
313
- try {
314
- process.kill(lockData.pid, 0);
315
- processExists = true;
316
- }
317
- catch {
318
- processExists = false;
319
- }
320
- if (!processExists) {
321
- console.error(`[Dashboard] Stale lock detected (PID ${lockData.pid} dead), reclaiming`);
322
- await promises_1.default.unlink(this.lockFile);
323
- return await this.tryBecomePrimary();
324
- }
325
- const isHealthy = await this.checkHealth(lockData.port);
326
- if (!isHealthy) {
327
- console.error(`[Dashboard] Primary (PID ${lockData.pid}) not responding, reclaiming`);
415
+ const { reclaim, reason } = this.shouldReclaimLock(lockData);
416
+ if (!reclaim) {
417
+ const isHealthy = await this.checkHealth(lockData.port);
418
+ if (isHealthy) {
419
+ return false;
420
+ }
421
+ console.error(`[Dashboard] Primary (PID ${lockData.pid}) not responding, attempting graceful shutdown`);
328
422
  try {
329
423
  process.kill(lockData.pid, 'SIGTERM');
330
424
  await new Promise(resolve => setTimeout(resolve, 2000));
331
425
  }
332
426
  catch { }
333
- await promises_1.default.unlink(this.lockFile);
334
- return await this.tryBecomePrimary();
427
+ const stillHealthy = await this.checkHealth(lockData.port);
428
+ if (stillHealthy) {
429
+ return false;
430
+ }
431
+ }
432
+ else {
433
+ console.error(`[Dashboard] Lock reclaim needed: ${reason}`);
434
+ }
435
+ const tempPath = `${this.lockFile}.${process.pid}.${Date.now()}`;
436
+ const newLockData = {
437
+ pid: process.pid,
438
+ port: 3456,
439
+ startedAt: new Date().toISOString(),
440
+ lastHeartbeat: new Date().toISOString(),
441
+ projectId: this.sessionManager.getProjectId(),
442
+ projectPath: this.sessionManager.getProjectPath()
443
+ };
444
+ try {
445
+ await promises_1.default.writeFile(tempPath, JSON.stringify(newLockData, null, 2));
446
+ await promises_1.default.rename(tempPath, this.lockFile);
447
+ console.error('[Dashboard] Lock reclaimed successfully');
448
+ this.isPrimary = true;
449
+ this.setupPrimaryCleanup();
450
+ this.heartbeat.start();
451
+ return true;
452
+ }
453
+ catch (error) {
454
+ await promises_1.default.unlink(tempPath).catch(() => { });
455
+ if (error.code === 'ENOENT') {
456
+ console.error('[Dashboard] Lock deleted during reclaim, trying fresh');
457
+ return await this.tryBecomePrimary();
458
+ }
459
+ console.error('[Dashboard] Lock reclaim failed:', error.message);
460
+ return false;
335
461
  }
336
- return false;
337
462
  }
338
463
  catch (error) {
339
- console.error('[Dashboard] Corrupted lock file, removing');
464
+ if (error.code === 'ENOENT') {
465
+ return await this.tryBecomePrimary();
466
+ }
467
+ console.error('[Dashboard] Lock file corrupted, attempting fresh claim');
340
468
  await promises_1.default.unlink(this.lockFile).catch(() => { });
341
469
  return await this.tryBecomePrimary();
342
470
  }
@@ -359,21 +487,44 @@ class HttpServer {
359
487
  }
360
488
  }
361
489
  setupPrimaryCleanup() {
362
- const cleanup = async () => {
363
- if (this.isPrimary) {
364
- console.error('[Dashboard] Primary shutting down, releasing lock');
365
- if (this.heartbeatInterval) {
366
- clearInterval(this.heartbeatInterval);
367
- this.heartbeatInterval = null;
490
+ if (this.processLifecyclePolicy.kind === 'no_signal_handlers') {
491
+ return;
492
+ }
493
+ let isCleaningUp = false;
494
+ const cleanupSync = () => {
495
+ if (isCleaningUp || !this.isPrimary)
496
+ return;
497
+ isCleaningUp = true;
498
+ console.error('[Dashboard] Primary shutting down (sync cleanup)');
499
+ this.heartbeat.stop();
500
+ try {
501
+ (0, DashboardLockRelease_js_1.releaseLockFileSync)(this.lockFile);
502
+ console.error('[Dashboard] Lock file released');
503
+ }
504
+ catch (error) {
505
+ if (error.code !== 'ENOENT') {
506
+ console.error('[Dashboard] Failed to release lock file:', error.message);
368
507
  }
369
- await promises_1.default.unlink(this.lockFile).catch(() => { });
370
- this.isPrimary = false;
371
508
  }
509
+ this.isPrimary = false;
372
510
  };
373
- process.on('exit', cleanup);
374
- process.on('SIGINT', cleanup);
375
- process.on('SIGTERM', cleanup);
376
- process.on('SIGHUP', cleanup);
511
+ const signalHandler = (signal) => {
512
+ if (isCleaningUp)
513
+ return;
514
+ isCleaningUp = true;
515
+ console.error(`[Dashboard] Received ${signal}`);
516
+ this.stop()
517
+ .catch(err => console.error('[Dashboard] Cleanup error:', err))
518
+ .finally(() => {
519
+ if (signal !== 'exit') {
520
+ this.shutdownEvents.emit({ kind: 'shutdown_requested', signal });
521
+ }
522
+ });
523
+ };
524
+ this.processSignals.on('exit', cleanupSync);
525
+ this.processSignals.on('SIGINT', () => signalHandler('SIGINT'));
526
+ this.processSignals.on('SIGTERM', () => signalHandler('SIGTERM'));
527
+ this.processSignals.on('SIGHUP', () => signalHandler('SIGHUP'));
377
528
  }
378
529
  async startAsPrimary() {
379
530
  await new Promise((resolve, reject) => {
@@ -438,7 +589,8 @@ class HttpServer {
438
589
  if (sessionId) {
439
590
  url += `?session=${sessionId}`;
440
591
  }
441
- if (this.config.autoOpen !== false) {
592
+ const behavior = this.config.browserBehavior ?? this.browserBehavior;
593
+ if (behavior.kind === 'auto_open') {
442
594
  try {
443
595
  await (0, open_1.default)(url);
444
596
  console.error(`🌐 Opened dashboard: ${url}`);
@@ -450,18 +602,25 @@ class HttpServer {
450
602
  return url;
451
603
  }
452
604
  async stop() {
605
+ this.heartbeat.stop();
453
606
  this.sessionManager.unwatchAll();
454
- return new Promise((resolve) => {
455
- if (this.server) {
456
- this.server.close(() => {
457
- console.error('HTTP server stopped');
458
- resolve();
459
- });
460
- }
461
- else {
607
+ await new Promise((resolve) => {
608
+ if (!this.server)
609
+ return resolve();
610
+ const closeTimeout = setTimeout(() => {
611
+ console.error('[Dashboard] Server close timeout after 5s, forcing shutdown');
462
612
  resolve();
463
- }
613
+ }, 5000);
614
+ this.server.close(() => {
615
+ clearTimeout(closeTimeout);
616
+ console.error('HTTP server stopped');
617
+ resolve();
618
+ });
464
619
  });
620
+ if (this.isPrimary) {
621
+ await (0, DashboardLockRelease_js_1.releaseLockFile)(this.lockFile).catch(() => { });
622
+ this.isPrimary = false;
623
+ }
465
624
  }
466
625
  getBaseUrl() {
467
626
  return this.baseUrl;
@@ -469,20 +628,6 @@ class HttpServer {
469
628
  getPort() {
470
629
  return this.port;
471
630
  }
472
- startHeartbeat() {
473
- this.heartbeatInterval = setInterval(async () => {
474
- if (this.isPrimary) {
475
- try {
476
- const lockContent = await promises_1.default.readFile(this.lockFile, 'utf-8');
477
- const lockData = JSON.parse(lockContent);
478
- lockData.lastHeartbeat = new Date().toISOString();
479
- await promises_1.default.writeFile(this.lockFile, JSON.stringify(lockData, null, 2));
480
- }
481
- catch (error) {
482
- }
483
- }
484
- }, 30000);
485
- }
486
631
  async quickCleanup() {
487
632
  try {
488
633
  const busyPorts = await this.getWorkrailPorts();
@@ -602,5 +747,15 @@ class HttpServer {
602
747
  throw error;
603
748
  }
604
749
  }
605
- }
750
+ };
606
751
  exports.HttpServer = HttpServer;
752
+ exports.HttpServer = HttpServer = __decorate([
753
+ (0, tsyringe_1.singleton)(),
754
+ __param(0, (0, tsyringe_1.inject)(SessionManager_js_1.SessionManager)),
755
+ __param(1, (0, tsyringe_1.inject)(tokens_js_1.DI.Runtime.ProcessLifecyclePolicy)),
756
+ __param(2, (0, tsyringe_1.inject)(tokens_js_1.DI.Runtime.ProcessSignals)),
757
+ __param(3, (0, tsyringe_1.inject)(tokens_js_1.DI.Runtime.ShutdownEvents)),
758
+ __param(4, (0, tsyringe_1.inject)(tokens_js_1.DI.Config.DashboardMode)),
759
+ __param(5, (0, tsyringe_1.inject)(tokens_js_1.DI.Config.BrowserBehavior)),
760
+ __metadata("design:paramtypes", [SessionManager_js_1.SessionManager, Object, Object, Object, Object, Object])
761
+ ], HttpServer);
@@ -1,7 +1,14 @@
1
1
  "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
2
8
  Object.defineProperty(exports, "__esModule", { value: true });
3
9
  exports.SessionDataNormalizer = void 0;
4
- class SessionDataNormalizer {
10
+ const tsyringe_1 = require("tsyringe");
11
+ let SessionDataNormalizer = class SessionDataNormalizer {
5
12
  normalize(workflowId, data) {
6
13
  if (!data || typeof data !== 'object') {
7
14
  return {};
@@ -207,5 +214,8 @@ class SessionDataNormalizer {
207
214
  return 'active';
208
215
  }
209
216
  }
210
- }
217
+ };
211
218
  exports.SessionDataNormalizer = SessionDataNormalizer;
219
+ exports.SessionDataNormalizer = SessionDataNormalizer = __decorate([
220
+ (0, tsyringe_1.singleton)()
221
+ ], SessionDataNormalizer);