botmux 2.33.0 → 2.34.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 (281) hide show
  1. package/README.en.md +12 -1
  2. package/README.md +45 -1
  3. package/dist/adapters/cli/claude-code.d.ts.map +1 -1
  4. package/dist/adapters/cli/claude-code.js +11 -0
  5. package/dist/adapters/cli/claude-code.js.map +1 -1
  6. package/dist/cli/bots-list-output.d.ts +21 -0
  7. package/dist/cli/bots-list-output.d.ts.map +1 -0
  8. package/dist/cli/bots-list-output.js +23 -0
  9. package/dist/cli/bots-list-output.js.map +1 -0
  10. package/dist/cli/workflow.d.ts +13 -0
  11. package/dist/cli/workflow.d.ts.map +1 -0
  12. package/dist/cli/workflow.js +781 -0
  13. package/dist/cli/workflow.js.map +1 -0
  14. package/dist/cli.js +69 -14
  15. package/dist/cli.js.map +1 -1
  16. package/dist/core/command-handler.d.ts.map +1 -1
  17. package/dist/core/command-handler.js +219 -6
  18. package/dist/core/command-handler.js.map +1 -1
  19. package/dist/core/session-manager.d.ts +6 -1
  20. package/dist/core/session-manager.d.ts.map +1 -1
  21. package/dist/core/session-manager.js +22 -12
  22. package/dist/core/session-manager.js.map +1 -1
  23. package/dist/core/worker-pool.d.ts +13 -0
  24. package/dist/core/worker-pool.d.ts.map +1 -1
  25. package/dist/core/worker-pool.js +100 -6
  26. package/dist/core/worker-pool.js.map +1 -1
  27. package/dist/daemon.d.ts +3 -0
  28. package/dist/daemon.d.ts.map +1 -1
  29. package/dist/daemon.js +884 -3
  30. package/dist/daemon.js.map +1 -1
  31. package/dist/dashboard/auth.d.ts +36 -0
  32. package/dist/dashboard/auth.d.ts.map +1 -1
  33. package/dist/dashboard/auth.js +22 -0
  34. package/dist/dashboard/auth.js.map +1 -1
  35. package/dist/dashboard/web/app.js +20 -1
  36. package/dist/dashboard/web/app.js.map +1 -1
  37. package/dist/dashboard/web/i18n.d.ts.map +1 -1
  38. package/dist/dashboard/web/i18n.js +356 -0
  39. package/dist/dashboard/web/i18n.js.map +1 -1
  40. package/dist/dashboard/web/workflow-catalog.d.ts +2 -0
  41. package/dist/dashboard/web/workflow-catalog.d.ts.map +1 -0
  42. package/dist/dashboard/web/workflow-catalog.js +323 -0
  43. package/dist/dashboard/web/workflow-catalog.js.map +1 -0
  44. package/dist/dashboard/web/workflows.d.ts +2 -0
  45. package/dist/dashboard/web/workflows.d.ts.map +1 -0
  46. package/dist/dashboard/web/workflows.js +1618 -0
  47. package/dist/dashboard/web/workflows.js.map +1 -0
  48. package/dist/dashboard/workflow-api.d.ts +23 -0
  49. package/dist/dashboard/workflow-api.d.ts.map +1 -0
  50. package/dist/dashboard/workflow-api.js +463 -0
  51. package/dist/dashboard/workflow-api.js.map +1 -0
  52. package/dist/dashboard-web/app.js +494 -199
  53. package/dist/dashboard-web/index.html +1 -0
  54. package/dist/dashboard-web/style.css +160 -6
  55. package/dist/dashboard-web/terminal-replay.html +227 -0
  56. package/dist/dashboard.js +29 -12
  57. package/dist/dashboard.js.map +1 -1
  58. package/dist/i18n/en.d.ts.map +1 -1
  59. package/dist/i18n/en.js +12 -0
  60. package/dist/i18n/en.js.map +1 -1
  61. package/dist/i18n/zh.d.ts.map +1 -1
  62. package/dist/i18n/zh.js +12 -0
  63. package/dist/i18n/zh.js.map +1 -1
  64. package/dist/im/lark/card-handler.d.ts +3 -0
  65. package/dist/im/lark/card-handler.d.ts.map +1 -1
  66. package/dist/im/lark/card-handler.js +27 -1
  67. package/dist/im/lark/card-handler.js.map +1 -1
  68. package/dist/im/lark/client.d.ts +19 -2
  69. package/dist/im/lark/client.d.ts.map +1 -1
  70. package/dist/im/lark/client.js +21 -2
  71. package/dist/im/lark/client.js.map +1 -1
  72. package/dist/im/lark/workflow-card-handler.d.ts +50 -0
  73. package/dist/im/lark/workflow-card-handler.d.ts.map +1 -0
  74. package/dist/im/lark/workflow-card-handler.js +152 -0
  75. package/dist/im/lark/workflow-card-handler.js.map +1 -0
  76. package/dist/im/lark/workflow-cards.d.ts +46 -0
  77. package/dist/im/lark/workflow-cards.d.ts.map +1 -0
  78. package/dist/im/lark/workflow-cards.js +226 -0
  79. package/dist/im/lark/workflow-cards.js.map +1 -0
  80. package/dist/im/lark/workflow-progress-card.d.ts +76 -0
  81. package/dist/im/lark/workflow-progress-card.d.ts.map +1 -0
  82. package/dist/im/lark/workflow-progress-card.js +279 -0
  83. package/dist/im/lark/workflow-progress-card.js.map +1 -0
  84. package/dist/im/lark/workflow-slash-command.d.ts +92 -0
  85. package/dist/im/lark/workflow-slash-command.d.ts.map +1 -0
  86. package/dist/im/lark/workflow-slash-command.js +185 -0
  87. package/dist/im/lark/workflow-slash-command.js.map +1 -0
  88. package/dist/services/group-creator.d.ts.map +1 -1
  89. package/dist/services/group-creator.js +17 -4
  90. package/dist/services/group-creator.js.map +1 -1
  91. package/dist/services/groups-store.d.ts +11 -0
  92. package/dist/services/groups-store.d.ts.map +1 -1
  93. package/dist/services/groups-store.js +26 -0
  94. package/dist/services/groups-store.js.map +1 -1
  95. package/dist/services/jsonl-cursor.d.ts +12 -0
  96. package/dist/services/jsonl-cursor.d.ts.map +1 -0
  97. package/dist/services/jsonl-cursor.js +45 -0
  98. package/dist/services/jsonl-cursor.js.map +1 -0
  99. package/dist/services/schedule-store.d.ts +35 -0
  100. package/dist/services/schedule-store.d.ts.map +1 -1
  101. package/dist/services/schedule-store.js +108 -1
  102. package/dist/services/schedule-store.js.map +1 -1
  103. package/dist/skills/definitions.d.ts.map +1 -1
  104. package/dist/skills/definitions.js +399 -0
  105. package/dist/skills/definitions.js.map +1 -1
  106. package/dist/types.d.ts +4 -0
  107. package/dist/types.d.ts.map +1 -1
  108. package/dist/utils/cli-usage-limit.d.ts.map +1 -1
  109. package/dist/utils/cli-usage-limit.js +4 -0
  110. package/dist/utils/cli-usage-limit.js.map +1 -1
  111. package/dist/worker.js +118 -14
  112. package/dist/worker.js.map +1 -1
  113. package/dist/workflows/attempt-resume.d.ts +114 -0
  114. package/dist/workflows/attempt-resume.d.ts.map +1 -0
  115. package/dist/workflows/attempt-resume.js +385 -0
  116. package/dist/workflows/attempt-resume.js.map +1 -0
  117. package/dist/workflows/attempt-terminal.d.ts +21 -0
  118. package/dist/workflows/attempt-terminal.d.ts.map +1 -0
  119. package/dist/workflows/attempt-terminal.js +7 -0
  120. package/dist/workflows/attempt-terminal.js.map +1 -0
  121. package/dist/workflows/blob.d.ts +27 -0
  122. package/dist/workflows/blob.d.ts.map +1 -0
  123. package/dist/workflows/blob.js +39 -0
  124. package/dist/workflows/blob.js.map +1 -0
  125. package/dist/workflows/cancel-run.d.ts +45 -0
  126. package/dist/workflows/cancel-run.d.ts.map +1 -0
  127. package/dist/workflows/cancel-run.js +99 -0
  128. package/dist/workflows/cancel-run.js.map +1 -0
  129. package/dist/workflows/cancel.d.ts +111 -0
  130. package/dist/workflows/cancel.d.ts.map +1 -0
  131. package/dist/workflows/cancel.js +120 -0
  132. package/dist/workflows/cancel.js.map +1 -0
  133. package/dist/workflows/catalog.d.ts +60 -0
  134. package/dist/workflows/catalog.d.ts.map +1 -0
  135. package/dist/workflows/catalog.js +119 -0
  136. package/dist/workflows/catalog.js.map +1 -0
  137. package/dist/workflows/cold-attach.d.ts +30 -0
  138. package/dist/workflows/cold-attach.d.ts.map +1 -0
  139. package/dist/workflows/cold-attach.js +40 -0
  140. package/dist/workflows/cold-attach.js.map +1 -0
  141. package/dist/workflows/cold-scan.d.ts +21 -0
  142. package/dist/workflows/cold-scan.d.ts.map +1 -0
  143. package/dist/workflows/cold-scan.js +70 -0
  144. package/dist/workflows/cold-scan.js.map +1 -0
  145. package/dist/workflows/daemon-spawn.d.ts +117 -0
  146. package/dist/workflows/daemon-spawn.d.ts.map +1 -0
  147. package/dist/workflows/daemon-spawn.js +551 -0
  148. package/dist/workflows/daemon-spawn.js.map +1 -0
  149. package/dist/workflows/definition.d.ts +1309 -0
  150. package/dist/workflows/definition.d.ts.map +1 -0
  151. package/dist/workflows/definition.js +334 -0
  152. package/dist/workflows/definition.js.map +1 -0
  153. package/dist/workflows/effect-input.d.ts +4 -0
  154. package/dist/workflows/effect-input.d.ts.map +1 -0
  155. package/dist/workflows/effect-input.js +18 -0
  156. package/dist/workflows/effect-input.js.map +1 -0
  157. package/dist/workflows/events/append.d.ts +77 -0
  158. package/dist/workflows/events/append.d.ts.map +1 -0
  159. package/dist/workflows/events/append.js +214 -0
  160. package/dist/workflows/events/append.js.map +1 -0
  161. package/dist/workflows/events/idempotency.d.ts +77 -0
  162. package/dist/workflows/events/idempotency.d.ts.map +1 -0
  163. package/dist/workflows/events/idempotency.js +116 -0
  164. package/dist/workflows/events/idempotency.js.map +1 -0
  165. package/dist/workflows/events/index.d.ts +7 -0
  166. package/dist/workflows/events/index.d.ts.map +1 -0
  167. package/dist/workflows/events/index.js +7 -0
  168. package/dist/workflows/events/index.js.map +1 -0
  169. package/dist/workflows/events/payloads.d.ts +917 -0
  170. package/dist/workflows/events/payloads.d.ts.map +1 -0
  171. package/dist/workflows/events/payloads.js +337 -0
  172. package/dist/workflows/events/payloads.js.map +1 -0
  173. package/dist/workflows/events/replay.d.ts +238 -0
  174. package/dist/workflows/events/replay.d.ts.map +1 -0
  175. package/dist/workflows/events/replay.js +608 -0
  176. package/dist/workflows/events/replay.js.map +1 -0
  177. package/dist/workflows/events/schema.d.ts +5242 -0
  178. package/dist/workflows/events/schema.d.ts.map +1 -0
  179. package/dist/workflows/events/schema.js +295 -0
  180. package/dist/workflows/events/schema.js.map +1 -0
  181. package/dist/workflows/events/types.d.ts +34 -0
  182. package/dist/workflows/events/types.d.ts.map +1 -0
  183. package/dist/workflows/events/types.js +2 -0
  184. package/dist/workflows/events/types.js.map +1 -0
  185. package/dist/workflows/fanout.d.ts +36 -0
  186. package/dist/workflows/fanout.d.ts.map +1 -0
  187. package/dist/workflows/fanout.js +114 -0
  188. package/dist/workflows/fanout.js.map +1 -0
  189. package/dist/workflows/hostExecutors/botmux-schedule.d.ts +41 -0
  190. package/dist/workflows/hostExecutors/botmux-schedule.d.ts.map +1 -0
  191. package/dist/workflows/hostExecutors/botmux-schedule.js +121 -0
  192. package/dist/workflows/hostExecutors/botmux-schedule.js.map +1 -0
  193. package/dist/workflows/hostExecutors/feishu-im.d.ts +12 -0
  194. package/dist/workflows/hostExecutors/feishu-im.d.ts.map +1 -0
  195. package/dist/workflows/hostExecutors/feishu-im.js +49 -0
  196. package/dist/workflows/hostExecutors/feishu-im.js.map +1 -0
  197. package/dist/workflows/hostExecutors/feishu-reply.d.ts +24 -0
  198. package/dist/workflows/hostExecutors/feishu-reply.d.ts.map +1 -0
  199. package/dist/workflows/hostExecutors/feishu-reply.js +88 -0
  200. package/dist/workflows/hostExecutors/feishu-reply.js.map +1 -0
  201. package/dist/workflows/hostExecutors/feishu-send.d.ts +23 -0
  202. package/dist/workflows/hostExecutors/feishu-send.d.ts.map +1 -0
  203. package/dist/workflows/hostExecutors/feishu-send.js +124 -0
  204. package/dist/workflows/hostExecutors/feishu-send.js.map +1 -0
  205. package/dist/workflows/hostExecutors/index.d.ts +8 -0
  206. package/dist/workflows/hostExecutors/index.d.ts.map +1 -0
  207. package/dist/workflows/hostExecutors/index.js +8 -0
  208. package/dist/workflows/hostExecutors/index.js.map +1 -0
  209. package/dist/workflows/hostExecutors/protocol.d.ts +42 -0
  210. package/dist/workflows/hostExecutors/protocol.d.ts.map +1 -0
  211. package/dist/workflows/hostExecutors/protocol.js +181 -0
  212. package/dist/workflows/hostExecutors/protocol.js.map +1 -0
  213. package/dist/workflows/hostExecutors/registry.d.ts +10 -0
  214. package/dist/workflows/hostExecutors/registry.d.ts.map +1 -0
  215. package/dist/workflows/hostExecutors/registry.js +36 -0
  216. package/dist/workflows/hostExecutors/registry.js.map +1 -0
  217. package/dist/workflows/hostExecutors/types.d.ts +78 -0
  218. package/dist/workflows/hostExecutors/types.d.ts.map +1 -0
  219. package/dist/workflows/hostExecutors/types.js +2 -0
  220. package/dist/workflows/hostExecutors/types.js.map +1 -0
  221. package/dist/workflows/loader.d.ts +16 -0
  222. package/dist/workflows/loader.d.ts.map +1 -0
  223. package/dist/workflows/loader.js +56 -0
  224. package/dist/workflows/loader.js.map +1 -0
  225. package/dist/workflows/loop.d.ts +50 -0
  226. package/dist/workflows/loop.d.ts.map +1 -0
  227. package/dist/workflows/loop.js +350 -0
  228. package/dist/workflows/loop.js.map +1 -0
  229. package/dist/workflows/ops-projection.d.ts +168 -0
  230. package/dist/workflows/ops-projection.d.ts.map +1 -0
  231. package/dist/workflows/ops-projection.js +707 -0
  232. package/dist/workflows/ops-projection.js.map +1 -0
  233. package/dist/workflows/orchestrator.d.ts +107 -0
  234. package/dist/workflows/orchestrator.d.ts.map +1 -0
  235. package/dist/workflows/orchestrator.js +197 -0
  236. package/dist/workflows/orchestrator.js.map +1 -0
  237. package/dist/workflows/output-binding.d.ts +70 -0
  238. package/dist/workflows/output-binding.d.ts.map +1 -0
  239. package/dist/workflows/output-binding.js +265 -0
  240. package/dist/workflows/output-binding.js.map +1 -0
  241. package/dist/workflows/params.d.ts +61 -0
  242. package/dist/workflows/params.d.ts.map +1 -0
  243. package/dist/workflows/params.js +195 -0
  244. package/dist/workflows/params.js.map +1 -0
  245. package/dist/workflows/resume.d.ts +263 -0
  246. package/dist/workflows/resume.d.ts.map +1 -0
  247. package/dist/workflows/resume.js +808 -0
  248. package/dist/workflows/resume.js.map +1 -0
  249. package/dist/workflows/run-id.d.ts +2 -0
  250. package/dist/workflows/run-id.d.ts.map +1 -0
  251. package/dist/workflows/run-id.js +7 -0
  252. package/dist/workflows/run-id.js.map +1 -0
  253. package/dist/workflows/run-init.d.ts +48 -0
  254. package/dist/workflows/run-init.d.ts.map +1 -0
  255. package/dist/workflows/run-init.js +99 -0
  256. package/dist/workflows/run-init.js.map +1 -0
  257. package/dist/workflows/runs-dir.d.ts +4 -0
  258. package/dist/workflows/runs-dir.d.ts.map +1 -0
  259. package/dist/workflows/runs-dir.js +15 -0
  260. package/dist/workflows/runs-dir.js.map +1 -0
  261. package/dist/workflows/runtime.d.ts +211 -0
  262. package/dist/workflows/runtime.d.ts.map +1 -0
  263. package/dist/workflows/runtime.js +594 -0
  264. package/dist/workflows/runtime.js.map +1 -0
  265. package/dist/workflows/spawn-bot.d.ts +165 -0
  266. package/dist/workflows/spawn-bot.d.ts.map +1 -0
  267. package/dist/workflows/spawn-bot.js +215 -0
  268. package/dist/workflows/spawn-bot.js.map +1 -0
  269. package/dist/workflows/system.d.ts +49 -0
  270. package/dist/workflows/system.d.ts.map +1 -0
  271. package/dist/workflows/system.js +48 -0
  272. package/dist/workflows/system.js.map +1 -0
  273. package/dist/workflows/trigger-run.d.ts +70 -0
  274. package/dist/workflows/trigger-run.d.ts.map +1 -0
  275. package/dist/workflows/trigger-run.js +88 -0
  276. package/dist/workflows/trigger-run.js.map +1 -0
  277. package/dist/workflows/wait.d.ts +120 -0
  278. package/dist/workflows/wait.d.ts.map +1 -0
  279. package/dist/workflows/wait.js +181 -0
  280. package/dist/workflows/wait.js.map +1 -0
  281. package/package.json +3 -3
@@ -0,0 +1,265 @@
1
+ /**
2
+ * Output binding resolver.
3
+ *
4
+ * Workflow author writes `{ "$ref": "<nodeId>.output.<path>" }` somewhere
5
+ * inside a hostExecutor `input` or a subagent / humanGate `prompt`. At
6
+ * dispatch time we walk the value, find every `$ref`, and substitute
7
+ * it with the corresponding upstream value. The substitution happens
8
+ * BEFORE `parseInput` / spawn / wait so consumers see fully-resolved
9
+ * literals.
10
+ *
11
+ * Failure model (codex round 6 tightenings):
12
+ * - All errors are `BindingError` — caller maps to `activityFailed`
13
+ * with `errorCode = 'InputBindingFailed'`, `errorClass = 'userFault'`.
14
+ * - We never silently fall back to the event payload `externalRefs` —
15
+ * `outputRef` blob is the contract. Missing blob file ⇒ binding fails
16
+ * loudly so the operator notices a write-side bug rather than getting
17
+ * a half-resolved input.
18
+ * - `{ "$ref": "..." }` is the typed binding primitive: an entire field
19
+ * value is replaced and objects/arrays/numbers are preserved.
20
+ * - String interpolation is intentionally narrow: `${...}` may embed the
21
+ * same ref grammar inside a string, and only scalar values are allowed.
22
+ * Objects/arrays must use whole-field `$ref`.
23
+ *
24
+ * Reference syntax:
25
+ * `<nodeId>.output.<segment>(.<segment>)*`
26
+ * `params.<segment>(.<segment>)*`
27
+ *
28
+ * - `nodeId` is everything before the FIRST `.output.` occurrence. We
29
+ * split on `.output.` rather than the first `.` because `NODE_ID_PATTERN`
30
+ * allows dots in node ids (e.g. `team.draft`).
31
+ * - `params.*` reads the immutable run input blob written at runCreated.
32
+ * - Each path segment must match `[A-Za-z0-9_-]+` or be a non-negative
33
+ * integer (array index). `__proto__` / `prototype` / `constructor`
34
+ * are explicitly rejected to prevent prototype pollution.
35
+ */
36
+ import { promises as fs } from 'node:fs';
37
+ import { workActivityId } from './orchestrator.js';
38
+ export class BindingError extends Error {
39
+ constructor(message) {
40
+ super(message);
41
+ this.name = 'BindingError';
42
+ }
43
+ }
44
+ const REF_MARKER = '.output.';
45
+ const PARAMS_PREFIX = 'params.';
46
+ const SEGMENT_PATTERN = /^[A-Za-z0-9_-]+$/;
47
+ const FORBIDDEN_SEGMENTS = new Set(['__proto__', 'prototype', 'constructor']);
48
+ export function parseRef(ref) {
49
+ const idx = ref.indexOf(REF_MARKER);
50
+ if (idx < 0 && ref.startsWith(PARAMS_PREFIX)) {
51
+ const rawPath = ref.slice(PARAMS_PREFIX.length);
52
+ return { nodeId: 'params', pathSegments: parsePathSegments(rawPath, ref) };
53
+ }
54
+ if (idx < 0) {
55
+ throw new BindingError(`$ref '${ref}' missing '.output.' separator (expected '<nodeId>.output.<path>' or 'params.<path>')`);
56
+ }
57
+ const nodeId = ref.slice(0, idx);
58
+ if (!nodeId) {
59
+ throw new BindingError(`$ref '${ref}' has empty nodeId before '.output.'`);
60
+ }
61
+ const rawPath = ref.slice(idx + REF_MARKER.length);
62
+ if (!rawPath) {
63
+ throw new BindingError(`$ref '${ref}' has empty path after '.output.'`);
64
+ }
65
+ const segments = parsePathSegments(rawPath, ref);
66
+ return { nodeId, pathSegments: segments };
67
+ }
68
+ function parsePathSegments(rawPath, ref) {
69
+ if (!rawPath) {
70
+ throw new BindingError(`$ref '${ref}' has empty path`);
71
+ }
72
+ const segments = rawPath.split('.');
73
+ for (const seg of segments) {
74
+ if (!seg) {
75
+ throw new BindingError(`$ref '${ref}' has empty path segment`);
76
+ }
77
+ if (FORBIDDEN_SEGMENTS.has(seg)) {
78
+ throw new BindingError(`$ref '${ref}' uses forbidden segment '${seg}'`);
79
+ }
80
+ if (!SEGMENT_PATTERN.test(seg)) {
81
+ throw new BindingError(`$ref '${ref}' has invalid segment '${seg}' (must match [A-Za-z0-9_-]+)`);
82
+ }
83
+ }
84
+ return segments;
85
+ }
86
+ function isOutputRefSpec(value) {
87
+ if (typeof value !== 'object' || value === null)
88
+ return false;
89
+ if (Array.isArray(value))
90
+ return false;
91
+ const keys = Object.keys(value);
92
+ if (keys.length !== 1 || keys[0] !== '$ref')
93
+ return false;
94
+ return typeof value.$ref === 'string';
95
+ }
96
+ export async function resolveOutputRef(ref, ctx) {
97
+ const { nodeId, pathSegments } = parseRef(ref);
98
+ if (nodeId === 'params' && !ref.includes(REF_MARKER)) {
99
+ const params = await loadRunParams(ref, ctx);
100
+ return walkPath(params, pathSegments, ref);
101
+ }
102
+ const nodeDef = ctx.def.nodes[nodeId];
103
+ if (!nodeDef) {
104
+ throw new BindingError(`$ref '${ref}' targets unknown node '${nodeId}' (not in workflow definition)`);
105
+ }
106
+ const actId = workActivityId(ctx.snapshot.run.runId, nodeId);
107
+ const outputRef = ctx.snapshot.outputs.get(actId);
108
+ if (!outputRef) {
109
+ throw new BindingError(`$ref '${ref}' references node '${nodeId}' which has not produced a successful output yet`);
110
+ }
111
+ if (!outputRef.outputPath) {
112
+ // OutputRef.outputPath is optional in the schema (for older runs whose
113
+ // blob was inlined elsewhere), but v0 writes all blobs to disk via
114
+ // writeJsonBlob. Fail loud rather than reading from event payload —
115
+ // codex round 6 finding: outputRef is the contract.
116
+ throw new BindingError(`$ref '${ref}' resolved to node '${nodeId}' outputRef with no outputPath; blob not on disk`);
117
+ }
118
+ let blob;
119
+ try {
120
+ const raw = await fs.readFile(outputRef.outputPath, 'utf-8');
121
+ blob = JSON.parse(raw);
122
+ }
123
+ catch (err) {
124
+ throw new BindingError(`$ref '${ref}' failed to read output blob at ${outputRef.outputPath}: ${err instanceof Error ? err.message : String(err)}`);
125
+ }
126
+ // hostExecutor blob is `{ output, externalRefs }`; subagent blob is the
127
+ // bare `output` payload. The `.output.` prefix in `$ref` syntax means
128
+ // "the logical output side" — for hostExecutor we go through the
129
+ // wrapping `output` key, for subagent we walk directly.
130
+ const root = nodeDef.type === 'hostExecutor'
131
+ ? blob?.output
132
+ : blob;
133
+ return walkPath(root, pathSegments, ref);
134
+ }
135
+ async function loadRunParams(ref, ctx) {
136
+ if (ctx.loadParams)
137
+ return ctx.loadParams();
138
+ const inputRef = ctx.snapshot.run.input;
139
+ if (!inputRef?.outputPath) {
140
+ throw new BindingError(`$ref '${ref}' requires run input params, but runCreated.inputRef has no outputPath`);
141
+ }
142
+ let params;
143
+ try {
144
+ const raw = await fs.readFile(inputRef.outputPath, 'utf-8');
145
+ params = JSON.parse(raw);
146
+ }
147
+ catch (err) {
148
+ throw new BindingError(`$ref '${ref}' failed to read run params at ${inputRef.outputPath}: ${err instanceof Error ? err.message : String(err)}`);
149
+ }
150
+ if (params === null || typeof params !== 'object' || Array.isArray(params)) {
151
+ throw new BindingError(`$ref '${ref}' resolved run params to non-object input`);
152
+ }
153
+ return params;
154
+ }
155
+ function walkPath(value, segments, ref) {
156
+ let cursor = value;
157
+ for (const [i, seg] of segments.entries()) {
158
+ if (cursor === null || cursor === undefined) {
159
+ throw new BindingError(`$ref '${ref}' hit ${cursor === null ? 'null' : 'undefined'} at segment '${seg}' (index ${i})`);
160
+ }
161
+ if (Array.isArray(cursor)) {
162
+ if (!/^\d+$/.test(seg)) {
163
+ throw new BindingError(`$ref '${ref}' segment '${seg}' is not a numeric index, but the current value is an array`);
164
+ }
165
+ const idx = Number(seg);
166
+ if (idx >= cursor.length) {
167
+ throw new BindingError(`$ref '${ref}' segment '${seg}' is out of array bounds (length ${cursor.length})`);
168
+ }
169
+ cursor = cursor[idx];
170
+ continue;
171
+ }
172
+ if (typeof cursor !== 'object') {
173
+ throw new BindingError(`$ref '${ref}' hit non-object '${typeof cursor}' at segment '${seg}' (index ${i})`);
174
+ }
175
+ // Use Object.prototype.hasOwnProperty to refuse inherited / prototype
176
+ // chain lookups even after the FORBIDDEN_SEGMENTS rejection in parseRef.
177
+ if (!Object.prototype.hasOwnProperty.call(cursor, seg)) {
178
+ throw new BindingError(`$ref '${ref}' segment '${seg}' not found on object (own-property check)`);
179
+ }
180
+ cursor = cursor[seg];
181
+ }
182
+ return cursor;
183
+ }
184
+ /**
185
+ * Recursive walker: every `$ref` form replaced by its resolved value,
186
+ * every other value left as-is. Arrays/objects are reconstructed
187
+ * fresh so the caller gets a tree it can mutate without aliasing the
188
+ * workflow definition.
189
+ *
190
+ * NOTE: We do not resolve refs nested inside resolved values. i.e. if
191
+ * upstream `output.x` itself contains a `$ref`-shaped object, that's
192
+ * data, not a ref. Refs only originate from the workflow definition.
193
+ */
194
+ export async function resolveBindings(value, ctx) {
195
+ if (isOutputRefSpec(value)) {
196
+ return resolveOutputRef(value.$ref, ctx);
197
+ }
198
+ if (typeof value === 'string') {
199
+ return interpolateStringRefs(value, ctx);
200
+ }
201
+ if (Array.isArray(value)) {
202
+ const out = [];
203
+ for (const v of value) {
204
+ out.push(await resolveBindings(v, ctx));
205
+ }
206
+ return out;
207
+ }
208
+ if (value !== null && typeof value === 'object') {
209
+ const out = {};
210
+ for (const [k, v] of Object.entries(value)) {
211
+ out[k] = await resolveBindings(v, ctx);
212
+ }
213
+ return out;
214
+ }
215
+ return value;
216
+ }
217
+ async function interpolateStringRefs(value, ctx) {
218
+ if (!value.includes('${'))
219
+ return value;
220
+ let out = '';
221
+ let cursor = 0;
222
+ while (cursor < value.length) {
223
+ const start = value.indexOf('${', cursor);
224
+ if (start < 0) {
225
+ out += value.slice(cursor);
226
+ break;
227
+ }
228
+ out += value.slice(cursor, start);
229
+ const end = value.indexOf('}', start + 2);
230
+ if (end < 0) {
231
+ throw new BindingError(`unterminated string ref interpolation in '${value}'`);
232
+ }
233
+ const ref = value.slice(start + 2, end);
234
+ if (!ref) {
235
+ throw new BindingError(`empty string ref interpolation in '${value}'`);
236
+ }
237
+ const resolved = await resolveOutputRef(ref, ctx);
238
+ out += stringifyInterpolatedValue(ref, resolved);
239
+ cursor = end + 1;
240
+ }
241
+ return out;
242
+ }
243
+ function stringifyInterpolatedValue(ref, value) {
244
+ if (value === null)
245
+ return 'null';
246
+ const t = typeof value;
247
+ if (t === 'string')
248
+ return value;
249
+ if (t === 'number' || t === 'boolean')
250
+ return String(value);
251
+ throw new BindingError(`string interpolation '\${${ref}}' resolved to ${Array.isArray(value) ? 'array' : t} ` +
252
+ `(expected string/number/boolean/null; use whole-field $ref for structured values)`);
253
+ }
254
+ /**
255
+ * Convenience for fields typed as `BoundString` — guaranteed to resolve
256
+ * to a string. Throws BindingError if a non-string ref slipped through.
257
+ */
258
+ export async function resolveBoundString(value, ctx) {
259
+ const resolved = await resolveBindings(value, ctx);
260
+ if (typeof resolved !== 'string') {
261
+ throw new BindingError(`bound string field resolved to ${typeof resolved} (expected string)`);
262
+ }
263
+ return resolved;
264
+ }
265
+ //# sourceMappingURL=output-binding.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output-binding.js","sourceRoot":"","sources":["../../src/workflows/output-binding.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Shared params coercion + validation for `workflow run`.
3
+ *
4
+ * Used by:
5
+ * - IM `/workflow run <id> key=value …` (key=value strings from chat)
6
+ * - CLI `botmux workflow run <id> --param key=value [--param-json key=<json>]`
7
+ *
8
+ * Behaviour contract (matches the schema in `ParamDefSchema`):
9
+ * - Unknown param names → throw `unknown param` (don't silently pass through;
10
+ * the workflow author hasn't declared them, so any binding would be a
11
+ * latent typo).
12
+ * - Missing required → throw.
13
+ * - Missing optional + has `default` → fill with default verbatim.
14
+ * - Missing optional + no default → omit (downstream `${params.X}` lookup
15
+ * surfaces a `BindingError` on use, which is the right place to fail).
16
+ * - Present + type=string → keep as string.
17
+ * - Present + type=number → `Number(raw)`; reject NaN / Infinity.
18
+ * - Present + type=boolean → accept `true/1/yes/y` / `false/0/no/n` (case
19
+ * insensitive); reject anything else.
20
+ * - Present + type=object|array → only valid via the JSON channel; the
21
+ * plain string channel throws to tell the caller to use `--param-json`
22
+ * (CLI) or pre-decoded JSON (programmatic).
23
+ */
24
+ import type { WorkflowDefinition } from './definition.js';
25
+ export type RawParamInput = {
26
+ kind: 'string';
27
+ value: string;
28
+ } | {
29
+ kind: 'json';
30
+ value: unknown;
31
+ };
32
+ export type ParamCoerceError = {
33
+ /** Param name that failed; undefined for whole-record-shape errors. */
34
+ name?: string;
35
+ /** Machine code for the failure category. */
36
+ code: 'unknown_param' | 'missing_required' | 'type_mismatch' | 'unsupported_string_channel' | 'invalid_json';
37
+ /** Human-readable Chinese-localized message (matches existing CLI/IM output). */
38
+ message: string;
39
+ };
40
+ export declare class ParamCoerceFailure extends Error {
41
+ readonly issues: ParamCoerceError[];
42
+ constructor(issues: ParamCoerceError[]);
43
+ }
44
+ /**
45
+ * Validate + coerce raw caller input against the workflow's `params` schema.
46
+ *
47
+ * `rawParams` accepts a mixed map of `{ kind: 'string' | 'json' }` so that
48
+ * the CLI can pipe `--param-json` through the same code path as `--param`.
49
+ * The IM `/workflow run` legacy entry calls `coerceWorkflowParamsFromStrings`
50
+ * below which wraps every value as `{ kind: 'string' }`.
51
+ *
52
+ * All errors are aggregated into a single `ParamCoerceFailure` so the caller
53
+ * can render every issue at once instead of one-by-one Enter-key fixes.
54
+ */
55
+ export declare function coerceWorkflowParams(def: WorkflowDefinition, rawParams: Record<string, RawParamInput>): Record<string, unknown>;
56
+ /**
57
+ * Legacy convenience: when every input is a raw string (IM chat path), wrap
58
+ * each value into `{ kind: 'string' }` and delegate to `coerceWorkflowParams`.
59
+ */
60
+ export declare function coerceWorkflowParamsFromStrings(def: WorkflowDefinition, rawParams: Record<string, string>): Record<string, unknown>;
61
+ //# sourceMappingURL=params.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"params.d.ts","sourceRoot":"","sources":["../../src/workflows/params.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAY,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAEpE,MAAM,MAAM,aAAa,GACrB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC;AAErC,MAAM,MAAM,gBAAgB,GAAG;IAC7B,uEAAuE;IACvE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6CAA6C;IAC7C,IAAI,EACA,eAAe,GACf,kBAAkB,GAClB,eAAe,GACf,4BAA4B,GAC5B,cAAc,CAAC;IACnB,iFAAiF;IACjF,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,QAAQ,CAAC,MAAM,EAAE,gBAAgB,EAAE,CAAC;gBACxB,MAAM,EAAE,gBAAgB,EAAE;CAKvC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,kBAAkB,EACvB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,GACvC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAkDzB;AAED;;;GAGG;AACH,wBAAgB,+BAA+B,CAC7C,GAAG,EAAE,kBAAkB,EACvB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAChC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAMzB"}
@@ -0,0 +1,195 @@
1
+ /**
2
+ * Shared params coercion + validation for `workflow run`.
3
+ *
4
+ * Used by:
5
+ * - IM `/workflow run <id> key=value …` (key=value strings from chat)
6
+ * - CLI `botmux workflow run <id> --param key=value [--param-json key=<json>]`
7
+ *
8
+ * Behaviour contract (matches the schema in `ParamDefSchema`):
9
+ * - Unknown param names → throw `unknown param` (don't silently pass through;
10
+ * the workflow author hasn't declared them, so any binding would be a
11
+ * latent typo).
12
+ * - Missing required → throw.
13
+ * - Missing optional + has `default` → fill with default verbatim.
14
+ * - Missing optional + no default → omit (downstream `${params.X}` lookup
15
+ * surfaces a `BindingError` on use, which is the right place to fail).
16
+ * - Present + type=string → keep as string.
17
+ * - Present + type=number → `Number(raw)`; reject NaN / Infinity.
18
+ * - Present + type=boolean → accept `true/1/yes/y` / `false/0/no/n` (case
19
+ * insensitive); reject anything else.
20
+ * - Present + type=object|array → only valid via the JSON channel; the
21
+ * plain string channel throws to tell the caller to use `--param-json`
22
+ * (CLI) or pre-decoded JSON (programmatic).
23
+ */
24
+ export class ParamCoerceFailure extends Error {
25
+ issues;
26
+ constructor(issues) {
27
+ super(issues.map((i) => i.message).join('; '));
28
+ this.name = 'ParamCoerceFailure';
29
+ this.issues = issues;
30
+ }
31
+ }
32
+ /**
33
+ * Validate + coerce raw caller input against the workflow's `params` schema.
34
+ *
35
+ * `rawParams` accepts a mixed map of `{ kind: 'string' | 'json' }` so that
36
+ * the CLI can pipe `--param-json` through the same code path as `--param`.
37
+ * The IM `/workflow run` legacy entry calls `coerceWorkflowParamsFromStrings`
38
+ * below which wraps every value as `{ kind: 'string' }`.
39
+ *
40
+ * All errors are aggregated into a single `ParamCoerceFailure` so the caller
41
+ * can render every issue at once instead of one-by-one Enter-key fixes.
42
+ */
43
+ export function coerceWorkflowParams(def, rawParams) {
44
+ const paramDefs = def.params ?? {};
45
+ const issues = [];
46
+ // 1) Reject unknown keys first. The user's mental model is "I told you
47
+ // everything I want"; unknown keys are likely typos.
48
+ for (const key of Object.keys(rawParams)) {
49
+ if (!Object.prototype.hasOwnProperty.call(paramDefs, key)) {
50
+ issues.push({
51
+ name: key,
52
+ code: 'unknown_param',
53
+ message: `未知参数:${key}`,
54
+ });
55
+ }
56
+ }
57
+ const out = {};
58
+ // 2) Walk the schema (not the caller input) so required + default rules
59
+ // always apply.
60
+ for (const [name, param] of Object.entries(paramDefs)) {
61
+ const raw = rawParams[name];
62
+ if (!raw) {
63
+ if (param.default !== undefined) {
64
+ out[name] = param.default;
65
+ continue;
66
+ }
67
+ if (param.required) {
68
+ issues.push({
69
+ name,
70
+ code: 'missing_required',
71
+ message: `缺少必填参数:${name}`,
72
+ });
73
+ }
74
+ continue;
75
+ }
76
+ try {
77
+ out[name] = coerceParam(name, param, raw);
78
+ }
79
+ catch (err) {
80
+ if (err instanceof ParamCoerceFailure)
81
+ issues.push(...err.issues);
82
+ else if (err instanceof Error) {
83
+ issues.push({ name, code: 'type_mismatch', message: err.message });
84
+ }
85
+ else {
86
+ issues.push({ name, code: 'type_mismatch', message: String(err) });
87
+ }
88
+ }
89
+ }
90
+ if (issues.length)
91
+ throw new ParamCoerceFailure(issues);
92
+ return out;
93
+ }
94
+ /**
95
+ * Legacy convenience: when every input is a raw string (IM chat path), wrap
96
+ * each value into `{ kind: 'string' }` and delegate to `coerceWorkflowParams`.
97
+ */
98
+ export function coerceWorkflowParamsFromStrings(def, rawParams) {
99
+ const wrapped = {};
100
+ for (const [k, v] of Object.entries(rawParams)) {
101
+ wrapped[k] = { kind: 'string', value: v };
102
+ }
103
+ return coerceWorkflowParams(def, wrapped);
104
+ }
105
+ function coerceParam(name, param, raw) {
106
+ if (raw.kind === 'json') {
107
+ return coerceParamFromJson(name, param, raw.value);
108
+ }
109
+ return coerceParamFromString(name, param, raw.value);
110
+ }
111
+ function coerceParamFromString(name, param, raw) {
112
+ switch (param.type) {
113
+ case 'string':
114
+ return raw;
115
+ case 'number': {
116
+ const n = Number(raw);
117
+ if (!Number.isFinite(n)) {
118
+ throw new ParamCoerceFailure([
119
+ {
120
+ name,
121
+ code: 'type_mismatch',
122
+ message: `参数 ${name} 必须是 number,收到 "${raw}"`,
123
+ },
124
+ ]);
125
+ }
126
+ return n;
127
+ }
128
+ case 'boolean':
129
+ return coerceBoolean(name, raw);
130
+ case 'object':
131
+ case 'array':
132
+ throw new ParamCoerceFailure([
133
+ {
134
+ name,
135
+ code: 'unsupported_string_channel',
136
+ message: `参数 ${name} 的 ${param.type} 类型不能用 key=value 字符串传入,` +
137
+ `请用 CLI \`--param-json ${name}=<json>\` 或 IM 端目前不支持 object/array`,
138
+ },
139
+ ]);
140
+ }
141
+ }
142
+ function coerceParamFromJson(name, param, value) {
143
+ switch (param.type) {
144
+ case 'string':
145
+ if (typeof value !== 'string') {
146
+ throw typeMismatch(name, param.type, value);
147
+ }
148
+ return value;
149
+ case 'number':
150
+ if (typeof value !== 'number' || !Number.isFinite(value)) {
151
+ throw typeMismatch(name, param.type, value);
152
+ }
153
+ return value;
154
+ case 'boolean':
155
+ if (typeof value !== 'boolean') {
156
+ throw typeMismatch(name, param.type, value);
157
+ }
158
+ return value;
159
+ case 'object':
160
+ if (value === null || typeof value !== 'object' || Array.isArray(value)) {
161
+ throw typeMismatch(name, param.type, value);
162
+ }
163
+ return value;
164
+ case 'array':
165
+ if (!Array.isArray(value)) {
166
+ throw typeMismatch(name, param.type, value);
167
+ }
168
+ return value;
169
+ }
170
+ }
171
+ function coerceBoolean(name, raw) {
172
+ const normalized = raw.trim().toLowerCase();
173
+ if (['true', '1', 'yes', 'y'].includes(normalized))
174
+ return true;
175
+ if (['false', '0', 'no', 'n'].includes(normalized))
176
+ return false;
177
+ throw new ParamCoerceFailure([
178
+ {
179
+ name,
180
+ code: 'type_mismatch',
181
+ message: `参数 ${name} 必须是 boolean (true/false/1/0/yes/no),收到 "${raw}"`,
182
+ },
183
+ ]);
184
+ }
185
+ function typeMismatch(name, expected, got) {
186
+ const actual = Array.isArray(got) ? 'array' : got === null ? 'null' : typeof got;
187
+ return new ParamCoerceFailure([
188
+ {
189
+ name,
190
+ code: 'type_mismatch',
191
+ message: `参数 ${name} 必须是 ${expected},收到 ${actual}`,
192
+ },
193
+ ]);
194
+ }
195
+ //# sourceMappingURL=params.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"params.js","sourceRoot":"","sources":["../../src/workflows/params.ts"],"names":[],"mappings":"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"}