weaver-work-cli 0.1.29 → 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 (185) 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/manifest.js +34 -11
  105. package/dist/shortcuts/invoice/operations/reim-auto.js +9 -0
  106. package/dist/shortcuts/invoice/operations/reim.js +81 -5
  107. package/dist/shortcuts/invoice/operations/shared.js +12 -5
  108. package/dist/shortcuts/meeting/host.js +45 -3
  109. package/dist/shortcuts/meeting/invitation/docx.js +442 -0
  110. package/dist/shortcuts/meeting/operations/attachment-content.js +418 -0
  111. package/dist/shortcuts/meeting/operations/attachment.js +442 -0
  112. package/dist/shortcuts/meeting/operations/eb/cache.js +57 -0
  113. package/dist/shortcuts/meeting/operations/eb/catalog.js +343 -28
  114. package/dist/shortcuts/meeting/operations/eb/conflict.js +372 -11
  115. package/dist/shortcuts/meeting/operations/eb/create-flow.js +710 -0
  116. package/dist/shortcuts/meeting/operations/eb/decision.js +47 -1
  117. package/dist/shortcuts/meeting/operations/eb/factory.js +129 -11
  118. package/dist/shortcuts/meeting/operations/eb/index.js +122 -2
  119. package/dist/shortcuts/meeting/operations/eb/room-recommend.js +378 -0
  120. package/dist/shortcuts/meeting/operations/eb/room-summary.js +84 -0
  121. package/dist/shortcuts/meeting/operations/eb/schedule.js +450 -0
  122. package/dist/shortcuts/meeting/operations/from-group-chat.js +576 -0
  123. package/dist/shortcuts/meeting/operations/invitation.js +458 -0
  124. package/dist/shortcuts/meeting/operations/minute-content.js +266 -0
  125. package/dist/shortcuts/meeting/operations/pipeline.js +489 -0
  126. package/dist/shortcuts/meeting/operations/qrcode.js +131 -0
  127. package/dist/shortcuts/meeting/operations/receipts.js +1 -1
  128. package/dist/shortcuts/meeting/operations/registry.js +18 -0
  129. package/dist/shortcuts/meeting/operations/summary.js +276 -0
  130. package/dist/shortcuts/meeting/operations/task-notify.js +325 -0
  131. package/dist/shortcuts/meeting/operations.js +42 -1
  132. package/dist/shortcuts/meeting/qr/encoder.js +427 -0
  133. package/dist/shortcuts/meeting/qr/render.js +103 -0
  134. package/dist/shortcuts/workflow/operations/form.js +17 -5
  135. package/docs/contract.md +39 -4
  136. package/docs/invoice.md +5 -5
  137. package/package.json +3 -2
  138. package/scripts/bundle.mjs +63 -0
  139. package/skill-template/business-info.json +25 -4
  140. package/skill-template/domains/jinchengda.md +16 -3
  141. package/skill-template/domains/yepiaotong.md +1 -1
  142. package/skills/weaver-e10-jinchengda/SKILL.md +111 -31
  143. package/skills/weaver-e10-jinchengda/references/contract-agent-entry.md +7 -13
  144. package/skills/weaver-e10-jinchengda/references/contract-ai-assistant.md +150 -0
  145. package/skills/weaver-e10-jinchengda/references/contract-ai-review.md +87 -0
  146. package/skills/weaver-e10-jinchengda/references/contract-clause-library-crud.md +111 -0
  147. package/skills/weaver-e10-jinchengda/references/contract-clause-recommender.md +0 -15
  148. package/skills/weaver-e10-jinchengda/references/contract-clause-reference-save.md +0 -13
  149. package/skills/weaver-e10-jinchengda/references/contract-credit-page.md +50 -0
  150. package/skills/weaver-e10-jinchengda/references/contract-disabled-capabilities.md +4 -2
  151. package/skills/weaver-e10-jinchengda/references/contract-doc-compare.md +74 -0
  152. package/skills/weaver-e10-jinchengda/references/contract-flow-launch.md +84 -0
  153. package/skills/weaver-e10-jinchengda/references/contract-performance-query.md +29 -0
  154. package/skills/weaver-e10-jinchengda/references/contract-quote-to-contract.md +28 -0
  155. package/skills/weaver-e10-jinchengda/references/contract-request-status.md +2 -21
  156. package/skills/weaver-e10-jinchengda/references/contract-request-write.md +0 -24
  157. package/skills/weaver-e10-jinchengda/references/contract-signing-subjects.md +0 -15
  158. package/skills/weaver-e10-jinchengda/references/contract-subject-create.md +0 -17
  159. package/skills/weaver-e10-jinchengda/references/contract-template-recommend.md +70 -0
  160. package/skills/weaver-e10-jinchengda/references/contract-template-selector.md +0 -15
  161. package/skills/weaver-e10-jinchengda/references/contract-workflow-discovery.md +0 -15
  162. package/skills/weaver-e10-jinchengda/references/source-manifest.json +1168 -152
  163. package/skills/weaver-e10-meeting/SKILL.md +493 -17
  164. package/skills/weaver-e10-meeting/references/meeting-change.md +4 -4
  165. package/skills/weaver-e10-meeting/references/meeting-create.md +6 -6
  166. package/skills/weaver-e10-meeting/references/meeting-eb.md +503 -27
  167. package/skills/weaver-e10-meeting/references/meeting-invitation.md +113 -0
  168. package/skills/weaver-e10-meeting/references/meeting-lifecycle.md +6 -6
  169. package/skills/weaver-e10-meeting/references/meeting-minute-file.md +425 -0
  170. package/skills/weaver-e10-meeting/references/meeting-queries.md +4 -4
  171. package/skills/weaver-e10-meeting/references/meeting-receipts-signs.md +15 -15
  172. package/skills/weaver-e10-meeting/references/meeting-verification.md +19 -11
  173. package/skills/weaver-e10-meeting.zip +0 -0
  174. package/skills/weaver-e10-yepiaotong/SKILL.md +9 -5
  175. package/skills/weaver-e10-yepiaotong/references/invoice-enterprise-list.md +1 -1
  176. package/skills/weaver-e10-yepiaotong/references/invoice-personal-list.md +6 -5
  177. package/skills/weaver-e10-yepiaotong/references/invoice-reim.md +14 -11
  178. package/skills/weaver-e10-yepiaotong/references/reim-api-reference.md +97 -56
  179. package/skills/weaver-e10-yepiaotong/references/reim-examples.md +84 -60
  180. package/skills/weaver-e10-yepiaotong/references/reim-form-fill-rules.md +142 -105
  181. package/skills/weaver-e10-yepiaotong/references/reim-matching-rules.md +53 -194
  182. package/skills/weaver-e10-yepiaotong/references/reim-phone-subsidy-rules.md +7 -7
  183. package/skills/weaver-e10-yepiaotong/references/reim-workflow.md +164 -72
  184. package/skills/weaver-e10-yepiaotong/references/source-manifest.json +6 -0
  185. package/templates/meeting/invitation.docx +0 -0
@@ -0,0 +1,427 @@
1
+ /**
2
+ * 零依赖 QR Code 编码器(字节模式 / 版本 1-40 / 纠错等级 L-M-Q-H / 8 种掩码)。
3
+ *
4
+ * 为什么自己写:CLI 是企业内网离线工具,`npm install -g` 走内部私服,多引一个第三方包
5
+ * (qrcode → pngjs/yargs/dijkstrajs …)就多一分装不上/装错版本的风险。二维码算法本身是
6
+ * 定死的有限状态机,自己实现把依赖成本降到 0。
7
+ *
8
+ * 编码链路(与 ISO/IEC 18004 一致,实现结构参考 nayuki qrcodegen 的公开算法):
9
+ * 文本 → UTF-8 字节 → 选版本(容纳 4bit 模式 + 计数字段 + 数据 + 终止符)
10
+ * → 数据码字 → Reed-Solomon 分块纠错 → 交织 → 功能图形(定位/定标/时序/格式/版本)
11
+ * → 之字形铺设 → 掩码 + 罚分择优 → 布尔矩阵
12
+ *
13
+ * 只做字节模式:中文/URL/JSON 走 UTF-8 字节,容量与通用扫码器完全兼容。
14
+ * 不做:汉字模式(GB2312 编码)、ECI、结构化追加。
15
+ */
16
+ /** ECC_CODEWORDS_PER_BLOCK[ecc][version](索引 0 占位,版本 1-40)。 */
17
+ const ECC_CODEWORDS_PER_BLOCK = {
18
+ L: [-1, 7, 10, 15, 20, 26, 18, 20, 24, 30, 18, 20, 24, 26, 30, 22, 24, 28, 30, 28, 28, 28, 28, 30, 30, 26, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30],
19
+ M: [-1, 10, 16, 26, 18, 24, 16, 18, 22, 22, 26, 30, 22, 22, 24, 24, 28, 28, 26, 26, 26, 26, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28],
20
+ Q: [-1, 13, 22, 18, 26, 18, 24, 18, 22, 20, 24, 28, 26, 24, 20, 30, 24, 28, 28, 26, 30, 28, 30, 30, 30, 30, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30],
21
+ H: [-1, 17, 28, 22, 16, 22, 28, 26, 26, 24, 28, 24, 28, 22, 24, 24, 30, 28, 28, 26, 28, 30, 24, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30],
22
+ };
23
+ /** NUM_ECC_BLOCKS[ecc][version](索引 0 占位,版本 1-40)。 */
24
+ const NUM_ECC_BLOCKS = {
25
+ L: [-1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 4, 4, 4, 4, 4, 6, 6, 6, 6, 7, 8, 8, 9, 9, 10, 12, 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 24, 25],
26
+ M: [-1, 1, 1, 1, 2, 2, 4, 4, 4, 5, 5, 5, 8, 9, 9, 10, 10, 11, 13, 14, 16, 17, 17, 18, 20, 21, 23, 25, 26, 28, 29, 31, 33, 35, 37, 38, 40, 43, 45, 47, 49],
27
+ Q: [-1, 1, 1, 2, 2, 4, 4, 6, 6, 8, 8, 8, 10, 12, 16, 12, 17, 16, 18, 21, 20, 23, 23, 25, 27, 29, 34, 34, 35, 38, 40, 43, 45, 48, 51, 53, 56, 59, 62, 65, 68],
28
+ H: [-1, 1, 1, 2, 4, 4, 4, 5, 6, 8, 8, 11, 11, 16, 16, 18, 16, 19, 21, 25, 25, 25, 34, 30, 32, 35, 37, 40, 42, 45, 48, 51, 54, 57, 60, 63, 66, 70, 74, 77, 81],
29
+ };
30
+ /** 格式信息里纠错等级的编码。 */
31
+ const ECC_FORMAT_BITS = { L: 1, M: 0, Q: 3, H: 2 };
32
+ const MIN_VERSION = 1;
33
+ const MAX_VERSION = 40;
34
+ function getBit(value, index) {
35
+ return ((value >>> index) & 1) !== 0;
36
+ }
37
+ /** 某个版本的原始数据模块数(比特);减去功能图形与格式/版本信息占位。 */
38
+ function getNumRawDataModules(version) {
39
+ let result = (16 * version + 128) * version + 64;
40
+ if (version >= 2) {
41
+ const numAlign = Math.floor(version / 7) + 2;
42
+ result -= (25 * numAlign - 10) * numAlign - 55;
43
+ if (version >= 7)
44
+ result -= 36;
45
+ }
46
+ return result;
47
+ }
48
+ function getNumDataCodewords(version, ecc) {
49
+ return Math.floor(getNumRawDataModules(version) / 8) - ECC_CODEWORDS_PER_BLOCK[ecc][version] * NUM_ECC_BLOCKS[ecc][version];
50
+ }
51
+ /** 字节模式的字符计数位数:版本 1-9 为 8 位,10-40 为 16 位。 */
52
+ function getCharCountBits(version) {
53
+ return version <= 9 ? 8 : 16;
54
+ }
55
+ /** GF(2^8) 乘法,本原多项式 0x11D。 */
56
+ function gfMultiply(x, y) {
57
+ let z = 0;
58
+ for (let i = 7; i >= 0; i--) {
59
+ z = (z << 1) ^ ((z >>> 7) * 0x11d);
60
+ z ^= ((y >>> i) & 1) * x;
61
+ }
62
+ return z & 0xff;
63
+ }
64
+ /** 生成多项式 ∏(x - α^i),系数按高次到低次(不含首项 1)。 */
65
+ function rsGeneratorPoly(degree) {
66
+ const result = new Array(degree).fill(0);
67
+ result[degree - 1] = 1;
68
+ let root = 1;
69
+ for (let i = 0; i < degree; i++) {
70
+ for (let j = 0; j < degree; j++) {
71
+ result[j] = gfMultiply(result[j], root);
72
+ if (j + 1 < degree)
73
+ result[j] ^= result[j + 1];
74
+ }
75
+ root = gfMultiply(root, 0x02);
76
+ }
77
+ return result;
78
+ }
79
+ /** 计算一段数据码字的纠错码字(多项式除法取余)。 */
80
+ function rsComputeRemainder(data, degree) {
81
+ const generator = rsGeneratorPoly(degree);
82
+ const remainder = new Array(degree).fill(0);
83
+ for (const byte of data) {
84
+ const factor = byte ^ remainder.shift();
85
+ remainder.push(0);
86
+ for (let i = 0; i < degree; i++) {
87
+ remainder[i] ^= gfMultiply(generator[i], factor);
88
+ }
89
+ }
90
+ return remainder;
91
+ }
92
+ function getAlignmentPatternPositions(version) {
93
+ if (version === 1)
94
+ return [];
95
+ const size = version * 4 + 17;
96
+ const numAlign = Math.floor(version / 7) + 2;
97
+ const step = Math.floor((version * 8 + numAlign * 3 + 5) / (numAlign * 4 - 4)) * 2;
98
+ const result = [6];
99
+ for (let pos = size - 7; result.length < numAlign; pos -= step) {
100
+ result.splice(1, 0, pos);
101
+ }
102
+ return result;
103
+ }
104
+ function maskPredicate(mask, x, y) {
105
+ switch (mask) {
106
+ case 0: return (x + y) % 2 === 0;
107
+ case 1: return y % 2 === 0;
108
+ case 2: return x % 3 === 0;
109
+ case 3: return (x + y) % 3 === 0;
110
+ case 4: return (Math.floor(x / 3) + Math.floor(y / 2)) % 2 === 0;
111
+ case 5: return ((x * y) % 2) + ((x * y) % 3) === 0;
112
+ case 6: return (((x * y) % 2) + ((x * y) % 3)) % 2 === 0;
113
+ case 7: return (((x + y) % 2) + ((x * y) % 3)) % 2 === 0;
114
+ default: throw new Error(`invalid mask: ${mask}`);
115
+ }
116
+ }
117
+ /** 掩码罚分(N1 连串/N2 色块/N3 类定位图形/N4 深浅比)。 */
118
+ function getPenaltyScore(modules, size) {
119
+ let result = 0;
120
+ const dark = (x, y) => modules[y][x];
121
+ // N1:横向/纵向连续同色 >= 5
122
+ for (let y = 0; y < size; y++) {
123
+ let runColor = dark(0, y);
124
+ let runLength = 1;
125
+ for (let x = 1; x < size; x++) {
126
+ if (dark(x, y) === runColor) {
127
+ runLength++;
128
+ }
129
+ else {
130
+ if (runLength >= 5)
131
+ result += 3 + (runLength - 5);
132
+ runColor = dark(x, y);
133
+ runLength = 1;
134
+ }
135
+ }
136
+ if (runLength >= 5)
137
+ result += 3 + (runLength - 5);
138
+ }
139
+ for (let x = 0; x < size; x++) {
140
+ let runColor = dark(x, 0);
141
+ let runLength = 1;
142
+ for (let y = 1; y < size; y++) {
143
+ if (dark(x, y) === runColor) {
144
+ runLength++;
145
+ }
146
+ else {
147
+ if (runLength >= 5)
148
+ result += 3 + (runLength - 5);
149
+ runColor = dark(x, y);
150
+ runLength = 1;
151
+ }
152
+ }
153
+ if (runLength >= 5)
154
+ result += 3 + (runLength - 5);
155
+ }
156
+ // N2:2x2 同色块
157
+ for (let y = 0; y < size - 1; y++) {
158
+ for (let x = 0; x < size - 1; x++) {
159
+ const color = dark(x, y);
160
+ if (color === dark(x + 1, y) && color === dark(x, y + 1) && color === dark(x + 1, y + 1)) {
161
+ result += 3;
162
+ }
163
+ }
164
+ }
165
+ // N3:1:1:3:1:1 且一侧有 4 个浅色的类定位图形(越界一律当浅色,避免 start-4 越界)
166
+ const safeDark = (x, y) => (x < 0 || y < 0 || x >= size || y >= size ? false : modules[y][x]);
167
+ const finderLike = (get, start) => {
168
+ const pattern = [true, false, true, true, true, false, true];
169
+ for (let i = 0; i < 7; i++) {
170
+ if (get(start + i) !== pattern[i])
171
+ return false;
172
+ }
173
+ let before = true;
174
+ for (let i = 1; i <= 4; i++)
175
+ if (get(start - i) !== false)
176
+ before = false;
177
+ let after = true;
178
+ for (let i = 7; i < 11; i++)
179
+ if (get(start + i) !== false)
180
+ after = false;
181
+ return before || after;
182
+ };
183
+ for (let y = 0; y < size; y++) {
184
+ for (let x = 0; x + 10 < size; x++) {
185
+ if (finderLike((i) => safeDark(i, y), x))
186
+ result += 40;
187
+ }
188
+ }
189
+ for (let x = 0; x < size; x++) {
190
+ for (let y = 0; y + 10 < size; y++) {
191
+ if (finderLike((i) => safeDark(x, i), y))
192
+ result += 40;
193
+ }
194
+ }
195
+ // N4:深色比例偏离 50%
196
+ let darkCount = 0;
197
+ for (let y = 0; y < size; y++) {
198
+ for (let x = 0; x < size; x++)
199
+ if (dark(x, y))
200
+ darkCount++;
201
+ }
202
+ const total = size * size;
203
+ const k = Math.ceil(Math.abs(darkCount * 20 - total * 10) / total) - 1;
204
+ result += Math.max(0, k) * 10;
205
+ return result;
206
+ }
207
+ function buildFunctionPatterns(version) {
208
+ const size = version * 4 + 17;
209
+ const modules = Array.from({ length: size }, () => new Array(size).fill(false));
210
+ const isFunction = Array.from({ length: size }, () => new Array(size).fill(false));
211
+ const setFunction = (x, y, isDark) => {
212
+ if (x < 0 || y < 0 || x >= size || y >= size)
213
+ return;
214
+ modules[y][x] = isDark;
215
+ isFunction[y][x] = true;
216
+ };
217
+ // 时序图形
218
+ for (let i = 0; i < size; i++) {
219
+ setFunction(6, i, i % 2 === 0);
220
+ setFunction(i, 6, i % 2 === 0);
221
+ }
222
+ // 三个定位图形(含分隔符)
223
+ const drawFinder = (cx, cy) => {
224
+ for (let dy = -4; dy <= 4; dy++) {
225
+ for (let dx = -4; dx <= 4; dx++) {
226
+ const dist = Math.max(Math.abs(dx), Math.abs(dy));
227
+ setFunction(cx + dx, cy + dy, dist !== 2 && dist !== 4);
228
+ }
229
+ }
230
+ };
231
+ drawFinder(3, 3);
232
+ drawFinder(size - 4, 3);
233
+ drawFinder(3, size - 4);
234
+ // 定标图形
235
+ const alignPositions = getAlignmentPatternPositions(version);
236
+ const numAlign = alignPositions.length;
237
+ for (let i = 0; i < numAlign; i++) {
238
+ for (let j = 0; j < numAlign; j++) {
239
+ const isCorner = (i === 0 && j === 0) || (i === 0 && j === numAlign - 1) || (i === numAlign - 1 && j === 0);
240
+ if (isCorner)
241
+ continue;
242
+ const cx = alignPositions[i];
243
+ const cy = alignPositions[j];
244
+ for (let dy = -2; dy <= 2; dy++) {
245
+ for (let dx = -2; dx <= 2; dx++) {
246
+ setFunction(cx + dx, cy + dy, Math.max(Math.abs(dx), Math.abs(dy)) !== 1);
247
+ }
248
+ }
249
+ }
250
+ }
251
+ // 先用掩码 0 写一份占位格式信息(真正格式信息在掩码确定后重写)
252
+ drawFormatBits(modules, isFunction, size, version, 'L', 0);
253
+ // 版本信息(版本 >= 7)
254
+ if (version >= 7) {
255
+ let rem = version;
256
+ for (let i = 0; i < 12; i++)
257
+ rem = (rem << 1) ^ ((rem >>> 11) * 0x1f25);
258
+ const bits = (version << 12) | rem;
259
+ for (let i = 0; i < 18; i++) {
260
+ const bit = getBit(bits, i);
261
+ const a = size - 11 + (i % 3);
262
+ const b = Math.floor(i / 3);
263
+ setFunction(a, b, bit);
264
+ setFunction(b, a, bit);
265
+ }
266
+ }
267
+ return { size, modules, isFunction };
268
+ }
269
+ function drawFormatBits(modules, isFunction, size, version, ecc, mask) {
270
+ void version;
271
+ const data = (ECC_FORMAT_BITS[ecc] << 3) | mask;
272
+ let rem = data;
273
+ for (let i = 0; i < 10; i++)
274
+ rem = (rem << 1) ^ ((rem >>> 9) * 0x537);
275
+ const bits = ((data << 10) | rem) ^ 0x5412;
276
+ const setFunction = (x, y, isDark) => {
277
+ modules[y][x] = isDark;
278
+ isFunction[y][x] = true;
279
+ };
280
+ // 左上角副本
281
+ for (let i = 0; i <= 5; i++)
282
+ setFunction(8, i, getBit(bits, i));
283
+ setFunction(8, 7, getBit(bits, 6));
284
+ setFunction(8, 8, getBit(bits, 7));
285
+ setFunction(7, 8, getBit(bits, 8));
286
+ for (let i = 9; i < 15; i++)
287
+ setFunction(14 - i, 8, getBit(bits, i));
288
+ // 右上 + 左下副本
289
+ for (let i = 0; i < 8; i++)
290
+ setFunction(size - 1 - i, 8, getBit(bits, i));
291
+ for (let i = 8; i < 15; i++)
292
+ setFunction(8, size - 15 + i, getBit(bits, i));
293
+ // 固定深色模块
294
+ setFunction(8, size - 8, true);
295
+ }
296
+ function drawCodewords(matrix, codewords) {
297
+ const { size, modules, isFunction } = matrix;
298
+ let index = 0;
299
+ for (let right = size - 1; right >= 1; right -= 2) {
300
+ if (right === 6)
301
+ right = 5;
302
+ for (let vert = 0; vert < size; vert++) {
303
+ for (let j = 0; j < 2; j++) {
304
+ const x = right - j;
305
+ const upward = ((right + 1) & 2) === 0;
306
+ const y = upward ? size - 1 - vert : vert;
307
+ if (!isFunction[y][x] && index < codewords.length * 8) {
308
+ modules[y][x] = getBit(codewords[index >>> 3], 7 - (index & 7));
309
+ index++;
310
+ }
311
+ }
312
+ }
313
+ }
314
+ }
315
+ function applyMask(matrix, mask) {
316
+ const { size, modules, isFunction } = matrix;
317
+ for (let y = 0; y < size; y++) {
318
+ for (let x = 0; x < size; x++) {
319
+ if (isFunction[y][x])
320
+ continue;
321
+ if (maskPredicate(mask, x, y))
322
+ modules[y][x] = !modules[y][x];
323
+ }
324
+ }
325
+ }
326
+ function buildCodewords(bytes, version, ecc) {
327
+ const capacityBits = getNumDataCodewords(version, ecc) * 8;
328
+ const bits = [];
329
+ const appendBits = (value, length) => {
330
+ for (let i = length - 1; i >= 0; i--)
331
+ bits.push((value >>> i) & 1);
332
+ };
333
+ appendBits(0b0100, 4);
334
+ appendBits(bytes.length, getCharCountBits(version));
335
+ for (const byte of bytes)
336
+ appendBits(byte, 8);
337
+ appendBits(0, Math.min(4, capacityBits - bits.length));
338
+ appendBits(0, (8 - (bits.length % 8)) % 8);
339
+ for (let pad = 0xec; bits.length < capacityBits; pad ^= 0xec ^ 0x11)
340
+ appendBits(pad, 8);
341
+ const dataCodewords = new Array(bits.length / 8).fill(0);
342
+ bits.forEach((bit, i) => {
343
+ dataCodewords[i >>> 3] |= bit << (7 - (i & 7));
344
+ });
345
+ const numBlocks = NUM_ECC_BLOCKS[ecc][version];
346
+ const blockEccLen = ECC_CODEWORDS_PER_BLOCK[ecc][version];
347
+ const rawCodewords = Math.floor(getNumRawDataModules(version) / 8);
348
+ const numShortBlocks = numBlocks - (rawCodewords % numBlocks);
349
+ const shortBlockLen = Math.floor(rawCodewords / numBlocks);
350
+ const blocks = [];
351
+ let offset = 0;
352
+ for (let i = 0; i < numBlocks; i++) {
353
+ const dataLen = shortBlockLen - blockEccLen + (i < numShortBlocks ? 0 : 1);
354
+ const data = dataCodewords.slice(offset, offset + dataLen);
355
+ offset += dataLen;
356
+ const block = data.slice();
357
+ const remainder = rsComputeRemainder(data, blockEccLen);
358
+ // 短块补一个占位 0(夹在数据与纠错码字之间),交织时跳过,保证各块等长
359
+ if (i < numShortBlocks)
360
+ block.push(0);
361
+ block.push(...remainder);
362
+ blocks.push(block);
363
+ }
364
+ const result = [];
365
+ for (let i = 0; i < blocks[0].length; i++) {
366
+ for (let j = 0; j < blocks.length; j++) {
367
+ if (i !== shortBlockLen - blockEccLen || j >= numShortBlocks) {
368
+ result.push(blocks[j][i]);
369
+ }
370
+ }
371
+ }
372
+ return result;
373
+ }
374
+ /** 把文本编码成二维码布尔矩阵。 */
375
+ export function encodeQrText(text, options = {}) {
376
+ if (typeof text !== 'string' || text.length === 0) {
377
+ throw new Error('text_required: 二维码内容不能为空');
378
+ }
379
+ if (text.length > 4000) {
380
+ throw new Error('text_too_long: 二维码内容超长(单码上限约 2953 字节,UTF-8 中文约 980 字)');
381
+ }
382
+ const ecc = options.ecc ?? 'M';
383
+ if (!['L', 'M', 'Q', 'H'].includes(ecc)) {
384
+ throw new Error(`ecc_invalid: 纠错等级只能是 L/M/Q/H,收到 ${String(options.ecc)}`);
385
+ }
386
+ const bytes = Array.from(Buffer.from(text, 'utf8'));
387
+ const minVersion = Math.max(MIN_VERSION, options.minVersion ?? MIN_VERSION);
388
+ const maxVersion = Math.min(MAX_VERSION, options.maxVersion ?? MAX_VERSION);
389
+ let version = -1;
390
+ for (let v = minVersion; v <= maxVersion; v++) {
391
+ const capacityBits = getNumDataCodewords(v, ecc) * 8;
392
+ const neededBits = 4 + getCharCountBits(v) + bytes.length * 8;
393
+ if (neededBits <= capacityBits) {
394
+ version = v;
395
+ break;
396
+ }
397
+ }
398
+ if (version < 0) {
399
+ throw new Error(`capacity_exceeded: ${bytes.length} 字节超出 ECM=${ecc} 的最大容量(版本 ${maxVersion})`);
400
+ }
401
+ const codewords = buildCodewords(bytes, version, ecc);
402
+ const candidateMasks = options.mask === undefined
403
+ ? [0, 1, 2, 3, 4, 5, 6, 7]
404
+ : [options.mask];
405
+ if (options.mask !== undefined && (options.mask < 0 || options.mask > 7)) {
406
+ throw new Error(`mask_invalid: 掩码只能是 0-7,收到 ${String(options.mask)}`);
407
+ }
408
+ let best = null;
409
+ for (const mask of candidateMasks) {
410
+ const matrix = buildFunctionPatterns(version);
411
+ drawCodewords(matrix, codewords);
412
+ applyMask(matrix, mask);
413
+ drawFormatBits(matrix.modules, matrix.isFunction, matrix.size, version, ecc, mask);
414
+ const score = getPenaltyScore(matrix.modules, matrix.size);
415
+ if (!best || score < best.score) {
416
+ best = { mask, modules: matrix.modules, score };
417
+ }
418
+ }
419
+ return {
420
+ size: version * 4 + 17,
421
+ version,
422
+ ecc,
423
+ mask: best.mask,
424
+ modules: best.modules,
425
+ byteLength: bytes.length,
426
+ };
427
+ }
@@ -0,0 +1,103 @@
1
+ /**
2
+ * 二维码矩阵 → 图片渲染(PNG / SVG),零依赖。
3
+ *
4
+ * PNG 用最小实现:8bit 灰度、filter 0、zlib deflate(node:zlib 内置)。
5
+ * 不出彩色/带 Logo 版本——扫码器对高对比度纯黑白最稳,参会码要能被门禁读头秒读。
6
+ */
7
+ import { deflateSync } from 'node:zlib';
8
+ const CRC_TABLE = (() => {
9
+ const table = new Uint32Array(256);
10
+ for (let n = 0; n < 256; n++) {
11
+ let c = n;
12
+ for (let k = 0; k < 8; k++) {
13
+ c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;
14
+ }
15
+ table[n] = c >>> 0;
16
+ }
17
+ return table;
18
+ })();
19
+ function crc32(buffer) {
20
+ let crc = 0xffffffff;
21
+ for (const byte of buffer) {
22
+ crc = CRC_TABLE[(crc ^ byte) & 0xff] ^ (crc >>> 8);
23
+ }
24
+ return (crc ^ 0xffffffff) >>> 0;
25
+ }
26
+ function chunk(type, data) {
27
+ const typeBytes = Buffer.from(type, 'ascii');
28
+ const length = Buffer.alloc(4);
29
+ length.writeUInt32BE(data.length, 0);
30
+ const body = Buffer.concat([typeBytes, Buffer.from(data)]);
31
+ const crc = Buffer.alloc(4);
32
+ crc.writeUInt32BE(crc32(body), 0);
33
+ return Buffer.concat([length, body, crc]);
34
+ }
35
+ /** 把矩阵渲染成 PNG(8bit 灰度,深色=0,浅色=255)。 */
36
+ export function renderQrPng(matrix, options = {}) {
37
+ const scale = Math.max(1, Math.floor(options.scale ?? 8));
38
+ const margin = Math.max(0, Math.floor(options.margin ?? 4));
39
+ const modulesPerSide = matrix.size + margin * 2;
40
+ const pixelSize = modulesPerSide * scale;
41
+ const rowBytes = pixelSize;
42
+ const raw = Buffer.alloc((rowBytes + 1) * pixelSize);
43
+ let cursor = 0;
44
+ for (let py = 0; py < pixelSize; py++) {
45
+ raw[cursor++] = 0; // filter type: none
46
+ const my = Math.floor(py / scale) - margin;
47
+ for (let px = 0; px < pixelSize; px++) {
48
+ const mx = Math.floor(px / scale) - margin;
49
+ const isDark = my >= 0 && mx >= 0 && my < matrix.size && mx < matrix.size
50
+ ? matrix.modules[my][mx]
51
+ : false;
52
+ raw[cursor++] = isDark ? 0 : 255;
53
+ }
54
+ }
55
+ const signature = Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]);
56
+ const ihdr = Buffer.alloc(13);
57
+ ihdr.writeUInt32BE(pixelSize, 0);
58
+ ihdr.writeUInt32BE(pixelSize, 4);
59
+ ihdr[8] = 8; // bit depth
60
+ ihdr[9] = 0; // color type: grayscale
61
+ ihdr[10] = 0; // compression
62
+ ihdr[11] = 0; // filter
63
+ ihdr[12] = 0; // interlace
64
+ return Buffer.concat([
65
+ signature,
66
+ chunk('IHDR', ihdr),
67
+ chunk('IDAT', deflateSync(raw, { level: 9 })),
68
+ chunk('IEND', new Uint8Array(0)),
69
+ ]);
70
+ }
71
+ /** 把矩阵渲染成 SVG(矢量,便于印刷/嵌入文档)。 */
72
+ export function renderQrSvg(matrix, options = {}) {
73
+ const scale = Math.max(1, Math.floor(options.scale ?? 8));
74
+ const margin = Math.max(0, Math.floor(options.margin ?? 4));
75
+ const modulesPerSide = matrix.size + margin * 2;
76
+ const pixelSize = modulesPerSide * scale;
77
+ const rects = [];
78
+ for (let y = 0; y < matrix.size; y++) {
79
+ let x = 0;
80
+ while (x < matrix.size) {
81
+ if (!matrix.modules[y][x]) {
82
+ x++;
83
+ continue;
84
+ }
85
+ let runEnd = x;
86
+ while (runEnd < matrix.size && matrix.modules[y][runEnd])
87
+ runEnd++;
88
+ const width = (runEnd - x) * scale;
89
+ rects.push(`<rect x="${(x + margin) * scale}" y="${(y + margin) * scale}" width="${width}" height="${scale}"/>`);
90
+ x = runEnd;
91
+ }
92
+ }
93
+ return [
94
+ `<?xml version="1.0" encoding="UTF-8"?>`,
95
+ `<svg xmlns="http://www.w3.org/2000/svg" width="${pixelSize}" height="${pixelSize}" viewBox="0 0 ${pixelSize} ${pixelSize}" shape-rendering="crispEdges">`,
96
+ `<rect width="100%" height="100%" fill="#ffffff"/>`,
97
+ `<g fill="#000000">`,
98
+ ...rects,
99
+ `</g>`,
100
+ `</svg>`,
101
+ '',
102
+ ].join('\n');
103
+ }
@@ -1640,8 +1640,14 @@ function extractWorkflowMemorySection(promptText, workflowId) {
1640
1640
  * best-effort:读不到(没开通记忆 / 404 / 接口故障)一律返回空串 —— 对模型而言
1641
1641
  * 「没有记忆」和「读取失败」的处理完全一样(按新用户处理、不要重试),不需要再分档。
1642
1642
  * 绝不阻断表单载入(与 `workflow.memoryPrompt` 同口径)。
1643
+ *
1644
+ * ★ 2026-10-28 用户裁定:**小e 环境不读记忆** —— 这一档的调用方(`createRequestDirect`)不再下发提示词
1645
+ * 属性,`createForm` 侧同样不消费,所以这条请求纯属白花一趟(小e 真机 200–400 ms)。返回空串 ⇒
1646
+ * 两个命令都不会出现 `workflowMemory` / `userMemory`。非小e 行为不变。
1643
1647
  */
1644
1648
  async function fetchWorkflowMemory(workflowId, env) {
1649
+ if (hasXiaoEEnv(env.ctx.env, env.ctx.getGlobalOptions?.()))
1650
+ return '';
1645
1651
  try {
1646
1652
  const response = await env.host.workflowRequest({
1647
1653
  method: 'POST',
@@ -5542,11 +5548,13 @@ function summarizeApiSpans(spans) {
5542
5548
  * 这条命令的 `risk` 因此从 `high-risk-write` 降为 `read`。
5543
5549
  * 3. **只返回填参原料**:`fields`(含 `initialValue`)、`historyRequestData`、`userMemory`
5544
5550
  * (=该工作流的记忆 `workflowMemory`),外加 `status` / `workflow` 两个元信息。
5551
+ * **小e 档不返回 `userMemory`**(2026-10-28 用户裁定):这一档不读记忆(见 `fetchWorkflowMemory`),
5552
+ * 提示词属性也没有下游,所以整个键都不出现(不是空串)。
5545
5553
  * 4. **不返回系统字段**:`systemFields` / `systemFieldWarning` 整块不出现(标题/紧急程度/密级的默认值
5546
5554
  * 与选项清单都不给)。
5547
5555
  * 5. **输出降级**(按 20,000 **字符**,与 `createForm` 同一个宿主口径):
5548
- * 全量超线 ⇒ `historyRequestData` 留空数组(键还在);仍超 ⇒ `userMemory` 留空串(键还在);
5549
- * **`fields` 自己也超线时不再裁**(宁大不丢)—— 它是唯一不可省的,砍了这条命令就没有意义。
5556
+ * 全量超线 ⇒ `historyRequestData` 留空数组(键还在);仍超 ⇒ `userMemory` 留空串(键还在;小e 档没有
5557
+ * 这个键,不补);**`fields` 自己也超线时不再裁**(宁大不丢)—— 它是唯一不可省的,砍了这条命令就没有意义。
5550
5558
  *
5551
5559
  * ## 耗时
5552
5560
  * 与 `createForm` 完全同口径,全部收在 `timing` 一个桶里:`durationMs`(整条命令)/
@@ -5573,12 +5581,15 @@ async function commandCreateRequestDirect(args, env) {
5573
5581
  // 句柄类(contextId/requestId/requestName)、`form`、`continuation`、`requiredInfoWarning` 全部不出
5574
5582
  // —— 本命令不发起,这些字段没有下游(2026-10-22 用户裁定)。`contextId` 仍在上面的守卫里用于
5575
5583
  // 判断"表单到底载入成功没有",只是不再交出去。
5584
+ //
5585
+ // 小e 档不返回 `userMemory`(2026-10-28 用户裁定):这一档本来就不读记忆,提示词属性没有下游。
5586
+ const isXiaoE = hasXiaoEEnv(env.ctx.env, env.ctx.getGlobalOptions?.());
5576
5587
  const data = {
5577
5588
  status: payload.status,
5578
5589
  workflow: payload.workflow,
5579
5590
  fields: payload.fields,
5580
5591
  historyRequestData: payload.historyRequestData,
5581
- userMemory: String(payload.workflowMemory ?? ''),
5592
+ ...(isXiaoE ? {} : { userMemory: String(payload.workflowMemory ?? '') }),
5582
5593
  };
5583
5594
  // 判线必须把「稍后才求得出」的耗时键先按位数占住(与 `createForm` 同一个哨兵口径,宁可高估),
5584
5595
  // 否则边界上的表单会被判成"没超"、然后在宿主那儿被真截断。
@@ -5592,9 +5603,10 @@ async function commandCreateRequestDirect(args, env) {
5592
5603
  };
5593
5604
  const overLine = () => finalStdoutChars({ ...data, ...reserve }, 'workflow.createRequestDirect') > CREATE_FORM_STDOUT_SAFE_CHARS;
5594
5605
  // 两级降级:先砍历史(留空 key)→ 再砍记忆(留空 key)。`fields` 不参与裁剪。
5606
+ // 小e 档没有 `userMemory` 这个键,第二级跳过(不能借"写空串"把它重新加回来)。
5595
5607
  if (overLine()) {
5596
5608
  data.historyRequestData = [];
5597
- if (overLine())
5609
+ if ('userMemory' in data && overLine())
5598
5610
  data.userMemory = '';
5599
5611
  }
5600
5612
  return workflowSuccess('workflow.createRequestDirect', {
@@ -6703,7 +6715,7 @@ const workflowCreateRequestDirect = {
6703
6715
  resource: 'workflow',
6704
6716
  method: 'createRequestDirect',
6705
6717
  action: 'workflow.createRequestDirect',
6706
- summary: '取数(不发起、不调智能体、不写库):载入发起表单后直接返回 fields(含 initialValue)、historyRequestData、userMemory,供你拼好 data 后再调 createRequest。不返回系统字段(标题/紧急程度/密级的默认值与选项),也不返回句柄、form、continuation。输出超过 2 万字符时依次降级:先让 historyRequestData 变成空数组,仍超再让 userMemory 变成空串(键都保留)。耗时全部收在 timing 一个键里:{durationMs, apiDurations, apiSlowest, authMs}',
6718
+ summary: '取数(不发起、不调智能体、不写库):载入发起表单后直接返回 fields(含 initialValue)、historyRequestData、userMemory,供你拼好 data 后再调 createRequest(小e 环境不读记忆,也不返回 userMemory)。不返回系统字段(标题/紧急程度/密级的默认值与选项),也不返回句柄、form、continuation。输出超过 2 万字符时依次降级:先让 historyRequestData 变成空数组,仍超再让 userMemory 变成空串(键都保留)。耗时全部收在 timing 一个键里:{durationMs, apiDurations, apiSlowest, authMs}',
6707
6719
  capability: 'read',
6708
6720
  risk: 'read',
6709
6721
  requiresConfirmation: false,