weaver-work-cli 0.1.23 → 0.1.25

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 (358) hide show
  1. package/README.md +33 -3
  2. package/dist/core/output.js +53 -1
  3. package/dist/internal/e10/auth/commands.js +210 -17
  4. package/dist/internal/e10/auth/crypto.js +52 -12
  5. package/dist/internal/e10/auth/xiaoe.js +117 -35
  6. package/dist/internal/e10/context.js +3 -3
  7. package/dist/internal/e10/request-runtime.js +46 -4
  8. package/dist/shortcuts/caizhilian/file-upload/metadata.js +124 -0
  9. package/dist/shortcuts/caizhilian/file-upload/multipart.js +47 -0
  10. package/dist/shortcuts/caizhilian/file-upload/protocol.js +116 -0
  11. package/dist/shortcuts/caizhilian/file-upload/receipt.js +37 -0
  12. package/dist/shortcuts/caizhilian/host.js +13 -5
  13. package/dist/shortcuts/caizhilian/operations/handlers/file-upload.js +72 -179
  14. package/dist/shortcuts/caizhilian/operations/handlers/fileops.js +67 -1
  15. package/dist/shortcuts/caizhilian/operations/handlers/folder.js +701 -4
  16. package/dist/shortcuts/caizhilian/operations/handlers/setting-attach.js +198 -0
  17. package/dist/shortcuts/caizhilian/operations/registry.js +5 -1
  18. package/dist/shortcuts/caizhilian/operations/shared.js +32 -0
  19. package/dist/shortcuts/caizhilian/operations/specs.js +67 -0
  20. package/dist/shortcuts/workflow/continuation.js +14 -9
  21. package/dist/shortcuts/workflow/endpoints.js +11 -1
  22. package/dist/shortcuts/workflow/index.js +55 -1
  23. package/dist/shortcuts/workflow/operations/flow-status.js +63 -0
  24. package/dist/shortcuts/workflow/operations/form.js +1822 -547
  25. package/dist/shortcuts/workflow/operations/read.js +414 -13
  26. package/dist/shortcuts/workflow/operations/shared.js +28 -0
  27. package/dist/shortcuts/workflow/operations/write.js +5 -5
  28. package/dist/shortcuts/workflow/operations.js +8 -6
  29. package/dist/shortcuts/workflow/stdout-compact.js +33 -0
  30. package/docs/caizhilian.md +12 -5
  31. package/docs/e10-auth.md +25 -3
  32. package/node_modules/@napi-rs/keyring/LICENSE +21 -0
  33. package/node_modules/@napi-rs/keyring/README.md +19 -0
  34. package/node_modules/@napi-rs/keyring/index.d.ts +166 -0
  35. package/node_modules/@napi-rs/keyring/index.js +514 -0
  36. package/node_modules/@napi-rs/keyring/keytar.d.ts +53 -0
  37. package/node_modules/@napi-rs/keyring/keytar.js +26 -0
  38. package/node_modules/@napi-rs/keyring/package.json +125 -0
  39. package/node_modules/@napi-rs/keyring-darwin-arm64/README.md +3 -0
  40. package/node_modules/@napi-rs/keyring-darwin-arm64/keyring.darwin-arm64.node +0 -0
  41. package/node_modules/@napi-rs/keyring-darwin-arm64/package.json +32 -0
  42. package/node_modules/commander/LICENSE +22 -0
  43. package/node_modules/commander/Readme.md +1149 -0
  44. package/node_modules/commander/esm.mjs +16 -0
  45. package/node_modules/commander/index.js +24 -0
  46. package/node_modules/commander/lib/argument.js +149 -0
  47. package/node_modules/commander/lib/command.js +2662 -0
  48. package/node_modules/commander/lib/error.js +39 -0
  49. package/node_modules/commander/lib/help.js +709 -0
  50. package/node_modules/commander/lib/option.js +367 -0
  51. package/node_modules/commander/lib/suggestSimilar.js +101 -0
  52. package/node_modules/commander/package-support.json +16 -0
  53. package/node_modules/commander/package.json +82 -0
  54. package/node_modules/commander/typings/esm.d.mts +3 -0
  55. package/node_modules/commander/typings/index.d.ts +1045 -0
  56. package/package.json +5 -1
  57. package/skills/weaver-e10-builder/SKILL.md +281 -0
  58. package/skills/weaver-e10-builder/_catalog.md +94 -0
  59. package/skills/weaver-e10-builder/actionflows/CONTEXT.md +71 -0
  60. package/skills/weaver-e10-builder/actionflows/SKILL.md +176 -0
  61. package/skills/weaver-e10-builder/actionflows/docs/adr/0001-generated-actionflow-cleanup-identity.md +5 -0
  62. package/skills/weaver-e10-builder/actionflows/docs/adr/0002-preserve-existing-actionflow-on-update.md +36 -0
  63. package/skills/weaver-e10-builder/actionflows/references/components/calendar/MeetingCreate.md +19 -0
  64. package/skills/weaver-e10-builder/actionflows/references/components/calendar/ScheduleCreate.md +17 -0
  65. package/skills/weaver-e10-builder/actionflows/references/components/database/DMLExecute.md +38 -0
  66. package/skills/weaver-e10-builder/actionflows/references/components/document/AttachmentCopy.md +17 -0
  67. package/skills/weaver-e10-builder/actionflows/references/components/document/AttachmentMove.md +17 -0
  68. package/skills/weaver-e10-builder/actionflows/references/components/document/DocumentCopy.md +17 -0
  69. package/skills/weaver-e10-builder/actionflows/references/components/document/DocumentDelete.md +17 -0
  70. package/skills/weaver-e10-builder/actionflows/references/components/document/DocumentEdit.md +17 -0
  71. package/skills/weaver-e10-builder/actionflows/references/components/document/DocumentMove.md +17 -0
  72. package/skills/weaver-e10-builder/actionflows/references/components/document/DocumentPermissionChange.md +17 -0
  73. package/skills/weaver-e10-builder/actionflows/references/components/document/DocumentRenewal.md +17 -0
  74. package/skills/weaver-e10-builder/actionflows/references/components/document/DocumentRevert.md +17 -0
  75. package/skills/weaver-e10-builder/actionflows/references/components/document/DocumentSave.md +17 -0
  76. package/skills/weaver-e10-builder/actionflows/references/components/document/DocumentSubscription.md +17 -0
  77. package/skills/weaver-e10-builder/actionflows/references/components/document/DocumentSubscriptionApprove.md +17 -0
  78. package/skills/weaver-e10-builder/actionflows/references/components/document/DocumentSubscriptionSendBack.md +17 -0
  79. package/skills/weaver-e10-builder/actionflows/references/components/document/DocumentSubscriptionWithdraw.md +17 -0
  80. package/skills/weaver-e10-builder/actionflows/references/components/document/FileFolderSave.md +17 -0
  81. package/skills/weaver-e10-builder/actionflows/references/components/document/GetAttachmentInfo.md +17 -0
  82. package/skills/weaver-e10-builder/actionflows/references/components/document/GetDocumentInfo.md +17 -0
  83. package/skills/weaver-e10-builder/actionflows/references/components/document/ModifyDocumentStatus.md +17 -0
  84. package/skills/weaver-e10-builder/actionflows/references/components/document/ReplaceAttachment.md +17 -0
  85. package/skills/weaver-e10-builder/actionflows/references/components/document/UpdatePrintNum.md +17 -0
  86. package/skills/weaver-e10-builder/actionflows/references/components/ebuilder/ActionEbAdd.md +100 -0
  87. package/skills/weaver-e10-builder/actionflows/references/components/ebuilder/ActionEbDelete.md +23 -0
  88. package/skills/weaver-e10-builder/actionflows/references/components/ebuilder/ActionEbRecover.md +17 -0
  89. package/skills/weaver-e10-builder/actionflows/references/components/ebuilder/ActionEbSaveVersion.md +17 -0
  90. package/skills/weaver-e10-builder/actionflows/references/components/ebuilder/ActionEbUpdate.md +67 -0
  91. package/skills/weaver-e10-builder/actionflows/references/components/ebuilder/DateTrigger.md +32 -0
  92. package/skills/weaver-e10-builder/actionflows/references/components/ebuilder/EbGetDataById.md +17 -0
  93. package/skills/weaver-e10-builder/actionflows/references/components/ebuilder/EnquiryForm.md +107 -0
  94. package/skills/weaver-e10-builder/actionflows/references/components/ebuilder/EventButton.md +33 -0
  95. package/skills/weaver-e10-builder/actionflows/references/components/ebuilder/EventFormData.md +19 -0
  96. package/skills/weaver-e10-builder/actionflows/references/components/ebuilder/TimeBatchTrigger.md +19 -0
  97. package/skills/weaver-e10-builder/actionflows/references/components/http/Http.md +77 -0
  98. package/skills/weaver-e10-builder/actionflows/references/components/logic/Condition.md +23 -0
  99. package/skills/weaver-e10-builder/actionflows/references/components/logic/LogicFlowSet.md +17 -0
  100. package/skills/weaver-e10-builder/actionflows/references/components/logic/MultipleExecution.md +38 -0
  101. package/skills/weaver-e10-builder/actionflows/references/components/logic/Output.md +37 -0
  102. package/skills/weaver-e10-builder/actionflows/references/components/message/InnerMQSend.md +50 -0
  103. package/skills/weaver-e10-builder/actionflows/references/components/message/SendMessage.md +30 -0
  104. package/skills/weaver-e10-builder/actionflows/references/components/personnel/AlterPersonStatus.md +30 -0
  105. package/skills/weaver-e10-builder/actionflows/references/components/personnel/HrmEmployeeUpdate.md +34 -0
  106. package/skills/weaver-e10-builder/actionflows/references/components/personnel/PersonnelAlterType.md +38 -0
  107. package/skills/weaver-e10-builder/actionflows/references/components/personnel/PersonnelOnboarding.md +36 -0
  108. package/skills/weaver-e10-builder/actionflows/references/components/serverless/ServerlessAction.md +42 -0
  109. package/skills/weaver-e10-builder/actionflows/references/components/trigger/CustomTrigger.md +82 -0
  110. package/skills/weaver-e10-builder/actionflows/references/components/trigger/InnerMQListener.md +41 -0
  111. package/skills/weaver-e10-builder/actionflows/references/components/trigger/SimpleScheduler.md +19 -0
  112. package/skills/weaver-e10-builder/actionflows/references/components/trigger/WebHookTrigger.md +91 -0
  113. package/skills/weaver-e10-builder/actionflows/references/components/workflow/ApproveAddSign.md +17 -0
  114. package/skills/weaver-e10-builder/actionflows/references/components/workflow/ApproveAgreeRejectApply.md +17 -0
  115. package/skills/weaver-e10-builder/actionflows/references/components/workflow/ApproveCommit.md +17 -0
  116. package/skills/weaver-e10-builder/actionflows/references/components/workflow/ApproveConsulTurnTodo.md +17 -0
  117. package/skills/weaver-e10-builder/actionflows/references/components/workflow/ApproveCreate.md +17 -0
  118. package/skills/weaver-e10-builder/actionflows/references/components/workflow/ApproveDelete.md +19 -0
  119. package/skills/weaver-e10-builder/actionflows/references/components/workflow/ApproveDoCirculate.md +17 -0
  120. package/skills/weaver-e10-builder/actionflows/references/components/workflow/ApproveDoForward.md +17 -0
  121. package/skills/weaver-e10-builder/actionflows/references/components/workflow/ApproveDoTurnTodo.md +17 -0
  122. package/skills/weaver-e10-builder/actionflows/references/components/workflow/ApproveEntrust.md +19 -0
  123. package/skills/weaver-e10-builder/actionflows/references/components/workflow/ApproveIntervention.md +17 -0
  124. package/skills/weaver-e10-builder/actionflows/references/components/workflow/ApproveMandatoryArchiving.md +17 -0
  125. package/skills/weaver-e10-builder/actionflows/references/components/workflow/ApproveManualCC.md +17 -0
  126. package/skills/weaver-e10-builder/actionflows/references/components/workflow/ApproveRefuseRejectApply.md +17 -0
  127. package/skills/weaver-e10-builder/actionflows/references/components/workflow/ApproveRejectApply.md +17 -0
  128. package/skills/weaver-e10-builder/actionflows/references/components/workflow/ApproveSave.md +17 -0
  129. package/skills/weaver-e10-builder/actionflows/references/components/workflow/ApproveSendBack.md +17 -0
  130. package/skills/weaver-e10-builder/actionflows/references/components/workflow/ApproveShareEntry.md +17 -0
  131. package/skills/weaver-e10-builder/actionflows/references/components/workflow/ApproveTrigger.md +99 -0
  132. package/skills/weaver-e10-builder/actionflows/references/components/workflow/ApproveWithdraw.md +17 -0
  133. package/skills/weaver-e10-builder/actionflows/references/components/workflow/WorkFlowDocEmpowerment.md +17 -0
  134. package/skills/weaver-e10-builder/actionflows/references/components/workflow/WorkflowToDoc.md +17 -0
  135. package/skills/weaver-e10-builder/actionflows/references/condition_rules.md +100 -0
  136. package/skills/weaver-e10-builder/actionflows/references/dynamic_capability_matrix.md +39 -0
  137. package/skills/weaver-e10-builder/actionflows/references/dynamic_resources.md +41 -0
  138. package/skills/weaver-e10-builder/actionflows/references/examples/enquiry-form-batch-insert-scene2.json +1043 -0
  139. package/skills/weaver-e10-builder/actionflows/references/function_rules.md +15 -0
  140. package/skills/weaver-e10-builder/actionflows/references/trigger_runtime_notes.md +53 -0
  141. package/skills/weaver-e10-builder/assets/dom-structure/Bar.json +341 -0
  142. package/skills/weaver-e10-builder/assets/dom-structure/BarStack.json +341 -0
  143. package/skills/weaver-e10-builder/assets/dom-structure/Bubble.json +323 -0
  144. package/skills/weaver-e10-builder/assets/dom-structure/Calendar.json +515 -0
  145. package/skills/weaver-e10-builder/assets/dom-structure/Circular.json +337 -0
  146. package/skills/weaver-e10-builder/assets/dom-structure/CollapsePanel.json +289 -0
  147. package/skills/weaver-e10-builder/assets/dom-structure/Comment.json +617 -0
  148. package/skills/weaver-e10-builder/assets/dom-structure/CountDown.json +755 -0
  149. package/skills/weaver-e10-builder/assets/dom-structure/DigitalPanel.json +191 -0
  150. package/skills/weaver-e10-builder/assets/dom-structure/EbButton.json +387 -0
  151. package/skills/weaver-e10-builder/assets/dom-structure/FastCreate.json +242 -0
  152. package/skills/weaver-e10-builder/assets/dom-structure/Gauge.json +282 -0
  153. package/skills/weaver-e10-builder/assets/dom-structure/HBar.json +336 -0
  154. package/skills/weaver-e10-builder/assets/dom-structure/HBarStack.json +337 -0
  155. package/skills/weaver-e10-builder/assets/dom-structure/Line.json +341 -0
  156. package/skills/weaver-e10-builder/assets/dom-structure/NList.json +712 -0
  157. package/skills/weaver-e10-builder/assets/dom-structure/NavBar.json +274 -0
  158. package/skills/weaver-e10-builder/assets/dom-structure/NavPanel.json +390 -0
  159. package/skills/weaver-e10-builder/assets/dom-structure/NewTab.json +606 -0
  160. package/skills/weaver-e10-builder/assets/dom-structure/Nightingale.json +336 -0
  161. package/skills/weaver-e10-builder/assets/dom-structure/PageHeader.json +205 -0
  162. package/skills/weaver-e10-builder/assets/dom-structure/Picture.json +209 -0
  163. package/skills/weaver-e10-builder/assets/dom-structure/Pie.json +338 -0
  164. package/skills/weaver-e10-builder/assets/dom-structure/ProgressChart.json +299 -0
  165. package/skills/weaver-e10-builder/assets/dom-structure/SearchGlobal.json +628 -0
  166. package/skills/weaver-e10-builder/assets/dom-structure/Slide.json +489 -0
  167. package/skills/weaver-e10-builder/assets/dom-structure/Treemap.json +324 -0
  168. package/skills/weaver-e10-builder/assets/factory/chart-dimensions.json +536 -0
  169. package/skills/weaver-e10-builder/assets/factory/example-btn-progress-collapse-configured.json +2515 -0
  170. package/skills/weaver-e10-builder/assets/factory/example-configured-2.json +13805 -0
  171. package/skills/weaver-e10-builder/assets/factory/example-configured.json +6735 -0
  172. package/skills/weaver-e10-builder/assets/factory/factory-bar-stack.json +326 -0
  173. package/skills/weaver-e10-builder/assets/factory/factory-bar.json +222 -0
  174. package/skills/weaver-e10-builder/assets/factory/factory-bubble.json +322 -0
  175. package/skills/weaver-e10-builder/assets/factory/factory-calendar.json +325 -0
  176. package/skills/weaver-e10-builder/assets/factory/factory-circular.json +320 -0
  177. package/skills/weaver-e10-builder/assets/factory/factory-collapse-panel.json +132 -0
  178. package/skills/weaver-e10-builder/assets/factory/factory-comment.json +388 -0
  179. package/skills/weaver-e10-builder/assets/factory/factory-count-down.json +198 -0
  180. package/skills/weaver-e10-builder/assets/factory/factory-digital-panel.json +108 -0
  181. package/skills/weaver-e10-builder/assets/factory/factory-eb-button.json +150 -0
  182. package/skills/weaver-e10-builder/assets/factory/factory-fast-create.json +62 -0
  183. package/skills/weaver-e10-builder/assets/factory/factory-gauge.json +312 -0
  184. package/skills/weaver-e10-builder/assets/factory/factory-h-bar-stack.json +328 -0
  185. package/skills/weaver-e10-builder/assets/factory/factory-h-bar.json +326 -0
  186. package/skills/weaver-e10-builder/assets/factory/factory-line.json +212 -0
  187. package/skills/weaver-e10-builder/assets/factory/factory-nav-bar.json +167 -0
  188. package/skills/weaver-e10-builder/assets/factory/factory-nav-menu.json +144 -0
  189. package/skills/weaver-e10-builder/assets/factory/factory-nav-panel.json +338 -0
  190. package/skills/weaver-e10-builder/assets/factory/factory-new-tab.json +163 -0
  191. package/skills/weaver-e10-builder/assets/factory/factory-nightingale.json +312 -0
  192. package/skills/weaver-e10-builder/assets/factory/factory-nlist.json +112 -0
  193. package/skills/weaver-e10-builder/assets/factory/factory-page-header.json +171 -0
  194. package/skills/weaver-e10-builder/assets/factory/factory-picture.json +169 -0
  195. package/skills/weaver-e10-builder/assets/factory/factory-pie.json +212 -0
  196. package/skills/weaver-e10-builder/assets/factory/factory-progress-chart.json +162 -0
  197. package/skills/weaver-e10-builder/assets/factory/factory-search-global.json +104 -0
  198. package/skills/weaver-e10-builder/assets/factory/factory-slide.json +164 -0
  199. package/skills/weaver-e10-builder/assets/factory/factory-treemap.json +322 -0
  200. package/skills/weaver-e10-builder/assets/icons.db +0 -0
  201. package/skills/weaver-e10-builder/assets/sample/.claude/settings.local.json +8 -0
  202. package/skills/weaver-e10-builder/assets/sample/api/formApi.js +510 -0
  203. package/skills/weaver-e10-builder/assets/sample/config/config.js +0 -0
  204. package/skills/weaver-e10-builder/assets/sample/config/configLoad.js +0 -0
  205. package/skills/weaver-e10-builder/assets/sample/config/configLoad_default.js +0 -0
  206. package/skills/weaver-e10-builder/assets/sample/config/config_default.js +0 -0
  207. package/skills/weaver-e10-builder/assets/sample/entry.js +22 -0
  208. package/skills/weaver-e10-builder/assets/sample/eslint.config.cjs +48 -0
  209. package/skills/weaver-e10-builder/assets/sample/memo.md +0 -0
  210. package/skills/weaver-e10-builder/assets/sample/readme.js +8 -0
  211. package/skills/weaver-e10-builder/references/app/guide-app-publish.md +92 -0
  212. package/skills/weaver-e10-builder/references/auth/guide-auth.md +88 -0
  213. package/skills/weaver-e10-builder/references/coding/guide-edit-backfill.md +189 -0
  214. package/skills/weaver-e10-builder/references/coding/guide-form-crud.md +262 -0
  215. package/skills/weaver-e10-builder/references/coding/guide-page-code.md +244 -0
  216. package/skills/weaver-e10-builder/references/coding/guide-page-export.md +119 -0
  217. package/skills/weaver-e10-builder/references/coding/ref-compile-rules.md +130 -0
  218. package/skills/weaver-e10-builder/references/common/guide-plan-template.md +164 -0
  219. package/skills/weaver-e10-builder/references/common/map.md +153 -0
  220. package/skills/weaver-e10-builder/references/common/ref-cli-commands.md +635 -0
  221. package/skills/weaver-e10-builder/references/components/@weapp-Button.md +104 -0
  222. package/skills/weaver-e10-builder/references/components/base-Badge.md +100 -0
  223. package/skills/weaver-e10-builder/references/components/base-Dialog.md +358 -0
  224. package/skills/weaver-e10-builder/references/components/base-Empty.md +58 -0
  225. package/skills/weaver-e10-builder/references/components/base-Tag.md +112 -0
  226. package/skills/weaver-e10-builder/references/components/display-Alert.md +64 -0
  227. package/skills/weaver-e10-builder/references/components/display-Avatar.md +150 -0
  228. package/skills/weaver-e10-builder/references/components/display-Calendar.md +263 -0
  229. package/skills/weaver-e10-builder/references/components/display-Carousel.md +115 -0
  230. package/skills/weaver-e10-builder/references/components/display-Collapse.md +299 -0
  231. package/skills/weaver-e10-builder/references/components/display-FilePreview.md +49 -0
  232. package/skills/weaver-e10-builder/references/components/display-Icon.md +66 -0
  233. package/skills/weaver-e10-builder/references/components/display-List.md +320 -0
  234. package/skills/weaver-e10-builder/references/components/display-Pagination.md +41 -0
  235. package/skills/weaver-e10-builder/references/components/display-Spin.md +34 -0
  236. package/skills/weaver-e10-builder/references/components/display-Steps.md +89 -0
  237. package/skills/weaver-e10-builder/references/components/display-Table.md +160 -0
  238. package/skills/weaver-e10-builder/references/components/display-Title.md +117 -0
  239. package/skills/weaver-e10-builder/references/components/form-Checkbox.md +161 -0
  240. package/skills/weaver-e10-builder/references/components/form-DepartmentBrowser-api.md +52 -0
  241. package/skills/weaver-e10-builder/references/components/form-EmployeeBrowser-api.md +51 -0
  242. package/skills/weaver-e10-builder/references/components/form-EmployeeBrowser.md +51 -0
  243. package/skills/weaver-e10-builder/references/components/form-Input.md +123 -0
  244. package/skills/weaver-e10-builder/references/components/form-Radio.md +145 -0
  245. package/skills/weaver-e10-builder/references/components/form-Select.md +191 -0
  246. package/skills/weaver-e10-builder/references/components/form-Switch.md +46 -0
  247. package/skills/weaver-e10-builder/references/components/form-Upload.md +53 -0
  248. package/skills/weaver-e10-builder/references/components/generic-Echarts.md +102 -0
  249. package/skills/weaver-e10-builder/references/ebuilder-designer/guide-designer-components.md +130 -0
  250. package/skills/weaver-e10-builder/references/ebuilder-designer/guide-designer-css.md +127 -0
  251. package/skills/weaver-e10-builder/references/ebuilder-designer/guide-designer-factory.md +460 -0
  252. package/skills/weaver-e10-builder/references/ebuilder-designer/guide-designer-version.md +111 -0
  253. package/skills/weaver-e10-builder/references/ebuilder-designer/guide-designer.md +288 -0
  254. package/skills/weaver-e10-builder/references/esb-interface/guide-import.md +34 -0
  255. package/skills/weaver-e10-builder/references/form/guide-create-form.md +248 -0
  256. package/skills/weaver-e10-builder/references/form/guide-ebuilder-filter.md +73 -0
  257. package/skills/weaver-e10-builder/references/form/guide-ebuilder-scope.md +82 -0
  258. package/skills/weaver-e10-builder/references/form/guide-field-linkage.md +123 -0
  259. package/skills/weaver-e10-builder/references/form/guide-form-archive-permission.md +175 -0
  260. package/skills/weaver-e10-builder/references/form/guide-form-association.md +124 -0
  261. package/skills/weaver-e10-builder/references/form/guide-form-button.md +169 -0
  262. package/skills/weaver-e10-builder/references/form/guide-form-data.md +78 -0
  263. package/skills/weaver-e10-builder/references/form/guide-form-formula-functions.md +343 -0
  264. package/skills/weaver-e10-builder/references/form/guide-form-layout-incremental.md +90 -0
  265. package/skills/weaver-e10-builder/references/form/guide-form-layout-planning.md +68 -0
  266. package/skills/weaver-e10-builder/references/form/guide-form-linkage.md +269 -0
  267. package/skills/weaver-e10-builder/references/form/guide-form-message.md +74 -0
  268. package/skills/weaver-e10-builder/references/form/guide-form-physical-table.md +146 -0
  269. package/skills/weaver-e10-builder/references/form/guide-form-serial-mark.md +47 -0
  270. package/skills/weaver-e10-builder/references/form/guide-form-sub-detail.md +82 -0
  271. package/skills/weaver-e10-builder/references/form/guide-form-view-permission.md +38 -0
  272. package/skills/weaver-e10-builder/references/form/guide-form-view.md +371 -0
  273. package/skills/weaver-e10-builder/references/form/guide-formula-linkage.md +281 -0
  274. package/skills/weaver-e10-builder/references/form/guide-list-columns.md +52 -0
  275. package/skills/weaver-e10-builder/references/form/guide-list-custom-text.md +52 -0
  276. package/skills/weaver-e10-builder/references/form/guide-list-stats.md +136 -0
  277. package/skills/weaver-e10-builder/references/form/guide-virtual-form.md +156 -0
  278. package/skills/weaver-e10-builder/references/form/ref-form-fields.md +293 -0
  279. package/skills/weaver-e10-builder/references/form/style-templates.md +97 -0
  280. package/skills/weaver-e10-builder/references/hrm/guide-matrix.md +245 -0
  281. package/skills/weaver-e10-builder/references/hrm/guide-org-employee.md +155 -0
  282. package/skills/weaver-e10-builder/references/menu/system-menus.md +75 -0
  283. package/skills/weaver-e10-builder/references/report/add-dataset-registration-guide.md +139 -0
  284. package/skills/weaver-e10-builder/references/report/ai-report-workflow.md +412 -0
  285. package/skills/weaver-e10-builder/references/report/api-report-build-fast-path.md +275 -0
  286. package/skills/weaver-e10-builder/references/report/app-datasource-lookup-guide.md +230 -0
  287. package/skills/weaver-e10-builder/references/report/cell-config-echo-guide.md +163 -0
  288. package/skills/weaver-e10-builder/references/report/cell-transform-guide.md +147 -0
  289. package/skills/weaver-e10-builder/references/report/condition-format-guide.md +140 -0
  290. package/skills/weaver-e10-builder/references/report/cross-dataset-filter-guide.md +304 -0
  291. package/skills/weaver-e10-builder/references/report/dataset-query-filter-guide.md +235 -0
  292. package/skills/weaver-e10-builder/references/report/dataset-sidebar-ops-guide.md +280 -0
  293. package/skills/weaver-e10-builder/references/report/dataset-table-field-contract-guide.md +339 -0
  294. package/skills/weaver-e10-builder/references/report/datasource-metadata-guide.md +365 -0
  295. package/skills/weaver-e10-builder/references/report/datasource-selection-and-parent-filter-guide.md +148 -0
  296. package/skills/weaver-e10-builder/references/report/date-range-query-reference.md +102 -0
  297. package/skills/weaver-e10-builder/references/report/default-header-style-guide.md +70 -0
  298. package/skills/weaver-e10-builder/references/report/designer-blank-prevention-guide.md +111 -0
  299. package/skills/weaver-e10-builder/references/report/event-hreflink-guide.md +184 -0
  300. package/skills/weaver-e10-builder/references/report/field-bind-exact-match-guide.md +208 -0
  301. package/skills/weaver-e10-builder/references/report/formula-cell-api-guide.md +258 -0
  302. package/skills/weaver-e10-builder/references/report/guide-report-build.md +131 -0
  303. package/skills/weaver-e10-builder/references/report/guide-report-modify.md +100 -0
  304. package/skills/weaver-e10-builder/references/report/guide-report-multisource.md +143 -0
  305. package/skills/weaver-e10-builder/references/report/guide-report-query.md +98 -0
  306. package/skills/weaver-e10-builder/references/report/hidden-row-and-header-merge-guide.md +100 -0
  307. package/skills/weaver-e10-builder/references/report/layout-showlocation-freeze-guide.md +167 -0
  308. package/skills/weaver-e10-builder/references/report/preaggregate-auto-disable-guide.md +107 -0
  309. package/skills/weaver-e10-builder/references/report/query-condition-api-guide.md +890 -0
  310. package/skills/weaver-e10-builder/references/report/ref-report-commands.md +122 -0
  311. package/skills/weaver-e10-builder/references/report/ref-report-pitfalls.md +226 -0
  312. package/skills/weaver-e10-builder/references/report/report-baseinfo-defaults-guide.md +117 -0
  313. package/skills/weaver-e10-builder/references/report/report-building-guide.md +511 -0
  314. package/skills/weaver-e10-builder/references/report/report-config-schema.md +445 -0
  315. package/skills/weaver-e10-builder/references/report/report-create-modes-guide.md +182 -0
  316. package/skills/weaver-e10-builder/references/report/report-data-model.md +447 -0
  317. package/skills/weaver-e10-builder/references/report/report-delivery-contract.md +101 -0
  318. package/skills/weaver-e10-builder/references/report/report-designer-feature-map.md +500 -0
  319. package/skills/weaver-e10-builder/references/report/report-internal-error-guide.md +78 -0
  320. package/skills/weaver-e10-builder/references/report/report-knowledge-base.md +389 -0
  321. package/skills/weaver-e10-builder/references/report/report-lifecycle-api-guide.md +392 -0
  322. package/skills/weaver-e10-builder/references/report/report-list-page-ops-guide.md +191 -0
  323. package/skills/weaver-e10-builder/references/report/report-permission-guide.md +365 -0
  324. package/skills/weaver-e10-builder/references/report/report-requirement-analysis-template.md +202 -0
  325. package/skills/weaver-e10-builder/references/report/report-self-check-guide.md +164 -0
  326. package/skills/weaver-e10-builder/references/report/safe-partial-save-guide.md +151 -0
  327. package/skills/weaver-e10-builder/references/report/snowflake-id-precision-guide.md +84 -0
  328. package/skills/weaver-e10-builder/references/report/spec-build-schema.md +294 -0
  329. package/skills/weaver-e10-builder/references/report/targeted-fix-guide.md +97 -0
  330. package/skills/weaver-e10-builder/references/report/user-request-scope-only-guide.md +82 -0
  331. package/skills/weaver-e10-builder/references/workflow/guide-function-management.md +154 -0
  332. package/skills/weaver-e10-builder/references/workflow/guide-opinion-settings.md +126 -0
  333. package/skills/weaver-e10-builder/references/workflow/guide-workflow-action.md +174 -0
  334. package/skills/weaver-e10-builder/references/workflow/guide-workflow-auth-resp.md +224 -0
  335. package/skills/weaver-e10-builder/references/workflow/guide-workflow-condition.md +447 -0
  336. package/skills/weaver-e10-builder/references/workflow/guide-workflow-node-layout.md +181 -0
  337. package/skills/weaver-e10-builder/references/workflow/guide-workflow-odoc-setting.md +248 -0
  338. package/skills/weaver-e10-builder/references/workflow/guide-workflow-odoc.md +68 -0
  339. package/skills/weaver-e10-builder/references/workflow/guide-workflow.md +527 -0
  340. package/skills/weaver-e10-builder/references/workflow/operator-matrix.md +76 -0
  341. package/skills/weaver-e10-caizhilian/SKILL.md +14 -4
  342. package/skills/weaver-e10-caizhilian/references/file-upload.md +100 -295
  343. package/skills/weaver-e10-caizhilian/references/files.md +15 -0
  344. package/skills/weaver-e10-caizhilian/references/folder.md +31 -3
  345. package/skills/weaver-e10-caizhilian/references/setting-attach.md +48 -3
  346. package/skills/weaver-e10-caizhilian/references/source-manifest.json +634 -25
  347. package/skills/weaver-e10-jiuchuanhui/SKILL.md +9 -1
  348. package/skills/weaver-e10-shared/SKILL.md +19 -5
  349. package/skills/weaver-e10-shared/references/e10-auth-and-session.md +25 -5
  350. package/skills/weaver-e10-workflow/SKILL.md +28 -47
  351. package/skills/weaver-e10-workflow/references/source-manifest.json +46 -36
  352. package/skills/weaver-e10-workflow/references/workflow-batch.md +2 -4
  353. package/skills/weaver-e10-workflow/references/workflow-create.md +261 -86
  354. package/skills/weaver-e10-workflow/references/workflow-edit.md +2 -1
  355. package/skills/weaver-e10-workflow/references/workflow-memory.md +3 -6
  356. package/skills/weaver-e10-workflow/references/workflow-operate.md +2 -1
  357. package/skills/weaver-e10-workflow/references/workflow-query.md +11 -9
  358. package/skills/weaver-e10-workflow/references/workflow-share.md +2 -0
package/README.md CHANGED
@@ -211,22 +211,30 @@ weaver-work-cli auth login --base-url "https://weapp.xxx.cn"
211
211
  weaver-work-cli auth oidc --base-url "https://weapp.xxx.cn"
212
212
  ```
213
213
 
214
- 在 XiaoE 宿主环境中,`auth login` / `auth oidc` / `auth xiaoe` 会优先使用平台注入的
214
+ 只有当前智能体身份明确为 XiaoE 时,`auth xiaoe` 和未显式指定认证来源的业务命令才会优先使用平台注入的
215
215
  `XIAOE_USER_TOKEN` + `XIAOE_DOMAIN` 换取 ETEAMSID:其中 `XIAOE_DOMAIN` 是
216
216
  XiaoE/erpa 换票服务地址,不是 E10 登录地址。CLI 的 Node 实现会直接调用与
217
217
  `xiaoe_env.py` / `tokens.py` 相同的换票接口,并校验业务码和 `data.eteamId`;它保留
218
218
  系统 CA 校验,且只允许同源重定向或同主机 HTTP→HTTPS 升级。平台凭证不可用时,
219
219
  CLI 会先在内部调用 npm 包自带的 `scripts/xiaoe_env.py` 兼容路径,再按顺序尝试
220
220
  宿主 `xiaoeUserData/tokens.py`、桌面 XiaoE 客户端当前会话
221
- (`XiaoE/Robots/<id>/user_settings.json`)和 `WEAVER_XIAOE_*` 环境映射。
221
+ (优先读取宿主注入的 `XIAOE_USER_SETTINGS_PATH`,其次查找
222
+ `XIAOE_ROBOT_DATA_ROOT` / `XIAOE_ROBOT_ROOT`,最后回退
223
+ `XiaoE/Robots/<id>/user_settings.json`)和 `WEAVER_XIAOE_*` 环境映射。只要会话文件中的
224
+ `session_id` 与 `erpa` 有效,Node 路径即可直接换票,不要求宿主存在 `tokens.py`。
222
225
  `xiaoe_env.py` 由 CLI 独占执行并解析,不放进 shared Skill,也不把 stdout 凭证暴露给
223
226
  Agent;Skill 只负责调用 `weaver-work-cli auth xiaoe`。CLI 自带脚本仅依赖 Python
224
227
  标准库,仍保持 TLS 证书校验,不会采用关闭证书校验的回退。
225
228
 
229
+ XiaoE 桌面客户端不一定注入上述 Token 对;它会注入 `XIAOE_DATA_ROOT`、
230
+ `XIAOE_ROBOT_DATA_ROOT`、`XIAOE_USER_SETTINGS_PATH`、`XIAOE_ROBOT_ROOT` 等精确的
231
+ 运行时路径标记,CLI 也把这些标记识别为当前 XiaoE 桌面宿主。普通 `XIAOE_SKILL_*`、
232
+ `WEAVER_XIAOE_*` 配置或仅在磁盘上发现客户端文件仍不构成宿主身份。
233
+
226
234
  E10 目标地址按“显式 `--base-url` → 专用 `WEAVER_XIAOE_*` E10 配置/映射 →
227
235
  当前 profile → `https://www.e-cology.com.cn`”解析,绝不会把 `XIAOE_DOMAIN`
228
236
  当作 E10 地址。匹配成功时直接保存登录态,并固定使用 `agentType=XiaoE`。业务命令
229
- 在未显式指定 `--auth` / `--profile` 时,也会自动优先尝试 XiaoE 统一登录。
237
+ 在已确认的 XiaoE 智能体环境中且未显式指定 `--auth` / `--profile` 时,也会自动优先尝试 XiaoE 统一登录。
230
238
  `auth xiaoe` 失败后仅在 macOS/Windows 桌面宿主自动降级浏览器 OAuth;Web/Linux
231
239
  环境会返回结构化的 `authentication/xiaoe_web_credential_unavailable` 错误,不再
232
240
  启动无法回调的 localhost 浏览器登录。确需浏览器授权时,应在可接收本地回调的宿主
@@ -236,6 +244,9 @@ E10 目标地址按“显式 `--base-url` → 专用 `WEAVER_XIAOE_*` E10 配置
236
244
  weaver-work-cli auth xiaoe
237
245
  ```
238
246
 
247
+ `auth login` / `auth oidc` 始终是纯浏览器 OAuth 入口。本机存在 `xiaoeUserData/tokens.py`、XiaoE 客户端目录、`XIAOE_SKILL_*` 或 `WEAVER_XIAOE_*` 配置,都不能单独证明当前智能体是 XiaoE,也不会让 WorkBuddy、Codex 或其他智能体切换到 XiaoE 登录。
248
+ `auth xiaoe` 会先输出不含凭证的 preflight 摘要(`hostDetected`、`attempted`、`tokenScriptDetected`、`clientSettingsDetected`、`baseUrl`);命中 `tokens.py` 或内置 Node 客户端会话路径时还会输出明确的尝试日志。统一登录成功后,登录结果以及后续 `auth status` 会显示 `credentialSourceStep`、`credentialSourceType`、`credentialSourceLabel`,可据此确认实际凭证来源;`3 / xiaoe_client / XiaoE client settings` 表示未依赖 `tokens.py`,由 Node 直接换票。
249
+
239
250
  默认本地回调地址为 `http://127.0.0.1:19800/callback`。如果端口被占用:
240
251
 
241
252
  ```text
@@ -252,6 +263,25 @@ weaver-work-cli auth login --base-url "https://weapp.xxx.cn" --port 19801
252
263
  weaver-work-cli auth login --base-url "https://weapp.xxx.cn" --agent_type workbuddy
253
264
  ```
254
265
 
266
+ 浏览器授权成功后,本地回调页会为已识别的桌面智能体显示应用打开弹层。CLI 内置
267
+ WorkBuddy(`workbuddy://`)、智能小 E(`xiaoe-client://`)和 Codex(`codex://`)映射;
268
+ 其他智能体在 `agent_type` 本身是合法协议名时,默认按 `<agent_type>://` 唤起。弹层显示
269
+ “打开客户端 / 始终打开客户端 / 取消”。用户确认后,页面通过一次性令牌请求本地 CLI,
270
+ 由 CLI 调用系统注册的桌面协议;浏览器不直接访问自定义
271
+ 协议,因此不会再出现 Chrome/Edge 无法定制的外部协议确认框。Windows/macOS 安装包都
272
+ 需要注册该协议。如果宿主要返回当前会话等更精确的位置,可传入宿主
273
+ 注册的深链(仅接受桌面应用自定义协议,不接受网页、脚本或本地文件 URL):
274
+
275
+ ```text
276
+ weaver-work-cli auth login --base-url "https://weapp.xxx.cn" --agent_type workbuddy --agent-return-url "workbuddy://<宿主提供的路径>"
277
+ ```
278
+
279
+ 宿主也可以注入 `WEAVER_AGENT_RETURN_URL`,命令行参数优先于环境变量;客户端协议名与
280
+ `agent_type` 不一致时也应使用该覆盖。“始终打开”偏好
281
+ 保存在当前本地回调地址的浏览器存储中;未识别到可用返回协议时,回调页保持原有提示,
282
+ 不显示应用打开弹层。本地 CLI 打开通道默认保留 15 分钟;超过时间再点击时会自动退回
283
+ 浏览器自定义协议打开方式,仍可打开应用,但浏览器可能重新显示原生协议确认框。
284
+
255
285
  方式二:手动写入浏览器中的 `ETEAMSID`。
256
286
 
257
287
  ```text
@@ -233,6 +233,58 @@ function fitEnvelope(value, leading, extraWarnings, budgetBytes) {
233
233
  warnings: [...extraWarnings, 'stdout_compacted'],
234
234
  };
235
235
  }
236
+ /**
237
+ * stdout 序列化:默认 `JSON.stringify(value, null, 2)`;给了 `compactPaths` 时,**只有**命中这些
238
+ * 路径的子树改成单行(紧凑)输出,其余照旧缩进。
239
+ *
240
+ * 为什么需要它:像 `historyRequestData` 这种「每条都长、层级又深」的数组,缩进空白能吃掉近 1/4
241
+ * 体积(真机实测:该键 13,017 B → 9,835 B,整份 21,620 B → 18,438 B),而它对读模型的**可读性
242
+ * 收益为零**——模型要的是"哪条历史、哪个字段、什么值",不是每层两个空格。
243
+ *
244
+ * **内容一字不改**:输出仍是合法 JSON,parse 出来的对象与全缩进版**完全一致**(只是空白不同),
245
+ * 消费端不需要任何改动;结构也保持数组/对象原样,不会退化成"需要再 parse 一次的字符串"。
246
+ *
247
+ * 路径口径:从信封根算起的点分路径(如 `data.historyRequestData`),**精确匹配**、不递归下钻。
248
+ * 实现用「占位符摘出 → 紧凑序列化 → 文本替换回填」,而**不是**自己递归拼 JSON:标量转义、
249
+ * `undefined` 键丢弃、数组里 `undefined` 补 `null`、`toJSON` 这些细节全部沿用 `JSON.stringify`
250
+ * 的原生行为,避免手写序列化器在边角上与原输出分叉。
251
+ */
252
+ export function stringifyForStdout(value, compactPaths) {
253
+ const wanted = new Set((compactPaths ?? []).filter((path) => typeof path === 'string' && path !== ''));
254
+ const plain = JSON.stringify(value, null, 2);
255
+ if (!wanted.size || plain === undefined)
256
+ return plain;
257
+ // 占位符必须不可能与真实内容撞车:随机盐 + 对已序列化文本做一次包含检查(撞了就换一个)。
258
+ let salt = '';
259
+ do {
260
+ salt = `__WEAVER_COMPACT_${Math.random().toString(36).slice(2, 12)}__`;
261
+ } while (plain.includes(salt));
262
+ const compacted = [];
263
+ const swap = (node, path) => {
264
+ if (node !== null && typeof node === 'object' && wanted.has(path)) {
265
+ const inline = JSON.stringify(node);
266
+ if (inline !== undefined) {
267
+ compacted.push(inline);
268
+ return `${salt}${compacted.length - 1}__`;
269
+ }
270
+ }
271
+ if (Array.isArray(node))
272
+ return node.map((item, index) => swap(item, `${path}[${index}]`));
273
+ if (node !== null && typeof node === 'object') {
274
+ const out = {};
275
+ for (const [key, item] of Object.entries(node)) {
276
+ out[key] = swap(item, path ? `${path}.${key}` : key);
277
+ }
278
+ return out;
279
+ }
280
+ return node;
281
+ };
282
+ const swapped = JSON.stringify(swap(value, ''), null, 2);
283
+ if (typeof swapped !== 'string')
284
+ return swapped;
285
+ // 占位符在文本里是一个普通字符串字面量(`"__WEAVER_COMPACT_xxx__0__"`),整体替换成紧凑 JSON。
286
+ return swapped.replace(new RegExp(`"${salt}(\\d+)__"`, 'g'), (_match, index) => compacted[Number(index)] ?? 'null');
287
+ }
236
288
  export class Output {
237
289
  ctx;
238
290
  constructor(ctx) {
@@ -245,7 +297,7 @@ export class Output {
245
297
  console.log(options.text);
246
298
  return;
247
299
  }
248
- console.log(JSON.stringify(this.prepare(value, options), null, 2));
300
+ console.log(stringifyForStdout(this.prepare(value, options), options.compactPaths));
249
301
  }
250
302
  prepare(value, options) {
251
303
  const threshold = resultThresholdBytes(this.ctx);
@@ -1,16 +1,54 @@
1
1
  import { execFile } from 'node:child_process';
2
+ import { randomBytes } from 'node:crypto';
2
3
  import { createServer } from 'node:http';
3
4
  import { CliError, ExitCode } from '../../../core/errors.js';
4
5
  import { clearInvoiceTokenForSession } from '../../../shortcuts/invoice/host.js';
5
6
  import { buildE10CookieHeader, E10AuthSession, clearProfileAuthFile, extractRawSetCookie, extractSessionTicket, findAuthFile, getActiveProfile, getProfileAuthPath, getProfileDir, listProfiles, profileNameFromUrl, readProfileConfig, readTeamsCheckUserInfo, saveAuthFile, saveProfileConfig, setActiveProfile, switchActiveProfile, } from './session.js';
6
7
  import { getE10AuthRoot } from './paths.js';
7
- import { XIAOE_AGENT_TYPE, createXiaoEUnifiedLoginUnavailableError, hasXiaoEEnv, resolveXiaoEPreferredBaseUrl, shouldUseXiaoEBrowserFallback, tryXiaoEUnifiedLogin as tryXiaoEUnifiedSessionLogin, } from './xiaoe.js';
8
+ import { XIAOE_AGENT_TYPE, createXiaoEUnifiedLoginUnavailableError, hasXiaoEClientCredential, hasXiaoEEnv, hasXiaoETokenScript, resolveXiaoEPreferredBaseUrl, shouldUseXiaoEBrowserFallback, tryXiaoEUnifiedLogin as tryXiaoEUnifiedSessionLogin, } from './xiaoe.js';
8
9
  export { DEFAULT_E10_BASE_URL, XIAOE_AGENT_TYPE, hasXiaoEEnv, hasXiaoETokenScript, resolveXiaoEDefaultBaseUrl, resolveXiaoEPreferredBaseUrl, resolveXiaoEUnifiedLoginCredential, shouldUseXiaoEBrowserFallback, } from './xiaoe.js';
9
10
  const DEFAULT_AGENT_TYPE = 'weaver-work-cli';
10
11
  const EXPLICIT_AGENT_TYPE_ENV_KEYS = [
11
- 'WEAVER_AGENT_TYPE',
12
12
  'WORKBUDDY_AGENT_TYPE',
13
13
  'CODEX_AGENT_TYPE',
14
+ 'WEAVER_AGENT_TYPE',
15
+ ];
16
+ const AGENT_RETURN_URL_ENV_KEY = 'WEAVER_AGENT_RETURN_URL';
17
+ const AGENT_RETURN_PATH = '/agent-return';
18
+ const AGENT_RETURN_TOKEN_HEADER = 'x-weaver-agent-return-token';
19
+ const AGENT_RETURN_TIMEOUT_MS = 900_000;
20
+ const UNSAFE_AGENT_RETURN_PROTOCOLS = new Set([
21
+ 'about:',
22
+ 'blob:',
23
+ 'data:',
24
+ 'file:',
25
+ 'ftp:',
26
+ 'http:',
27
+ 'https:',
28
+ 'javascript:',
29
+ 'mailto:',
30
+ 'sms:',
31
+ 'tel:',
32
+ 'vbscript:',
33
+ 'ws:',
34
+ 'wss:',
35
+ ]);
36
+ const BUILT_IN_AGENT_RETURN_TARGETS = [
37
+ {
38
+ aliases: ['workbuddy'],
39
+ label: 'WorkBuddy',
40
+ url: 'workbuddy://',
41
+ },
42
+ {
43
+ aliases: ['xiaoe', 'xiaoeclient', '小e', '智能小e'],
44
+ label: '智能小 E',
45
+ url: 'xiaoe-client://',
46
+ },
47
+ {
48
+ aliases: ['codex', 'openaicodex'],
49
+ label: 'Codex',
50
+ url: 'codex://',
51
+ },
14
52
  ];
15
53
  function asOptions(value) {
16
54
  return value && typeof value === 'object' && !Array.isArray(value) ? value : {};
@@ -49,6 +87,59 @@ export function resolveAgentType(options = {}, env = process.env) {
49
87
  || inferAgentTypeFromEnv(env)
50
88
  || DEFAULT_AGENT_TYPE;
51
89
  }
90
+ function normalizeAgentKey(value) {
91
+ return value.toLowerCase().replace(/[^a-z0-9]+/gu, '');
92
+ }
93
+ function normalizeAgentAlias(value) {
94
+ return value.trim().toLowerCase().replace(/[^\p{Letter}\p{Number}]+/gu, '');
95
+ }
96
+ function builtInAgentReturnTarget(agentType) {
97
+ const alias = normalizeAgentAlias(agentType);
98
+ const target = BUILT_IN_AGENT_RETURN_TARGETS.find((candidate) => candidate.aliases.includes(alias));
99
+ return target ? { label: target.label, url: target.url } : null;
100
+ }
101
+ function conventionalAgentReturnUrl(agentType) {
102
+ const scheme = agentType.trim().toLowerCase();
103
+ if (normalizeAgentAlias(agentType) === normalizeAgentAlias(DEFAULT_AGENT_TYPE)
104
+ || scheme.length > 64
105
+ || !/^[a-z][a-z0-9+.-]*$/u.test(scheme)
106
+ || UNSAFE_AGENT_RETURN_PROTOCOLS.has(`${scheme}:`)) {
107
+ return '';
108
+ }
109
+ return `${scheme}://`;
110
+ }
111
+ function validateAgentReturnUrl(value) {
112
+ if (value.length > 2048
113
+ || /[\u0000-\u001f\u007f\s]/u.test(value)
114
+ || !/^[a-z][a-z0-9+.-]*:\/\//iu.test(value)) {
115
+ throw new CliError('Invalid --agent-return-url value', ExitCode.UsageError);
116
+ }
117
+ let url;
118
+ try {
119
+ url = new URL(value);
120
+ }
121
+ catch {
122
+ throw new CliError('Invalid --agent-return-url value', ExitCode.UsageError);
123
+ }
124
+ if (UNSAFE_AGENT_RETURN_PROTOCOLS.has(url.protocol)) {
125
+ throw new CliError('--agent-return-url must use a registered desktop application URL scheme.', ExitCode.UsageError);
126
+ }
127
+ return value;
128
+ }
129
+ export function resolveAgentReturnTarget(options = {}, env = process.env, agentType = resolveAgentType(options, env)) {
130
+ const builtInTarget = builtInAgentReturnTarget(agentType);
131
+ const explicitUrl = optionString(options, 'agentReturnUrl') || envString(env, AGENT_RETURN_URL_ENV_KEY);
132
+ if (explicitUrl) {
133
+ return {
134
+ label: builtInTarget?.label || agentType,
135
+ url: validateAgentReturnUrl(explicitUrl),
136
+ };
137
+ }
138
+ if (builtInTarget)
139
+ return builtInTarget;
140
+ const conventionalUrl = conventionalAgentReturnUrl(agentType);
141
+ return conventionalUrl ? { label: agentType, url: conventionalUrl } : null;
142
+ }
52
143
  function normalizeUrl(value) {
53
144
  return value.replace(/\/+$/, '');
54
145
  }
@@ -101,6 +192,10 @@ function formatAuthStatus(status) {
101
192
  'baseUrl: ' + status.baseUrl,
102
193
  'profile: ' + status.profile,
103
194
  'authFile: ' + status.authFile,
195
+ ...('loginSource' in status && status.loginSource ? ['loginSource: ' + status.loginSource] : []),
196
+ ...('credentialSourceStep' in status && status.credentialSourceStep ? ['credentialSourceStep: ' + status.credentialSourceStep] : []),
197
+ ...('credentialSourceType' in status && status.credentialSourceType ? ['credentialSourceType: ' + status.credentialSourceType] : []),
198
+ ...('credentialSourceLabel' in status && status.credentialSourceLabel ? ['credentialSourceLabel: ' + status.credentialSourceLabel] : []),
104
199
  ];
105
200
  if ('valid' in status) {
106
201
  lines.push('valid: ' + String(status.valid));
@@ -160,8 +255,18 @@ function esc(value) {
160
255
  .replace(/"/g, '&quot;')
161
256
  .replace(/'/g, '&#39;');
162
257
  }
163
- export function renderE10LoginSuccessPage(userId) {
164
- return `<!doctype html><html lang="zh-CN"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>weaver-work-cli 登录成功</title><style>body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Arial,sans-serif;background:#f6f7f9;color:#20242a;display:grid;place-items:center;min-height:100vh;margin:0}.card{background:#fff;border:1px solid #e6e8ec;border-radius:8px;padding:28px 32px;box-shadow:0 8px 32px rgba(18,24,40,.08);min-width:320px;text-align:center}.title{font-size:20px;font-weight:600;margin-bottom:8px}.desc{color:#667085;font-size:14px;line-height:22px}.user{color:#98a2b3;font-size:12px;margin-top:12px}</style></head><body><main class="card"><div class="title">登录授权成功</div><div class="desc">你可以关闭此页面,返回智能体或终端继续使用。</div><div class="user">${esc(userId)}</div></main></body></html>`;
258
+ export function renderE10LoginSuccessPage(userId, returnTarget = null, launchToken = '') {
259
+ const safeReturnTarget = returnTarget
260
+ ? { ...returnTarget, url: validateAgentReturnUrl(returnTarget.url) }
261
+ : null;
262
+ const agentKey = safeReturnTarget ? normalizeAgentKey(safeReturnTarget.label) || 'agent' : '';
263
+ const returnAction = safeReturnTarget && launchToken
264
+ ? `<div class="overlay" data-agent-return data-token="${esc(launchToken)}" data-agent-key="${esc(agentKey)}" data-agent-label="${esc(safeReturnTarget.label)}" data-fallback-url="${esc(safeReturnTarget.url)}"><section class="prompt" role="dialog" aria-modal="true" aria-labelledby="agent-return-title"><div class="app-icon" aria-hidden="true"><svg viewBox="0 0 64 64"><defs><linearGradient id="app-gradient" x1="8" y1="4" x2="56" y2="60" gradientUnits="userSpaceOnUse"><stop stop-color="#24d3b5"/><stop offset="1" stop-color="#08aa82"/></linearGradient></defs><rect width="64" height="64" rx="16" fill="url(#app-gradient)"/><path d="M18 21.5 32 13l14 8.5v17L32 47 18 38.5v-17Z" fill="#fff" fill-opacity=".96"/><rect x="23" y="25" width="18" height="15" rx="6" fill="#12b991"/><circle cx="28.5" cy="32.5" r="1.8" fill="#fff"/><circle cx="35.5" cy="32.5" r="1.8" fill="#fff"/></svg></div><h1 id="agent-return-title">是否打开“${esc(safeReturnTarget.label)}”?</h1><p>登录授权已完成,返回 ${esc(safeReturnTarget.label)} 继续使用。</p><button class="primary" type="button" data-action="open">打开“${esc(safeReturnTarget.label)}”</button><button class="secondary" type="button" data-action="always">始终打开“${esc(safeReturnTarget.label)}”</button><button class="secondary" type="button" data-action="cancel">取消</button><div class="status" role="status" aria-live="polite"></div></section></div>`
265
+ : '';
266
+ const returnScript = safeReturnTarget && launchToken
267
+ ? `<script nonce="${esc(launchToken)}">(()=>{const root=document.querySelector('[data-agent-return]');if(!root)return;const status=root.querySelector('.status');const buttons=[...root.querySelectorAll('button')];const agentLabel=root.dataset.agentLabel||'应用';const fallbackUrl=root.dataset.fallbackUrl||'';const storageKey='weaver-work-cli.agent-return.'+root.dataset.agentKey;let busy=false;const setBusy=value=>{busy=value;buttons.forEach(button=>{button.disabled=value;});};const closePrompt=()=>{root.hidden=true;};const savePreference=()=>{try{localStorage.setItem(storageKey,'1');}catch{}};const clearPreference=()=>{try{localStorage.removeItem(storageKey);}catch{}};const hasPreference=()=>{try{return localStorage.getItem(storageKey)==='1';}catch{return false;}};const post=async action=>{let response;try{response=await fetch('${AGENT_RETURN_PATH}?action='+encodeURIComponent(action),{method:'POST',headers:{'${AGENT_RETURN_TOKEN_HEADER}':root.dataset.token}});}catch{return false;}if(!response.ok)throw new Error(await response.text()||'请求失败');return true;};const openAgent=async persist=>{if(busy)return;setBusy(true);status.textContent='正在打开 '+agentLabel+'…';try{const openedLocally=await post('open');if(persist)savePreference();if(!openedLocally){closePrompt();window.location.href=fallbackUrl;return;}closePrompt();}catch(error){if(persist)clearPreference();status.textContent=error instanceof Error?error.message:'无法打开应用,请稍后重试。';setBusy(false);}};root.querySelector('[data-action="open"]').addEventListener('click',()=>openAgent(false));root.querySelector('[data-action="always"]').addEventListener('click',()=>openAgent(true));root.querySelector('[data-action="cancel"]').addEventListener('click',()=>{if(busy)return;clearPreference();closePrompt();post('cancel').catch(()=>{});});if(hasPreference())openAgent(false);})();</script>`
268
+ : '';
269
+ return `<!doctype html><html lang="zh-CN"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>weaver-work-cli 登录成功</title><style>:root{color-scheme:light}*{box-sizing:border-box}body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Arial,sans-serif;background:radial-gradient(circle at 50% 18%,#eefbf8 0,#f6f7f9 42%,#eef1f5 100%);color:#20242a;display:grid;place-items:center;min-height:100vh;margin:0}.card{background:rgba(255,255,255,.88);border:1px solid #e6e8ec;border-radius:18px;padding:34px 38px;box-shadow:0 18px 55px rgba(18,24,40,.09);width:min(560px,calc(100vw - 40px));text-align:center}.title{font-size:24px;font-weight:700;margin-bottom:10px}.desc{color:#667085;font-size:15px;line-height:24px}.user{color:#98a2b3;font-size:12px;margin-top:18px}.overlay{position:fixed;inset:0;z-index:10;display:grid;place-items:center;padding:20px;background:rgba(28,34,41,.36);backdrop-filter:blur(5px)}.overlay[hidden]{display:none}.prompt{width:min(410px,calc(100vw - 32px));padding:32px 28px 26px;border:1px solid rgba(255,255,255,.75);border-radius:24px;background:rgba(250,250,251,.97);box-shadow:0 24px 70px rgba(15,23,42,.28);text-align:center}.app-icon{width:74px;height:74px;margin:0 auto 24px;filter:drop-shadow(0 8px 14px rgba(8,170,130,.22))}.app-icon svg{display:block;width:100%;height:100%}.prompt h1{margin:0;font-size:20px;line-height:30px;font-weight:700;letter-spacing:-.2px}.prompt p{margin:10px 0 24px;color:#667085;font-size:14px;line-height:22px}.prompt button{display:block;width:100%;min-height:40px;border:0;border-radius:12px;font:600 16px/22px inherit;cursor:pointer;transition:transform .12s ease,filter .12s ease}.prompt button+button{margin-top:10px}.prompt button:hover{filter:brightness(.98)}.prompt button:active{transform:scale(.99)}.prompt button:disabled{cursor:wait;opacity:.62}.primary{background:linear-gradient(180deg,#2f91ff,#0b74e5);color:#fff;box-shadow:0 8px 18px rgba(11,116,229,.2)}.secondary{background:#e9eaec;color:#22252a}.status{min-height:18px;margin-top:14px;color:#667085;font-size:12px;line-height:18px}</style></head><body><main class="card"><div class="title">登录授权成功</div><div class="desc">你可以关闭此页面,返回智能体或终端继续使用。</div><div class="user">${esc(userId)}</div></main>${returnAction}${returnScript}</body></html>`;
165
270
  }
166
271
  export function resolveBrowserOpenCommand(url, platform = process.platform) {
167
272
  if (platform === 'win32') {
@@ -179,6 +284,17 @@ function openUrlInBrowser(url, ctx) {
179
284
  }
180
285
  });
181
286
  }
287
+ function openUrlWithSystemHandler(url) {
288
+ const command = resolveBrowserOpenCommand(url);
289
+ return new Promise((resolve, reject) => {
290
+ execFile(command.file, command.args, (error) => {
291
+ if (error)
292
+ reject(error);
293
+ else
294
+ resolve();
295
+ });
296
+ });
297
+ }
182
298
  export function buildE10AuthorizeUrl(baseUrl, redirectUri, agentType) {
183
299
  const authorizeParams = new URLSearchParams({
184
300
  redirect_uri: redirectUri,
@@ -380,11 +496,15 @@ async function runBrowserLogin(ctx, options, behavior = {}) {
380
496
  const profileFromGlobal = globalOptions.profile;
381
497
  const cfg = readProfileConfig(profileFromGlobal || getActiveProfile());
382
498
  const explicitBaseUrl = optionString(commandOpts, 'baseUrl') || globalOptions.baseUrl || '';
383
- const baseUrl = resolveXiaoEPreferredBaseUrl({
384
- explicitBaseUrl,
385
- profileBaseUrl: cfg.baseUrl,
386
- env: ctx.env,
387
- });
499
+ const xiaoEHostDetected = hasXiaoEEnv(ctx.env);
500
+ const useXiaoELogin = behavior.tryXiaoEUnifiedLogin === true && xiaoEHostDetected;
501
+ const baseUrl = useXiaoELogin
502
+ ? resolveXiaoEPreferredBaseUrl({
503
+ explicitBaseUrl,
504
+ profileBaseUrl: cfg.baseUrl,
505
+ env: ctx.env,
506
+ })
507
+ : normalizeUrl(explicitBaseUrl || cfg.baseUrl || '');
388
508
  const tenantKey = optionString(commandOpts, 'tenantKey');
389
509
  const portText = optionString(commandOpts, 'port') || '19800';
390
510
  const port = Number.parseInt(portText, 10);
@@ -393,11 +513,25 @@ async function runBrowserLogin(ctx, options, behavior = {}) {
393
513
  if (!Number.isInteger(port) || port <= 0 || port > 65535) {
394
514
  throw new CliError('Invalid --port value', ExitCode.UsageError);
395
515
  }
396
- const xiaoEResult = await tryXiaoEUnifiedLogin(ctx, baseUrl, tenantKey, profileFromGlobal, behavior.allowXiaoETokenScript === true);
397
- if (xiaoEResult)
398
- return xiaoEResult;
399
- const willOpenBrowser = behavior.browserFallback !== 'desktop-only' || shouldUseXiaoEBrowserFallback();
400
- if (behavior.explainXiaoEFallback) {
516
+ if (behavior.tryXiaoEUnifiedLogin) {
517
+ ctx.logger.info([
518
+ 'XiaoE unified login preflight:',
519
+ `hostDetected=${String(xiaoEHostDetected)}`,
520
+ `attempted=${String(useXiaoELogin)}`,
521
+ `tokenScriptDetected=${String(hasXiaoETokenScript(ctx.env))}`,
522
+ `clientSettingsDetected=${String(hasXiaoEClientCredential(ctx.env))}`,
523
+ `baseUrl=${baseUrl || '(unresolved)'}`,
524
+ ].join(' '));
525
+ }
526
+ if (useXiaoELogin) {
527
+ const xiaoEResult = await tryXiaoEUnifiedLogin(ctx, baseUrl, tenantKey, profileFromGlobal, behavior.allowXiaoETokenScript === true);
528
+ if (xiaoEResult)
529
+ return xiaoEResult;
530
+ }
531
+ const willOpenBrowser = !useXiaoELogin
532
+ || behavior.browserFallback !== 'desktop-only'
533
+ || shouldUseXiaoEBrowserFallback();
534
+ if (useXiaoELogin && behavior.explainXiaoEFallback) {
401
535
  ctx.logger.warn(xiaoEUnifiedLoginUnavailableMessage(baseUrl, willOpenBrowser));
402
536
  }
403
537
  if (!willOpenBrowser) {
@@ -405,6 +539,8 @@ async function runBrowserLogin(ctx, options, behavior = {}) {
405
539
  }
406
540
  if (!baseUrl)
407
541
  throw new CliError('Missing --base-url', ExitCode.UsageError);
542
+ const agentReturnTarget = resolveAgentReturnTarget(commandOpts, ctx.env, agentType);
543
+ const agentReturnToken = agentReturnTarget ? randomBytes(24).toString('base64url') : '';
408
544
  const redirectUri = `http://127.0.0.1:${port}/callback`;
409
545
  const loginUrl = buildE10AuthorizeUrl(baseUrl, redirectUri, agentType);
410
546
  ctx.logger.info('Open browser login: ' + loginUrl);
@@ -412,6 +548,7 @@ async function runBrowserLogin(ctx, options, behavior = {}) {
412
548
  return await new Promise((resolve, reject) => {
413
549
  let settled = false;
414
550
  let timer = null;
551
+ let pendingLoginResult = null;
415
552
  const finish = (error, result) => {
416
553
  if (settled)
417
554
  return;
@@ -433,6 +570,43 @@ async function runBrowserLogin(ctx, options, behavior = {}) {
433
570
  };
434
571
  const server = createServer(async (req, res) => {
435
572
  const callbackUrl = new URL(req.url || '/', `http://127.0.0.1:${port}`);
573
+ if (callbackUrl.pathname === AGENT_RETURN_PATH) {
574
+ const requestToken = req.headers[AGENT_RETURN_TOKEN_HEADER];
575
+ if (req.method !== 'POST'
576
+ || !agentReturnTarget
577
+ || !pendingLoginResult
578
+ || requestToken !== agentReturnToken) {
579
+ res.writeHead(403, { 'cache-control': 'no-store', 'content-type': 'text/plain; charset=utf-8' });
580
+ res.end('Forbidden');
581
+ return;
582
+ }
583
+ const action = callbackUrl.searchParams.get('action');
584
+ if (action === 'cancel') {
585
+ const result = pendingLoginResult;
586
+ res.writeHead(204, { 'cache-control': 'no-store' });
587
+ res.end();
588
+ finish(null, result);
589
+ return;
590
+ }
591
+ if (action !== 'open') {
592
+ res.writeHead(400, { 'cache-control': 'no-store', 'content-type': 'text/plain; charset=utf-8' });
593
+ res.end('Invalid action');
594
+ return;
595
+ }
596
+ try {
597
+ await openUrlWithSystemHandler(agentReturnTarget.url);
598
+ const result = pendingLoginResult;
599
+ res.writeHead(200, { 'cache-control': 'no-store', 'content-type': 'application/json; charset=utf-8' });
600
+ res.end('{"ok":true}');
601
+ finish(null, result);
602
+ }
603
+ catch {
604
+ ctx.logger.warn(`Could not open ${agentReturnTarget.label} automatically.`);
605
+ res.writeHead(500, { 'cache-control': 'no-store', 'content-type': 'text/plain; charset=utf-8' });
606
+ res.end(`无法打开 ${agentReturnTarget.label},请确认应用已安装。`);
607
+ }
608
+ return;
609
+ }
436
610
  if (callbackUrl.pathname !== '/callback') {
437
611
  res.writeHead(404, { 'content-type': 'text/plain; charset=utf-8' });
438
612
  res.end('Not found');
@@ -460,9 +634,26 @@ async function runBrowserLogin(ctx, options, behavior = {}) {
460
634
  }
461
635
  try {
462
636
  const result = await oidcExchange(code, redirectUri, baseUrl, tenantKey, redirectAgentType, profileFromGlobal);
463
- res.writeHead(200, { 'content-type': 'text/html; charset=utf-8' });
464
- res.end(renderE10LoginSuccessPage(result.userId));
465
- finish(null, result);
637
+ const responseHeaders = {
638
+ 'cache-control': 'no-store',
639
+ 'content-security-policy': agentReturnTarget
640
+ ? `default-src 'none'; style-src 'unsafe-inline'; script-src 'nonce-${agentReturnToken}'; connect-src 'self'`
641
+ : `default-src 'none'; style-src 'unsafe-inline'`,
642
+ 'content-type': 'text/html; charset=utf-8',
643
+ 'referrer-policy': 'no-referrer',
644
+ 'x-content-type-options': 'nosniff',
645
+ 'x-frame-options': 'DENY',
646
+ };
647
+ res.writeHead(200, responseHeaders);
648
+ res.end(renderE10LoginSuccessPage(result.userId, agentReturnTarget, agentReturnToken));
649
+ if (!agentReturnTarget) {
650
+ finish(null, result);
651
+ return;
652
+ }
653
+ pendingLoginResult = result;
654
+ if (timer)
655
+ clearTimeout(timer);
656
+ timer = setTimeout(() => finish(null, result), AGENT_RETURN_TIMEOUT_MS);
466
657
  }
467
658
  catch (exchangeError) {
468
659
  const message = exchangeError instanceof Error ? exchangeError.message : String(exchangeError);
@@ -530,6 +721,7 @@ function registerBrowserLoginCommand(auth, action, name, description, behavior =
530
721
  .option('--port <n>', 'Local OAuth callback port', '19800')
531
722
  .option('--agent_type <value>', 'Agent type sent to E10 authorize endpoint')
532
723
  .option('--agent-type <value>', 'Alias of --agent_type')
724
+ .option('--agent-return-url <url>', 'Desktop application URL linked by the login success page')
533
725
  .action(action(async (ctx, options) => {
534
726
  const result = await runBrowserLogin(ctx, options, behavior);
535
727
  ctx.output.write(result, { text: formatLoginResult(result) });
@@ -617,6 +809,7 @@ export function registerE10AuthCommands(parent, action) {
617
809
  registerBrowserLoginCommand(auth, action, 'login', 'Open browser OAuth2.0 login and save E10 auth');
618
810
  registerBrowserLoginCommand(auth, action, 'oidc', 'Alias of auth login for OAuth2.0 browser login');
619
811
  registerBrowserLoginCommand(auth, action, 'xiaoe', 'Try XiaoE unified login and explain before browser OAuth fallback', {
812
+ tryXiaoEUnifiedLogin: true,
620
813
  allowXiaoETokenScript: true,
621
814
  explainXiaoEFallback: true,
622
815
  browserFallback: 'desktop-only',
@@ -1,7 +1,7 @@
1
1
  import { createCipheriv, createDecipheriv, randomBytes } from 'node:crypto';
2
2
  import { existsSync, mkdirSync, readFileSync } from 'node:fs';
3
+ import { createRequire } from 'node:module';
3
4
  import { resolve } from 'node:path';
4
- import { Entry as KeyringEntry } from '@napi-rs/keyring';
5
5
  import { writeWithRetry } from '../../../core/write-with-retry.js';
6
6
  import { getE10AuthRoot } from './paths.js';
7
7
  const ALGORITHM = 'aes-256-gcm';
@@ -9,11 +9,40 @@ const IV_LENGTH = 12;
9
9
  const TAG_LENGTH = 16;
10
10
  const KEYCHAIN_SERVICE = 'weaver-work-cli';
11
11
  const KEYCHAIN_ACCOUNT = 'auth-key';
12
+ const require = createRequire(import.meta.url);
12
13
  let encKey = null;
14
+ let keyringEntryConstructor;
13
15
  function getKeyFilePath() {
14
16
  return resolve(getE10AuthRoot(), '.key');
15
17
  }
18
+ /**
19
+ * Load the native keyring binding only when auth encryption actually needs it.
20
+ *
21
+ * A top-level ESM import would dlopen the platform binary while the CLI command
22
+ * tree is being initialized. If a native dependency is unavailable (for
23
+ * example VCRUNTIME140.dll on Windows), even unrelated commands such as
24
+ * `--version` would terminate before the file-key fallback could run.
25
+ */
26
+ function loadKeyringEntryConstructor() {
27
+ if (keyringEntryConstructor !== undefined)
28
+ return keyringEntryConstructor;
29
+ try {
30
+ const module = require('@napi-rs/keyring');
31
+ keyringEntryConstructor = typeof module.Entry === 'function'
32
+ ? module.Entry
33
+ : null;
34
+ }
35
+ catch {
36
+ // Missing packages, native dlopen failures and unavailable platform
37
+ // backends all use the existing encrypted file-key fallback.
38
+ keyringEntryConstructor = null;
39
+ }
40
+ return keyringEntryConstructor;
41
+ }
16
42
  function readKeychainKey(service) {
43
+ const KeyringEntry = loadKeyringEntryConstructor();
44
+ if (!KeyringEntry)
45
+ return null;
17
46
  try {
18
47
  const entry = new KeyringEntry(service, KEYCHAIN_ACCOUNT);
19
48
  const stored = entry.getPassword();
@@ -28,6 +57,19 @@ function readKeychainKey(service) {
28
57
  }
29
58
  return null;
30
59
  }
60
+ function writeKeychainKey(service, key) {
61
+ const KeyringEntry = loadKeyringEntryConstructor();
62
+ if (!KeyringEntry)
63
+ return false;
64
+ try {
65
+ const entry = new KeyringEntry(service, KEYCHAIN_ACCOUNT);
66
+ entry.setPassword(key.toString('base64'));
67
+ return true;
68
+ }
69
+ catch {
70
+ return false;
71
+ }
72
+ }
31
73
  function readKeyFile(filePath) {
32
74
  if (!existsSync(filePath))
33
75
  return null;
@@ -47,23 +89,21 @@ function getEncKey() {
47
89
  encKey = storedKey;
48
90
  return encKey;
49
91
  }
50
- try {
51
- const fresh = randomBytes(32);
52
- const entry = new KeyringEntry(KEYCHAIN_SERVICE, KEYCHAIN_ACCOUNT);
53
- entry.setPassword(fresh.toString('base64'));
54
- encKey = fresh;
55
- return encKey;
56
- }
57
- catch {
58
- // Keychain may be unavailable in headless environments; fall back to a 0600 file.
59
- }
92
+ // Reuse a previously created fallback key before generating a new keychain
93
+ // value. This keeps existing auth files decryptable if keyring availability
94
+ // changes between CLI runs.
60
95
  const keyFile = getKeyFilePath();
61
96
  const fileKey = readKeyFile(keyFile);
62
97
  if (fileKey) {
63
98
  encKey = fileKey;
64
99
  return encKey;
65
100
  }
66
- encKey = randomBytes(32);
101
+ const fresh = randomBytes(32);
102
+ if (writeKeychainKey(KEYCHAIN_SERVICE, fresh)) {
103
+ encKey = fresh;
104
+ return encKey;
105
+ }
106
+ encKey = fresh;
67
107
  mkdirSync(getE10AuthRoot(), { recursive: true });
68
108
  writeWithRetry(keyFile, encKey.toString('base64'), { mode: 0o600 });
69
109
  return encKey;