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,121 @@
1
+ import { z } from 'zod';
2
+ import { createTask, getTask, IdempotencyConflictError, } from '../../services/schedule-store.js';
3
+ const ParsedScheduleSchema = z.object({
4
+ kind: z.enum(['once', 'interval', 'cron']),
5
+ runAt: z.string().optional(),
6
+ minutes: z.number().optional(),
7
+ expr: z.string().optional(),
8
+ display: z.string(),
9
+ });
10
+ const ScheduleInputSchema = z.object({
11
+ name: z.string().min(1),
12
+ schedule: z.string().min(1),
13
+ parsed: ParsedScheduleSchema,
14
+ prompt: z.string(),
15
+ workingDir: z.string().min(1),
16
+ chatId: z.string().min(1),
17
+ rootMessageId: z.string().optional(),
18
+ scope: z.enum(['thread', 'chat']).optional(),
19
+ larkAppId: z.string().optional(),
20
+ repeat: z.object({ times: z.number().int().nonnegative().nullable() }).optional(),
21
+ deliver: z.enum(['origin', 'local']).optional(),
22
+ });
23
+ export function parseScheduleInput(input) {
24
+ return ScheduleInputSchema.parse(input);
25
+ }
26
+ /**
27
+ * `botmux-schedule` hostExecutor. Calls `schedule-store.createTask`
28
+ * passing the runtime-derived `idempotencyKey` as the deterministic
29
+ * task id; schedule-store applies create-or-return-identical semantics
30
+ * (Step 5).
31
+ *
32
+ * Provider TTL is effectively infinite for schedule (the task entry
33
+ * lives until removed), so dangling effectAttempted reconcile uses
34
+ * readOnlyLookup (`getTask(idempotencyKey)`) — no TTL boundary.
35
+ */
36
+ export const botmuxScheduleExecutor = {
37
+ provider: 'botmux-schedule',
38
+ idempotencyTtlMs: Number.MAX_SAFE_INTEGER,
39
+ canonicalInput(input) {
40
+ // Mirrors schedule-store's `canonicalScheduleInput`. Keeping them in
41
+ // sync is critical: if they diverge, two callers can produce the
42
+ // same idempotencyKey but disagree on canonicality and trip the
43
+ // IdempotencyConflict path on every retry.
44
+ return {
45
+ name: input.name,
46
+ schedule: input.schedule,
47
+ parsed: {
48
+ kind: input.parsed.kind,
49
+ runAt: input.parsed.runAt,
50
+ minutes: input.parsed.minutes,
51
+ expr: input.parsed.expr,
52
+ },
53
+ prompt: input.prompt,
54
+ workingDir: input.workingDir,
55
+ chatId: input.chatId,
56
+ rootMessageId: input.rootMessageId,
57
+ scope: input.scope,
58
+ larkAppId: input.larkAppId,
59
+ repeat: input.repeat ? { times: input.repeat.times } : undefined,
60
+ deliver: input.deliver ?? 'origin',
61
+ };
62
+ },
63
+ async invoke(input, idempotencyKey) {
64
+ const task = createTask({
65
+ id: idempotencyKey,
66
+ name: input.name,
67
+ schedule: input.schedule,
68
+ parsed: input.parsed,
69
+ prompt: input.prompt,
70
+ workingDir: input.workingDir,
71
+ chatId: input.chatId,
72
+ rootMessageId: input.rootMessageId,
73
+ scope: input.scope,
74
+ larkAppId: input.larkAppId,
75
+ repeat: input.repeat ? { times: input.repeat.times, completed: 0 } : undefined,
76
+ deliver: input.deliver,
77
+ });
78
+ return {
79
+ output: { taskId: task.id },
80
+ externalRefs: { taskId: task.id },
81
+ };
82
+ },
83
+ classifyError(err) {
84
+ if (err instanceof IdempotencyConflictError) {
85
+ return {
86
+ errorCode: 'IdempotencyConflict',
87
+ errorClass: 'fatal',
88
+ errorMessage: err.message,
89
+ };
90
+ }
91
+ return null;
92
+ },
93
+ };
94
+ export const botmuxScheduleReconciler = {
95
+ provider: 'botmux-schedule',
96
+ // Schedule reconciler doesn't load effect input (idempotencyKey is
97
+ // self-sufficient), so the resume-side hash guard never fires. We
98
+ // still expose `canonicalInput` for interface uniformity — anyone
99
+ // re-using the reconciler in a context that DOES load sidecars (e.g.
100
+ // future ScheduleStore variants requiring body verification) gets the
101
+ // same check for free.
102
+ canonicalInput(input) {
103
+ return botmuxScheduleExecutor.canonicalInput(input);
104
+ },
105
+ async readOnlyLookup(idempotencyKey) {
106
+ const task = getTask(idempotencyKey);
107
+ if (!task) {
108
+ return {
109
+ found: false,
110
+ evidence: { source: 'getTask', returned: 'undefined' },
111
+ };
112
+ }
113
+ const externalRefs = { taskId: task.id };
114
+ return {
115
+ found: true,
116
+ externalRefs,
117
+ evidence: { source: 'getTask', externalRefs },
118
+ };
119
+ },
120
+ };
121
+ //# sourceMappingURL=botmux-schedule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"botmux-schedule.js","sourceRoot":"","sources":["../../../src/workflows/hostExecutors/botmux-schedule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EACL,UAAU,EACV,OAAO,EACP,wBAAwB,GACzB,MAAM,kCAAkC,CAAC;AA6B1C,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IACpC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;IAC1C,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC5B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC9B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC3B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;CACpB,CAAC,CAAC;AAEH,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IACnC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3B,MAAM,EAAE,oBAAoB;IAC5B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;IAClB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACzB,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACpC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE;IAC5C,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAChC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,QAAQ,EAAE;IACjF,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE;CAChD,CAAC,CAAC;AAEH,MAAM,UAAU,kBAAkB,CAAC,KAAc;IAC/C,OAAO,mBAAmB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;AAC1C,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAyD;IAC1F,QAAQ,EAAE,iBAAiB;IAC3B,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;IAEzC,cAAc,CAAC,KAAK;QAClB,sEAAsE;QACtE,iEAAiE;QACjE,gEAAgE;QAChE,2CAA2C;QAC3C,OAAO;YACL,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,MAAM,EAAE;gBACN,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,IAAI;gBACvB,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,KAAK;gBACzB,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,OAAO;gBAC7B,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,IAAI;aACxB;YACD,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,aAAa,EAAE,KAAK,CAAC,aAAa;YAClC,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS;YAChE,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,QAAQ;SACnC,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,cAAc;QAChC,MAAM,IAAI,GAAG,UAAU,CAAC;YACtB,EAAE,EAAE,cAAc;YAClB,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,aAAa,EAAE,KAAK,CAAC,aAAa;YAClC,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS;YAC9E,OAAO,EAAE,KAAK,CAAC,OAAO;SACvB,CAAC,CAAC;QACH,OAAO;YACL,MAAM,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE;YAC3B,YAAY,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE;SAClC,CAAC;IACJ,CAAC;IAED,aAAa,CAAC,GAAG;QACf,IAAI,GAAG,YAAY,wBAAwB,EAAE,CAAC;YAC5C,OAAO;gBACL,SAAS,EAAE,qBAAqB;gBAChC,UAAU,EAAE,OAAO;gBACnB,YAAY,EAAE,GAAG,CAAC,OAAO;aAC1B,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,wBAAwB,GAAuB;IAC1D,QAAQ,EAAE,iBAAiB;IAE3B,mEAAmE;IACnE,mEAAmE;IACnE,kEAAkE;IAClE,qEAAqE;IACrE,sEAAsE;IACtE,uBAAuB;IACvB,cAAc,CAAC,KAAK;QAClB,OAAO,sBAAsB,CAAC,cAAc,CAAC,KAAsB,CAAC,CAAC;IACvE,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,cAAc;QACjC,MAAM,IAAI,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;QACrC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO;gBACL,KAAK,EAAE,KAAK;gBACZ,QAAQ,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAE;aACvD,CAAC;QACJ,CAAC;QACD,MAAM,YAAY,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC;QACzC,OAAO;YACL,KAAK,EAAE,IAAI;YACX,YAAY;YACZ,QAAQ,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE;SAC9C,CAAC;IACJ,CAAC;CACF,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { ProviderReconciler } from '../resume.js';
2
+ /**
3
+ * Single Feishu IM provider reconciler.
4
+ *
5
+ * `effectAttempted.provider` is intentionally `feishu-im` for both
6
+ * `feishu-send` and `feishu-reply` because Feishu's idempotency surface
7
+ * is the IM uuid field. The executor id identifies the author-facing
8
+ * operation; resume only sees the provider, so it dispatches by the
9
+ * recovered effect input shape.
10
+ */
11
+ export declare const feishuImReconciler: ProviderReconciler;
12
+ //# sourceMappingURL=feishu-im.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feishu-im.d.ts","sourceRoot":"","sources":["../../../src/workflows/hostExecutors/feishu-im.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAIvD;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,EAAE,kBAoChC,CAAC"}
@@ -0,0 +1,49 @@
1
+ import { feishuReplyReconciler } from './feishu-reply.js';
2
+ import { feishuSendReconciler } from './feishu-send.js';
3
+ /**
4
+ * Single Feishu IM provider reconciler.
5
+ *
6
+ * `effectAttempted.provider` is intentionally `feishu-im` for both
7
+ * `feishu-send` and `feishu-reply` because Feishu's idempotency surface
8
+ * is the IM uuid field. The executor id identifies the author-facing
9
+ * operation; resume only sees the provider, so it dispatches by the
10
+ * recovered effect input shape.
11
+ */
12
+ export const feishuImReconciler = {
13
+ provider: 'feishu-im',
14
+ requiresEffectInput: true,
15
+ canonicalInput(input) {
16
+ // The hash guard in resume needs to canonicalize via the SAME shape
17
+ // the original executor used. Dispatch by input discriminator —
18
+ // identical logic to idempotentSubmit's routing.
19
+ if (isRecord(input) && Object.prototype.hasOwnProperty.call(input, 'rootMessageId')) {
20
+ return feishuReplyReconciler.canonicalInput(input);
21
+ }
22
+ if (isRecord(input) && Object.prototype.hasOwnProperty.call(input, 'chatId')) {
23
+ return feishuSendReconciler.canonicalInput(input);
24
+ }
25
+ // Unknown shape: return the input verbatim so the recomputed hash
26
+ // ends up SHA-stable but different from the original; the guard
27
+ // surfaces this as a mismatch rather than swallowing it.
28
+ return input;
29
+ },
30
+ async idempotentSubmit(idempotencyKey, input) {
31
+ if (isRecord(input) && Object.prototype.hasOwnProperty.call(input, 'rootMessageId')) {
32
+ return feishuReplyReconciler.idempotentSubmit(idempotencyKey, input);
33
+ }
34
+ if (isRecord(input) && Object.prototype.hasOwnProperty.call(input, 'chatId')) {
35
+ return feishuSendReconciler.idempotentSubmit(idempotencyKey, input);
36
+ }
37
+ return {
38
+ ok: false,
39
+ errorCode: 'InputValidationFailed',
40
+ errorClass: 'manual',
41
+ errorMessage: "Feishu IM effect input must include either 'chatId' (send) or 'rootMessageId' (reply)",
42
+ evidence: { source: 'idempotentSubmit', reason: 'unknown_feishu_im_input' },
43
+ };
44
+ },
45
+ };
46
+ function isRecord(value) {
47
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
48
+ }
49
+ //# sourceMappingURL=feishu-im.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feishu-im.js","sourceRoot":"","sources":["../../../src/workflows/hostExecutors/feishu-im.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAExD;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAuB;IACpD,QAAQ,EAAE,WAAW;IACrB,mBAAmB,EAAE,IAAI;IAEzB,cAAc,CAAC,KAAK;QAClB,oEAAoE;QACpE,iEAAiE;QACjE,iDAAiD;QACjD,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,eAAe,CAAC,EAAE,CAAC;YACpF,OAAO,qBAAqB,CAAC,cAAe,CAAC,KAAK,CAAC,CAAC;QACtD,CAAC;QACD,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,EAAE,CAAC;YAC7E,OAAO,oBAAoB,CAAC,cAAe,CAAC,KAAK,CAAC,CAAC;QACrD,CAAC;QACD,kEAAkE;QAClE,gEAAgE;QAChE,yDAAyD;QACzD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,cAAc,EAAE,KAAK;QAC1C,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,eAAe,CAAC,EAAE,CAAC;YACpF,OAAO,qBAAqB,CAAC,gBAAiB,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;QACxE,CAAC;QACD,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,EAAE,CAAC;YAC7E,OAAO,oBAAoB,CAAC,gBAAiB,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;QACvE,CAAC;QACD,OAAO;YACL,EAAE,EAAE,KAAK;YACT,SAAS,EAAE,uBAAuB;YAClC,UAAU,EAAE,QAAQ;YACpB,YAAY,EACV,uFAAuF;YACzF,QAAQ,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,EAAE,yBAAyB,EAAE;SAC5E,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC"}
@@ -0,0 +1,24 @@
1
+ import type { ProviderReconciler } from '../resume.js';
2
+ import type { SideEffectingExecutor } from './types.js';
3
+ export type FeishuReplyInput = {
4
+ larkAppId: string;
5
+ /** Parent message id (om_xxx) being replied to. */
6
+ rootMessageId: string;
7
+ content: string;
8
+ msgType?: string;
9
+ replyInThread?: boolean;
10
+ };
11
+ export type FeishuReplyOutput = {
12
+ messageId: string;
13
+ };
14
+ export declare function parseFeishuReplyInput(input: unknown): FeishuReplyInput;
15
+ /**
16
+ * `feishu-reply` is similar to `feishu-send` but the canonical input
17
+ * additionally pins `rootMessageId` — spike Test 3c proved that Feishu
18
+ * uuid dedupe IGNORES `parent_id` mismatches, so we must lock the parent
19
+ * into the inputHash; otherwise a retry against a different parent would
20
+ * silently land on the original parent.
21
+ */
22
+ export declare const feishuReplyExecutor: SideEffectingExecutor<FeishuReplyInput, FeishuReplyOutput>;
23
+ export declare const feishuReplyReconciler: ProviderReconciler;
24
+ //# sourceMappingURL=feishu-reply.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feishu-reply.d.ts","sourceRoot":"","sources":["../../../src/workflows/hostExecutors/feishu-reply.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAGxD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,mDAAmD;IACnD,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAUF,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB,CAEtE;AAED;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,EAAE,qBAAqB,CAAC,gBAAgB,EAAE,iBAAiB,CA8B1F,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,kBAsCnC,CAAC"}
@@ -0,0 +1,88 @@
1
+ import { z } from 'zod';
2
+ import { replyMessage } from '../../im/lark/client.js';
3
+ import { PROVIDER_TTL_MS } from '../events/schema.js';
4
+ import { classifyFeishuError } from './feishu-send.js';
5
+ const FeishuReplyInputSchema = z.object({
6
+ larkAppId: z.string().min(1),
7
+ rootMessageId: z.string().min(1),
8
+ content: z.string(),
9
+ msgType: z.string().min(1).optional(),
10
+ replyInThread: z.boolean().optional(),
11
+ }).strict();
12
+ export function parseFeishuReplyInput(input) {
13
+ return FeishuReplyInputSchema.parse(input);
14
+ }
15
+ /**
16
+ * `feishu-reply` is similar to `feishu-send` but the canonical input
17
+ * additionally pins `rootMessageId` — spike Test 3c proved that Feishu
18
+ * uuid dedupe IGNORES `parent_id` mismatches, so we must lock the parent
19
+ * into the inputHash; otherwise a retry against a different parent would
20
+ * silently land on the original parent.
21
+ */
22
+ export const feishuReplyExecutor = {
23
+ provider: 'feishu-im',
24
+ idempotencyTtlMs: PROVIDER_TTL_MS['feishu-im'],
25
+ canonicalInput(input) {
26
+ return {
27
+ root_message_id: input.rootMessageId,
28
+ msg_type: input.msgType ?? 'text',
29
+ content: input.content,
30
+ reply_in_thread: input.replyInThread ?? false,
31
+ larkAppId: input.larkAppId,
32
+ };
33
+ },
34
+ async invoke(input, idempotencyKey) {
35
+ const messageId = await replyMessage(input.larkAppId, input.rootMessageId, input.content, input.msgType ?? 'text', input.replyInThread ?? false, idempotencyKey);
36
+ return {
37
+ output: { messageId },
38
+ externalRefs: { messageId },
39
+ };
40
+ },
41
+ classifyError: classifyFeishuError,
42
+ };
43
+ export const feishuReplyReconciler = {
44
+ provider: 'feishu-im',
45
+ requiresEffectInput: true,
46
+ canonicalInput(input) {
47
+ return feishuReplyExecutor.canonicalInput(input);
48
+ },
49
+ async idempotentSubmit(idempotencyKey, input) {
50
+ let parsed;
51
+ try {
52
+ parsed = parseFeishuReplyInput(input);
53
+ }
54
+ catch (err) {
55
+ return {
56
+ ok: false,
57
+ errorCode: 'InputValidationFailed',
58
+ errorClass: 'manual',
59
+ errorMessage: err instanceof Error ? err.message : String(err),
60
+ evidence: { source: 'idempotentSubmit', reason: 'invalid_effect_input' },
61
+ };
62
+ }
63
+ try {
64
+ const { externalRefs } = await feishuReplyExecutor.invoke(parsed, idempotencyKey);
65
+ return {
66
+ ok: true,
67
+ externalRefs,
68
+ evidence: { source: 'idempotentSubmit', externalRefs },
69
+ };
70
+ }
71
+ catch (err) {
72
+ const classification = classifyFeishuError(err) ?? defaultFeishuClassification(err);
73
+ return {
74
+ ok: false,
75
+ ...classification,
76
+ evidence: { source: 'idempotentSubmit' },
77
+ };
78
+ }
79
+ },
80
+ };
81
+ function defaultFeishuClassification(err) {
82
+ return {
83
+ errorCode: 'UnknownProviderError',
84
+ errorClass: 'manual',
85
+ errorMessage: err instanceof Error ? err.message : String(err),
86
+ };
87
+ }
88
+ //# sourceMappingURL=feishu-reply.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feishu-reply.js","sourceRoot":"","sources":["../../../src/workflows/hostExecutors/feishu-reply.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import type { ProviderReconciler } from '../resume.js';
2
+ import type { ExecutorErrorClassification, SideEffectingExecutor } from './types.js';
3
+ /**
4
+ * Input for the `feishu-send` hostExecutor. Mirrors the surface area of
5
+ * `client.sendMessage`; the canonical hash covers every field that
6
+ * participates in the external effect (spike report §1.5 / events doc
7
+ * v0.1.2 §3.2).
8
+ */
9
+ export type FeishuSendInput = {
10
+ larkAppId: string;
11
+ chatId: string;
12
+ content: string;
13
+ /** Defaults to 'text'. */
14
+ msgType?: string;
15
+ };
16
+ export type FeishuSendOutput = {
17
+ messageId: string;
18
+ };
19
+ export declare function parseFeishuSendInput(input: unknown): FeishuSendInput;
20
+ export declare const feishuSendExecutor: SideEffectingExecutor<FeishuSendInput, FeishuSendOutput>;
21
+ export declare const feishuSendReconciler: ProviderReconciler;
22
+ export declare function classifyFeishuError(err: unknown): ExecutorErrorClassification | null;
23
+ //# sourceMappingURL=feishu-send.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feishu-send.d.ts","sourceRoot":"","sources":["../../../src/workflows/hostExecutors/feishu-send.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,KAAK,EACV,2BAA2B,EAC3B,qBAAqB,EACtB,MAAM,YAAY,CAAC;AAEpB;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,0BAA0B;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AASF,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,CAEpE;AAED,eAAO,MAAM,kBAAkB,EAAE,qBAAqB,CAAC,eAAe,EAAE,gBAAgB,CAqCvF,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,kBAsClC,CAAC;AAIF,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,GAAG,2BAA2B,GAAG,IAAI,CAuCpF"}
@@ -0,0 +1,124 @@
1
+ import { z } from 'zod';
2
+ import { sendMessage, MessageWithdrawnError } from '../../im/lark/client.js';
3
+ import { PROVIDER_TTL_MS } from '../events/schema.js';
4
+ const FeishuSendInputSchema = z.object({
5
+ larkAppId: z.string().min(1),
6
+ chatId: z.string().min(1),
7
+ content: z.string(),
8
+ msgType: z.string().min(1).optional(),
9
+ }).strict();
10
+ export function parseFeishuSendInput(input) {
11
+ return FeishuSendInputSchema.parse(input);
12
+ }
13
+ export const feishuSendExecutor = {
14
+ provider: 'feishu-im',
15
+ idempotencyTtlMs: PROVIDER_TTL_MS['feishu-im'],
16
+ canonicalInput(input) {
17
+ return {
18
+ // receive_id + receive_id_type fully identify the destination. We
19
+ // pin receive_id_type to 'chat_id' because that's all
20
+ // `client.sendMessage` supports today; future variants would extend
21
+ // this canonical shape.
22
+ receive_id: input.chatId,
23
+ receive_id_type: 'chat_id',
24
+ msg_type: input.msgType ?? 'text',
25
+ content: input.content,
26
+ // larkAppId is part of "who sends" — different bots writing the
27
+ // same content to the same chat are distinct effects.
28
+ larkAppId: input.larkAppId,
29
+ };
30
+ },
31
+ async invoke(input, idempotencyKey) {
32
+ const messageId = await sendMessage(input.larkAppId, input.chatId, input.content, input.msgType ?? 'text', idempotencyKey);
33
+ return {
34
+ output: { messageId },
35
+ externalRefs: { messageId },
36
+ };
37
+ },
38
+ classifyError(err) {
39
+ return classifyFeishuError(err);
40
+ },
41
+ };
42
+ export const feishuSendReconciler = {
43
+ provider: 'feishu-im',
44
+ requiresEffectInput: true,
45
+ canonicalInput(input) {
46
+ return feishuSendExecutor.canonicalInput(input);
47
+ },
48
+ async idempotentSubmit(idempotencyKey, input) {
49
+ let parsed;
50
+ try {
51
+ parsed = parseFeishuSendInput(input);
52
+ }
53
+ catch (err) {
54
+ return {
55
+ ok: false,
56
+ errorCode: 'InputValidationFailed',
57
+ errorClass: 'manual',
58
+ errorMessage: err instanceof Error ? err.message : String(err),
59
+ evidence: { source: 'idempotentSubmit', reason: 'invalid_effect_input' },
60
+ };
61
+ }
62
+ try {
63
+ const { externalRefs } = await feishuSendExecutor.invoke(parsed, idempotencyKey);
64
+ return {
65
+ ok: true,
66
+ externalRefs,
67
+ evidence: { source: 'idempotentSubmit', externalRefs },
68
+ };
69
+ }
70
+ catch (err) {
71
+ const classification = classifyFeishuError(err) ?? defaultFeishuClassification(err);
72
+ return {
73
+ ok: false,
74
+ ...classification,
75
+ evidence: { source: 'idempotentSubmit' },
76
+ };
77
+ }
78
+ },
79
+ };
80
+ // ─── Error classification (shared with feishu-reply) ────────────────────────
81
+ export function classifyFeishuError(err) {
82
+ if (err instanceof MessageWithdrawnError) {
83
+ return {
84
+ errorCode: 'UnknownProviderError',
85
+ // Withdrawn message means the parent or target is gone — the user
86
+ // would need to retarget (effectively manual). Could be refined
87
+ // to a dedicated WithdrawnTarget code later.
88
+ errorClass: 'manual',
89
+ errorMessage: err.message,
90
+ };
91
+ }
92
+ if (err instanceof Error) {
93
+ const status = err?.response?.status ?? err?.status;
94
+ const code = err?.response?.data?.code ?? err?.code;
95
+ // Rate-limited
96
+ if (status === 429 || code === 99991663 /* feishu rate-limited */) {
97
+ return {
98
+ errorCode: 'ProviderRateLimited',
99
+ errorClass: 'retryable',
100
+ errorMessage: err.message,
101
+ };
102
+ }
103
+ // Generic network — connection refused / DNS / 5xx
104
+ if (status >= 500 ||
105
+ /ECONNREFUSED|ETIMEDOUT|EHOSTUNREACH|ENOTFOUND|getaddrinfo/i.test(err.message)) {
106
+ return {
107
+ errorCode: 'NetworkError',
108
+ errorClass: 'retryable',
109
+ errorMessage: err.message,
110
+ };
111
+ }
112
+ }
113
+ // Unknown — fall through to protocol default (UnknownProviderError /
114
+ // manual) by returning null.
115
+ return null;
116
+ }
117
+ function defaultFeishuClassification(err) {
118
+ return {
119
+ errorCode: 'UnknownProviderError',
120
+ errorClass: 'manual',
121
+ errorMessage: err instanceof Error ? err.message : String(err),
122
+ };
123
+ }
124
+ //# sourceMappingURL=feishu-send.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feishu-send.js","sourceRoot":"","sources":["../../../src/workflows/hostExecutors/feishu-send.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export * from './types.js';
2
+ export * from './protocol.js';
3
+ export * from './feishu-send.js';
4
+ export * from './feishu-reply.js';
5
+ export * from './feishu-im.js';
6
+ export * from './botmux-schedule.js';
7
+ export * from './registry.js';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/workflows/hostExecutors/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,eAAe,CAAC"}
@@ -0,0 +1,8 @@
1
+ export * from './types.js';
2
+ export * from './protocol.js';
3
+ export * from './feishu-send.js';
4
+ export * from './feishu-reply.js';
5
+ export * from './feishu-im.js';
6
+ export * from './botmux-schedule.js';
7
+ export * from './registry.js';
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/workflows/hostExecutors/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,eAAe,CAAC"}
@@ -0,0 +1,42 @@
1
+ import type { ActivityFailedEvent, ActivitySucceededEvent } from '../events/types.js';
2
+ import type { ExecutorErrorClassification, HostExecutorContext, SideEffectingExecutor } from './types.js';
3
+ export type SideEffectingResult<Output> = {
4
+ ok: true;
5
+ event: ActivitySucceededEvent;
6
+ output: Output;
7
+ externalRefs: Record<string, unknown>;
8
+ } | {
9
+ ok: false;
10
+ event: ActivityFailedEvent;
11
+ error: ExecutorErrorClassification;
12
+ };
13
+ /**
14
+ * Drive the side-effecting protocol for one attempt (events doc v0.1.2
15
+ * §2.3, §4.3). Writes three events in order:
16
+ *
17
+ * 1. `effectAttempted` — written **before** invoking the provider so a
18
+ * crash mid-call leaves a dangling intent that resume can reconcile.
19
+ * 2. provider invocation (via `executor.invoke`).
20
+ * 3. `activitySucceeded` OR `activityFailed` — terminal event for this
21
+ * attempt; carries `externalRefs` on success or classified error on
22
+ * failure.
23
+ *
24
+ * The protocol does NOT write `attemptCreated/leaseSigned/activityRunning`
25
+ * — those are the scheduler/worker layer's responsibility. This function
26
+ * assumes the caller has already advanced the activity to `running`.
27
+ *
28
+ * The protocol does NOT do retry/backoff — that's the scheduler's job
29
+ * (Step 7+). A failed invocation is reported via `ok: false` and the
30
+ * caller decides whether to spawn a new `attemptCreated`.
31
+ *
32
+ * Idempotency contract:
33
+ * - `idempotencyKey` is deterministic per attempt (5-tuple hash), so
34
+ * re-running the same attempt with the same input produces the same
35
+ * uuid → Feishu/schedule provider returns the original ref.
36
+ * - `inputHash` is recorded for the resume path to detect attempt
37
+ * mutability violations (Step 7). This function doesn't enforce
38
+ * immutability across calls — Step 7 reads recorded inputHash and
39
+ * fails if a future attempt re-derives a different one.
40
+ */
41
+ export declare function executeSideEffect<I, O>(ctx: HostExecutorContext, input: I, executor: SideEffectingExecutor<I, O>): Promise<SideEffectingResult<O>>;
42
+ //# sourceMappingURL=protocol.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../../src/workflows/hostExecutors/protocol.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,mBAAmB,EACnB,sBAAsB,EAEvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,2BAA2B,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAI1G,MAAM,MAAM,mBAAmB,CAAC,MAAM,IAClC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,sBAAsB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GAClG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,mBAAmB,CAAC;IAAC,KAAK,EAAE,2BAA2B,CAAA;CAAE,CAAC;AAIlF;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAsB,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAC1C,GAAG,EAAE,mBAAmB,EACxB,KAAK,EAAE,CAAC,EACR,QAAQ,EAAE,qBAAqB,CAAC,CAAC,EAAE,CAAC,CAAC,GACpC,OAAO,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAwFjC"}