botmux 2.33.0 → 2.33.1

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 +211 -4
  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,226 @@
1
+ import { config } from '../../config.js';
2
+ import { isPayloadRef } from '../../workflows/events/schema.js';
3
+ export const WORKFLOW_APPROVE_ACTION = 'wf_approve';
4
+ export const WORKFLOW_REJECT_ACTION = 'wf_reject';
5
+ export const WORKFLOW_CANCEL_ACTION = 'wf_cancel';
6
+ export const WORKFLOW_COMMENT_FIELD = 'wf_comment';
7
+ export const WORKFLOW_APPROVAL_FORM = 'wf_approval_form';
8
+ const DEFAULT_PROMPT_MAX_CHARS = 500;
9
+ export function workflowApprovalCardNonce(runId, activityId, attemptId) {
10
+ return `wf:${runId}:${activityId}:${attemptId}`;
11
+ }
12
+ export function workflowRunDetailUrl(runId) {
13
+ return `http://${config.dashboard.externalHost}:${config.dashboard.port}/#/workflows/${encodeURIComponent(runId)}`;
14
+ }
15
+ export function getWorkflowApprovalCardContext(event, snapshot, opts = {}) {
16
+ if (isPayloadRef(event.payload)) {
17
+ throw new Error('buildWorkflowApprovalCard: payload ref is not supported for waitCreated cards');
18
+ }
19
+ if (event.payload.waitKind !== 'human-gate') {
20
+ throw new Error(`buildWorkflowApprovalCard: expected human-gate, got ${event.payload.waitKind}`);
21
+ }
22
+ const activity = snapshot.activities.get(event.payload.activityId);
23
+ const attemptId = activity?.currentAttemptId ?? activity?.attempts.at(-1)?.attemptId;
24
+ if (!attemptId) {
25
+ throw new Error(`buildWorkflowApprovalCard: no attempt found for activity ${event.payload.activityId}`);
26
+ }
27
+ // Promptref / promptPreview split (v0.1.3): the card never reads the
28
+ // blob — promptPreview exists specifically so cards can render without
29
+ // touching disk and the dashboard owns the full-text path.
30
+ const hasFullBehindRef = event.payload.promptRef !== undefined;
31
+ const promptBody = event.payload.prompt ?? event.payload.promptPreview ?? '';
32
+ return {
33
+ runId: event.runId,
34
+ workflowId: snapshot.run.workflowId,
35
+ revisionId: snapshot.run.revisionId,
36
+ nodeId: event.payload.nodeId,
37
+ activityId: event.payload.activityId,
38
+ attemptId,
39
+ deadlineAt: event.payload.deadlineAt,
40
+ prompt: promptBody,
41
+ hasFullBehindRef,
42
+ cardNonce: opts.cardNonce ?? workflowApprovalCardNonce(event.runId, event.payload.activityId, attemptId),
43
+ webDetailUrl: opts.webDetailUrl ?? workflowRunDetailUrl(event.runId),
44
+ };
45
+ }
46
+ export function buildWorkflowApprovalCard(event, snapshot, opts = {}) {
47
+ const ctx = getWorkflowApprovalCardContext(event, snapshot, opts);
48
+ const promptMaxChars = opts.promptMaxChars ?? DEFAULT_PROMPT_MAX_CHARS;
49
+ const prompt = truncatePrompt(ctx.prompt, promptMaxChars);
50
+ const revision = ctx.revisionId ? short(ctx.revisionId, 12) : 'unknown';
51
+ const workflow = ctx.workflowId ? `${ctx.workflowId} @ ${revision}` : `unknown @ ${revision}`;
52
+ const deadline = ctx.deadlineAt ? new Date(ctx.deadlineAt).toLocaleString('zh-CN') : '无';
53
+ const resolution = opts.resolution;
54
+ const title = resolution
55
+ ? `${resolutionTitlePrefix(resolution.kind)}:${titleText(ctx.nodeId)}`
56
+ : `需要审批:${titleText(ctx.nodeId)}`;
57
+ const template = resolution ? resolutionTemplate(resolution.kind) : 'blue';
58
+ const elements = [
59
+ {
60
+ tag: 'div',
61
+ fields: [
62
+ { is_short: true, text: { tag: 'lark_md', content: `**Workflow**\n${escapeMd(workflow)}` } },
63
+ { is_short: true, text: { tag: 'lark_md', content: `**Run**\n${escapeMd(short(ctx.runId, 16))}` } },
64
+ { is_short: true, text: { tag: 'lark_md', content: `**Step**\n${escapeMd(ctx.nodeId)}` } },
65
+ { is_short: true, text: { tag: 'lark_md', content: `**Deadline**\n${escapeMd(deadline)}` } },
66
+ ],
67
+ },
68
+ { tag: 'hr' },
69
+ {
70
+ tag: 'div',
71
+ text: {
72
+ tag: 'lark_md',
73
+ content: ctx.hasFullBehindRef
74
+ ? `**审批内容**(预览,完整内容见下方 Web 详情)\n${escapeMd(prompt)}`
75
+ : `**审批内容**\n${escapeMd(prompt)}`,
76
+ },
77
+ },
78
+ ];
79
+ if (resolution) {
80
+ elements.push({ tag: 'hr' });
81
+ elements.push({
82
+ tag: 'div',
83
+ text: { tag: 'lark_md', content: resolutionBanner(resolution) },
84
+ });
85
+ }
86
+ else {
87
+ elements.push({
88
+ tag: 'form',
89
+ name: WORKFLOW_APPROVAL_FORM,
90
+ elements: [
91
+ {
92
+ tag: 'input',
93
+ name: WORKFLOW_COMMENT_FIELD,
94
+ placeholder: { tag: 'plain_text', content: '可选:填写审批意见' },
95
+ },
96
+ {
97
+ tag: 'column_set',
98
+ flex_mode: 'none',
99
+ horizontal_spacing: 'default',
100
+ columns: [
101
+ {
102
+ tag: 'column',
103
+ width: 'weighted',
104
+ weight: 1,
105
+ vertical_align: 'center',
106
+ elements: [
107
+ {
108
+ tag: 'button',
109
+ text: { tag: 'plain_text', content: '✅ 通过' },
110
+ type: 'primary',
111
+ name: 'workflow_approve',
112
+ action_type: 'form_submit',
113
+ value: actionValue(ctx, WORKFLOW_APPROVE_ACTION),
114
+ },
115
+ ],
116
+ },
117
+ {
118
+ tag: 'column',
119
+ width: 'weighted',
120
+ weight: 1,
121
+ vertical_align: 'center',
122
+ elements: [
123
+ {
124
+ tag: 'button',
125
+ text: { tag: 'plain_text', content: '❌ 拒绝' },
126
+ type: 'danger',
127
+ name: 'workflow_reject',
128
+ action_type: 'form_submit',
129
+ value: actionValue(ctx, WORKFLOW_REJECT_ACTION),
130
+ },
131
+ ],
132
+ },
133
+ ],
134
+ },
135
+ {
136
+ tag: 'button',
137
+ text: { tag: 'plain_text', content: '取消 Run' },
138
+ type: 'default',
139
+ name: 'workflow_cancel',
140
+ action_type: 'form_submit',
141
+ value: actionValue(ctx, WORKFLOW_CANCEL_ACTION),
142
+ },
143
+ ],
144
+ });
145
+ }
146
+ elements.push({
147
+ tag: 'action',
148
+ actions: [
149
+ {
150
+ tag: 'button',
151
+ text: { tag: 'plain_text', content: 'Web 详情' },
152
+ type: 'default',
153
+ multi_url: {
154
+ url: ctx.webDetailUrl,
155
+ pc_url: ctx.webDetailUrl,
156
+ android_url: ctx.webDetailUrl,
157
+ ios_url: ctx.webDetailUrl,
158
+ },
159
+ },
160
+ ],
161
+ });
162
+ return JSON.stringify({
163
+ config: { wide_screen_mode: true },
164
+ header: {
165
+ template,
166
+ title: { tag: 'plain_text', content: title },
167
+ },
168
+ elements,
169
+ });
170
+ }
171
+ function resolutionTitlePrefix(kind) {
172
+ switch (kind) {
173
+ case 'approved': return '已通过';
174
+ case 'rejected': return '已拒绝';
175
+ case 'cancelled': return '已取消';
176
+ }
177
+ }
178
+ function resolutionTemplate(kind) {
179
+ switch (kind) {
180
+ case 'approved': return 'green';
181
+ case 'rejected': return 'red';
182
+ case 'cancelled': return 'grey';
183
+ }
184
+ }
185
+ function resolutionBanner(r) {
186
+ const label = r.kind === 'approved'
187
+ ? '✅ 已通过'
188
+ : r.kind === 'rejected'
189
+ ? '❌ 已拒绝'
190
+ : '🛑 已取消';
191
+ // Open_id contains underscores that are markdown-significant; wrapping in
192
+ // backticks would force the escape backslashes to render literally in
193
+ // some Lark clients (codex review nit). Plain text with escapeMd keeps
194
+ // it portable — Lark renders escaped `_` as `_` outside code spans.
195
+ const lines = [`**${label}**`, `操作人:${escapeMd(short(r.by, 28))}`];
196
+ if (r.comment)
197
+ lines.push(`备注:${escapeMd(r.comment)}`);
198
+ return lines.join('\n');
199
+ }
200
+ function actionValue(ctx, action) {
201
+ return {
202
+ action,
203
+ run_id: ctx.runId,
204
+ workflow_id: ctx.workflowId ?? '',
205
+ revision_id: ctx.revisionId ?? '',
206
+ node_id: ctx.nodeId,
207
+ activity_id: ctx.activityId,
208
+ attempt_id: ctx.attemptId,
209
+ card_nonce: ctx.cardNonce,
210
+ };
211
+ }
212
+ function truncatePrompt(s, maxChars) {
213
+ if (s.length <= maxChars)
214
+ return s || '无';
215
+ return `${s.slice(0, maxChars)}\n\n…(已截断,完整内容请在 Web 查看)`;
216
+ }
217
+ function escapeMd(s) {
218
+ return s.replace(/\\/g, '\\\\').replace(/\*/g, '\\*').replace(/_/g, '\\_').replace(/`/g, '\\`');
219
+ }
220
+ function short(s, n) {
221
+ return s.length > n ? `${s.slice(0, n)}…` : s;
222
+ }
223
+ function titleText(nodeId) {
224
+ return short(nodeId, 48);
225
+ }
226
+ //# sourceMappingURL=workflow-cards.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow-cards.js","sourceRoot":"","sources":["../../../src/im/lark/workflow-cards.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Run-level workflow progress card (v0.1.5 slice 1).
3
+ *
4
+ * Single Feishu card per workflow run that gets PATCHed on every state
5
+ * change so a chat thread sees one self-updating tile instead of a wall
6
+ * of per-event replies.
7
+ *
8
+ * Codex co-designed the public hook contract:
9
+ * - `enrichWithTerminalLink(activityId, attemptId)` returns a
10
+ * `WorkflowProgressCardTerminalLink` when the workflow-attempt
11
+ * terminal sidecar (slice 2, owned by codex) has something
12
+ * openable. Slice 1 ships without ever wiring this; the field is
13
+ * a placeholder so slice 3 plugs in without re-shaping the JSON.
14
+ * - Card-update failures must never disturb workflow runtime — every
15
+ * send/patch site is wrapped in try/catch + logger.warn.
16
+ * - daemon-internal Map only (no on-disk persistence) — daemon
17
+ * restart losing the cardMessageId is an accepted limitation for
18
+ * this slice.
19
+ */
20
+ import type { Snapshot } from '../../workflows/events/replay.js';
21
+ import { workflowRunDetailUrl } from './workflow-cards.js';
22
+ export { workflowRunDetailUrl };
23
+ export type WorkflowProgressCardTerminalLink = {
24
+ url: string;
25
+ /** UI label. Defaults derive from `kind` when omitted. */
26
+ label?: string;
27
+ /** `live-terminal` = attempt still in-flight; `execution-log` = attempt ended. */
28
+ kind: 'live-terminal' | 'execution-log';
29
+ };
30
+ export type WorkflowProgressCardOptions = {
31
+ /** Codex slice-2 hook. Returning undefined hides the per-attempt button. */
32
+ enrichWithTerminalLink?: (activityId: string, attemptId: string) => WorkflowProgressCardTerminalLink | undefined;
33
+ /** Override the dashboard link (mostly tests). */
34
+ webDetailUrl?: string;
35
+ /** Max running/waiting nodes to inline. Excess collapses to "+N more". */
36
+ maxInlineRows?: number;
37
+ /**
38
+ * Total number of nodes in the workflow definition. Used as the
39
+ * denominator in the "X / Y 节点完成" progress line. Falls back to
40
+ * `snapshot.nodes.size` when omitted — that only counts TRIGGERED
41
+ * nodes so the fraction grows misleadingly (1/2 → 2/3 …) on
42
+ * longer workflows.
43
+ */
44
+ totalNodes?: number;
45
+ };
46
+ /**
47
+ * Build the initial "starting" card body (no events past `runCreated`).
48
+ *
49
+ * Called once at IM-side `/workflow run` time so the user sees the tile
50
+ * BEFORE the first `attemptCreated` lands — otherwise there's a multi-
51
+ * second hole between "I sent the command" and "card shows up".
52
+ */
53
+ export declare function buildWorkflowStartingCard(input: {
54
+ runId: string;
55
+ workflowId: string;
56
+ webDetailUrl?: string;
57
+ }): string;
58
+ /**
59
+ * Build the card body from the current snapshot — called every time
60
+ * the fanout watcher sees a state-changing event for this run.
61
+ */
62
+ export declare function buildWorkflowProgressCard(snapshot: Snapshot, opts?: WorkflowProgressCardOptions): string;
63
+ /**
64
+ * Slice 3 default enricher: pair the run-level card's per-row link with a
65
+ * deeplink into Run Detail focused on the given attempt. The dashboard
66
+ * side (slice 2, codex 3335adc) reads `attemptIO[attemptId].terminal` and
67
+ * renders the iframe — this enricher just constructs the URL.
68
+ *
69
+ * Only `running` activities get a link: that is the state where a
70
+ * subagent worker has spawned and is expected to expose `terminal.json`
71
+ * with a live web port. `effectAttempting` is hostExecutor-side work
72
+ * with no worker sidecar; `acquired` / `waiting` / `pending` skip for
73
+ * the same "no sidecar yet" reason.
74
+ */
75
+ export declare function buildAttemptDeeplinkEnricher(runId: string, snapshot: Snapshot): NonNullable<WorkflowProgressCardOptions['enrichWithTerminalLink']>;
76
+ //# sourceMappingURL=workflow-progress-card.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow-progress-card.d.ts","sourceRoot":"","sources":["../../../src/im/lark/workflow-progress-card.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAyC,MAAM,kCAAkC,CAAC;AACxG,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAE3D,OAAO,EAAE,oBAAoB,EAAE,CAAC;AAEhC,MAAM,MAAM,gCAAgC,GAAG;IAC7C,GAAG,EAAE,MAAM,CAAC;IACZ,2DAA2D;IAC3D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kFAAkF;IAClF,IAAI,EAAE,eAAe,GAAG,eAAe,CAAC;CACzC,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG;IACxC,6EAA6E;IAC7E,sBAAsB,CAAC,EAAE,CACvB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,KACd,gCAAgC,GAAG,SAAS,CAAC;IAClD,kDAAkD;IAClD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,2EAA2E;IAC3E,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAIF;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE;IAC/C,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GAAG,MAAM,CAmBT;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,QAAQ,EAClB,IAAI,GAAE,2BAAgC,GACrC,MAAM,CAuER;AAyJD;;;;;;;;;;;GAWG;AACH,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,QAAQ,GACjB,WAAW,CAAC,2BAA2B,CAAC,wBAAwB,CAAC,CAAC,CAepE"}
@@ -0,0 +1,279 @@
1
+ /**
2
+ * Run-level workflow progress card (v0.1.5 slice 1).
3
+ *
4
+ * Single Feishu card per workflow run that gets PATCHed on every state
5
+ * change so a chat thread sees one self-updating tile instead of a wall
6
+ * of per-event replies.
7
+ *
8
+ * Codex co-designed the public hook contract:
9
+ * - `enrichWithTerminalLink(activityId, attemptId)` returns a
10
+ * `WorkflowProgressCardTerminalLink` when the workflow-attempt
11
+ * terminal sidecar (slice 2, owned by codex) has something
12
+ * openable. Slice 1 ships without ever wiring this; the field is
13
+ * a placeholder so slice 3 plugs in without re-shaping the JSON.
14
+ * - Card-update failures must never disturb workflow runtime — every
15
+ * send/patch site is wrapped in try/catch + logger.warn.
16
+ * - daemon-internal Map only (no on-disk persistence) — daemon
17
+ * restart losing the cardMessageId is an accepted limitation for
18
+ * this slice.
19
+ */
20
+ import { workflowRunDetailUrl } from './workflow-cards.js';
21
+ export { workflowRunDetailUrl };
22
+ const DEFAULT_MAX_INLINE_ROWS = 6;
23
+ /**
24
+ * Build the initial "starting" card body (no events past `runCreated`).
25
+ *
26
+ * Called once at IM-side `/workflow run` time so the user sees the tile
27
+ * BEFORE the first `attemptCreated` lands — otherwise there's a multi-
28
+ * second hole between "I sent the command" and "card shows up".
29
+ */
30
+ export function buildWorkflowStartingCard(input) {
31
+ const webDetailUrl = input.webDetailUrl ?? workflowRunDetailUrl(input.runId);
32
+ return JSON.stringify({
33
+ config: { wide_screen_mode: true },
34
+ header: {
35
+ template: 'blue',
36
+ title: { tag: 'plain_text', content: `🔄 Workflow · ${input.workflowId}` },
37
+ },
38
+ elements: [
39
+ {
40
+ tag: 'div',
41
+ fields: [
42
+ { is_short: true, text: { tag: 'lark_md', content: `**runId**\n${escapeMd(short(input.runId, 28))}` } },
43
+ { is_short: true, text: { tag: 'lark_md', content: '**状态**\n⏳ starting' } },
44
+ ],
45
+ },
46
+ detailButton(webDetailUrl),
47
+ ],
48
+ });
49
+ }
50
+ /**
51
+ * Build the card body from the current snapshot — called every time
52
+ * the fanout watcher sees a state-changing event for this run.
53
+ */
54
+ export function buildWorkflowProgressCard(snapshot, opts = {}) {
55
+ const webDetailUrl = opts.webDetailUrl ?? workflowRunDetailUrl(snapshot.run.runId);
56
+ const maxRows = opts.maxInlineRows ?? DEFAULT_MAX_INLINE_ROWS;
57
+ const status = snapshot.run.status;
58
+ const template = headerTemplateForStatus(status);
59
+ const title = `${headerEmoji(status)} Workflow · ${snapshot.run.workflowId ?? 'unknown'}`;
60
+ const counts = summarizeNodes(snapshot);
61
+ // Use the workflow-definition total when supplied; falls back to
62
+ // observed-triggered count (the old behaviour) only when the caller
63
+ // doesn't know. Either way clamp to `max(observed, total)` so a
64
+ // stale def can't claim fewer nodes than we've actually seen events
65
+ // for.
66
+ const denominator = opts.totalNodes != null
67
+ ? Math.max(opts.totalNodes, counts.total)
68
+ : counts.total;
69
+ const isTerminal = status === 'succeeded' || status === 'failed' || status === 'cancelled';
70
+ // Run-terminal state hides the 🏃 进行中 list — otherwise a parallel
71
+ // branch whose `activityCanceled` hasn't been written yet would
72
+ // appear "still running" on a card that's already red/grey, which
73
+ // contradicts the header status.
74
+ const runningRows = isTerminal ? [] : collectRunningRows(snapshot);
75
+ const waitingRows = isTerminal ? [] : collectWaitingRows(snapshot);
76
+ const failureSummary = summarizeFailure(snapshot);
77
+ const elements = [
78
+ {
79
+ tag: 'div',
80
+ fields: [
81
+ { is_short: true, text: { tag: 'lark_md', content: `**runId**\n${escapeMd(short(snapshot.run.runId, 28))}` } },
82
+ { is_short: true, text: { tag: 'lark_md', content: `**状态**\n${statusBadge(status)}` } },
83
+ { is_short: true, text: { tag: 'lark_md', content: `**进度**\n${counts.succeeded} / ${denominator} 节点完成` } },
84
+ { is_short: true, text: { tag: 'lark_md', content: `**失败**\n${counts.failed}` } },
85
+ { is_short: true, text: { tag: 'lark_md', content: `**已取消**\n${counts.cancelled}` } },
86
+ ],
87
+ },
88
+ ];
89
+ if (runningRows.length > 0) {
90
+ elements.push({ tag: 'hr' });
91
+ elements.push({
92
+ tag: 'div',
93
+ text: { tag: 'lark_md', content: `**🏃 进行中** (${runningRows.length})` },
94
+ });
95
+ appendRows(elements, runningRows, maxRows, opts);
96
+ }
97
+ if (waitingRows.length > 0) {
98
+ elements.push({ tag: 'hr' });
99
+ elements.push({
100
+ tag: 'div',
101
+ text: { tag: 'lark_md', content: `**⏸ 等待审批** (${waitingRows.length})` },
102
+ });
103
+ appendRows(elements, waitingRows, maxRows, opts);
104
+ }
105
+ if (failureSummary) {
106
+ elements.push({ tag: 'hr' });
107
+ elements.push({
108
+ tag: 'div',
109
+ text: { tag: 'lark_md', content: failureSummary },
110
+ });
111
+ }
112
+ elements.push(detailButton(webDetailUrl));
113
+ return JSON.stringify({
114
+ config: { wide_screen_mode: true },
115
+ header: { template, title: { tag: 'plain_text', content: title } },
116
+ elements,
117
+ });
118
+ }
119
+ function summarizeNodes(snap) {
120
+ let succeeded = 0;
121
+ let failed = 0;
122
+ let cancelled = 0;
123
+ for (const node of snap.nodes.values()) {
124
+ if (node.status === 'succeeded')
125
+ succeeded++;
126
+ else if (node.status === 'failed')
127
+ failed++;
128
+ else if (node.status === 'cancelled')
129
+ cancelled++;
130
+ }
131
+ return { total: snap.nodes.size, succeeded, failed, cancelled };
132
+ }
133
+ function collectRunningRows(snap) {
134
+ const rows = [];
135
+ for (const node of snap.nodes.values()) {
136
+ if (node.status !== 'running' && node.status !== 'retrying')
137
+ continue;
138
+ const activity = node.activityId ? snap.activities.get(node.activityId) : undefined;
139
+ rows.push({
140
+ nodeId: node.nodeId,
141
+ activityId: activity?.activityId ?? node.activityId ?? '',
142
+ attemptId: activity?.currentAttemptId,
143
+ status: activity?.status ?? node.status,
144
+ });
145
+ }
146
+ return rows;
147
+ }
148
+ function collectWaitingRows(snap) {
149
+ const rows = [];
150
+ for (const node of snap.nodes.values()) {
151
+ if (node.status !== 'waiting')
152
+ continue;
153
+ const activity = node.activityId ? snap.activities.get(node.activityId) : undefined;
154
+ rows.push({
155
+ nodeId: node.nodeId,
156
+ activityId: activity?.activityId ?? node.activityId ?? '',
157
+ attemptId: activity?.currentAttemptId,
158
+ status: activity?.status ?? node.status,
159
+ });
160
+ }
161
+ return rows;
162
+ }
163
+ function summarizeFailure(snap) {
164
+ if (snap.run.status === 'failed' && snap.run.failedNodeId) {
165
+ return `**💥 失败摘要**\nnode: \`${escapeMd(snap.run.failedNodeId)}\``;
166
+ }
167
+ if (snap.run.status === 'cancelled' && snap.run.cancelOriginEventId) {
168
+ return `**🛑 已取消**\norigin: \`${escapeMd(short(snap.run.cancelOriginEventId, 32))}\``;
169
+ }
170
+ return undefined;
171
+ }
172
+ function appendRows(elements, rows, maxRows, opts) {
173
+ const shown = rows.slice(0, maxRows);
174
+ const lines = [];
175
+ for (const row of shown) {
176
+ const terminalLink = row.attemptId && opts.enrichWithTerminalLink
177
+ ? safeEnrich(opts.enrichWithTerminalLink, row.activityId, row.attemptId)
178
+ : undefined;
179
+ const linkText = terminalLink
180
+ ? ` · [${escapeMd(terminalLink.label ?? defaultTerminalLabel(terminalLink.kind))}](${terminalLink.url})`
181
+ : '';
182
+ lines.push(`• \`${escapeMd(row.nodeId)}\` (${row.status})${linkText}`);
183
+ }
184
+ if (rows.length > maxRows) {
185
+ lines.push(`…(+${rows.length - maxRows} more)`);
186
+ }
187
+ elements.push({
188
+ tag: 'div',
189
+ text: { tag: 'lark_md', content: lines.join('\n') },
190
+ });
191
+ }
192
+ function safeEnrich(fn, activityId, attemptId) {
193
+ try {
194
+ return fn(activityId, attemptId);
195
+ }
196
+ catch {
197
+ // Codex contract boundary 1: card-side enrichment never breaks
198
+ // runtime — silently drop the link, let the row render anyway.
199
+ return undefined;
200
+ }
201
+ }
202
+ function defaultTerminalLabel(kind) {
203
+ return kind === 'live-terminal' ? '查看当前终端' : '查看执行日志';
204
+ }
205
+ function detailButton(url) {
206
+ return {
207
+ tag: 'action',
208
+ actions: [
209
+ {
210
+ tag: 'button',
211
+ text: { tag: 'plain_text', content: 'Web 详情' },
212
+ type: 'default',
213
+ multi_url: { url, pc_url: url, android_url: url, ios_url: url },
214
+ },
215
+ ],
216
+ };
217
+ }
218
+ function headerTemplateForStatus(status) {
219
+ switch (status) {
220
+ case 'succeeded': return 'green';
221
+ case 'failed': return 'red';
222
+ case 'cancelled': return 'grey';
223
+ case 'waiting': return 'orange';
224
+ case 'running': return 'blue';
225
+ case 'pending':
226
+ default: return 'blue';
227
+ }
228
+ }
229
+ function headerEmoji(status) {
230
+ switch (status) {
231
+ case 'succeeded': return '✅';
232
+ case 'failed': return '❌';
233
+ case 'cancelled': return '🛑';
234
+ case 'waiting': return '⏸';
235
+ case 'running': return '🔄';
236
+ case 'pending':
237
+ default: return '⏳';
238
+ }
239
+ }
240
+ function statusBadge(status) {
241
+ return `${headerEmoji(status)} ${status}`;
242
+ }
243
+ /**
244
+ * Slice 3 default enricher: pair the run-level card's per-row link with a
245
+ * deeplink into Run Detail focused on the given attempt. The dashboard
246
+ * side (slice 2, codex 3335adc) reads `attemptIO[attemptId].terminal` and
247
+ * renders the iframe — this enricher just constructs the URL.
248
+ *
249
+ * Only `running` activities get a link: that is the state where a
250
+ * subagent worker has spawned and is expected to expose `terminal.json`
251
+ * with a live web port. `effectAttempting` is hostExecutor-side work
252
+ * with no worker sidecar; `acquired` / `waiting` / `pending` skip for
253
+ * the same "no sidecar yet" reason.
254
+ */
255
+ export function buildAttemptDeeplinkEnricher(runId, snapshot) {
256
+ return (activityId, attemptId) => {
257
+ const activity = snapshot.activities.get(activityId);
258
+ if (!activity)
259
+ return undefined;
260
+ // Only subagent activities own a worker + web-terminal sidecar.
261
+ // `effectAttempting` is a hostExecutor-side state (no worker, no
262
+ // sidecar) — handing the user a live-terminal link there would land
263
+ // them on an attempt with no terminal block. `acquired` / `pending`
264
+ // / `waiting` skip for the same "no sidecar yet" reason.
265
+ if (activity.status !== 'running')
266
+ return undefined;
267
+ return {
268
+ url: `${workflowRunDetailUrl(runId)}?attempt=${encodeURIComponent(attemptId)}`,
269
+ kind: 'live-terminal',
270
+ };
271
+ };
272
+ }
273
+ function escapeMd(s) {
274
+ return s.replace(/\\/g, '\\\\').replace(/\*/g, '\\*').replace(/_/g, '\\_').replace(/`/g, '\\`');
275
+ }
276
+ function short(s, n) {
277
+ return s.length > n ? `${s.slice(0, n)}…` : s;
278
+ }
279
+ //# sourceMappingURL=workflow-progress-card.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow-progress-card.js","sourceRoot":"","sources":["../../../src/im/lark/workflow-progress-card.ts"],"names":[],"mappings":"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"}