botmux 2.46.1 → 2.47.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 (468) hide show
  1. package/README.en.md +5 -10
  2. package/README.md +5 -10
  3. package/dist/adapters/backend/tmux-backend.d.ts.map +1 -1
  4. package/dist/adapters/backend/tmux-backend.js +0 -11
  5. package/dist/adapters/backend/tmux-backend.js.map +1 -1
  6. package/dist/adapters/cli/claude-code.d.ts.map +1 -1
  7. package/dist/adapters/cli/claude-code.js +9 -36
  8. package/dist/adapters/cli/claude-code.js.map +1 -1
  9. package/dist/adapters/cli/coco.d.ts.map +1 -1
  10. package/dist/adapters/cli/coco.js +1 -26
  11. package/dist/adapters/cli/coco.js.map +1 -1
  12. package/dist/adapters/cli/codex.d.ts.map +1 -1
  13. package/dist/adapters/cli/codex.js +1 -6
  14. package/dist/adapters/cli/codex.js.map +1 -1
  15. package/dist/adapters/cli/cursor.d.ts.map +1 -1
  16. package/dist/adapters/cli/cursor.js +12 -58
  17. package/dist/adapters/cli/cursor.js.map +1 -1
  18. package/dist/adapters/cli/gemini.d.ts.map +1 -1
  19. package/dist/adapters/cli/gemini.js +1 -5
  20. package/dist/adapters/cli/gemini.js.map +1 -1
  21. package/dist/adapters/cli/opencode.d.ts.map +1 -1
  22. package/dist/adapters/cli/opencode.js +1 -19
  23. package/dist/adapters/cli/opencode.js.map +1 -1
  24. package/dist/adapters/cli/registry.d.ts +1 -5
  25. package/dist/adapters/cli/registry.d.ts.map +1 -1
  26. package/dist/adapters/cli/registry.js +2 -22
  27. package/dist/adapters/cli/registry.js.map +1 -1
  28. package/dist/adapters/cli/shared-hints.d.ts +1 -1
  29. package/dist/adapters/cli/shared-hints.d.ts.map +1 -1
  30. package/dist/adapters/cli/shared-hints.js +1 -2
  31. package/dist/adapters/cli/shared-hints.js.map +1 -1
  32. package/dist/adapters/cli/types.d.ts +2 -35
  33. package/dist/adapters/cli/types.d.ts.map +1 -1
  34. package/dist/bot-registry.d.ts +0 -59
  35. package/dist/bot-registry.d.ts.map +1 -1
  36. package/dist/bot-registry.js +0 -67
  37. package/dist/bot-registry.js.map +1 -1
  38. package/dist/cli/bots-list-output.d.ts +0 -8
  39. package/dist/cli/bots-list-output.d.ts.map +1 -1
  40. package/dist/cli/bots-list-output.js +0 -9
  41. package/dist/cli/bots-list-output.js.map +1 -1
  42. package/dist/cli.d.ts +1 -15
  43. package/dist/cli.d.ts.map +1 -1
  44. package/dist/cli.js +106 -603
  45. package/dist/cli.js.map +1 -1
  46. package/dist/config.d.ts +2 -11
  47. package/dist/config.d.ts.map +1 -1
  48. package/dist/config.js +4 -17
  49. package/dist/config.js.map +1 -1
  50. package/dist/core/command-handler.d.ts +0 -20
  51. package/dist/core/command-handler.d.ts.map +1 -1
  52. package/dist/core/command-handler.js +313 -762
  53. package/dist/core/command-handler.js.map +1 -1
  54. package/dist/core/dashboard-ipc-server.d.ts +0 -2
  55. package/dist/core/dashboard-ipc-server.d.ts.map +1 -1
  56. package/dist/core/dashboard-ipc-server.js +2 -222
  57. package/dist/core/dashboard-ipc-server.js.map +1 -1
  58. package/dist/core/role-resolver.d.ts +1 -17
  59. package/dist/core/role-resolver.d.ts.map +1 -1
  60. package/dist/core/role-resolver.js +10 -64
  61. package/dist/core/role-resolver.js.map +1 -1
  62. package/dist/core/session-discovery.d.ts.map +1 -1
  63. package/dist/core/session-discovery.js +5 -19
  64. package/dist/core/session-discovery.js.map +1 -1
  65. package/dist/core/session-manager.d.ts +1 -1
  66. package/dist/core/session-manager.d.ts.map +1 -1
  67. package/dist/core/session-manager.js +20 -37
  68. package/dist/core/session-manager.js.map +1 -1
  69. package/dist/core/types.d.ts +0 -5
  70. package/dist/core/types.d.ts.map +1 -1
  71. package/dist/core/types.js.map +1 -1
  72. package/dist/core/worker-pool.d.ts +0 -141
  73. package/dist/core/worker-pool.d.ts.map +1 -1
  74. package/dist/core/worker-pool.js +24 -543
  75. package/dist/core/worker-pool.js.map +1 -1
  76. package/dist/daemon.d.ts.map +1 -1
  77. package/dist/daemon.js +58 -213
  78. package/dist/daemon.js.map +1 -1
  79. package/dist/dashboard/auth.d.ts +1 -6
  80. package/dist/dashboard/auth.d.ts.map +1 -1
  81. package/dist/dashboard/auth.js +1 -9
  82. package/dist/dashboard/auth.js.map +1 -1
  83. package/dist/dashboard/web/app.js +0 -8
  84. package/dist/dashboard/web/app.js.map +1 -1
  85. package/dist/dashboard/web/bot-defaults.d.ts.map +1 -1
  86. package/dist/dashboard/web/bot-defaults.js +21 -205
  87. package/dist/dashboard/web/bot-defaults.js.map +1 -1
  88. package/dist/dashboard/web/i18n.d.ts.map +1 -1
  89. package/dist/dashboard/web/i18n.js +5 -43
  90. package/dist/dashboard/web/i18n.js.map +1 -1
  91. package/dist/dashboard/web/sessions.d.ts.map +1 -1
  92. package/dist/dashboard/web/sessions.js +0 -4
  93. package/dist/dashboard/web/sessions.js.map +1 -1
  94. package/dist/dashboard/web/workflows.js +3 -3
  95. package/dist/dashboard/web/workflows.js.map +1 -1
  96. package/dist/dashboard/workflow-api.d.ts +1 -8
  97. package/dist/dashboard/workflow-api.d.ts.map +1 -1
  98. package/dist/dashboard/workflow-api.js +4 -19
  99. package/dist/dashboard/workflow-api.js.map +1 -1
  100. package/dist/dashboard-web/app.js +375 -539
  101. package/dist/dashboard-web/index.html +1 -3
  102. package/dist/dashboard-web/style.css +0 -22
  103. package/dist/dashboard.js +2 -199
  104. package/dist/dashboard.js.map +1 -1
  105. package/dist/i18n/en.d.ts.map +1 -1
  106. package/dist/i18n/en.js +11 -104
  107. package/dist/i18n/en.js.map +1 -1
  108. package/dist/i18n/zh.d.ts.map +1 -1
  109. package/dist/i18n/zh.js +11 -104
  110. package/dist/i18n/zh.js.map +1 -1
  111. package/dist/im/lark/card-builder.d.ts +3 -108
  112. package/dist/im/lark/card-builder.d.ts.map +1 -1
  113. package/dist/im/lark/card-builder.js +50 -480
  114. package/dist/im/lark/card-builder.js.map +1 -1
  115. package/dist/im/lark/card-handler.d.ts.map +1 -1
  116. package/dist/im/lark/card-handler.js +18 -241
  117. package/dist/im/lark/card-handler.js.map +1 -1
  118. package/dist/im/lark/client.d.ts +0 -83
  119. package/dist/im/lark/client.d.ts.map +1 -1
  120. package/dist/im/lark/client.js +70 -286
  121. package/dist/im/lark/client.js.map +1 -1
  122. package/dist/im/lark/event-dispatcher.d.ts.map +1 -1
  123. package/dist/im/lark/event-dispatcher.js +4 -29
  124. package/dist/im/lark/event-dispatcher.js.map +1 -1
  125. package/dist/im/lark/grant-command.d.ts +1 -2
  126. package/dist/im/lark/grant-command.d.ts.map +1 -1
  127. package/dist/im/lark/grant-command.js +2 -3
  128. package/dist/im/lark/grant-command.js.map +1 -1
  129. package/dist/im/lark/identity-cache.d.ts.map +1 -1
  130. package/dist/im/lark/identity-cache.js +3 -3
  131. package/dist/im/lark/identity-cache.js.map +1 -1
  132. package/dist/im/lark/md-card.d.ts +2 -20
  133. package/dist/im/lark/md-card.d.ts.map +1 -1
  134. package/dist/im/lark/md-card.js +17 -49
  135. package/dist/im/lark/md-card.js.map +1 -1
  136. package/dist/im/lark/message-parser.d.ts.map +1 -1
  137. package/dist/im/lark/message-parser.js +31 -87
  138. package/dist/im/lark/message-parser.js.map +1 -1
  139. package/dist/im/lark/workflow-card-handler.d.ts +2 -2
  140. package/dist/im/lark/workflow-card-handler.d.ts.map +1 -1
  141. package/dist/im/lark/workflow-card-handler.js +1 -12
  142. package/dist/im/lark/workflow-card-handler.js.map +1 -1
  143. package/dist/im/lark/workflow-progress-card.d.ts.map +1 -1
  144. package/dist/im/lark/workflow-progress-card.js +0 -53
  145. package/dist/im/lark/workflow-progress-card.js.map +1 -1
  146. package/dist/services/codex-bridge-queue.d.ts +0 -1
  147. package/dist/services/codex-bridge-queue.d.ts.map +1 -1
  148. package/dist/services/codex-bridge-queue.js +0 -23
  149. package/dist/services/codex-bridge-queue.js.map +1 -1
  150. package/dist/services/codex-transcript.d.ts +0 -1
  151. package/dist/services/codex-transcript.d.ts.map +1 -1
  152. package/dist/services/codex-transcript.js.map +1 -1
  153. package/dist/services/feishu-task-client.d.ts +28 -0
  154. package/dist/services/feishu-task-client.d.ts.map +1 -0
  155. package/dist/services/feishu-task-client.js +123 -0
  156. package/dist/services/feishu-task-client.js.map +1 -0
  157. package/dist/services/grant-store.d.ts +2 -12
  158. package/dist/services/grant-store.d.ts.map +1 -1
  159. package/dist/services/grant-store.js +4 -51
  160. package/dist/services/grant-store.js.map +1 -1
  161. package/dist/services/group-creator.d.ts +0 -10
  162. package/dist/services/group-creator.d.ts.map +1 -1
  163. package/dist/services/group-creator.js +1 -26
  164. package/dist/services/group-creator.js.map +1 -1
  165. package/dist/services/groups-store.d.ts +0 -30
  166. package/dist/services/groups-store.d.ts.map +1 -1
  167. package/dist/services/groups-store.js +12 -85
  168. package/dist/services/groups-store.js.map +1 -1
  169. package/dist/services/project-scanner.d.ts +0 -10
  170. package/dist/services/project-scanner.d.ts.map +1 -1
  171. package/dist/services/project-scanner.js +0 -11
  172. package/dist/services/project-scanner.js.map +1 -1
  173. package/dist/services/session-store.js +1 -1
  174. package/dist/services/session-store.js.map +1 -1
  175. package/dist/services/task-store.d.ts +37 -0
  176. package/dist/services/task-store.d.ts.map +1 -0
  177. package/dist/services/task-store.js +115 -0
  178. package/dist/services/task-store.js.map +1 -0
  179. package/dist/setup/bot-config-editor.d.ts +1 -8
  180. package/dist/setup/bot-config-editor.d.ts.map +1 -1
  181. package/dist/setup/bot-config-editor.js +2 -20
  182. package/dist/setup/bot-config-editor.js.map +1 -1
  183. package/dist/setup/ensure-tmux.d.ts +22 -0
  184. package/dist/setup/ensure-tmux.d.ts.map +1 -1
  185. package/dist/setup/ensure-tmux.js +1 -25
  186. package/dist/setup/ensure-tmux.js.map +1 -1
  187. package/dist/setup/verify-permissions.d.ts.map +1 -1
  188. package/dist/setup/verify-permissions.js +1 -15
  189. package/dist/setup/verify-permissions.js.map +1 -1
  190. package/dist/skills/definitions.d.ts +0 -2
  191. package/dist/skills/definitions.d.ts.map +1 -1
  192. package/dist/skills/definitions.js +12 -178
  193. package/dist/skills/definitions.js.map +1 -1
  194. package/dist/skills/installer.d.ts +0 -34
  195. package/dist/skills/installer.d.ts.map +1 -1
  196. package/dist/skills/installer.js +2 -119
  197. package/dist/skills/installer.js.map +1 -1
  198. package/dist/types.d.ts +0 -25
  199. package/dist/types.d.ts.map +1 -1
  200. package/dist/utils/bot-routing.d.ts +0 -50
  201. package/dist/utils/bot-routing.d.ts.map +1 -1
  202. package/dist/utils/bot-routing.js +0 -83
  203. package/dist/utils/bot-routing.js.map +1 -1
  204. package/dist/utils/user-token.d.ts.map +1 -1
  205. package/dist/utils/user-token.js +2 -0
  206. package/dist/utils/user-token.js.map +1 -1
  207. package/dist/worker.js +27 -198
  208. package/dist/worker.js.map +1 -1
  209. package/dist/workflows/attempt-resume.d.ts.map +1 -1
  210. package/dist/workflows/attempt-resume.js +2 -2
  211. package/dist/workflows/attempt-resume.js.map +1 -1
  212. package/dist/workflows/definition.d.ts +9 -412
  213. package/dist/workflows/definition.d.ts.map +1 -1
  214. package/dist/workflows/definition.js +3 -238
  215. package/dist/workflows/definition.js.map +1 -1
  216. package/dist/workflows/events/payloads.d.ts +11 -114
  217. package/dist/workflows/events/payloads.d.ts.map +1 -1
  218. package/dist/workflows/events/payloads.js +0 -46
  219. package/dist/workflows/events/payloads.js.map +1 -1
  220. package/dist/workflows/events/replay.d.ts +0 -21
  221. package/dist/workflows/events/replay.d.ts.map +1 -1
  222. package/dist/workflows/events/replay.js +0 -103
  223. package/dist/workflows/events/replay.js.map +1 -1
  224. package/dist/workflows/events/schema.d.ts +1017 -1712
  225. package/dist/workflows/events/schema.d.ts.map +1 -1
  226. package/dist/workflows/events/schema.js +1 -37
  227. package/dist/workflows/events/schema.js.map +1 -1
  228. package/dist/workflows/events/types.d.ts +1 -5
  229. package/dist/workflows/events/types.d.ts.map +1 -1
  230. package/dist/workflows/loader.d.ts +0 -14
  231. package/dist/workflows/loader.d.ts.map +1 -1
  232. package/dist/workflows/loader.js +0 -27
  233. package/dist/workflows/loader.js.map +1 -1
  234. package/dist/workflows/loop.js +0 -58
  235. package/dist/workflows/loop.js.map +1 -1
  236. package/dist/workflows/ops-projection.d.ts +0 -58
  237. package/dist/workflows/ops-projection.d.ts.map +1 -1
  238. package/dist/workflows/ops-projection.js +0 -74
  239. package/dist/workflows/ops-projection.js.map +1 -1
  240. package/dist/workflows/orchestrator.d.ts +1 -65
  241. package/dist/workflows/orchestrator.d.ts.map +1 -1
  242. package/dist/workflows/orchestrator.js +74 -486
  243. package/dist/workflows/orchestrator.js.map +1 -1
  244. package/dist/workflows/output-binding.d.ts +1 -8
  245. package/dist/workflows/output-binding.d.ts.map +1 -1
  246. package/dist/workflows/output-binding.js +11 -75
  247. package/dist/workflows/output-binding.js.map +1 -1
  248. package/dist/workflows/runtime.d.ts +1 -1
  249. package/dist/workflows/runtime.d.ts.map +1 -1
  250. package/dist/workflows/runtime.js +4 -39
  251. package/dist/workflows/runtime.js.map +1 -1
  252. package/dist/workflows/wait.d.ts +2 -23
  253. package/dist/workflows/wait.d.ts.map +1 -1
  254. package/dist/workflows/wait.js +17 -39
  255. package/dist/workflows/wait.js.map +1 -1
  256. package/package.json +1 -1
  257. package/dist/adapters/adopt-route.d.ts +0 -63
  258. package/dist/adapters/adopt-route.d.ts.map +0 -1
  259. package/dist/adapters/adopt-route.js +0 -195
  260. package/dist/adapters/adopt-route.js.map +0 -1
  261. package/dist/adapters/cli/codex-app.d.ts +0 -4
  262. package/dist/adapters/cli/codex-app.d.ts.map +0 -1
  263. package/dist/adapters/cli/codex-app.js +0 -72
  264. package/dist/adapters/cli/codex-app.js.map +0 -1
  265. package/dist/adapters/cli/hermes.d.ts +0 -4
  266. package/dist/adapters/cli/hermes.d.ts.map +0 -1
  267. package/dist/adapters/cli/hermes.js +0 -40
  268. package/dist/adapters/cli/hermes.js.map +0 -1
  269. package/dist/adapters/cli/mira.d.ts +0 -4
  270. package/dist/adapters/cli/mira.d.ts.map +0 -1
  271. package/dist/adapters/cli/mira.js +0 -67
  272. package/dist/adapters/cli/mira.js.map +0 -1
  273. package/dist/adapters/cli/mtr.d.ts +0 -5
  274. package/dist/adapters/cli/mtr.d.ts.map +0 -1
  275. package/dist/adapters/cli/mtr.js +0 -62
  276. package/dist/adapters/cli/mtr.js.map +0 -1
  277. package/dist/adapters/hook-command.d.ts +0 -18
  278. package/dist/adapters/hook-command.d.ts.map +0 -1
  279. package/dist/adapters/hook-command.js +0 -38
  280. package/dist/adapters/hook-command.js.map +0 -1
  281. package/dist/adapters/hook-installer.d.ts +0 -14
  282. package/dist/adapters/hook-installer.d.ts.map +0 -1
  283. package/dist/adapters/hook-installer.js +0 -192
  284. package/dist/adapters/hook-installer.js.map +0 -1
  285. package/dist/codex-app-runner.d.ts +0 -3
  286. package/dist/codex-app-runner.d.ts.map +0 -1
  287. package/dist/codex-app-runner.js +0 -512
  288. package/dist/codex-app-runner.js.map +0 -1
  289. package/dist/core/ask-api.d.ts +0 -47
  290. package/dist/core/ask-api.d.ts.map +0 -1
  291. package/dist/core/ask-api.js +0 -139
  292. package/dist/core/ask-api.js.map +0 -1
  293. package/dist/core/ask-args.d.ts +0 -53
  294. package/dist/core/ask-args.d.ts.map +0 -1
  295. package/dist/core/ask-args.js +0 -122
  296. package/dist/core/ask-args.js.map +0 -1
  297. package/dist/core/ask-broker.d.ts +0 -98
  298. package/dist/core/ask-broker.d.ts.map +0 -1
  299. package/dist/core/ask-broker.js +0 -329
  300. package/dist/core/ask-broker.js.map +0 -1
  301. package/dist/core/ask-hook/claude-code.d.ts +0 -50
  302. package/dist/core/ask-hook/claude-code.d.ts.map +0 -1
  303. package/dist/core/ask-hook/claude-code.js +0 -145
  304. package/dist/core/ask-hook/claude-code.js.map +0 -1
  305. package/dist/core/ask-hook/codex.d.ts +0 -43
  306. package/dist/core/ask-hook/codex.d.ts.map +0 -1
  307. package/dist/core/ask-hook/codex.js +0 -69
  308. package/dist/core/ask-hook/codex.js.map +0 -1
  309. package/dist/core/ask-hook/opencode.d.ts +0 -41
  310. package/dist/core/ask-hook/opencode.d.ts.map +0 -1
  311. package/dist/core/ask-hook/opencode.js +0 -108
  312. package/dist/core/ask-hook/opencode.js.map +0 -1
  313. package/dist/core/ask-hook/registry.d.ts +0 -3
  314. package/dist/core/ask-hook/registry.d.ts.map +0 -1
  315. package/dist/core/ask-hook/registry.js +0 -12
  316. package/dist/core/ask-hook/registry.js.map +0 -1
  317. package/dist/core/ask-hook/types.d.ts +0 -26
  318. package/dist/core/ask-hook/types.d.ts.map +0 -1
  319. package/dist/core/ask-hook/types.js +0 -2
  320. package/dist/core/ask-hook/types.js.map +0 -1
  321. package/dist/core/ask-types.d.ts +0 -146
  322. package/dist/core/ask-types.d.ts.map +0 -1
  323. package/dist/core/ask-types.js +0 -18
  324. package/dist/core/ask-types.js.map +0 -1
  325. package/dist/core/trigger-session.d.ts +0 -9
  326. package/dist/core/trigger-session.d.ts.map +0 -1
  327. package/dist/core/trigger-session.js +0 -158
  328. package/dist/core/trigger-session.js.map +0 -1
  329. package/dist/dashboard/connector-api.d.ts +0 -3
  330. package/dist/dashboard/connector-api.d.ts.map +0 -1
  331. package/dist/dashboard/connector-api.js +0 -351
  332. package/dist/dashboard/connector-api.js.map +0 -1
  333. package/dist/dashboard/federated-group-core.d.ts +0 -54
  334. package/dist/dashboard/federated-group-core.d.ts.map +0 -1
  335. package/dist/dashboard/federated-group-core.js +0 -165
  336. package/dist/dashboard/federated-group-core.js.map +0 -1
  337. package/dist/dashboard/federation-api.d.ts +0 -42
  338. package/dist/dashboard/federation-api.d.ts.map +0 -1
  339. package/dist/dashboard/federation-api.js +0 -408
  340. package/dist/dashboard/federation-api.js.map +0 -1
  341. package/dist/dashboard/federation-spoke-api.d.ts +0 -76
  342. package/dist/dashboard/federation-spoke-api.d.ts.map +0 -1
  343. package/dist/dashboard/federation-spoke-api.js +0 -618
  344. package/dist/dashboard/federation-spoke-api.js.map +0 -1
  345. package/dist/dashboard/team-group.d.ts +0 -18
  346. package/dist/dashboard/team-group.d.ts.map +0 -1
  347. package/dist/dashboard/team-group.js +0 -7
  348. package/dist/dashboard/team-group.js.map +0 -1
  349. package/dist/dashboard/trigger-api.d.ts +0 -13
  350. package/dist/dashboard/trigger-api.d.ts.map +0 -1
  351. package/dist/dashboard/trigger-api.js +0 -77
  352. package/dist/dashboard/trigger-api.js.map +0 -1
  353. package/dist/dashboard/web/connectors.d.ts +0 -2
  354. package/dist/dashboard/web/connectors.d.ts.map +0 -1
  355. package/dist/dashboard/web/connectors.js +0 -187
  356. package/dist/dashboard/web/connectors.js.map +0 -1
  357. package/dist/dashboard/web/team-federation.d.ts +0 -3
  358. package/dist/dashboard/web/team-federation.d.ts.map +0 -1
  359. package/dist/dashboard/web/team-federation.js +0 -487
  360. package/dist/dashboard/web/team-federation.js.map +0 -1
  361. package/dist/dashboard/webhook-routes.d.ts +0 -19
  362. package/dist/dashboard/webhook-routes.d.ts.map +0 -1
  363. package/dist/dashboard/webhook-routes.js +0 -321
  364. package/dist/dashboard/webhook-routes.js.map +0 -1
  365. package/dist/im/lark/ask-card.d.ts +0 -55
  366. package/dist/im/lark/ask-card.d.ts.map +0 -1
  367. package/dist/im/lark/ask-card.js +0 -328
  368. package/dist/im/lark/ask-card.js.map +0 -1
  369. package/dist/mira-output.d.ts +0 -3
  370. package/dist/mira-output.d.ts.map +0 -1
  371. package/dist/mira-output.js +0 -136
  372. package/dist/mira-output.js.map +0 -1
  373. package/dist/mira-runner.d.ts +0 -3
  374. package/dist/mira-runner.d.ts.map +0 -1
  375. package/dist/mira-runner.js +0 -534
  376. package/dist/mira-runner.js.map +0 -1
  377. package/dist/services/bot-owner-store.d.ts +0 -28
  378. package/dist/services/bot-owner-store.d.ts.map +0 -1
  379. package/dist/services/bot-owner-store.js +0 -82
  380. package/dist/services/bot-owner-store.js.map +0 -1
  381. package/dist/services/bot-profile-store.d.ts +0 -16
  382. package/dist/services/bot-profile-store.d.ts.map +0 -1
  383. package/dist/services/bot-profile-store.js +0 -98
  384. package/dist/services/bot-profile-store.js.map +0 -1
  385. package/dist/services/brand-store.d.ts +0 -15
  386. package/dist/services/brand-store.d.ts.map +0 -1
  387. package/dist/services/brand-store.js +0 -47
  388. package/dist/services/brand-store.js.map +0 -1
  389. package/dist/services/card-prefs-store.d.ts +0 -20
  390. package/dist/services/card-prefs-store.d.ts.map +0 -1
  391. package/dist/services/card-prefs-store.js +0 -82
  392. package/dist/services/card-prefs-store.js.map +0 -1
  393. package/dist/services/connector-store.d.ts +0 -58
  394. package/dist/services/connector-store.d.ts.map +0 -1
  395. package/dist/services/connector-store.js +0 -79
  396. package/dist/services/connector-store.js.map +0 -1
  397. package/dist/services/deployment-identity.d.ts +0 -22
  398. package/dist/services/deployment-identity.d.ts.map +0 -1
  399. package/dist/services/deployment-identity.js +0 -67
  400. package/dist/services/deployment-identity.js.map +0 -1
  401. package/dist/services/federation-membership-store.d.ts +0 -23
  402. package/dist/services/federation-membership-store.d.ts.map +0 -1
  403. package/dist/services/federation-membership-store.js +0 -66
  404. package/dist/services/federation-membership-store.js.map +0 -1
  405. package/dist/services/federation-roster.d.ts +0 -54
  406. package/dist/services/federation-roster.d.ts.map +0 -1
  407. package/dist/services/federation-roster.js +0 -51
  408. package/dist/services/federation-roster.js.map +0 -1
  409. package/dist/services/federation-store.d.ts +0 -76
  410. package/dist/services/federation-store.d.ts.map +0 -1
  411. package/dist/services/federation-store.js +0 -133
  412. package/dist/services/federation-store.js.map +0 -1
  413. package/dist/services/hermes-transcript.d.ts +0 -7
  414. package/dist/services/hermes-transcript.d.ts.map +0 -1
  415. package/dist/services/hermes-transcript.js +0 -117
  416. package/dist/services/hermes-transcript.js.map +0 -1
  417. package/dist/services/invite-store.d.ts +0 -28
  418. package/dist/services/invite-store.d.ts.map +0 -1
  419. package/dist/services/invite-store.js +0 -85
  420. package/dist/services/invite-store.js.map +0 -1
  421. package/dist/services/pairing-store.d.ts +0 -47
  422. package/dist/services/pairing-store.d.ts.map +0 -1
  423. package/dist/services/pairing-store.js +0 -132
  424. package/dist/services/pairing-store.js.map +0 -1
  425. package/dist/services/relay-picker.d.ts +0 -22
  426. package/dist/services/relay-picker.d.ts.map +0 -1
  427. package/dist/services/relay-picker.js +0 -62
  428. package/dist/services/relay-picker.js.map +0 -1
  429. package/dist/services/send-policy.d.ts +0 -55
  430. package/dist/services/send-policy.d.ts.map +0 -1
  431. package/dist/services/send-policy.js +0 -47
  432. package/dist/services/send-policy.js.map +0 -1
  433. package/dist/services/team-roster.d.ts +0 -38
  434. package/dist/services/team-roster.d.ts.map +0 -1
  435. package/dist/services/team-roster.js +0 -82
  436. package/dist/services/team-roster.js.map +0 -1
  437. package/dist/services/team-store.d.ts +0 -54
  438. package/dist/services/team-store.d.ts.map +0 -1
  439. package/dist/services/team-store.js +0 -156
  440. package/dist/services/team-store.js.map +0 -1
  441. package/dist/services/trigger-log-store.d.ts +0 -46
  442. package/dist/services/trigger-log-store.d.ts.map +0 -1
  443. package/dist/services/trigger-log-store.js +0 -132
  444. package/dist/services/trigger-log-store.js.map +0 -1
  445. package/dist/services/trigger-types.d.ts +0 -57
  446. package/dist/services/trigger-types.d.ts.map +0 -1
  447. package/dist/services/trigger-types.js +0 -28
  448. package/dist/services/trigger-types.js.map +0 -1
  449. package/dist/services/webhook-key.d.ts +0 -16
  450. package/dist/services/webhook-key.d.ts.map +0 -1
  451. package/dist/services/webhook-key.js +0 -123
  452. package/dist/services/webhook-key.js.map +0 -1
  453. package/dist/services/webhook-lifecycle-extractors.d.ts +0 -15
  454. package/dist/services/webhook-lifecycle-extractors.d.ts.map +0 -1
  455. package/dist/services/webhook-lifecycle-extractors.js +0 -59
  456. package/dist/services/webhook-lifecycle-extractors.js.map +0 -1
  457. package/dist/services/webhook-lifecycle-store.d.ts +0 -45
  458. package/dist/services/webhook-lifecycle-store.d.ts.map +0 -1
  459. package/dist/services/webhook-lifecycle-store.js +0 -159
  460. package/dist/services/webhook-lifecycle-store.js.map +0 -1
  461. package/dist/utils/daemon-discovery.d.ts +0 -11
  462. package/dist/utils/daemon-discovery.d.ts.map +0 -1
  463. package/dist/utils/daemon-discovery.js +0 -59
  464. package/dist/utils/daemon-discovery.js.map +0 -1
  465. package/dist/workflows/trigger-from-envelope.d.ts +0 -13
  466. package/dist/workflows/trigger-from-envelope.d.ts.map +0 -1
  467. package/dist/workflows/trigger-from-envelope.js +0 -67
  468. package/dist/workflows/trigger-from-envelope.js.map +0 -1
@@ -21,16 +21,6 @@
21
21
  *
22
22
  * One node may own at most one gate (before-gate) and one work
23
23
  * activity in v0. After-gates and re-runs are deferred.
24
- *
25
- * v0.2 loop body activities are scoped by a `loop::<loopId>.<N>` segment:
26
- *
27
- * loop work activity: `<runId>::loop::<loopId>.<N>::work::<bodyNodeId>`
28
- * loop gate activity: `<runId>::loop::<loopId>.<N>::gate::<bodyNodeId>`
29
- *
30
- * `<N>` is the 1-indexed iteration; `<loopId>` is the loop block's
31
- * nodeId. All segments stay within `SEGMENT_RE` (allows
32
- * `[A-Za-z0-9._:-]`), so existing `isValidPathSegment` / attempt-
33
- * sidecar path guards continue to apply without modification.
34
24
  * ────────────────────────────────────────────────────────────────────
35
25
  */
36
26
  import { topologicalOrder, } from './definition.js';
@@ -41,58 +31,6 @@ export function gateActivityId(runId, nodeId) {
41
31
  export function workActivityId(runId, nodeId) {
42
32
  return `${runId}::work::${nodeId}`;
43
33
  }
44
- // ─── Loop iteration activity IDs (v0.2) ───────────────────────────────────
45
- //
46
- // See /tmp/wf-loop-v02.md §4.2 and the top-of-file ASCII spec.
47
- //
48
- // Iteration `N` is 1-indexed. We refuse to encode `N < 1` so callers
49
- // never accidentally emit `loop::foo.0` ids (the iteration counter is a
50
- // real loop-state position, not a placeholder).
51
- export function loopWorkActivityId(runId, loopId, iteration, bodyNodeId) {
52
- if (!Number.isInteger(iteration) || iteration < 1) {
53
- throw new Error(`loopWorkActivityId: iteration must be a positive integer (got ${iteration})`);
54
- }
55
- return `${runId}::loop::${loopId}.${iteration}::work::${bodyNodeId}`;
56
- }
57
- export function loopGateActivityId(runId, loopId, iteration, bodyNodeId) {
58
- if (!Number.isInteger(iteration) || iteration < 1) {
59
- throw new Error(`loopGateActivityId: iteration must be a positive integer (got ${iteration})`);
60
- }
61
- return `${runId}::loop::${loopId}.${iteration}::gate::${bodyNodeId}`;
62
- }
63
- const PLAIN_RE = /^([^:]+(?:::?[^:]+)*?)::(work|gate)::([A-Za-z0-9_.-]+)$/;
64
- const LOOP_RE = /^(.+)::loop::([A-Za-z0-9_.-]+)\.(\d+)::(work|gate)::([A-Za-z0-9_.-]+)$/;
65
- export function parseActivityId(s) {
66
- // Loop form first — the `::loop::` segment is unambiguous and would
67
- // also accidentally satisfy a greedy plain match if we tried plain
68
- // first (`runId` would absorb `::loop::<id>.<N>::work`).
69
- const loopMatch = LOOP_RE.exec(s);
70
- if (loopMatch) {
71
- const [, runId, loopId, iterStr, activityKind, nodeId] = loopMatch;
72
- const iteration = Number(iterStr);
73
- if (!Number.isFinite(iteration) || iteration < 1)
74
- return undefined;
75
- return {
76
- kind: 'loop',
77
- runId,
78
- loopId,
79
- iteration,
80
- activityKind: activityKind,
81
- nodeId,
82
- };
83
- }
84
- const plainMatch = PLAIN_RE.exec(s);
85
- if (plainMatch) {
86
- const [, runId, activityKind, nodeId] = plainMatch;
87
- return {
88
- kind: 'plain',
89
- runId,
90
- activityKind: activityKind,
91
- nodeId,
92
- };
93
- }
94
- return undefined;
95
- }
96
34
  // ─── Decision function ───────────────────────────────────────────────────
97
35
  /**
98
36
  * Pure decision function. Read-only — never throws on graph cycles
@@ -126,309 +64,110 @@ export function decideNextActions(snapshot, def) {
126
64
  const actions = [];
127
65
  const runId = snapshot.run.runId;
128
66
  const order = topologicalOrder(def);
129
- // v0.2: compute loop body membership once so the top-level scheduler
130
- // skips body nodes (they're dispatched by the loop branch only).
131
- const bodyOwner = buildBodyOwnerMap(def);
132
67
  let failedNodeId;
133
68
  let pendingCount = 0;
134
- // ─── Loop lifecycle + body dispatch pass (v0.2) ──────────────────────
135
- //
136
- // For each loop block in topo order, this pass owns:
137
- // 1. emitting `startLoop` when the loop's `depends` first go green
138
- // 2. emitting `startLoopIteration` to open each iteration
139
- // 3. dispatching body activities under loop-iteration activityIds
140
- // 4. emitting `finishLoopIteration` once the terminator decision
141
- // attempt settles (approve or reject)
142
- // 5. emitting `finishLoop` once iteration loop closes (approved /
143
- // max-iterations-exceeded / non-terminator body failure / decision
144
- // humanGate timeout)
145
- //
146
- // Per codex round 3: lifecycle actions are returned as the SOLE action
147
- // of the tick so event ordering — `loopStarted` → `loopIterationStarted`
148
- // → body attempts — is deterministic and never interleaves with body
149
- // dispatches. Body dispatches batch up only when no lifecycle action
150
- // fires this tick.
151
69
  for (const nodeId of order) {
152
70
  const node = def.nodes[nodeId];
153
- if (node.type !== 'loop')
71
+ const nstatus = snapshot.nodes.get(nodeId)?.status ?? 'idle';
72
+ // Already settled at the node level — nothing for us to advance.
73
+ if (nstatus === 'succeeded' || nstatus === 'skipped' || nstatus === 'cancelled') {
154
74
  continue;
155
- const loopId = nodeId;
156
- const loopState = snapshot.loops.get(loopId);
157
- const depsOk = (node.depends ?? []).every((dep) => snapshot.nodes.get(dep)?.status === 'succeeded');
158
- // (1) Loop not yet entered.
159
- if (!loopState) {
160
- if (!depsOk) {
161
- pendingCount++;
162
- continue;
163
- }
164
- return [{ kind: 'startLoop', loopId, maxIterations: node.maxIterations }];
165
75
  }
166
- // Loop already finalized — nothing else to do.
167
- if (loopState.status !== 'running')
76
+ if (nstatus === 'failed') {
77
+ failedNodeId = failedNodeId ?? nodeId;
168
78
  continue;
169
- // (2) Loop started but no iteration opened yet.
170
- if (loopState.iteration === 0) {
171
- return [
172
- { kind: 'startLoopIteration', loopId, iteration: 1, prevResolution: 'initial' },
173
- ];
174
79
  }
175
- // Active iteration in progress.
176
- const currentIter = loopState.iteration;
177
- const iterState = loopState.iterations[currentIter - 1];
178
- if (!iterState) {
80
+ // Dependencies gate dispatch.
81
+ const depsOk = (node.depends ?? []).every((dep) => snapshot.nodes.get(dep)?.status === 'succeeded');
82
+ if (!depsOk) {
179
83
  pendingCount++;
180
- continue; // anomalous — shouldn't happen, skip safely
181
- }
182
- // (4) Current iteration already has a settled resolution:
183
- if (iterState.status === 'approved') {
184
- const outputRef = computeLoopOutputRef(snapshot, runId, node, loopId, currentIter);
185
- return [
186
- {
187
- kind: 'finishLoop',
188
- loopId,
189
- finalIteration: currentIter,
190
- resolution: 'approved',
191
- outputRef,
192
- },
193
- ];
194
- }
195
- if (iterState.status === 'rejected') {
196
- if (currentIter < loopState.maxIterations) {
197
- return [
198
- {
199
- kind: 'startLoopIteration',
200
- loopId,
201
- iteration: currentIter + 1,
202
- prevResolution: 'rejected',
203
- },
204
- ];
205
- }
206
- return [
207
- {
208
- kind: 'finishLoop',
209
- loopId,
210
- finalIteration: currentIter,
211
- resolution: 'max-iterations-exceeded',
212
- errorCode: 'LoopMaxIterationsExceeded',
213
- errorClass: 'userFault',
214
- },
215
- ];
216
- }
217
- if (iterState.status === 'failed' || iterState.status === 'cancelled') {
218
- // Non-terminator failure already finalized this iteration; close
219
- // the loop block with `body-failed` resolution (codex Step 3
220
- // review Medium). `cancelled` is reserved for user-initiated
221
- // cancel; `body-failed` distinguishes "this loop died because a
222
- // body node failed" from "user clicked cancel".
223
- return [
224
- {
225
- kind: 'finishLoop',
226
- loopId,
227
- finalIteration: currentIter,
228
- resolution: 'body-failed',
229
- errorCode: 'LoopBodyFailed',
230
- errorClass: 'fatal',
231
- },
232
- ];
84
+ continue;
233
85
  }
234
- // (3) Iteration is `running` — dispatch body / terminator.
235
- //
236
- // Step through body nodes in topo order *within* this iteration.
237
- // Use a small per-iteration helper map: bodyId → succeeded? so we
238
- // can resolve intra-body deps without touching the v0.1 node-level
239
- // status (which never advances for body nodes in v0.2).
240
- const bodySet = new Set(node.body);
241
- const bodyDone = new Map();
242
- let bodyFailureFinish;
243
- const iterDispatch = [];
244
- for (const bodyId of orderForBody(order, bodySet)) {
245
- const bodyNode = def.nodes[bodyId];
246
- // Intra-body dep check: all body-side deps must have a succeeded
247
- // activity in *this* iteration; loop-external deps were guaranteed
248
- // already by the loop block's own `depends` gate.
249
- const intraDepsOk = (bodyNode.depends ?? [])
250
- .filter((d) => bodySet.has(d))
251
- .every((d) => bodyDone.get(d) === true);
252
- if (!intraDepsOk) {
86
+ const gateActId = gateActivityId(runId, nodeId);
87
+ const workActId = workActivityId(runId, nodeId);
88
+ const gateAct = snapshot.activities.get(gateActId);
89
+ const workAct = snapshot.activities.get(workActId);
90
+ if (node.humanGate) {
91
+ if (!gateAct) {
92
+ actions.push({
93
+ kind: 'dispatchGate',
94
+ nodeId,
95
+ activityId: gateActId,
96
+ humanGate: node.humanGate,
97
+ });
253
98
  pendingCount++;
254
99
  continue;
255
100
  }
256
- const isTerminator = bodyId === node.terminate.node;
257
- const bodyGateActId = loopGateActivityId(runId, loopId, currentIter, bodyId);
258
- const bodyWorkActId = loopWorkActivityId(runId, loopId, currentIter, bodyId);
259
- const advance = decideNodeAdvancement(snapshot, bodyNode, bodyId, bodyGateActId, bodyWorkActId);
260
- if (advance.isSucceeded) {
261
- bodyDone.set(bodyId, true);
262
- if (isTerminator) {
263
- // Terminator settled — read its wait resolution out of the
264
- // activity attempt, then return `finishLoopIteration` as the
265
- // sole action this tick so the iteration advances cleanly.
266
- const decisionAct = snapshot.activities.get(bodyGateActId);
267
- const lastAt = decisionAct?.attempts[decisionAct.attempts.length - 1];
268
- const wait = lastAt?.wait?.resolution;
269
- if (wait &&
270
- wait.kind === 'resolved' &&
271
- (wait.resolution === 'approved' || wait.resolution === 'rejected')) {
272
- return [
273
- {
274
- kind: 'finishLoopIteration',
275
- loopId,
276
- iteration: currentIter,
277
- resolution: wait.resolution,
278
- decisionActivityId: bodyGateActId,
279
- waitResolvedEventId: wait.eventId,
280
- by: wait.by,
281
- comment: wait.comment,
282
- },
283
- ];
284
- }
285
- if (wait && wait.kind === 'deadlineExceeded') {
286
- return [
287
- {
288
- kind: 'finishLoopIteration',
289
- loopId,
290
- iteration: currentIter,
291
- resolution: 'rejected',
292
- decisionActivityId: bodyGateActId,
293
- waitResolvedEventId: wait.eventId,
294
- by: 'system',
295
- timedOut: true,
296
- },
297
- ];
298
- }
299
- // Decision attempt succeeded but no resolution found — defer.
300
- pendingCount++;
301
- }
101
+ if (gateAct.status === 'failed') {
102
+ actions.push({
103
+ kind: 'completeNodeFailed',
104
+ nodeId,
105
+ lastActivityId: gateActId,
106
+ errorClass: 'userFault',
107
+ });
302
108
  continue;
303
109
  }
304
- if (advance.isFailed) {
305
- if (isTerminator) {
306
- // Terminator humanGate timed out / failed → finish the loop
307
- // with `timeout` + WaitDeadlineExceeded (codex Step 3 review
308
- // Medium — schema invariant requires this errorCode pairing).
309
- bodyFailureFinish = {
310
- kind: 'finishLoop',
311
- loopId,
312
- finalIteration: currentIter,
313
- resolution: 'timeout',
314
- errorCode: 'WaitDeadlineExceeded',
315
- errorClass: 'userFault',
316
- };
317
- }
318
- else {
319
- // Non-terminator body node failed (subagent crash / hostExecutor
320
- // error / non-terminator humanGate.reject = fail-run per
321
- // /tmp/wf-loop-v02.md §10.8) → close as `body-failed`.
322
- bodyFailureFinish = {
323
- kind: 'finishLoop',
324
- loopId,
325
- finalIteration: currentIter,
326
- resolution: 'body-failed',
327
- errorCode: 'LoopBodyFailed',
328
- errorClass: 'fatal',
329
- };
330
- }
331
- break; // stop iterating body; we'll close the loop instead
110
+ if (gateAct.status !== 'succeeded') {
111
+ // gate in-flight (acquired / running / waiting) — wait.
112
+ pendingCount++;
113
+ continue;
332
114
  }
333
- // Not yet succeeded / failed accumulate dispatch actions.
334
- iterDispatch.push(...advance.actions);
335
- pendingCount += advance.actions.length === 0 ? 1 : 0;
336
- }
337
- if (bodyFailureFinish) {
338
- return [bodyFailureFinish];
339
- }
340
- // Body dispatches accumulate into the outer `actions` array; the
341
- // legacy plain-node pass below will also push into it, so a single
342
- // tick can dispatch multiple body nodes + plain nodes together.
343
- // Lifecycle actions never reach this branch (they early-return
344
- // above).
345
- for (const a of iterDispatch)
346
- actions.push(a);
347
- }
348
- // ─── Loop terminal propagation ────────────────────────────────────────
349
- //
350
- // After the loop branch may have emitted `finishLoop`, the next tick
351
- // sees `loopState.status` settled but the legacy node-level state
352
- // machine doesn't know about it. Propagate failed / cancelled loop
353
- // blocks into `failedNodeId` so the actions.length===0 sweep below
354
- // can emit `completeRunFailed`. Succeeded loop blocks expose their
355
- // projected output via `outputs[workActivityId(runId, loopId)]` and
356
- // are handled naturally by the sink sweep.
357
- for (const [loopId, loopState] of snapshot.loops) {
358
- if (loopState.status === 'failed' || loopState.status === 'cancelled') {
359
- failedNodeId = failedNodeId ?? loopId;
360
- }
361
- }
362
- // ─── Plain (non-loop, non-body) node pass ────────────────────────────
363
- //
364
- // Same logic as v0.1: dispatch gate → dispatch work → settle node.
365
- // Skips loop blocks (already handled) + decision nodes (only valid in
366
- // loop body) + body nodes (dispatched only by the loop branch above).
367
- for (const nodeId of order) {
368
- const node = def.nodes[nodeId];
369
- if (node.type === 'loop')
370
- continue;
371
- if (node.type === 'decision')
372
- continue; // validateLoopBlocks guarantees in-body
373
- if (bodyOwner.has(nodeId))
374
- continue; // dispatched by loop branch
375
- const nstatus = snapshot.nodes.get(nodeId)?.status ?? 'idle';
376
- if (nstatus === 'succeeded' || nstatus === 'skipped' || nstatus === 'cancelled') {
377
- continue;
378
- }
379
- if (nstatus === 'failed') {
380
- failedNodeId = failedNodeId ?? nodeId;
381
- continue;
115
+ // gate cleared fall through to work dispatch / advancement
382
116
  }
383
- // Dependencies gate dispatch. Loop blocks are treated as "succeeded"
384
- // for the purpose of downstream deps when their snapshot status is
385
- // 'succeeded'. This is how `${review-loop.output.x}` and direct
386
- // body-node refs become resolvable for downstream plain nodes.
387
- const depsOk = (node.depends ?? []).every((dep) => {
388
- const depNode = def.nodes[dep];
389
- if (depNode?.type === 'loop') {
390
- return snapshot.loops.get(dep)?.status === 'succeeded';
391
- }
392
- return snapshot.nodes.get(dep)?.status === 'succeeded';
393
- });
394
- if (!depsOk) {
117
+ if (!workAct) {
118
+ actions.push({
119
+ kind: 'dispatchWork',
120
+ nodeId,
121
+ activityId: workActId,
122
+ node,
123
+ });
395
124
  pendingCount++;
396
125
  continue;
397
126
  }
398
- const gateActId = gateActivityId(runId, nodeId);
399
- const workActId = workActivityId(runId, nodeId);
400
- const advance = decideNodeAdvancement(snapshot, node, nodeId, gateActId, workActId);
401
- if (advance.isSucceeded) {
402
- for (const a of advance.actions)
403
- actions.push(a);
127
+ if (workAct.status === 'succeeded') {
128
+ const output = snapshot.outputs.get(workActId);
129
+ if (output) {
130
+ actions.push({
131
+ kind: 'completeNodeSucceeded',
132
+ nodeId,
133
+ lastActivityId: workActId,
134
+ outputRef: output,
135
+ });
136
+ }
137
+ else {
138
+ pendingCount++;
139
+ }
404
140
  continue;
405
141
  }
406
- if (advance.isFailed) {
407
- for (const a of advance.actions)
408
- actions.push(a);
409
- // completeNodeFailed action records nodeId in actions; the
410
- // downstream sweep uses node.status='failed' from the next
411
- // replay to fail the run.
142
+ if (workAct.status === 'failed' || workAct.status === 'timedOut') {
143
+ // activityTimedOut payload pins errorClass='retryable' (spec §2.1),
144
+ // but replay doesn't propagate it onto the attempt's `error` field —
145
+ // it only records `runningMs`. Special-case here so the orchestrator
146
+ // doesn't silently upgrade the class to fatal via `deriveErrorClass`.
147
+ const errorClass = workAct.status === 'timedOut' ? 'retryable' : deriveErrorClass(workAct);
148
+ actions.push({
149
+ kind: 'completeNodeFailed',
150
+ nodeId,
151
+ lastActivityId: workActId,
152
+ errorClass,
153
+ });
412
154
  continue;
413
155
  }
414
- for (const a of advance.actions)
415
- actions.push(a);
416
- if (advance.actions.length === 0)
417
- pendingCount++;
156
+ // running / waiting / acquired / effectAttempting — pending.
157
+ pendingCount++;
418
158
  }
419
159
  if (actions.length === 0) {
420
160
  if (failedNodeId) {
161
+ // Fail-fast: a node terminal-failed. Any pending downstream nodes
162
+ // are stuck on the failed dep and will never advance; in-flight
163
+ // peer nodes are caller's problem to cancel-fanout if they want.
421
164
  actions.push({ kind: 'completeRunFailed', failedNodeId });
422
165
  }
423
166
  else if (pendingCount === 0) {
424
167
  const sinks = findSinks(def);
425
168
  if (sinks.length === 1) {
426
169
  const sinkId = sinks[0];
427
- const sinkNode = def.nodes[sinkId];
428
- const sinkActId = workActivityId(runId, sinkId);
429
- const sinkOutput = sinkNode?.type === 'loop'
430
- ? snapshot.outputs.get(sinkActId) // loopFinished projection (codex Step 2)
431
- : snapshot.outputs.get(sinkActId);
170
+ const sinkOutput = snapshot.outputs.get(workActivityId(runId, sinkId));
432
171
  if (sinkOutput) {
433
172
  actions.push({
434
173
  kind: 'completeRunSucceeded',
@@ -437,173 +176,22 @@ export function decideNextActions(snapshot, def) {
437
176
  });
438
177
  }
439
178
  }
179
+ // Multi-sink: caller composes the run output (out of v0 scope).
440
180
  }
441
181
  }
442
182
  return actions;
443
183
  }
444
- /**
445
- * Per-node advancement decision used by both the top-level scheduler
446
- * (plain nodes) and the v0.2 loop branch (body / decision nodes). The
447
- * caller supplies the gate and work activityIds so the same logic
448
- * applies to plain `runId::work::node` ids and loop iteration
449
- * `runId::loop::loopId.N::work::node` ids without leaking the
450
- * activityId convention into this helper.
451
- *
452
- * Returns the actions the caller should emit plus a small status
453
- * triplet — exactly one of `isSucceeded` / `isFailed` is true when
454
- * the node has reached its terminal; otherwise the call is "pending"
455
- * (in-flight) and the returned actions are dispatch instructions for
456
- * gate/work that haven't yet been emitted.
457
- */
458
- function decideNodeAdvancement(snapshot, node, nodeId, gateActId, workActId) {
459
- const actions = [];
460
- // Decision node: gate-only. Both reject and approve resolve to
461
- // `activitySucceeded` per wait.ts decision-mode (see N2 in
462
- // /tmp/wf-loop-v02.md §4.3); only humanGate timeout produces a
463
- // failed activity.
464
- if (node.type === 'decision') {
465
- const gateAct = snapshot.activities.get(gateActId);
466
- if (!gateAct) {
467
- actions.push({
468
- kind: 'dispatchGate',
469
- nodeId,
470
- activityId: gateActId,
471
- humanGate: node.humanGate,
472
- });
473
- return { actions, isSucceeded: false, isFailed: false };
474
- }
475
- if (gateAct.status === 'succeeded') {
476
- return { actions, isSucceeded: true, isFailed: false };
477
- }
478
- if (gateAct.status === 'failed' || gateAct.status === 'timedOut') {
479
- return { actions, isSucceeded: false, isFailed: true };
480
- }
481
- return { actions, isSucceeded: false, isFailed: false };
482
- }
483
- // Loop blocks are not handled by this helper.
484
- if (node.type === 'loop') {
485
- return { actions, isSucceeded: false, isFailed: false };
486
- }
487
- const gateAct = snapshot.activities.get(gateActId);
488
- const workAct = snapshot.activities.get(workActId);
489
- if (node.humanGate) {
490
- if (!gateAct) {
491
- actions.push({
492
- kind: 'dispatchGate',
493
- nodeId,
494
- activityId: gateActId,
495
- humanGate: node.humanGate,
496
- });
497
- return { actions, isSucceeded: false, isFailed: false };
498
- }
499
- if (gateAct.status === 'failed' || gateAct.status === 'timedOut') {
500
- actions.push({
501
- kind: 'completeNodeFailed',
502
- nodeId,
503
- lastActivityId: gateActId,
504
- errorClass: 'userFault',
505
- });
506
- return { actions, isSucceeded: false, isFailed: true };
507
- }
508
- if (gateAct.status !== 'succeeded') {
509
- // gate in-flight — caller treats this as pending
510
- return { actions, isSucceeded: false, isFailed: false };
511
- }
512
- // gate cleared → fall through to work
513
- }
514
- if (!workAct) {
515
- actions.push({
516
- kind: 'dispatchWork',
517
- nodeId,
518
- activityId: workActId,
519
- node,
520
- });
521
- return { actions, isSucceeded: false, isFailed: false };
522
- }
523
- if (workAct.status === 'succeeded') {
524
- const output = snapshot.outputs.get(workActId);
525
- if (output) {
526
- actions.push({
527
- kind: 'completeNodeSucceeded',
528
- nodeId,
529
- lastActivityId: workActId,
530
- outputRef: output,
531
- });
532
- return { actions, isSucceeded: true, isFailed: false };
533
- }
534
- return { actions, isSucceeded: false, isFailed: false };
535
- }
536
- if (workAct.status === 'failed' || workAct.status === 'timedOut') {
537
- const errorClass = workAct.status === 'timedOut' ? 'retryable' : deriveErrorClass(workAct);
538
- actions.push({
539
- kind: 'completeNodeFailed',
540
- nodeId,
541
- lastActivityId: workActId,
542
- errorClass,
543
- });
544
- return { actions, isSucceeded: false, isFailed: true };
545
- }
546
- // running / waiting / acquired / effectAttempting — pending.
547
- return { actions, isSucceeded: false, isFailed: false };
548
- }
549
- /**
550
- * Build `bodyNodeId → owningLoopId` map for fast carve-out lookups.
551
- * Mirrors `validateLoopBlocks`'s body collection but built every tick
552
- * because the orchestrator is a pure function and doesn't carry state.
553
- */
554
- function buildBodyOwnerMap(def) {
555
- const owner = new Map();
556
- for (const [id, node] of Object.entries(def.nodes)) {
557
- if (node.type !== 'loop')
558
- continue;
559
- for (const bodyId of node.body)
560
- owner.set(bodyId, id);
561
- }
562
- return owner;
563
- }
564
- /**
565
- * Filter a workflow-level topological order down to body nodes only,
566
- * preserving the global order. Used to dispatch body nodes inside an
567
- * active loop iteration in deterministic order.
568
- */
569
- function orderForBody(allOrder, bodySet) {
570
- return allOrder.filter((id) => bodySet.has(id));
571
- }
572
- /**
573
- * Resolve `loop.output.from` to the OutputRef of the body node's
574
- * latest successful iteration so `finishLoop` can carry it forward.
575
- * Returns `undefined` if the loop did not declare `output.from`, or if
576
- * the body node hasn't produced a succeeded output in `iteration` yet
577
- * (which shouldn't happen if the terminator already approved — but
578
- * defensive against partial replay state).
579
- */
580
- function computeLoopOutputRef(snapshot, runId, loopNode, loopId, iteration) {
581
- const from = loopNode.output?.from;
582
- if (!from)
583
- return undefined;
584
- const bodyWorkActId = loopWorkActivityId(runId, loopId, iteration, from);
585
- return snapshot.outputs.get(bodyWorkActId);
586
- }
587
184
  // ─── Helpers ─────────────────────────────────────────────────────────────
588
185
  function deriveErrorClass(activity) {
589
186
  const last = activity.attempts[activity.attempts.length - 1];
590
187
  return last?.error?.errorClass ?? 'fatal';
591
188
  }
592
189
  function findSinks(def) {
593
- const bodyOwner = buildBodyOwnerMap(def);
594
- // Only consider top-level (non-body) nodes when computing sinks. Body
595
- // nodes are dispatched by their owning loop block; the outside view of
596
- // a loop is "the loop block itself produces output" so body nodes must
597
- // never count as workflow-level sinks even if no peer depends on them
598
- // directly. (`reviewDecision` is the canonical example — nothing
599
- // outside the loop depends on it, but it's structurally internal.)
600
190
  const referenced = new Set();
601
- for (const [id, node] of Object.entries(def.nodes)) {
602
- if (bodyOwner.has(id))
603
- continue;
191
+ for (const node of Object.values(def.nodes)) {
604
192
  for (const dep of node.depends ?? [])
605
193
  referenced.add(dep);
606
194
  }
607
- return Object.keys(def.nodes).filter((id) => !bodyOwner.has(id) && !referenced.has(id));
195
+ return Object.keys(def.nodes).filter((id) => !referenced.has(id));
608
196
  }
609
197
  //# sourceMappingURL=orchestrator.js.map