weaver-work-cli 0.1.28 → 0.1.31

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 (219) hide show
  1. package/dist/chunks/archive-U766FTFH.js +2537 -0
  2. package/dist/chunks/archive-oa-DMWEKX3L.js +1317 -0
  3. package/dist/chunks/asset-TCR7VDEV.js +2109 -0
  4. package/dist/chunks/attachment-content-AQNX5N3S.js +23 -0
  5. package/dist/chunks/blog-EVZWGDVM.js +2157 -0
  6. package/dist/chunks/caizhilian-JOWS6SL5.js +10087 -0
  7. package/dist/chunks/calendar-5WNCV66Q.js +1195 -0
  8. package/dist/chunks/chunk-2DUV44UX.js +15606 -0
  9. package/dist/chunks/chunk-324YPTC2.js +1607 -0
  10. package/dist/chunks/chunk-65QMVWHS.js +231 -0
  11. package/dist/chunks/chunk-6V7ZLF34.js +387 -0
  12. package/dist/chunks/chunk-AC7KJWC5.js +358 -0
  13. package/dist/chunks/chunk-AJ62BGAW.js +29 -0
  14. package/dist/chunks/chunk-BUSC6UAE.js +43 -0
  15. package/dist/chunks/chunk-CVZ2JOSW.js +62 -0
  16. package/dist/chunks/chunk-D4LTJSJD.js +477 -0
  17. package/dist/chunks/chunk-EG6ZU444.js +654 -0
  18. package/dist/chunks/chunk-EZALDOQH.js +383 -0
  19. package/dist/chunks/chunk-FMPJJYYI.js +106 -0
  20. package/dist/chunks/chunk-G2JSIUWF.js +769 -0
  21. package/dist/chunks/chunk-GCG2NMWR.js +703 -0
  22. package/dist/chunks/chunk-GPMFD4RD.js +75 -0
  23. package/dist/chunks/chunk-H3WDBYJW.js +508 -0
  24. package/dist/chunks/chunk-H6XSTSLM.js +2357 -0
  25. package/dist/chunks/chunk-J7RJTZSV.js +5556 -0
  26. package/dist/chunks/chunk-LUSPKZKY.js +53 -0
  27. package/dist/chunks/chunk-NIAJ5ZCG.js +73 -0
  28. package/dist/chunks/chunk-NOODWMCL.js +584 -0
  29. package/dist/chunks/chunk-OOUTBLZ4.js +51 -0
  30. package/dist/chunks/chunk-P26ZWSKU.js +73 -0
  31. package/dist/chunks/chunk-QWY6PGL6.js +3472 -0
  32. package/dist/chunks/chunk-R2IJAK7T.js +464 -0
  33. package/dist/chunks/chunk-R7O5PUWO.js +205 -0
  34. package/dist/chunks/chunk-RCGYCOMG.js +6962 -0
  35. package/dist/chunks/chunk-VZTXRG6X.js +403 -0
  36. package/dist/chunks/chunk-WHD4XMRP.js +161 -0
  37. package/dist/chunks/chunk-YLCYX7LE.js +371 -0
  38. package/dist/chunks/chunk-ZEDWSH32.js +68 -0
  39. package/dist/chunks/continuation-2CKSBLA6.js +11 -0
  40. package/dist/chunks/continuation-HZIZRZBX.js +13 -0
  41. package/dist/chunks/continuation-NLECEJPX.js +11 -0
  42. package/dist/chunks/ebuilder-form-NJ4YK6CC.js +2276 -0
  43. package/dist/chunks/ehr-MMYN36VA.js +5241 -0
  44. package/dist/chunks/employee-SAK2QYXX.js +11 -0
  45. package/dist/chunks/esb-HIWHOU7Q.js +141 -0
  46. package/dist/chunks/fna-KBACQTA5.js +1444 -0
  47. package/dist/chunks/host-3OHS5QUX.js +21 -0
  48. package/dist/chunks/host-IG6KEH5Q.js +19 -0
  49. package/dist/chunks/host-KQL5N4HO.js +23 -0
  50. package/dist/chunks/host-LLSZQCWR.js +17 -0
  51. package/dist/chunks/hrm-LYEC67ZQ.js +244 -0
  52. package/dist/chunks/im-RN2UKAEU.js +252 -0
  53. package/dist/chunks/invoice-EEPHLAF6.js +5179 -0
  54. package/dist/chunks/jiuchuanhui-WVVZYSJE.js +1940 -0
  55. package/dist/chunks/lazy-dispatch-MDOFFL2S.js +28 -0
  56. package/dist/chunks/mail-LNQLTF6L.js +2695 -0
  57. package/dist/chunks/meeting-XSD3BDVQ.js +504 -0
  58. package/dist/chunks/msg-parse-4GSQ2WTO.js +41 -0
  59. package/dist/chunks/okr-TMWTIU2K.js +2482 -0
  60. package/dist/chunks/plan-A2FSFA7T.js +2025 -0
  61. package/dist/chunks/project-T26QLBQF.js +1361 -0
  62. package/dist/chunks/registry-2VLUAESA.js +14 -0
  63. package/dist/chunks/registry-JCFEYXOE.js +18 -0
  64. package/dist/chunks/registry-NYPYMZXG.js +16 -0
  65. package/dist/chunks/registry-Q7OQJ3SU.js +19 -0
  66. package/dist/chunks/registry-ZJMJVWFA.js +19 -0
  67. package/dist/chunks/room-recommend-UR4ZDZS6.js +20 -0
  68. package/dist/chunks/schedule-5L2PM4M6.js +24 -0
  69. package/dist/chunks/state-Y2XBP6YE.js +15 -0
  70. package/dist/chunks/workflow-TR6PG2SL.js +245 -0
  71. package/dist/cmd/argv.js +45 -0
  72. package/dist/cmd/docs/index.js +3 -3
  73. package/dist/cmd/lazy-dispatch.js +20 -0
  74. package/dist/cmd/root.js +2 -4
  75. package/dist/cmd/setup/index.js +2 -2
  76. package/dist/cmd/skills/index.js +2 -2
  77. package/dist/core/package-paths.js +47 -0
  78. package/dist/index.js +163 -7
  79. package/dist/internal/e10/auth/xiaoe.js +3 -3
  80. package/dist/internal/e10/request-runtime.js +18 -62
  81. package/dist/internal/skills/detector.js +2 -2
  82. package/dist/shortcuts/contract/data/performance-catalog.js +1306 -0
  83. package/dist/shortcuts/contract/host.js +91 -35
  84. package/dist/shortcuts/contract/index.js +213 -0
  85. package/dist/shortcuts/contract/manifest.js +928 -0
  86. package/dist/shortcuts/contract/ooxml/docx.js +295 -0
  87. package/dist/shortcuts/contract/ooxml/xlsx.js +221 -0
  88. package/dist/shortcuts/contract/ooxml/zip.js +158 -0
  89. package/dist/shortcuts/contract/operations/assistant.js +1156 -0
  90. package/dist/shortcuts/contract/operations/clause-library.js +522 -0
  91. package/dist/shortcuts/contract/operations/compare.js +193 -0
  92. package/dist/shortcuts/contract/operations/credit-page.js +34 -0
  93. package/dist/shortcuts/contract/operations/flow.js +98 -0
  94. package/dist/shortcuts/contract/operations/page.js +66 -0
  95. package/dist/shortcuts/contract/operations/performance.js +733 -0
  96. package/dist/shortcuts/contract/operations/quote.js +557 -0
  97. package/dist/shortcuts/contract/operations/recommend.js +78 -0
  98. package/dist/shortcuts/contract/operations/registry.js +18 -0
  99. package/dist/shortcuts/contract/operations/review.js +83 -0
  100. package/dist/shortcuts/contract/operations/shared.js +37 -0
  101. package/dist/shortcuts/contract/operations/upload.js +108 -0
  102. package/dist/shortcuts/contract/operations/write.js +3 -2
  103. package/dist/shortcuts/index.js +140 -40
  104. package/dist/shortcuts/invoice/host.js +2 -1
  105. package/dist/shortcuts/invoice/manifest.js +36 -12
  106. package/dist/shortcuts/invoice/operations/issuing-qys.js +132 -36
  107. package/dist/shortcuts/invoice/operations/reim-auto.js +9 -0
  108. package/dist/shortcuts/invoice/operations/reim.js +81 -5
  109. package/dist/shortcuts/invoice/operations/shared.js +12 -5
  110. package/dist/shortcuts/meeting/host.js +45 -3
  111. package/dist/shortcuts/meeting/invitation/docx.js +442 -0
  112. package/dist/shortcuts/meeting/operations/attachment-content.js +418 -0
  113. package/dist/shortcuts/meeting/operations/attachment.js +442 -0
  114. package/dist/shortcuts/meeting/operations/eb/cache.js +57 -0
  115. package/dist/shortcuts/meeting/operations/eb/catalog.js +343 -28
  116. package/dist/shortcuts/meeting/operations/eb/conflict.js +372 -11
  117. package/dist/shortcuts/meeting/operations/eb/create-flow.js +710 -0
  118. package/dist/shortcuts/meeting/operations/eb/decision.js +47 -1
  119. package/dist/shortcuts/meeting/operations/eb/factory.js +129 -11
  120. package/dist/shortcuts/meeting/operations/eb/index.js +122 -2
  121. package/dist/shortcuts/meeting/operations/eb/room-recommend.js +378 -0
  122. package/dist/shortcuts/meeting/operations/eb/room-summary.js +84 -0
  123. package/dist/shortcuts/meeting/operations/eb/schedule.js +450 -0
  124. package/dist/shortcuts/meeting/operations/from-group-chat.js +576 -0
  125. package/dist/shortcuts/meeting/operations/invitation.js +458 -0
  126. package/dist/shortcuts/meeting/operations/minute-content.js +266 -0
  127. package/dist/shortcuts/meeting/operations/pipeline.js +489 -0
  128. package/dist/shortcuts/meeting/operations/qrcode.js +131 -0
  129. package/dist/shortcuts/meeting/operations/receipts.js +1 -1
  130. package/dist/shortcuts/meeting/operations/registry.js +18 -0
  131. package/dist/shortcuts/meeting/operations/summary.js +276 -0
  132. package/dist/shortcuts/meeting/operations/task-notify.js +325 -0
  133. package/dist/shortcuts/meeting/operations.js +42 -1
  134. package/dist/shortcuts/meeting/qr/encoder.js +427 -0
  135. package/dist/shortcuts/meeting/qr/render.js +103 -0
  136. package/dist/shortcuts/workflow/index.js +3 -0
  137. package/dist/shortcuts/workflow/operations/form.js +17 -5
  138. package/dist/shortcuts/workflow/operations/read.js +13 -6
  139. package/dist/shortcuts/workflow/operations/registry.js +2 -0
  140. package/dist/shortcuts/workflow/operations/todoSmartConvert/businessRules.js +331 -0
  141. package/dist/shortcuts/workflow/operations/todoSmartConvert/detailFieldRules.js +133 -0
  142. package/dist/shortcuts/workflow/operations/todoSmartConvert/summaryCache.js +326 -0
  143. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoDetailCache.js +113 -0
  144. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoDetailFetcher.js +259 -0
  145. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoListRows.js +64 -0
  146. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoOutputPlanner.js +28 -0
  147. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.aggregate.js +70 -0
  148. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.collect.js +267 -0
  149. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.core.js +392 -0
  150. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.detail.js +165 -0
  151. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.group.js +448 -0
  152. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.groupSummary.js +348 -0
  153. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.js +222 -0
  154. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.pipeline.js +66 -0
  155. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.smartGroup.js +502 -0
  156. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.summary.js +540 -0
  157. package/docs/_catalog.md +1 -0
  158. package/docs/contract.md +39 -4
  159. package/docs/invoice.md +7 -7
  160. package/docs/todo-smart-convert/README.md +171 -0
  161. package/docs/todo-smart-convert/data-contract.md +236 -0
  162. package/docs/todo-smart-convert/mock/ai-todo-query-target.json +209 -0
  163. package/docs/todo-smart-convert/subgroup-rules.md +245 -0
  164. package/package.json +3 -2
  165. package/scripts/bundle.mjs +63 -0
  166. package/scripts/package-skill.mjs +1 -1
  167. package/skill-template/business-info.json +25 -4
  168. package/skill-template/domains/jinchengda.md +16 -3
  169. package/skill-template/domains/yepiaotong.md +3 -3
  170. package/skills/weaver-e10-jinchengda/SKILL.md +111 -31
  171. package/skills/weaver-e10-jinchengda/references/contract-agent-entry.md +7 -13
  172. package/skills/weaver-e10-jinchengda/references/contract-ai-assistant.md +150 -0
  173. package/skills/weaver-e10-jinchengda/references/contract-ai-review.md +87 -0
  174. package/skills/weaver-e10-jinchengda/references/contract-clause-library-crud.md +111 -0
  175. package/skills/weaver-e10-jinchengda/references/contract-clause-recommender.md +0 -15
  176. package/skills/weaver-e10-jinchengda/references/contract-clause-reference-save.md +0 -13
  177. package/skills/weaver-e10-jinchengda/references/contract-credit-page.md +50 -0
  178. package/skills/weaver-e10-jinchengda/references/contract-disabled-capabilities.md +4 -2
  179. package/skills/weaver-e10-jinchengda/references/contract-doc-compare.md +74 -0
  180. package/skills/weaver-e10-jinchengda/references/contract-flow-launch.md +84 -0
  181. package/skills/weaver-e10-jinchengda/references/contract-performance-query.md +29 -0
  182. package/skills/weaver-e10-jinchengda/references/contract-quote-to-contract.md +28 -0
  183. package/skills/weaver-e10-jinchengda/references/contract-request-status.md +2 -21
  184. package/skills/weaver-e10-jinchengda/references/contract-request-write.md +0 -24
  185. package/skills/weaver-e10-jinchengda/references/contract-signing-subjects.md +0 -15
  186. package/skills/weaver-e10-jinchengda/references/contract-subject-create.md +0 -17
  187. package/skills/weaver-e10-jinchengda/references/contract-template-recommend.md +70 -0
  188. package/skills/weaver-e10-jinchengda/references/contract-template-selector.md +0 -15
  189. package/skills/weaver-e10-jinchengda/references/contract-workflow-discovery.md +0 -15
  190. package/skills/weaver-e10-jinchengda/references/source-manifest.json +1168 -152
  191. package/skills/weaver-e10-meeting/SKILL.md +493 -17
  192. package/skills/weaver-e10-meeting/references/meeting-change.md +4 -4
  193. package/skills/weaver-e10-meeting/references/meeting-create.md +6 -6
  194. package/skills/weaver-e10-meeting/references/meeting-eb.md +503 -27
  195. package/skills/weaver-e10-meeting/references/meeting-invitation.md +113 -0
  196. package/skills/weaver-e10-meeting/references/meeting-lifecycle.md +6 -6
  197. package/skills/weaver-e10-meeting/references/meeting-minute-file.md +425 -0
  198. package/skills/weaver-e10-meeting/references/meeting-queries.md +4 -4
  199. package/skills/weaver-e10-meeting/references/meeting-receipts-signs.md +15 -15
  200. package/skills/weaver-e10-meeting/references/meeting-verification.md +19 -11
  201. package/skills/weaver-e10-meeting.zip +0 -0
  202. package/skills/weaver-e10-workflow/SKILL.md +23 -1
  203. package/skills/weaver-e10-workflow/references/todo-smart-convert.md +282 -0
  204. package/skills/weaver-e10-workflow/scripts/todo-summary.cjs +695 -0
  205. package/skills/weaver-e10-yepiaotong/SKILL.md +15 -11
  206. package/skills/weaver-e10-yepiaotong/references/invoice-enterprise-list.md +1 -1
  207. package/skills/weaver-e10-yepiaotong/references/invoice-issuing-examples.md +10 -7
  208. package/skills/weaver-e10-yepiaotong/references/invoice-issuing-form-fill-rules.md +41 -14
  209. package/skills/weaver-e10-yepiaotong/references/invoice-issuing-workflow.md +54 -26
  210. package/skills/weaver-e10-yepiaotong/references/invoice-personal-list.md +6 -5
  211. package/skills/weaver-e10-yepiaotong/references/invoice-reim.md +14 -11
  212. package/skills/weaver-e10-yepiaotong/references/reim-api-reference.md +97 -56
  213. package/skills/weaver-e10-yepiaotong/references/reim-examples.md +84 -60
  214. package/skills/weaver-e10-yepiaotong/references/reim-form-fill-rules.md +142 -105
  215. package/skills/weaver-e10-yepiaotong/references/reim-matching-rules.md +53 -194
  216. package/skills/weaver-e10-yepiaotong/references/reim-phone-subsidy-rules.md +7 -7
  217. package/skills/weaver-e10-yepiaotong/references/reim-workflow.md +164 -72
  218. package/skills/weaver-e10-yepiaotong/references/source-manifest.json +8 -2
  219. package/templates/meeting/invitation.docx +0 -0
@@ -0,0 +1,383 @@
1
+ import { createRequire as __esbuildCreateRequire } from 'node:module';
2
+ const require = __esbuildCreateRequire(import.meta.url);
3
+ import {
4
+ workflowAlreadyAppliedError,
5
+ workflowPartialError,
6
+ workflowValidationError
7
+ } from "./chunk-FMPJJYYI.js";
8
+
9
+ // src/shortcuts/workflow/continuation.ts
10
+ import { createHash, createHmac, randomBytes, randomUUID, timingSafeEqual } from "node:crypto";
11
+ import { existsSync } from "node:fs";
12
+ import { chmod, mkdir, readFile, readdir, unlink, writeFile } from "node:fs/promises";
13
+ import { homedir, hostname } from "node:os";
14
+ import { resolve } from "node:path";
15
+ var DEFAULT_TTL_MS = 10 * 6e4;
16
+ var RECLAIM_GRACE_MS = 3e4;
17
+ var HANDLE_PATTERN = /^wc-[0-9a-f]{16}$/;
18
+ var SWEEP_THRESHOLD = 200;
19
+ async function shouldSweep(dir) {
20
+ try {
21
+ return (await readdir(dir)).length > SWEEP_THRESHOLD;
22
+ } catch {
23
+ return false;
24
+ }
25
+ }
26
+ function stateRoot(ctx) {
27
+ const configured = ctx?.config?.path();
28
+ if (configured) return resolve(configured, "..");
29
+ return process.env.WEAVER_WORK_CLI_HOME || process.env.WORK_CLI_HOME || resolve(homedir(), ".weaver-work-cli");
30
+ }
31
+ async function loadKey(ctx) {
32
+ const keysDir = resolve(stateRoot(ctx), "keys");
33
+ const filename = resolve(keysDir, "workflow-continuation.key");
34
+ await mkdir(keysDir, { recursive: true, mode: 448 });
35
+ if (existsSync(filename)) return readFile(filename);
36
+ const key = randomBytes(32);
37
+ try {
38
+ await writeFile(filename, key, { flag: "wx", mode: 384 });
39
+ if (process.platform !== "win32") await chmod(filename, 384).catch(() => void 0);
40
+ return key;
41
+ } catch {
42
+ return readFile(filename);
43
+ }
44
+ }
45
+ function signature(payload, key) {
46
+ return createHmac("sha256", key).update(payload).digest("base64url");
47
+ }
48
+ function referenceFingerprint(reference) {
49
+ return createHash("sha256").update(reference).digest("hex");
50
+ }
51
+ function pendingDir(ctx) {
52
+ return resolve(stateRoot(ctx), "state", "workflow", "continuation-pending");
53
+ }
54
+ function consumedDir(ctx) {
55
+ return resolve(stateRoot(ctx), "state", "workflow", "continuation-consumed");
56
+ }
57
+ async function sweepConsumed(dir) {
58
+ let names;
59
+ try {
60
+ names = await readdir(dir);
61
+ } catch {
62
+ return;
63
+ }
64
+ const now = Date.now();
65
+ for (const name of names) {
66
+ const file = resolve(dir, name);
67
+ try {
68
+ const content = await readFile(file, "utf8");
69
+ let expiresAt = Number(content);
70
+ if (!Number.isFinite(expiresAt)) {
71
+ try {
72
+ expiresAt = Number(JSON.parse(content)?.expiresAt);
73
+ } catch {
74
+ }
75
+ }
76
+ if (Number.isFinite(expiresAt) && expiresAt < now) await unlink(file);
77
+ } catch {
78
+ }
79
+ }
80
+ }
81
+ async function readConsumedMarker(ctx, reference) {
82
+ const file = resolve(consumedDir(ctx), referenceFingerprint(reference));
83
+ let raw;
84
+ try {
85
+ raw = await readFile(file, "utf8");
86
+ } catch {
87
+ return null;
88
+ }
89
+ try {
90
+ const parsed = JSON.parse(raw);
91
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) return parsed;
92
+ } catch {
93
+ }
94
+ return { state: "unknown" };
95
+ }
96
+ function markerProcessAlive(marker) {
97
+ const pid = Number(marker.pid);
98
+ if (!Number.isFinite(pid) || pid <= 0) return true;
99
+ if (typeof marker.hostname === "string" && marker.hostname && marker.hostname !== hostname()) return true;
100
+ try {
101
+ process.kill(pid, 0);
102
+ return true;
103
+ } catch (error) {
104
+ return error?.code !== "ESRCH";
105
+ }
106
+ }
107
+ function replayOf(marker) {
108
+ let state = "unknown";
109
+ if (marker.state === "succeeded") {
110
+ state = "succeeded";
111
+ } else if (marker.state === "running") {
112
+ state = marker.stage === "claimed" ? "claimed" : marker.stage === "committed" ? "committed" : "saving";
113
+ }
114
+ const stage = marker.stage === "claimed" || marker.stage === "saving" || marker.stage === "committed" ? marker.stage : void 0;
115
+ return {
116
+ state,
117
+ ...stage ? { stage } : {},
118
+ ...typeof marker.operation === "string" ? { operation: marker.operation } : {},
119
+ ...Number.isFinite(Number(marker.consumedAt)) ? { consumedAt: Number(marker.consumedAt) } : {},
120
+ ...Number.isFinite(Number(marker.finishedAt)) ? { finishedAt: Number(marker.finishedAt) } : {},
121
+ ...typeof marker.requestId === "string" && marker.requestId ? { requestId: marker.requestId } : {},
122
+ ...state === "succeeded" ? { result: marker.result ?? null } : {}
123
+ };
124
+ }
125
+ function continuationReplayError(replay, expectedOperation) {
126
+ const operation = replay.operation ?? expectedOperation;
127
+ if (replay.state === "succeeded") {
128
+ return workflowAlreadyAppliedError(operation, replay);
129
+ }
130
+ if (replay.state === "committed") {
131
+ return workflowAlreadyAppliedError(operation, replay);
132
+ }
133
+ if (replay.state === "saving") {
134
+ const recovery = operation === "workflow.createForm" ? "\u8981\u91CD\u65B0\u53D1\u8D77\uFF0C\u8BF7**\u91CD\u65B0\u6267\u884C workflow.createForm \u83B7\u53D6\u65B0\u53E5\u67C4**\uFF08\u672C\u6B21\u53E5\u67C4\u5DF2\u6D88\u8D39\uFF0C\u91CD\u53D1\u540C\u4E00\u53E5\u67C4\u65E0\u6548\uFF09\u3002" : /Apply$/u.test(operation) ? "\u786E\u8BA4\u672A\u751F\u6548\u540E\uFF0C\u91CD\u8DD1\u5BF9\u5E94\u7684 Prepare \u83B7\u53D6\u65B0\u53E5\u67C4\u3002" : "\u8BE5\u547D\u4EE4\u6CA1\u6709\u53EF\u91CD\u8DD1\u7684 Prepare\uFF0C\u4E5F**\u4E0D\u8981\u539F\u6837\u91CD\u8DD1**\uFF1B\u8BF7\u628A\u7ED3\u679C\u5982\u5B9E\u544A\u77E5\u7528\u6237\u3002";
135
+ return workflowPartialError(
136
+ '\u8BE5 continuation \u5BF9\u5E94\u7684\u4E0A\u4E00\u6B21\u6267\u884C**\u5DF2\u7ECF\u53D1\u51FA\u5199\u5165\u8BF7\u6C42\uFF0C\u4F46\u7ED3\u679C\u672A\u786E\u8BA4**\uFF08\u8FDB\u7A0B\u88AB\u4E2D\u6B62\u6216\u56DE\u6267\u4E22\u5931\uFF09\uFF0C\u672C\u6B21\u672A\u6267\u884C\u3002**\u8BF7\u628A"\u4E0A\u4E00\u6B21\u7ED3\u679C\u672A\u786E\u8BA4"\u5982\u5B9E\u544A\u77E5\u7528\u6237\u5E76\u505C\u4E0B\uFF0C\u4E0D\u8981\u81EA\u884C\u7EE7\u7EED**\uFF08\u4E0D\u8981\u91CD\u8BD5\u3001\u4E0D\u8981\u6539\u7528\u5176\u5B83\u547D\u4EE4\u53CD\u590D\u63A8\u65AD\u3001\u4E0D\u8981\u66FF\u7528\u6237\u4E0B\u7ED3\u8BBA\uFF09\u3002' + recovery,
137
+ replay,
138
+ { stage: "continuation_replay", ...replay }
139
+ );
140
+ }
141
+ if (replay.state === "claimed") {
142
+ return workflowValidationError(
143
+ "continuation_busy",
144
+ "\u8BE5 continuation \u6B63\u88AB\u53E6\u4E00\u6B21\u6267\u884C\u5360\u7528\uFF08\u4E0A\u4E00\u6B21\u53EA\u62A2\u5230\u53E5\u67C4\u3001\u5C1A\u672A\u53D1\u51FA\u5199\u5165\u8BF7\u6C42\uFF09\uFF0C\u672C\u6B21\u672A\u6267\u884C\u3002\u8BF7\u7A0D\u540E\u91CD\u8BD5\u540C\u4E00\u6761\u547D\u4EE4\uFF1B\u82E5\u4E0A\u4E00\u6B21\u6267\u884C\u5176\u5B9E\u5DF2\u7ECF\u5B8C\u6210\uFF0C\u76F4\u63A5\u770B\u8FD4\u56DE\u7ED3\u679C\u5373\u53EF\u3002",
145
+ replay
146
+ );
147
+ }
148
+ return workflowValidationError(
149
+ "continuation_consumed",
150
+ "continuation \u5DF2\u4F7F\u7528\uFF08\u4E00\u6B21\u6027\uFF09\uFF0C\u7981\u6B62\u91CD\u590D\u63D0\u4EA4\u3002\u82E5\u6000\u7591\u4E0A\u4E00\u6B21\u6CA1\u751F\u6548\uFF0C\u8BF7\u5148\u53EA\u8BFB\u6838\u5BF9\u76EE\u6807\u6D41\u7A0B\u662F\u5426\u5DF2\u5B58\u5728\uFF08workflow.search --category done/mine --requestId <\u76EE\u6807ID>\uFF09\uFF0C\u786E\u8BA4\u672A\u751F\u6548\u518D\u91CD\u8DD1\u5BF9\u5E94\u7684 Prepare\u3002",
151
+ replay
152
+ );
153
+ }
154
+ async function sweepPending(dir) {
155
+ let names;
156
+ try {
157
+ names = await readdir(dir);
158
+ } catch {
159
+ return;
160
+ }
161
+ const now = Date.now();
162
+ for (const name of names) {
163
+ const file = resolve(dir, name);
164
+ try {
165
+ const value = JSON.parse(await readFile(file, "utf8"));
166
+ const expiresAt = Number(value?.expiresAt);
167
+ if (Number.isFinite(expiresAt) && expiresAt < now) await unlink(file);
168
+ } catch {
169
+ }
170
+ }
171
+ }
172
+ async function readPendingPayload(ctx, handle) {
173
+ let content;
174
+ try {
175
+ content = await readFile(resolve(pendingDir(ctx), handle), "utf8");
176
+ } catch {
177
+ throw workflowValidationError(
178
+ "continuation_expired",
179
+ "continuation \u5728\u672C\u673A\u72B6\u6001\u76EE\u5F55\u4E2D\u4E0D\u5B58\u5728\uFF08\u5DF2\u88AB\u4F7F\u7528\u3001\u5DF2\u8FC7\u671F\uFF0C\u6216\u4E0D\u662F\u672C\u673A\u7B7E\u53D1\u7684\u53E5\u67C4\uFF09\u3002\u8BF7\u91CD\u65B0\u6267\u884C\u5BF9\u5E94\u7684 Prepare \u547D\u4EE4\u540E\u518D apply\uFF0C\u4E0D\u8981\u590D\u7528\u65E7\u53E5\u67C4\u3002"
180
+ );
181
+ }
182
+ try {
183
+ return JSON.parse(content);
184
+ } catch {
185
+ throw workflowValidationError("continuation_invalid", "continuation \u672C\u673A\u8F7D\u8377\u65E0\u6CD5\u89E3\u6790\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C\u5BF9\u5E94\u7684 Prepare \u547D\u4EE4");
186
+ }
187
+ }
188
+ async function verifyLegacyToken(ctx, token) {
189
+ const [body, provided] = token.split(".");
190
+ const expected = signature(body, await loadKey(ctx));
191
+ const valid = typeof provided === "string" && provided.length === expected.length && timingSafeEqual(Buffer.from(provided), Buffer.from(expected));
192
+ if (!valid) throw workflowValidationError("continuation_invalid", "continuation \u7B7E\u540D\u6821\u9A8C\u5931\u8D25");
193
+ try {
194
+ return JSON.parse(Buffer.from(body, "base64url").toString("utf8"));
195
+ } catch {
196
+ throw workflowValidationError("continuation_invalid", "continuation \u5185\u5BB9\u65E0\u6CD5\u89E3\u6790");
197
+ }
198
+ }
199
+ async function tryReclaim(ctx, reference, marker, record) {
200
+ const age = Date.now() - Number(marker.consumedAt);
201
+ const claimable = marker.state === "running" && marker.stage === "claimed";
202
+ if (!claimable || !Number.isFinite(age) || age < RECLAIM_GRACE_MS || markerProcessAlive(marker)) {
203
+ return replayOf(marker);
204
+ }
205
+ const file = resolve(consumedDir(ctx), referenceFingerprint(reference));
206
+ try {
207
+ await writeFile(file, JSON.stringify(record), { mode: 384 });
208
+ } catch {
209
+ return replayOf(marker);
210
+ }
211
+ const after = await readConsumedMarker(ctx, reference);
212
+ if (after && after.owner === record.owner) return null;
213
+ return replayOf(after ?? marker);
214
+ }
215
+ async function tryTakeoverExpiredWindow(ctx, reference, marker, record) {
216
+ const expiresAt = Number(marker.expiresAt);
217
+ if (!Number.isFinite(expiresAt) || expiresAt >= Date.now()) return false;
218
+ if (marker.state !== "succeeded") return false;
219
+ const file = resolve(consumedDir(ctx), referenceFingerprint(reference));
220
+ try {
221
+ await writeFile(file, JSON.stringify(record), { mode: 384 });
222
+ } catch {
223
+ return false;
224
+ }
225
+ const after = await readConsumedMarker(ctx, reference);
226
+ return Boolean(after && after.owner === record.owner);
227
+ }
228
+ function createWorkflowContinuationSigner(ctx) {
229
+ return {
230
+ async issue(payload, ttlMs = DEFAULT_TTL_MS) {
231
+ const issuedAt = Date.now();
232
+ const ttl = Number.isFinite(ttlMs) ? Math.trunc(ttlMs) : DEFAULT_TTL_MS;
233
+ const record = JSON.stringify({ ...payload, issuedAt, expiresAt: issuedAt + ttl });
234
+ const dir = pendingDir(ctx);
235
+ await mkdir(dir, { recursive: true, mode: 448 });
236
+ for (let attempt = 0; attempt < 5; attempt += 1) {
237
+ const handle = `wc-${randomBytes(8).toString("hex")}`;
238
+ try {
239
+ await writeFile(resolve(dir, handle), record, { flag: "wx", mode: 384 });
240
+ if (await shouldSweep(dir)) await sweepPending(dir);
241
+ return handle;
242
+ } catch (error) {
243
+ if (error?.code !== "EEXIST") {
244
+ throw workflowValidationError(
245
+ "continuation_unavailable",
246
+ `\u672C\u673A\u72B6\u6001\u76EE\u5F55\u4E0D\u53EF\u5199\uFF0C\u65E0\u6CD5\u6258\u7BA1 continuation\uFF1A${dir}`
247
+ );
248
+ }
249
+ }
250
+ }
251
+ throw workflowValidationError("continuation_unavailable", "\u7B7E\u53D1 continuation \u5931\u8D25\uFF08\u53E5\u67C4\u8FDE\u7EED\u51B2\u7A81\uFF09\uFF0C\u8BF7\u91CD\u8BD5");
252
+ },
253
+ async verify(reference, expectedOperation) {
254
+ if (typeof reference !== "string" || !reference.trim()) {
255
+ throw workflowValidationError("continuation_invalid", "continuation \u65E0\u6548\uFF08\u7F3A\u5C11\u5165\u53C2\uFF09");
256
+ }
257
+ const ref = reference.trim();
258
+ if (ref.startsWith("wc-") && !HANDLE_PATTERN.test(ref)) {
259
+ throw workflowValidationError(
260
+ "continuation_invalid",
261
+ "continuation \u53E5\u67C4\u683C\u5F0F\u65E0\u6548\uFF1A\u5FC5\u987B\u539F\u6837\u56DE\u4F20 Prepare \u8FD4\u56DE\u7684 wc-\u2026 \u503C\uFF0C\u7981\u6B62\u624B\u5DE5\u6784\u9020\u6216\u62FC\u63A5\u3002"
262
+ );
263
+ }
264
+ const marker = await readConsumedMarker(ctx, ref);
265
+ if (marker) {
266
+ const replay = replayOf(marker);
267
+ if (replay.state !== "claimed") throw continuationReplayError(replay, expectedOperation);
268
+ }
269
+ const handle = HANDLE_PATTERN.test(ref);
270
+ const value = handle ? await readPendingPayload(ctx, ref) : await verifyLegacyToken(ctx, ref);
271
+ if (value.operation !== expectedOperation) {
272
+ throw workflowValidationError("continuation_mismatch", "continuation \u4E0D\u5C5E\u4E8E\u5F53\u524D\u64CD\u4F5C");
273
+ }
274
+ if (!Number.isSafeInteger(value.expiresAt) || value.expiresAt < Date.now()) {
275
+ throw workflowValidationError("continuation_expired", "continuation \u5DF2\u8FC7\u671F");
276
+ }
277
+ return value;
278
+ },
279
+ async consume(reference, operation, ttlMs) {
280
+ if (typeof reference !== "string" || !reference.trim()) return { claimed: true };
281
+ const ref = reference.trim();
282
+ const handle = HANDLE_PATTERN.test(ref);
283
+ const window = Number.isFinite(ttlMs) && Number(ttlMs) > 0 ? Math.trunc(Number(ttlMs)) : 0;
284
+ let expiresAt = Date.now() + (window || DEFAULT_TTL_MS);
285
+ let prepared;
286
+ try {
287
+ const value = handle ? JSON.parse(await readFile(resolve(pendingDir(ctx), ref), "utf8")) : JSON.parse(Buffer.from(ref.split(".")[0], "base64url").toString("utf8"));
288
+ if (!window && Number.isSafeInteger(value.expiresAt)) expiresAt = value.expiresAt;
289
+ prepared = value.prepared;
290
+ } catch {
291
+ }
292
+ const dir = consumedDir(ctx);
293
+ const file = resolve(dir, referenceFingerprint(ref));
294
+ const record = {
295
+ state: "running",
296
+ stage: "claimed",
297
+ ...operation ? { operation } : {},
298
+ // owner/pid/hostname 只服务于"上一次死在写入之前"的安全重占判定(见 tryReclaim)。
299
+ owner: randomUUID(),
300
+ pid: process.pid,
301
+ hostname: hostname(),
302
+ consumedAt: Date.now(),
303
+ expiresAt,
304
+ ...prepared === void 0 ? {} : { prepared }
305
+ };
306
+ try {
307
+ await mkdir(dir, { recursive: true, mode: 448 });
308
+ await writeFile(file, JSON.stringify(record), { flag: "wx", mode: 384 });
309
+ } catch (error) {
310
+ if (error?.code === "EEXIST") {
311
+ const existing = await readConsumedMarker(ctx, ref);
312
+ if (!existing) return { claimed: false, previous: { state: "unknown" } };
313
+ if (window && await tryTakeoverExpiredWindow(ctx, ref, existing, record)) {
314
+ if (await shouldSweep(dir)) await sweepConsumed(dir);
315
+ return { claimed: true };
316
+ }
317
+ const blocker = await tryReclaim(ctx, ref, existing, record);
318
+ if (!blocker) return { claimed: true };
319
+ return { claimed: false, previous: blocker };
320
+ }
321
+ }
322
+ if (await shouldSweep(dir)) await sweepConsumed(dir);
323
+ return { claimed: true };
324
+ },
325
+ async markStage(reference, stage, extra) {
326
+ if (typeof reference !== "string" || !reference.trim()) return;
327
+ const file = resolve(consumedDir(ctx), referenceFingerprint(reference.trim()));
328
+ let raw;
329
+ try {
330
+ raw = await readFile(file, "utf8");
331
+ } catch {
332
+ return;
333
+ }
334
+ let marker;
335
+ try {
336
+ marker = JSON.parse(raw);
337
+ } catch {
338
+ return;
339
+ }
340
+ if (!marker || typeof marker !== "object" || Array.isArray(marker)) return;
341
+ try {
342
+ await writeFile(
343
+ file,
344
+ JSON.stringify({ ...marker, stage, ...extra ?? {} }),
345
+ { mode: 384 }
346
+ );
347
+ } catch {
348
+ throw workflowValidationError(
349
+ "continuation_unavailable",
350
+ "\u672C\u673A\u65E0\u6CD5\u8BB0\u5F55\u672C\u6B21\u5199\u5165\u7684\u8FDB\u5EA6\uFF08\u72B6\u6001\u76EE\u5F55\u4E0D\u53EF\u5199\uFF09\uFF0C\u4E3A\u907F\u514D\u7559\u4E0B\u65E0\u6CD5\u5224\u5B9A\u7ED3\u679C\u7684\u4E00\u6B21\u6027\u5199\u5165\uFF0C\u5DF2\u505C\u6B62\u672C\u6B21\u64CD\u4F5C\u3002"
351
+ );
352
+ }
353
+ },
354
+ async settle(reference, result, operation) {
355
+ if (typeof reference !== "string" || !reference.trim()) return;
356
+ const ref = reference.trim();
357
+ const file = resolve(consumedDir(ctx), referenceFingerprint(ref));
358
+ try {
359
+ const raw = await readFile(file, "utf8");
360
+ const marker = JSON.parse(raw);
361
+ if (marker && typeof marker === "object" && !Array.isArray(marker)) {
362
+ await writeFile(
363
+ file,
364
+ JSON.stringify({
365
+ ...marker,
366
+ state: "succeeded",
367
+ ...operation ? { operation } : {},
368
+ finishedAt: Date.now(),
369
+ result: result ?? null
370
+ }),
371
+ { mode: 384 }
372
+ );
373
+ }
374
+ } catch {
375
+ }
376
+ }
377
+ };
378
+ }
379
+
380
+ export {
381
+ continuationReplayError,
382
+ createWorkflowContinuationSigner
383
+ };
@@ -0,0 +1,106 @@
1
+ import { createRequire as __esbuildCreateRequire } from 'node:module';
2
+ const require = __esbuildCreateRequire(import.meta.url);
3
+ import {
4
+ CliError
5
+ } from "./chunk-LUSPKZKY.js";
6
+
7
+ // src/shortcuts/workflow/errors.ts
8
+ var WorkflowCliError = class extends CliError {
9
+ type;
10
+ subtype;
11
+ code;
12
+ retryable;
13
+ stage;
14
+ details;
15
+ partialData;
16
+ constructor(type, subtype, message, options = {}) {
17
+ super(message, options.exitCode ?? 5 /* InternalError */);
18
+ this.name = "WorkflowCliError";
19
+ this.type = type;
20
+ this.subtype = subtype;
21
+ this.code = options.code;
22
+ this.retryable = options.retryable ?? false;
23
+ this.stage = options.stage;
24
+ this.details = options.details;
25
+ this.partialData = options.partialData;
26
+ }
27
+ };
28
+ function workflowValidationError(subtype, message, details) {
29
+ return new WorkflowCliError("validation", subtype, message, {
30
+ details,
31
+ exitCode: 2 /* UsageError */
32
+ });
33
+ }
34
+ function workflowAuthError(subtype, message, details) {
35
+ return new WorkflowCliError("authentication", subtype, message, {
36
+ details,
37
+ exitCode: 3 /* AuthError */
38
+ });
39
+ }
40
+ function workflowApiError(subtype, message, options = {}) {
41
+ return new WorkflowCliError("api", subtype, message, {
42
+ ...options,
43
+ exitCode: 1 /* GeneralError */
44
+ });
45
+ }
46
+ function workflowNetworkError(subtype, message, options = {}) {
47
+ return new WorkflowCliError("network", subtype, message, {
48
+ ...options,
49
+ retryable: options.retryable ?? true,
50
+ exitCode: 4 /* NetworkError */
51
+ });
52
+ }
53
+ function workflowConfirmationError(action, details) {
54
+ return new WorkflowCliError("confirmation", "required", "\u8BE5\u64CD\u4F5C\u9700\u8981\u660E\u786E\u786E\u8BA4", {
55
+ details: { action, ...details },
56
+ exitCode: 10 /* ConfirmationRequired */
57
+ });
58
+ }
59
+ function workflowPartialError(message, partialData, details) {
60
+ return new WorkflowCliError("partial", "write_uncertain", message, {
61
+ details,
62
+ partialData,
63
+ exitCode: 11 /* Partial */
64
+ });
65
+ }
66
+ function workflowAlreadyAppliedError(operation, details) {
67
+ return new WorkflowCliError(
68
+ "validation",
69
+ "continuation_already_applied",
70
+ `\u8BE5 continuation \u5DF2\u7ECF\u6267\u884C\u8FC7\u4E14\u5DF2\u6210\u529F\uFF08${operation}\uFF09\uFF0C\u672C\u6B21\u672A\u91CD\u590D\u5199\u5165\u3002\u8BF7\u4E0D\u8981\u91CD\u8DD1 Prepare\uFF0C\u4E5F\u4E0D\u8981\u518D\u6B21\u63D0\u4EA4\u2014\u2014\u5982\u9700\u786E\u8BA4\u7ED3\u679C\uFF0C\u76F4\u63A5\u770B\u672C\u6B21\u8FD4\u56DE\u7684\u4E0A\u4E00\u6B21\u6267\u884C\u7ED3\u679C\u3002`,
71
+ { details, exitCode: 2 /* UsageError */ }
72
+ );
73
+ }
74
+ function workflowPolicyError(subtype, message, details) {
75
+ return new WorkflowCliError("policy", subtype, message, {
76
+ details,
77
+ exitCode: 6 /* PolicyError */
78
+ });
79
+ }
80
+ var CLARIFICATION_SUBTYPE = "needs_clarification";
81
+ function workflowClarificationError(clarificationType, keyword, question, candidates = [], extra = {}) {
82
+ return new WorkflowCliError("validation", CLARIFICATION_SUBTYPE, question, {
83
+ details: {
84
+ clarificationType,
85
+ clarificationKeyword: keyword,
86
+ clarificationQuestion: question,
87
+ candidates,
88
+ ...extra
89
+ },
90
+ exitCode: 2 /* UsageError */
91
+ });
92
+ }
93
+
94
+ export {
95
+ WorkflowCliError,
96
+ workflowValidationError,
97
+ workflowAuthError,
98
+ workflowApiError,
99
+ workflowNetworkError,
100
+ workflowConfirmationError,
101
+ workflowPartialError,
102
+ workflowAlreadyAppliedError,
103
+ workflowPolicyError,
104
+ CLARIFICATION_SUBTYPE,
105
+ workflowClarificationError
106
+ };