botmux 2.93.1 → 2.94.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 (197) hide show
  1. package/dist/adapters/cli/claude-code.d.ts.map +1 -1
  2. package/dist/adapters/cli/claude-code.js +6 -1
  3. package/dist/adapters/cli/claude-code.js.map +1 -1
  4. package/dist/bot-registry.d.ts +10 -1
  5. package/dist/bot-registry.d.ts.map +1 -1
  6. package/dist/bot-registry.js +2 -0
  7. package/dist/bot-registry.js.map +1 -1
  8. package/dist/cli/workflow.d.ts.map +1 -1
  9. package/dist/cli/workflow.js +11 -4
  10. package/dist/cli/workflow.js.map +1 -1
  11. package/dist/cli.d.ts.map +1 -1
  12. package/dist/cli.js +133 -1
  13. package/dist/cli.js.map +1 -1
  14. package/dist/core/dashboard-ipc-server.d.ts.map +1 -1
  15. package/dist/core/dashboard-ipc-server.js +3 -0
  16. package/dist/core/dashboard-ipc-server.js.map +1 -1
  17. package/dist/core/inherit-peer.d.ts +5 -0
  18. package/dist/core/inherit-peer.d.ts.map +1 -1
  19. package/dist/core/inherit-peer.js +3 -0
  20. package/dist/core/inherit-peer.js.map +1 -1
  21. package/dist/core/worker-pool.d.ts.map +1 -1
  22. package/dist/core/worker-pool.js +29 -0
  23. package/dist/core/worker-pool.js.map +1 -1
  24. package/dist/daemon.d.ts.map +1 -1
  25. package/dist/daemon.js +282 -12
  26. package/dist/daemon.js.map +1 -1
  27. package/dist/dashboard/auth.d.ts.map +1 -1
  28. package/dist/dashboard/auth.js +7 -1
  29. package/dist/dashboard/auth.js.map +1 -1
  30. package/dist/dashboard/bot-payload.d.ts +1 -0
  31. package/dist/dashboard/bot-payload.d.ts.map +1 -1
  32. package/dist/dashboard/bot-payload.js +1 -0
  33. package/dist/dashboard/bot-payload.js.map +1 -1
  34. package/dist/dashboard/v3-runs-api.d.ts +26 -0
  35. package/dist/dashboard/v3-runs-api.d.ts.map +1 -0
  36. package/dist/dashboard/v3-runs-api.js +67 -0
  37. package/dist/dashboard/v3-runs-api.js.map +1 -0
  38. package/dist/dashboard/web/app.js +21 -9
  39. package/dist/dashboard/web/app.js.map +1 -1
  40. package/dist/dashboard/web/bot-defaults.d.ts.map +1 -1
  41. package/dist/dashboard/web/bot-defaults.js +24 -1
  42. package/dist/dashboard/web/bot-defaults.js.map +1 -1
  43. package/dist/dashboard/web/i18n.d.ts.map +1 -1
  44. package/dist/dashboard/web/i18n.js +12 -4
  45. package/dist/dashboard/web/i18n.js.map +1 -1
  46. package/dist/dashboard/web/legacy-workflow-link.d.ts +2 -0
  47. package/dist/dashboard/web/legacy-workflow-link.d.ts.map +1 -0
  48. package/dist/dashboard/web/legacy-workflow-link.js +12 -0
  49. package/dist/dashboard/web/legacy-workflow-link.js.map +1 -0
  50. package/dist/dashboard/web/v3-terminal.d.ts +11 -0
  51. package/dist/dashboard/web/v3-terminal.d.ts.map +1 -0
  52. package/dist/dashboard/web/v3-terminal.js +143 -0
  53. package/dist/dashboard/web/v3-terminal.js.map +1 -0
  54. package/dist/dashboard/web/v3.d.ts +2 -0
  55. package/dist/dashboard/web/v3.d.ts.map +1 -0
  56. package/dist/dashboard/web/v3.js +564 -0
  57. package/dist/dashboard/web/v3.js.map +1 -0
  58. package/dist/dashboard/web/workflows.d.ts.map +1 -1
  59. package/dist/dashboard/web/workflows.js +12 -8
  60. package/dist/dashboard/web/workflows.js.map +1 -1
  61. package/dist/dashboard-web/app.js +787 -699
  62. package/dist/dashboard-web/index.html +1 -1
  63. package/dist/dashboard-web/style.css +223 -0
  64. package/dist/dashboard.js +7 -0
  65. package/dist/dashboard.js.map +1 -1
  66. package/dist/i18n/en.js +3 -3
  67. package/dist/i18n/zh.js +3 -3
  68. package/dist/im/lark/card-handler.d.ts +12 -0
  69. package/dist/im/lark/card-handler.d.ts.map +1 -1
  70. package/dist/im/lark/card-handler.js +28 -0
  71. package/dist/im/lark/card-handler.js.map +1 -1
  72. package/dist/im/lark/v3-blocked-card-handler.d.ts +28 -0
  73. package/dist/im/lark/v3-blocked-card-handler.d.ts.map +1 -0
  74. package/dist/im/lark/v3-blocked-card-handler.js +134 -0
  75. package/dist/im/lark/v3-blocked-card-handler.js.map +1 -0
  76. package/dist/im/lark/v3-blocked-card.d.ts +75 -0
  77. package/dist/im/lark/v3-blocked-card.d.ts.map +1 -0
  78. package/dist/im/lark/v3-blocked-card.js +206 -0
  79. package/dist/im/lark/v3-blocked-card.js.map +1 -0
  80. package/dist/im/lark/v3-gate-card-handler.d.ts +31 -0
  81. package/dist/im/lark/v3-gate-card-handler.d.ts.map +1 -0
  82. package/dist/im/lark/v3-gate-card-handler.js +110 -0
  83. package/dist/im/lark/v3-gate-card-handler.js.map +1 -0
  84. package/dist/im/lark/v3-gate-card.d.ts +47 -0
  85. package/dist/im/lark/v3-gate-card.d.ts.map +1 -0
  86. package/dist/im/lark/v3-gate-card.js +119 -0
  87. package/dist/im/lark/v3-gate-card.js.map +1 -0
  88. package/dist/im/lark/v3-loop-grant-card-handler.d.ts +28 -0
  89. package/dist/im/lark/v3-loop-grant-card-handler.d.ts.map +1 -0
  90. package/dist/im/lark/v3-loop-grant-card-handler.js +90 -0
  91. package/dist/im/lark/v3-loop-grant-card-handler.js.map +1 -0
  92. package/dist/im/lark/v3-loop-grant-card.d.ts +46 -0
  93. package/dist/im/lark/v3-loop-grant-card.d.ts.map +1 -0
  94. package/dist/im/lark/v3-loop-grant-card.js +119 -0
  95. package/dist/im/lark/v3-loop-grant-card.js.map +1 -0
  96. package/dist/im/lark/v3-revisit-grant-card-handler.d.ts +29 -0
  97. package/dist/im/lark/v3-revisit-grant-card-handler.d.ts.map +1 -0
  98. package/dist/im/lark/v3-revisit-grant-card-handler.js +96 -0
  99. package/dist/im/lark/v3-revisit-grant-card-handler.js.map +1 -0
  100. package/dist/im/lark/v3-revisit-grant-card.d.ts +52 -0
  101. package/dist/im/lark/v3-revisit-grant-card.d.ts.map +1 -0
  102. package/dist/im/lark/v3-revisit-grant-card.js +123 -0
  103. package/dist/im/lark/v3-revisit-grant-card.js.map +1 -0
  104. package/dist/im/lark/workflow-cards.d.ts.map +1 -1
  105. package/dist/im/lark/workflow-cards.js +5 -1
  106. package/dist/im/lark/workflow-cards.js.map +1 -1
  107. package/dist/im/lark/workflow-progress-card.d.ts +1 -1
  108. package/dist/im/lark/workflow-progress-card.js +1 -1
  109. package/dist/im/lark/workflow-slash-command.d.ts +28 -0
  110. package/dist/im/lark/workflow-slash-command.d.ts.map +1 -1
  111. package/dist/im/lark/workflow-slash-command.js +61 -5
  112. package/dist/im/lark/workflow-slash-command.js.map +1 -1
  113. package/dist/services/card-prefs-store.d.ts +4 -0
  114. package/dist/services/card-prefs-store.d.ts.map +1 -1
  115. package/dist/services/card-prefs-store.js +19 -0
  116. package/dist/services/card-prefs-store.js.map +1 -1
  117. package/dist/skills/definitions.d.ts.map +1 -1
  118. package/dist/skills/definitions.js +208 -4
  119. package/dist/skills/definitions.js.map +1 -1
  120. package/dist/worker.js +10 -1
  121. package/dist/worker.js.map +1 -1
  122. package/dist/workflows/definition.d.ts +80 -80
  123. package/dist/workflows/events/payloads.d.ts +4 -4
  124. package/dist/workflows/events/schema.d.ts +16 -16
  125. package/dist/workflows/v3/architect.d.ts +37 -0
  126. package/dist/workflows/v3/architect.d.ts.map +1 -0
  127. package/dist/workflows/v3/architect.js +226 -0
  128. package/dist/workflows/v3/architect.js.map +1 -0
  129. package/dist/workflows/v3/bot-resolve.d.ts +21 -0
  130. package/dist/workflows/v3/bot-resolve.d.ts.map +1 -0
  131. package/dist/workflows/v3/bot-resolve.js +47 -0
  132. package/dist/workflows/v3/bot-resolve.js.map +1 -0
  133. package/dist/workflows/v3/cli-run.d.ts +24 -0
  134. package/dist/workflows/v3/cli-run.d.ts.map +1 -0
  135. package/dist/workflows/v3/cli-run.js +265 -0
  136. package/dist/workflows/v3/cli-run.js.map +1 -0
  137. package/dist/workflows/v3/contract.d.ts +302 -0
  138. package/dist/workflows/v3/contract.d.ts.map +1 -0
  139. package/dist/workflows/v3/contract.js +91 -0
  140. package/dist/workflows/v3/contract.js.map +1 -0
  141. package/dist/workflows/v3/daemon-run.d.ts +311 -0
  142. package/dist/workflows/v3/daemon-run.d.ts.map +1 -0
  143. package/dist/workflows/v3/daemon-run.js +775 -0
  144. package/dist/workflows/v3/daemon-run.js.map +1 -0
  145. package/dist/workflows/v3/dag.d.ts +332 -0
  146. package/dist/workflows/v3/dag.d.ts.map +1 -0
  147. package/dist/workflows/v3/dag.js +1040 -0
  148. package/dist/workflows/v3/dag.js.map +1 -0
  149. package/dist/workflows/v3/ephemeral-pool.d.ts +29 -0
  150. package/dist/workflows/v3/ephemeral-pool.d.ts.map +1 -0
  151. package/dist/workflows/v3/ephemeral-pool.js +331 -0
  152. package/dist/workflows/v3/ephemeral-pool.js.map +1 -0
  153. package/dist/workflows/v3/grill-state.d.ts +92 -0
  154. package/dist/workflows/v3/grill-state.d.ts.map +1 -0
  155. package/dist/workflows/v3/grill-state.js +151 -0
  156. package/dist/workflows/v3/grill-state.js.map +1 -0
  157. package/dist/workflows/v3/host.d.ts +88 -0
  158. package/dist/workflows/v3/host.d.ts.map +1 -0
  159. package/dist/workflows/v3/host.js +349 -0
  160. package/dist/workflows/v3/host.js.map +1 -0
  161. package/dist/workflows/v3/human-gate.d.ts +85 -0
  162. package/dist/workflows/v3/human-gate.d.ts.map +1 -0
  163. package/dist/workflows/v3/human-gate.js +153 -0
  164. package/dist/workflows/v3/human-gate.js.map +1 -0
  165. package/dist/workflows/v3/journal.d.ts +207 -0
  166. package/dist/workflows/v3/journal.d.ts.map +1 -0
  167. package/dist/workflows/v3/journal.js +74 -0
  168. package/dist/workflows/v3/journal.js.map +1 -0
  169. package/dist/workflows/v3/manifest.d.ts +17 -0
  170. package/dist/workflows/v3/manifest.d.ts.map +1 -0
  171. package/dist/workflows/v3/manifest.js +266 -0
  172. package/dist/workflows/v3/manifest.js.map +1 -0
  173. package/dist/workflows/v3/ops-projection.d.ts +110 -0
  174. package/dist/workflows/v3/ops-projection.d.ts.map +1 -0
  175. package/dist/workflows/v3/ops-projection.js +0 -0
  176. package/dist/workflows/v3/ops-projection.js.map +1 -0
  177. package/dist/workflows/v3/orchestrator.d.ts +168 -0
  178. package/dist/workflows/v3/orchestrator.d.ts.map +1 -0
  179. package/dist/workflows/v3/orchestrator.js +417 -0
  180. package/dist/workflows/v3/orchestrator.js.map +1 -0
  181. package/dist/workflows/v3/runtime.d.ts +193 -0
  182. package/dist/workflows/v3/runtime.d.ts.map +1 -0
  183. package/dist/workflows/v3/runtime.js +1284 -0
  184. package/dist/workflows/v3/runtime.js.map +1 -0
  185. package/dist/workflows/v3/spec.d.ts +32 -0
  186. package/dist/workflows/v3/spec.d.ts.map +1 -0
  187. package/dist/workflows/v3/spec.js +173 -0
  188. package/dist/workflows/v3/spec.js.map +1 -0
  189. package/dist/workflows/v3/state.d.ts +74 -0
  190. package/dist/workflows/v3/state.d.ts.map +1 -0
  191. package/dist/workflows/v3/state.js +353 -0
  192. package/dist/workflows/v3/state.js.map +1 -0
  193. package/package.json +1 -1
  194. package/dist/dashboard/web/workflow-catalog.d.ts +0 -2
  195. package/dist/dashboard/web/workflow-catalog.d.ts.map +0 -1
  196. package/dist/dashboard/web/workflow-catalog.js +0 -323
  197. package/dist/dashboard/web/workflow-catalog.js.map +0 -1
@@ -0,0 +1,417 @@
1
+ /**
2
+ * v3 orchestrator — pure decision layer.
3
+ *
4
+ * Mirrors v0.2's `orchestrator.ts` pattern: a pure function maps the current
5
+ * run state + DAG to a list of action descriptors. The runtime (`runtime.ts`)
6
+ * owns every side effect — journal/STATE writes, ephemeral-worker dispatch via
7
+ * `runNode`, humanGate card posting — and the per-bot/per-CLI/global
8
+ * concurrency caps. Keeping the decision pure makes the critical-path
9
+ * semantics testable without spawning workers or touching the filesystem.
10
+ *
11
+ * MVP scope: static DAG, fail-fast. No loops / decisions / dynamic expand
12
+ * (those are deferred — design Q3/§7). Gate set is frozen at authoring time;
13
+ * the orchestrator never invents or skips a gate (design Q10).
14
+ */
15
+ import { isLoopNode, loopInstanceId, topologicalOrder } from './dag.js';
16
+ // ─── Decision function ──────────────────────────────────────────────────────
17
+ /**
18
+ * Pure decision: given the current `state`, return every action that can be
19
+ * taken *now*. The runtime applies concurrency caps by acting on a prefix of
20
+ * the returned dispatch actions and re-invoking on the next tick — this
21
+ * function intentionally returns ALL ready dispatches (it does not throttle).
22
+ *
23
+ * Ordering follows topological order so callers see deps-ready nodes first.
24
+ * Fail-fast: the moment any node is `failed`, the only action is
25
+ * `completeRunFailed` (in-flight peers are torn down by the runtime / cancel).
26
+ * When no dispatch is possible and nothing is pending, the run is complete.
27
+ */
28
+ export function decideNext(dag, state, loops = new Map(), edges = new Map(), instances = new Map()) {
29
+ const order = topologicalOrder(dag);
30
+ const nodes = new Map(dag.nodes.map((n) => [n.id, n]));
31
+ // Fail-fast sweep first: a single failed node ends the run. Pick the
32
+ // earliest in topo order for a deterministic `failedNodeId`. `failed`
33
+ // (infrastructure, needs intervention) takes priority over `blocked`
34
+ // (contract failure, retryable) when both exist. Loop body instances are
35
+ // swept too — only the CURRENT iteration can be non-done (a decision is
36
+ // only ever recorded once the whole iteration completed).
37
+ for (const id of order) {
38
+ const node = nodes.get(id);
39
+ for (const sweepId of [id, ...currentInstanceIds(node, loops)]) {
40
+ if (st(state, sweepId).status === 'failed' &&
41
+ (sweepId !== id || isFailureRelevant(id, dag, state, edges))) {
42
+ return [{ kind: 'completeRunFailed', failedNodeId: sweepId }];
43
+ }
44
+ }
45
+ }
46
+ for (const id of order) {
47
+ const node = nodes.get(id);
48
+ for (const sweepId of [id, ...currentInstanceIds(node, loops)]) {
49
+ if (st(state, sweepId).status === 'blocked' &&
50
+ (sweepId !== id || isFailureRelevant(id, dag, state, edges))) {
51
+ return [{ kind: 'completeRunBlocked', blockedNodeId: sweepId }];
52
+ }
53
+ }
54
+ }
55
+ const actions = [];
56
+ let pending = 0; // nodes not yet terminal — gates the success sweep
57
+ for (const id of order) {
58
+ const node = nodes.get(id);
59
+ const s = st(state, id);
60
+ if (isAcceptableTerminal(id, s.status, dag, state, edges))
61
+ continue;
62
+ if (isLoopNode(node)) {
63
+ pending++;
64
+ const ls = loops.get(id);
65
+ if (!ls) {
66
+ const readiness = readinessFor(node, state, edges);
67
+ if (readiness.kind === 'wait')
68
+ continue;
69
+ if (readiness.kind === 'resolveEdge') {
70
+ actions.push({ kind: 'resolveEdge', from: readiness.from, to: id });
71
+ continue;
72
+ }
73
+ if (readiness.kind === 'skip') {
74
+ actions.push({ kind: 'skipNode', nodeId: id, detail: readiness.detail });
75
+ continue;
76
+ }
77
+ // Not started: deps/trigger satisfied, start the composite node.
78
+ actions.push({ kind: 'startLoop', loopId: id });
79
+ continue;
80
+ }
81
+ if (ls.iteration === 0) {
82
+ actions.push({ kind: 'startLoopIteration', loopId: id, iteration: 1 });
83
+ continue;
84
+ }
85
+ if (ls.decided) {
86
+ if (ls.lastDecision === 'exit') {
87
+ actions.push({ kind: 'completeLoop', loopId: id, iteration: ls.iteration });
88
+ }
89
+ else if (ls.lastDecision === 'continue' ||
90
+ // After an exhausted-block, a grant re-opens exactly one round. An
91
+ // exhausted loop WITHOUT a pending grant never reaches here — its
92
+ // node status is 'blocked' and the sweep above already returned.
93
+ (ls.lastDecision === 'exhausted' && ls.pendingGrant)) {
94
+ actions.push({ kind: 'startLoopIteration', loopId: id, iteration: ls.iteration + 1 });
95
+ }
96
+ continue;
97
+ }
98
+ // Undecided current iteration: schedule the body like a mini-DAG over
99
+ // instance ids; once every body instance is done, ask for the decision.
100
+ const bodyOrder = topologicalOrder({ runId: id, nodes: node.body.nodes });
101
+ const bodyById = new Map(node.body.nodes.map((b) => [b.id, b]));
102
+ let allDone = true;
103
+ for (const bodyId of bodyOrder) {
104
+ const instId = loopInstanceId(id, ls.iteration, bodyId);
105
+ const bs = st(state, instId);
106
+ if (bs.status === 'done')
107
+ continue;
108
+ allDone = false;
109
+ if (bs.status === 'running' || bs.status === 'gateWaiting')
110
+ continue;
111
+ const bodyDef = bodyById.get(bodyId);
112
+ const depsOk = bodyDef.depends.every((dep) => st(state, loopInstanceId(id, ls.iteration, dep.from)).status === 'done');
113
+ if (!depsOk)
114
+ continue;
115
+ actions.push({
116
+ kind: 'dispatchWork',
117
+ nodeId: instId,
118
+ loop: { loopId: id, iteration: ls.iteration, bodyNodeId: bodyId },
119
+ });
120
+ }
121
+ if (allDone) {
122
+ actions.push({ kind: 'evaluateLoopIteration', loopId: id, iteration: ls.iteration });
123
+ }
124
+ continue;
125
+ }
126
+ // In-flight: a dispatched worker or an open gate. Nothing to emit; the
127
+ // node is still pending completion.
128
+ if (s.status === 'running' || s.status === 'gateWaiting') {
129
+ pending++;
130
+ continue;
131
+ }
132
+ // s.status === 'pending'
133
+ pending++;
134
+ const readiness = readinessFor(node, state, edges);
135
+ if (readiness.kind === 'wait')
136
+ continue;
137
+ if (readiness.kind === 'resolveEdge') {
138
+ actions.push({ kind: 'resolveEdge', from: readiness.from, to: id });
139
+ continue;
140
+ }
141
+ if (readiness.kind === 'skip') {
142
+ actions.push({ kind: 'skipNode', nodeId: id, detail: readiness.detail });
143
+ continue;
144
+ }
145
+ if (node.humanGate && !s.gateCleared) {
146
+ // The gate belongs to the instance that will run on approval — same
147
+ // id resolution as dispatchWork (constraint 6), so gate + work share it.
148
+ actions.push({ kind: 'dispatchGate', nodeId: id, instanceId: s.effectiveInstanceId ?? nextInstanceId(id, instances) });
149
+ continue;
150
+ }
151
+ // Every plain-node dispatch runs under a runtime instance (constraint 4 +
152
+ // design rule: 首派也要 #001). decideNext — not the runtime — owns the id:
153
+ // - blocked / human-ask RETRY stays in the SAME instance (constraint 5):
154
+ // the node still carries `effectiveInstanceId`, so reuse it (the retry
155
+ // is a new attempt INSIDE it, e.g. A#001/attempts/002).
156
+ // - first dispatch (no effective) → #001; a revisit re-dispatch (supersede
157
+ // cleared the effective) → next #NNN from state.instances.
158
+ // (loop body dispatches use loopInstanceId, handled above.)
159
+ const instanceId = s.effectiveInstanceId ?? nextInstanceId(id, instances);
160
+ actions.push({
161
+ kind: 'dispatchWork',
162
+ nodeId: id,
163
+ instanceId,
164
+ ...(readiness.omitted ? { omitted: readiness.omitted } : {}),
165
+ });
166
+ for (const loser of readiness.earlyLosers ?? []) {
167
+ if (canCancelLoser(loser, id, dag, state, edges)) {
168
+ actions.push({
169
+ kind: 'cancelNode',
170
+ nodeId: loser,
171
+ byNodeId: id,
172
+ detail: `early-release loser for "${id}"`,
173
+ });
174
+ }
175
+ }
176
+ }
177
+ if (actions.length === 0 && pending === 0) {
178
+ const sinks = findSinks(dag);
179
+ if (sinks.some((id) => st(state, id).status === 'done')) {
180
+ return [{ kind: 'completeRunSucceeded' }];
181
+ }
182
+ return [{
183
+ kind: 'completeRunFailed',
184
+ reason: 'allSinksSkipped',
185
+ detail: sinkOmissionDetail(sinks, state),
186
+ }];
187
+ }
188
+ return actions;
189
+ }
190
+ function readinessFor(node, state, edges) {
191
+ if (node.depends.length === 0)
192
+ return { kind: 'ready' };
193
+ const activities = node.depends.map((dep) => {
194
+ const source = st(state, dep.from);
195
+ if (source.status === 'done') {
196
+ if (!dep.when)
197
+ return { kind: 'active', from: dep.from };
198
+ const edge = edges.get(currentEdgeKey(dep.from, node.id, state));
199
+ if (!edge)
200
+ return { kind: 'unresolved', from: dep.from };
201
+ return edge.active
202
+ ? { kind: 'active', from: dep.from }
203
+ : { kind: 'inactive', from: dep.from, reason: 'edgeInactive' };
204
+ }
205
+ if (source.status === 'skipped')
206
+ return { kind: 'inactive', from: dep.from, reason: 'sourceSkipped' };
207
+ if (source.status === 'cancelled')
208
+ return { kind: 'inactive', from: dep.from, reason: 'sourceCancelled' };
209
+ return { kind: 'unsettled', from: dep.from };
210
+ });
211
+ const active = activities.filter((a) => a.kind === 'active').length;
212
+ const triggerRule = node.triggerRule ?? 'all_success';
213
+ const required = triggerRule === 'all_success' ? node.depends.length
214
+ : triggerRule === 'one_success' ? 1
215
+ : triggerRule.quorum;
216
+ if (triggerRule === 'all_success') {
217
+ if (activities.some((a) => a.kind === 'unsettled'))
218
+ return { kind: 'wait' };
219
+ const unresolved = firstUnresolved(activities);
220
+ if (unresolved)
221
+ return { kind: 'resolveEdge', from: unresolved.from };
222
+ }
223
+ else if (active < required) {
224
+ const unresolved = firstUnresolved(activities);
225
+ if (unresolved)
226
+ return { kind: 'resolveEdge', from: unresolved.from };
227
+ }
228
+ const maybe = activities.filter((a) => a.kind === 'unsettled' || a.kind === 'unresolved').length;
229
+ if (active >= required) {
230
+ const omitted = activities
231
+ .filter((a) => a.kind !== 'active')
232
+ .map((a) => ({
233
+ from: a.from,
234
+ reason: a.kind === 'inactive' ? a.reason : 'earlyRelease',
235
+ }));
236
+ const earlyLosers = activities
237
+ .filter((a) => a.kind === 'unsettled')
238
+ .map((a) => a.from);
239
+ return {
240
+ kind: 'ready',
241
+ ...(omitted.length > 0 ? { omitted } : {}),
242
+ ...(earlyLosers.length > 0 ? { earlyLosers } : {}),
243
+ };
244
+ }
245
+ if (active + maybe >= required)
246
+ return { kind: 'wait' };
247
+ const detail = activities
248
+ .map((a, idx) => {
249
+ const dep = node.depends[idx];
250
+ if (a.kind === 'active')
251
+ return `${dep.from}:active`;
252
+ if (a.kind === 'inactive')
253
+ return `${dep.from}:inactive(${a.reason})`;
254
+ return `${dep.from}:${a.kind}`;
255
+ })
256
+ .join(', ');
257
+ return { kind: 'skip', detail: `triggerRule=${JSON.stringify(triggerRule)} unsatisfied; ${detail}` };
258
+ }
259
+ function firstUnresolved(activities) {
260
+ return activities.find((a) => a.kind === 'unresolved');
261
+ }
262
+ /** The edge key for the source's CURRENT effective instance — mirrors the key
263
+ * materialize stores edgeResolved under (verdict bound to SOURCE instance, per code
264
+ * review). A source revisit (`A#001`→`A#002`) reads a fresh `A#002->B`, never
265
+ * the superseded `A#001->B`. Target is keyed by nodeId (it has no instance at
266
+ * edge-resolve time); a target-only revisit reusing the verdict is a known,
267
+ * documented limitation. */
268
+ function currentEdgeKey(from, to, state) {
269
+ const fromInst = st(state, from).effectiveInstanceId ?? from;
270
+ return `${fromInst}->${to}`;
271
+ }
272
+ /** The CURRENT iteration's expanded instance ids of a loop node (empty for
273
+ * plain nodes / unstarted loops) — the sweep surface for failed/blocked. */
274
+ function currentInstanceIds(node, loops) {
275
+ if (!isLoopNode(node))
276
+ return [];
277
+ const ls = loops.get(node.id);
278
+ if (!ls || ls.iteration === 0)
279
+ return [];
280
+ return node.body.nodes.map((b) => loopInstanceId(node.id, ls.iteration, b.id));
281
+ }
282
+ function isAcceptableTerminal(id, status, dag, state, edges) {
283
+ if (status === 'done' || status === 'skipped' || status === 'cancelled')
284
+ return true;
285
+ if (status === 'failed' || status === 'blocked')
286
+ return !isFailureRelevant(id, dag, state, edges);
287
+ return false;
288
+ }
289
+ function canCancelLoser(candidateId, byNodeId, dag, state, edges) {
290
+ const candidate = dag.nodes.find((n) => n.id === candidateId);
291
+ if (!candidate || isLoopNode(candidate))
292
+ return false;
293
+ const status = st(state, candidateId).status;
294
+ if (status !== 'pending' && status !== 'gateWaiting' && status !== 'running')
295
+ return false;
296
+ for (const downstream of downstreamsOf(candidateId, dag)) {
297
+ const ds = st(state, downstream.id).status;
298
+ if (terminalStatus(ds))
299
+ continue;
300
+ if (downstream.id === byNodeId)
301
+ continue;
302
+ if (isSatisfiedWithoutSource(downstream, candidateId, state, edges))
303
+ continue;
304
+ if (isImpossibleNow(downstream, state, edges))
305
+ continue;
306
+ return false;
307
+ }
308
+ return true;
309
+ }
310
+ function isFailureRelevant(failedNodeId, dag, state, edges) {
311
+ const downstreams = downstreamsOf(failedNodeId, dag);
312
+ if (downstreams.length === 0)
313
+ return true;
314
+ for (const downstream of downstreams) {
315
+ const ds = st(state, downstream.id).status;
316
+ if (terminalStatus(ds))
317
+ continue;
318
+ if (!isSatisfiedWithoutSource(downstream, failedNodeId, state, edges))
319
+ return true;
320
+ }
321
+ return false;
322
+ }
323
+ function isSatisfiedWithoutSource(node, ignoredSourceId, state, edges) {
324
+ const activities = node.depends
325
+ .filter((dep) => dep.from !== ignoredSourceId)
326
+ .map((dep) => edgeActivityFor(dep.from, node.id, dep.when !== undefined, state, edges));
327
+ const active = activities.filter((a) => a.kind === 'active').length;
328
+ return active >= requiredFor(node);
329
+ }
330
+ function isImpossibleNow(node, state, edges) {
331
+ const activities = node.depends.map((dep) => edgeActivityFor(dep.from, node.id, dep.when !== undefined, state, edges));
332
+ const active = activities.filter((a) => a.kind === 'active').length;
333
+ const maybe = activities.filter((a) => a.kind === 'unsettled' || a.kind === 'unresolved').length;
334
+ return active + maybe < requiredFor(node);
335
+ }
336
+ function edgeActivityFor(from, to, conditional, state, edges) {
337
+ const source = st(state, from);
338
+ if (source.status === 'done') {
339
+ if (!conditional)
340
+ return { kind: 'active', from };
341
+ const edge = edges.get(currentEdgeKey(from, to, state));
342
+ if (!edge)
343
+ return { kind: 'unresolved', from };
344
+ return edge.active
345
+ ? { kind: 'active', from }
346
+ : { kind: 'inactive', from, reason: 'edgeInactive' };
347
+ }
348
+ if (source.status === 'skipped')
349
+ return { kind: 'inactive', from, reason: 'sourceSkipped' };
350
+ if (source.status === 'cancelled')
351
+ return { kind: 'inactive', from, reason: 'sourceCancelled' };
352
+ return { kind: 'unsettled', from };
353
+ }
354
+ function requiredFor(node) {
355
+ const triggerRule = node.triggerRule ?? 'all_success';
356
+ return triggerRule === 'all_success' ? node.depends.length
357
+ : triggerRule === 'one_success' ? 1
358
+ : triggerRule.quorum;
359
+ }
360
+ function downstreamsOf(nodeId, dag) {
361
+ return dag.nodes.filter((n) => n.depends.some((dep) => dep.from === nodeId));
362
+ }
363
+ function terminalStatus(status) {
364
+ return status === 'done' ||
365
+ status === 'skipped' ||
366
+ status === 'cancelled' ||
367
+ status === 'failed' ||
368
+ status === 'blocked' ||
369
+ // A superseded INSTANCE is settled (it won't change); the DEFINITION node
370
+ // re-dispatches under a fresh instance, but that is tracked at the node
371
+ // level (effectiveInstanceId), not by this per-instance status.
372
+ status === 'superseded';
373
+ }
374
+ function sinkOmissionDetail(sinks, state) {
375
+ let skipped = 0;
376
+ let cancelled = 0;
377
+ for (const id of sinks) {
378
+ const status = st(state, id).status;
379
+ if (status === 'skipped')
380
+ skipped++;
381
+ if (status === 'cancelled')
382
+ cancelled++;
383
+ }
384
+ return `${skipped} skipped, ${cancelled} cancelled`;
385
+ }
386
+ /** Sink nodes — no other node depends on them. Their products are the run's
387
+ * output. Pure helper for the runtime's success path. */
388
+ export function findSinks(dag) {
389
+ const referenced = new Set();
390
+ for (const node of dag.nodes)
391
+ for (const dep of node.depends)
392
+ referenced.add(dep.from);
393
+ return dag.nodes.map((n) => n.id).filter((id) => !referenced.has(id));
394
+ }
395
+ function st(state, id) {
396
+ return state.get(id) ?? { status: 'pending' };
397
+ }
398
+ /** The next runtime instance id for a definition node, computed from every
399
+ * instance that has EVER appeared for it (`running/done/blocked/superseded`,
400
+ * per code review — not just the effective/terminal ones, else a re-dispatch
401
+ * could collide with an existing `A#002`). First dispatch (no instances) →
402
+ * `#001`; a revisit re-dispatch → `#002`, … — instance is the real runtime
403
+ * node, so EVERY plain-node dispatch gets one (design rule: 首派也要 #001). Instance
404
+ * ids are `<nodeId>#NNN`, zero-padded to mirror attempt `001`. */
405
+ function nextInstanceId(nodeId, instances) {
406
+ const prefix = `${nodeId}#`;
407
+ let max = 0;
408
+ for (const instanceId of instances.keys()) {
409
+ if (!instanceId.startsWith(prefix))
410
+ continue;
411
+ const n = Number.parseInt(instanceId.slice(prefix.length), 10);
412
+ if (Number.isFinite(n) && n > max)
413
+ max = n;
414
+ }
415
+ return `${prefix}${String(max + 1).padStart(3, '0')}`;
416
+ }
417
+ //# sourceMappingURL=orchestrator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orchestrator.js","sourceRoot":"","sources":["../../../src/workflows/v3/orchestrator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,193 @@
1
+ /**
2
+ * v3 runtime — the scheduling main loop.
3
+ *
4
+ * Ties the pure pieces together against the SHARED contract:
5
+ * load dag → freeze bot snapshots → init runDir →
6
+ * { materialize journal → decideNext → dispatch ready work under caps →
7
+ * await a settle → repeat } until terminal.
8
+ *
9
+ * Every side effect lives here (journal append, STATE checkpoint, dir layout,
10
+ * goal/inputs/env materialization). The actual worker spawn (`runNode`) and
11
+ * manifest validation (`validateManifest`) are INJECTED — codex's
12
+ * `ephemeral-pool.ts` / `manifest.ts` provide them, but the runtime compiles
13
+ * against the contract types alone so the two halves build independently.
14
+ *
15
+ * MVP scope: static DAG, fail-fast, no retry (always `attempts/001`). Retry
16
+ * (`attempts/NNN`) and richer cancel semantics are deferred — see
17
+ * `docs/design/2026-06-01-v3-mvp-engine-split.md`.
18
+ */
19
+ import { type V3Dag, type V3LoopExitWhen, type V3Node, type V3ResultSchema } from './dag.js';
20
+ import { type StoredEvent, type V3ErrorClass } from './journal.js';
21
+ import { type BotSnapshot, type GoalAsk, type Manifest, type RunNode, type ValidateManifest } from './contract.js';
22
+ /**
23
+ * Render the self-contained instruction file the goal-mode agent reads via
24
+ * `$BOTMUX_GOAL_PATH`. The execution contract (read inputs / write products /
25
+ * write the manifest) lives HERE — in a file — rather than inside the `/goal`
26
+ * command text, because a long multi-line `/goal` argument trips Claude Code's
27
+ * paste-detection (the TUI folds it into a "[Pasted text]" blob and the
28
+ * slash-command parser never fires). The pool's `buildGoalCommand` therefore
29
+ * sends only a short single-line `/goal` that points the agent at this file.
30
+ *
31
+ * Rendered from `contract.ts` constants so the manifest shape stays a single
32
+ * source of truth shared with codex's validator.
33
+ */
34
+ export declare function renderGoalFile(goal: string, resultSchema?: V3ResultSchema, loopCtx?: {
35
+ loopId: string;
36
+ iteration: number;
37
+ maxIterations: number;
38
+ }, nodeInstructions?: string): string;
39
+ /**
40
+ * Map a node's failure to its terminal kind (the blocked/failed split):
41
+ * - `blocked` = semantic/contract failure — retryable via a new attempt
42
+ * - `failed` = infrastructure / human-veto / budget — needs intervention
43
+ *
44
+ * `selfReportedFail` marks the special case where the manifest is structurally
45
+ * VALID but declares `status:'fail'` — then the node's own `error.retryable`
46
+ * decides (`false` → failed; `true`/absent → blocked, the agent presumably
47
+ * knows a human can unblock it).
48
+ */
49
+ export declare function classifyTerminal(errorClass: V3ErrorClass, opts?: {
50
+ selfReportedFail?: boolean;
51
+ retryable?: boolean;
52
+ }): 'blocked' | 'failed';
53
+ /**
54
+ * Read + validate a goal worker's `ask.json` (the runtime human-ask payload).
55
+ * Defensive: a missing / malformed / out-of-bounds file yields `undefined`, so a
56
+ * broken ask degrades to a plain blocked card rather than crashing the drive —
57
+ * the manifest's `error.message` still carries the question text for the human.
58
+ * Accepts either 2–6 concrete options or `freeText:true`. Exported for tests.
59
+ */
60
+ export declare function readGoalAsk(askPath: string): GoalAsk | undefined;
61
+ /**
62
+ * Merge a node's capability override onto the bot's frozen snapshot (P2).
63
+ * Pure + exported for tests. Direction is one-way by construction:
64
+ * - model: node override wins (redirect, not escalation);
65
+ * - disableCliBypass: sticky-true — `restricted` can SET it, nothing can
66
+ * clear a bot-level restriction (`inherit` keeps whatever the bot has).
67
+ */
68
+ export declare function mergeNodeCapability(snap: BotSnapshot, override: V3Node['override']): BotSnapshot;
69
+ /** Validation outcome for an opt-in `result.json` against its node schema. */
70
+ export interface ResultValidation {
71
+ ok: boolean;
72
+ problems?: string[];
73
+ }
74
+ /** Read a worker's cross-node revisit request from `result.json` (if any). A
75
+ * revisit is `{ "status": "revisit", "revisitTo": "<ancestor>", "reason"? }`.
76
+ * Absent result.json / non-revisit status → `{ ok:true }` (no request). A
77
+ * malformed revisit (missing/blank revisitTo, non-string reason) → `ok:false`
78
+ * so the runtime blocks it as resultInvalid. The ancestor membership check
79
+ * (toNodeId ∈ node.revisitTo) is the caller's (it has the node). */
80
+ /** Two-tier revisit budget check (anti-infinite-loop): a source→target pair may
81
+ * revisit `DEFAULT_REVISIT_BUDGET_PER_PAIR` times, and the whole run
82
+ * `DEFAULT_REVISIT_BUDGET_PER_RUN` times, each extendable by a
83
+ * `revisitBudgetGranted` event. Counts revisits ALREADY made; returns
84
+ * `{ok:false, tier, detail}` when this next revisit would exceed a tier —
85
+ * `tier` tells the grant card which scope to extend (菲菲 review). */
86
+ export declare function revisitBudgetStatus(events: StoredEvent[], sourceNodeId: string, toNodeId: string): {
87
+ ok: true;
88
+ } | {
89
+ ok: false;
90
+ tier: 'pair' | 'run';
91
+ detail: string;
92
+ };
93
+ export declare function readRevisitRequest(manifest: Manifest, outputDir: string): {
94
+ ok: true;
95
+ request?: {
96
+ toNodeId: string;
97
+ reason?: string;
98
+ };
99
+ } | {
100
+ ok: false;
101
+ problems: string[];
102
+ };
103
+ /**
104
+ * Validate a `result.json` against the node's (already dag-validated) result
105
+ * schema subset. Top-level types only — see `V3ResultSchema`. Undeclared
106
+ * extra properties are allowed (JSON-Schema default).
107
+ */
108
+ export declare function validateResult(filePath: string, schema: V3ResultSchema): ResultValidation;
109
+ /**
110
+ * Evaluate a (dag-validated) loop exit predicate against the observed result
111
+ * field. Pure + exported for tests. Type mismatches simply don't match —
112
+ * validateDag already guarantees the field is declared/required with a
113
+ * compatible type, so a mismatch here means the result was tampered with
114
+ * post-validation; not-matching (→ continue/exhausted) is the safe answer.
115
+ */
116
+ export declare function matchLoopExitWhen(when: V3LoopExitWhen, value: unknown): boolean;
117
+ /**
118
+ * Compute the attemptId the NEXT dispatch of `nodeId` must use, from the
119
+ * journal: an unconsumed `nodeRetryRequested` reservation wins (retry intent
120
+ * is authoritative for the redrive); otherwise max(seen)+1 — which is 001 for
121
+ * a first dispatch. Dispatch events are the authority for "seen"; a
122
+ * reservation is consumed by a later `nodeDispatched` with the same number.
123
+ */
124
+ export declare function nextAttemptIdFor(events: StoredEvent[], key: string): string;
125
+ /** Latest dispatched attemptId for a dispatch `key` (the `previousAttemptId` a
126
+ * retry entrypoint must reference). `key` is an instance (`A#001`), a loop
127
+ * body expansion, or a legacy nodeId — matched by `(instanceId ?? nodeId)` so
128
+ * a retry stays inside the same instance. Undefined when never dispatched. */
129
+ export declare function latestAttemptIdFor(events: StoredEvent[], key: string): string | undefined;
130
+ export interface V3RuntimeDeps {
131
+ /** Spawn an ephemeral worker for one goal node (codex's pool). */
132
+ runNode: RunNode;
133
+ /** Validate a node's manifest after the worker exits (codex's manifest.ts). */
134
+ validateManifest: ValidateManifest;
135
+ /** Freeze a node's bot spawn config at run start. Given `node.bot` (may be
136
+ * undefined → the run's default bot), returns the snapshot persisted in the
137
+ * runDir and threaded through `runNode` (never re-resolved mid-run). */
138
+ resolveBotSnapshot: (botId: string | undefined) => BotSnapshot;
139
+ /** Resolve a humanGate. Required only if the DAG declares any gate; the
140
+ * runtime throws if a gate is hit without a handler. (Wired by
141
+ * `human-gate.ts` post-milestone.) */
142
+ resolveGate?: (req: {
143
+ nodeId: string;
144
+ prompt: string;
145
+ waitId: string;
146
+ runDir: string;
147
+ }) => Promise<{
148
+ resolution: 'approved' | 'rejected';
149
+ by: string;
150
+ selected?: string;
151
+ }>;
152
+ }
153
+ export interface V3RuntimeOptions {
154
+ /** The run lives in `${baseDir}/${dag.runId}`. */
155
+ baseDir: string;
156
+ /** Gate handling model. `blocking` keeps the CLI/dev y/N path; `suspend`
157
+ * writes the pending wait and returns `awaitingGate` for a daemon/card layer
158
+ * to resolve and re-drive from disk. */
159
+ gateMode?: 'blocking' | 'suspend';
160
+ /** Concurrency caps (codex's three-layer cap; conservative defaults). */
161
+ globalConcurrency?: number;
162
+ perBotConcurrency?: number;
163
+ perCliConcurrency?: number;
164
+ cancelSignal?: AbortSignal;
165
+ }
166
+ export interface V3PendingGate {
167
+ nodeId: string;
168
+ waitId: string;
169
+ prompt: string;
170
+ options: string[];
171
+ approveOptions: string[];
172
+ approvers: string[];
173
+ }
174
+ export type V3RunOutcome = {
175
+ reason: 'terminal';
176
+ runStatus: 'succeeded' | 'failed' | 'blocked';
177
+ failedNodeId?: string;
178
+ blockedNodeId?: string;
179
+ failureReason?: 'allSinksSkipped';
180
+ failureDetail?: string;
181
+ runDir: string;
182
+ } | {
183
+ reason: 'awaitingGate';
184
+ pendingWaits: V3PendingGate[];
185
+ runDir: string;
186
+ };
187
+ /**
188
+ * Run a validated DAG to terminal. Resumable: if `journal.ndjson` already has
189
+ * events (daemon restart), the loop picks up from the materialized state
190
+ * instead of re-running completed nodes.
191
+ */
192
+ export declare function runWorkflow(dag: V3Dag, deps: V3RuntimeDeps, opts: V3RuntimeOptions): Promise<V3RunOutcome>;
193
+ //# sourceMappingURL=runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../src/workflows/v3/runtime.ts"],"names":[],"mappings":"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"}