chainlesschain 0.162.11 → 0.162.13

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 (166) hide show
  1. package/README.md +30 -25
  2. package/package.json +4 -1
  3. package/src/assets/web-panel/.build-hash +1 -1
  4. package/src/assets/web-panel/assets/{AIOps-ebtJGjAG.js → AIOps-Bq_zxhCr.js} +1 -1
  5. package/src/assets/web-panel/assets/{ActionButton-CypkRN-G.js → ActionButton-CaevDm9t.js} +1 -1
  6. package/src/assets/web-panel/assets/{Analytics-B2JMlIng.js → Analytics-B0gOmwPw.js} +1 -1
  7. package/src/assets/web-panel/assets/{AppLayout-B8QQ4pk7.js → AppLayout-DWhZiV0Q.js} +2 -2
  8. package/src/assets/web-panel/assets/{Audit-BoYaAyFa.js → Audit-ZuZJBCxo.js} +1 -1
  9. package/src/assets/web-panel/assets/{Backup-BfackGZ5.js → Backup-CX7jhH5l.js} +1 -1
  10. package/src/assets/web-panel/assets/{BaseInput-C06FUpDz.js → BaseInput-CVLx7HVq.js} +1 -1
  11. package/src/assets/web-panel/assets/{Chat-BWxMkBYZ.js → Chat-C6yL5tRD.js} +1 -1
  12. package/src/assets/web-panel/assets/{Checkbox-XJMvS3PV.js → Checkbox-BePhbqVq.js} +1 -1
  13. package/src/assets/web-panel/assets/{Codegen-CzR462RK.js → Codegen-B5E4x1Lm.js} +1 -1
  14. package/src/assets/web-panel/assets/{Col-BQHpLNCA.js → Col-CWhNU6A7.js} +1 -1
  15. package/src/assets/web-panel/assets/{Community-BWRRbJYd.js → Community-mSEAuJhp.js} +1 -1
  16. package/src/assets/web-panel/assets/{Compact-BunoKIy9.js → Compact-DSudHzX3.js} +1 -1
  17. package/src/assets/web-panel/assets/{Compliance-CtJfZctm.js → Compliance-CxJLYjyn.js} +1 -1
  18. package/src/assets/web-panel/assets/{Cowork-ER5-_bod.js → Cowork-C-trppQj.js} +1 -1
  19. package/src/assets/web-panel/assets/{Cron-C80jYBw1.js → Cron-_Ij4v5fY.js} +1 -1
  20. package/src/assets/web-panel/assets/{Crosschain-fEMlCNsL.js → Crosschain-eLHXzp5T.js} +1 -1
  21. package/src/assets/web-panel/assets/{DID-BZpctKmU.js → DID-BP04AUUB.js} +1 -1
  22. package/src/assets/web-panel/assets/{Dashboard-RQhZmLi4.js → Dashboard-CzEeQv62.js} +2 -2
  23. package/src/assets/web-panel/assets/{Dropdown-CrpwS84l.js → Dropdown-C_SGOB22.js} +1 -1
  24. package/src/assets/web-panel/assets/{Federation-BEQyZtdR.js → Federation-BgaP4BOv.js} +1 -1
  25. package/src/assets/web-panel/assets/{FormItemContext-DCwvl6Vh.js → FormItemContext-BxGLLt9r.js} +1 -1
  26. package/src/assets/web-panel/assets/{Git-6FihOxMK.js → Git-Bt_uM_Gw.js} +2 -2
  27. package/src/assets/web-panel/assets/{Governance-DlBLHSlJ.js → Governance-N2-0RG_o.js} +1 -1
  28. package/src/assets/web-panel/assets/{Inference-DdSokzV0.js → Inference-eS3g-CzP.js} +1 -1
  29. package/src/assets/web-panel/assets/{KnowledgeGraph-bg8GBHMr.js → KnowledgeGraph-CUuvNVah.js} +1 -1
  30. package/src/assets/web-panel/assets/{Logs-DdFYdLQ-.js → Logs-wPbwEt2r.js} +1 -1
  31. package/src/assets/web-panel/assets/{Marketplace-DjnlAeYF.js → Marketplace-DH91kTwo.js} +1 -1
  32. package/src/assets/web-panel/assets/{McpTools-Czs41YUh.js → McpTools-D-GyyBrI.js} +1 -1
  33. package/src/assets/web-panel/assets/{Memory-CX0b3c8D.js → Memory-BOtUy-tw.js} +1 -1
  34. package/src/assets/web-panel/assets/{MobileBridge-BoFGb9Mm.js → MobileBridge-DIP__XQd.js} +1 -1
  35. package/src/assets/web-panel/assets/{MobileProjects-B8qQ9H-0.js → MobileProjects-1nqr1UsU.js} +1 -1
  36. package/src/assets/web-panel/assets/{Mtc-CRF1NLae.js → Mtc-CCE0x7h2.js} +1 -1
  37. package/src/assets/web-panel/assets/{MtcAudit-CdCm70cJ.js → MtcAudit-BBkz0XUO.js} +1 -1
  38. package/src/assets/web-panel/assets/{Multisig-yoZlpq2Y.js → Multisig-CIKSJvTY.js} +2 -2
  39. package/src/assets/web-panel/assets/{NLProgramming-hFCgqDxJ.js → NLProgramming-BDkgeFcq.js} +1 -1
  40. package/src/assets/web-panel/assets/{Notes-DC8pnxs-.js → Notes-ONiUxfN1.js} +1 -1
  41. package/src/assets/web-panel/assets/{NotificationSettings-DDVg5Nc8.js → NotificationSettings-CGcyKEIe.js} +1 -1
  42. package/src/assets/web-panel/assets/{Organization-0YCtAFMS.js → Organization-BZtMYBJt.js} +4 -4
  43. package/src/assets/web-panel/assets/{Overflow-DhPLoAdz.js → Overflow-C4LfFZAI.js} +1 -1
  44. package/src/assets/web-panel/assets/{OverrideContext-x9ZzjLwk.js → OverrideContext-C_4H9tGA.js} +1 -1
  45. package/src/assets/web-panel/assets/{P2P-BWpuJhkD.js → P2P-D71Cpk-m.js} +1 -1
  46. package/src/assets/web-panel/assets/{Permissions-B4IrizO9.js → Permissions-DRGYF29v.js} +1 -1
  47. package/src/assets/web-panel/assets/PersonalDataHub-CfRYoIua.js +1 -0
  48. package/src/assets/web-panel/assets/PersonalDataHub-Dvaa8niQ.css +1 -0
  49. package/src/assets/web-panel/assets/{Pipeline-M65jR6sq.js → Pipeline-BOyp0_Qo.js} +1 -1
  50. package/src/assets/web-panel/assets/{Privacy-BeO8zLup.js → Privacy-a_AcphvF.js} +1 -1
  51. package/src/assets/web-panel/assets/{ProjectInit-Ck_ZjrVZ.js → ProjectInit-CFu1grYt.js} +1 -1
  52. package/src/assets/web-panel/assets/{ProjectSettings-ijn-97s0.js → ProjectSettings-p54Eivhh.js} +1 -1
  53. package/src/assets/web-panel/assets/{Projects-BsNBemeh.js → Projects-DkB88XAu.js} +1 -1
  54. package/src/assets/web-panel/assets/{Providers-CI7UxKVO.js → Providers-EK7f8DEd.js} +1 -1
  55. package/src/assets/web-panel/assets/{QuickAsk-dE2M1KOB.js → QuickAsk-CpO0w3iP.js} +1 -1
  56. package/src/assets/web-panel/assets/{Recommend-B30EgbKS.js → Recommend-BUJVQdv9.js} +1 -1
  57. package/src/assets/web-panel/assets/{Reputation-CV6n7wMx.js → Reputation-kU2fOuZt.js} +1 -1
  58. package/src/assets/web-panel/assets/{Row-DSaoTjlN.js → Row-oGWRbk6g.js} +1 -1
  59. package/src/assets/web-panel/assets/{RssFeed-_NgBmHaC.js → RssFeed-saC_46Yo.js} +1 -1
  60. package/src/assets/web-panel/assets/{Search-B341ooTV.js → Search-CjtRqFUu.js} +1 -1
  61. package/src/assets/web-panel/assets/{Security-CqCQD8hf.js → Security-BX0NBVfQ.js} +1 -1
  62. package/src/assets/web-panel/assets/{Services-Cju_95rB.js → Services-Bgxsnei_.js} +1 -1
  63. package/src/assets/web-panel/assets/{Skeleton-kh_uW22l.js → Skeleton-CwBb3k2a.js} +1 -1
  64. package/src/assets/web-panel/assets/{Skills-BVRPgciI.js → Skills-CZCMYH6Z.js} +1 -1
  65. package/src/assets/web-panel/assets/{Sla-y-vKFYkI.js → Sla-Djy1uHnZ.js} +1 -1
  66. package/src/assets/web-panel/assets/{SpeechSettings-BXJm9zyo.js → SpeechSettings-CGUI_Uyh.js} +1 -1
  67. package/src/assets/web-panel/assets/{SyncSettings-BmHZR-Kv.js → SyncSettings-DK2CKHRD.js} +1 -1
  68. package/src/assets/web-panel/assets/{Tasks-C7zmYW9f.js → Tasks-BKiOzeIO.js} +1 -1
  69. package/src/assets/web-panel/assets/{Templates-DVEG7FdA.js → Templates-CnQpleXj.js} +1 -1
  70. package/src/assets/web-panel/assets/{Tenant-CpvjzPCo.js → Tenant-DwKz0cjm.js} +1 -1
  71. package/src/assets/web-panel/assets/{Terminal-D_Wpp2iE.js → Terminal-A7t_wsR8.js} +1 -1
  72. package/src/assets/web-panel/assets/{Tokens-QBrjdNqi.js → Tokens-BqYY9l44.js} +1 -1
  73. package/src/assets/web-panel/assets/{Trigger-BhR_VEvQ.js → Trigger-BI4bXFmi.js} +1 -1
  74. package/src/assets/web-panel/assets/{Trust-C0xhM2lC.js → Trust-yMynKTRG.js} +1 -1
  75. package/src/assets/web-panel/assets/{UkeySign-BnyP-W3-.js → UkeySign-Br4IScM6.js} +1 -1
  76. package/src/assets/web-panel/assets/{VideoEditing-C5Y8MyEK.js → VideoEditing-CWcThGsP.js} +1 -1
  77. package/src/assets/web-panel/assets/{Wallet-DzCPCQNF.js → Wallet-CZcAtjxj.js} +1 -1
  78. package/src/assets/web-panel/assets/{WebAuthn-6X5bLtHU.js → WebAuthn-BnTZFMA0.js} +3 -3
  79. package/src/assets/web-panel/assets/{WorkflowEditor-ekS27G9f.js → WorkflowEditor-N7gGz3_n.js} +1 -1
  80. package/src/assets/web-panel/assets/{chat-BikodUwh.js → chat-D175ZIO0.js} +1 -1
  81. package/src/assets/web-panel/assets/{collapseMotion-CjFH_Jop.js → collapseMotion-DfnRZex1.js} +1 -1
  82. package/src/assets/web-panel/assets/{colors-8yIg5K7E.js → colors-LKhZyttv.js} +1 -1
  83. package/src/assets/web-panel/assets/{compact-item-MLWo5-GY.js → compact-item-CsJSebxT.js} +1 -1
  84. package/src/assets/web-panel/assets/{createContext-nir7ccDv.js → createContext-BJ_CPYFC.js} +1 -1
  85. package/src/assets/web-panel/assets/{echarts-Bq-n0MtJ.js → echarts-Dj_pBaVI.js} +1 -1
  86. package/src/assets/web-panel/assets/{hasIn-DxUIHW2P.js → hasIn-CzD3IqH8.js} +1 -1
  87. package/src/assets/web-panel/assets/{icons-CLQTHa5-.js → icons-BOPtEWK4.js} +4 -4
  88. package/src/assets/web-panel/assets/{index-vVrIg9Jk.js → index-6qPbrYF7.js} +1 -1
  89. package/src/assets/web-panel/assets/{index-CCGf6IJj.js → index-B7UYymse.js} +1 -1
  90. package/src/assets/web-panel/assets/{index-DSjWvxVr.js → index-BDSZDDb2.js} +4 -4
  91. package/src/assets/web-panel/assets/{index-BURKtxBq.js → index-BEDFHKO3.js} +1 -1
  92. package/src/assets/web-panel/assets/{index-q3Lr2UzW.js → index-BMvdoiFr.js} +1 -1
  93. package/src/assets/web-panel/assets/{index-BgQtoOHc.js → index-BNVLVzN5.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-Bn5VWKW1.js → index-BSNibAqz.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-4SFekeAy.js → index-BV-__mlC.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-CfeuuE7v.js → index-BXH9ujMW.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-h05fIj9Q.js → index-BZluCuTH.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-9Y0IyfeM.js → index-BhiZDGg7.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-BkMtxzcM.js → index-BjOrt4vw.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-DOIryna2.js → index-BmJdof_c.js} +2 -2
  101. package/src/assets/web-panel/assets/{index-TB5vrA0Z.js → index-BsirlkJ0.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-BgHPrMXP.js → index-BvF2tC6C.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-BSIaRmzU.js → index-C2HBKw07.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-CkSN2Ki_.js → index-CKjBAdm0.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-DLiexKJ2.js → index-CRGNuUIM.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-CeX-HLIi.js → index-CTIkCKav.js} +1 -1
  107. package/src/assets/web-panel/assets/index-CY1mQA2I.js +1 -0
  108. package/src/assets/web-panel/assets/{index-78olN7S9.js → index-CyHdYUeZ.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-BcyG-9vV.js → index-D401L3yx.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-C_W1kVtY.js → index-D5IZCkZG.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-Bpa9senE.js → index-D7ZcBI5s.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-dgZZAsxo.js → index-D8kltMTW.js} +1 -1
  113. package/src/assets/web-panel/assets/index-D9nXHfUB.js +1 -0
  114. package/src/assets/web-panel/assets/{index-DkIon-Gv.js → index-DJVkBmSc.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-C-UB9bYd.js → index-DM3uBEWD.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-Dx5xZmzt.js → index-DOO73rHE.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-DVLJ1iGu.js → index-DXp1jVsK.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-S8mYImvf.js → index-Dd7dICwB.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-SUYLhwZI.js → index-Dm-3kvtD.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-C_Xi08tu.js → index-DnPt5OdD.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-hu-wjfWv.js → index-E7t1hAnk.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-Cp-YnzHN.js → index-JTX9A7w0.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-8qrwsaKy.js → index-Kn-Of5ew.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-Dl-O2OkQ.js → index-R1cFADfk.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-yfNusVbo.js → index-RIO4JKMP.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-DDmc4cig.js → index-uTEVWPYA.js} +1 -1
  127. package/src/assets/web-panel/assets/{initDefaultProps-xUjF_bq0.js → initDefaultProps-CBW0okek.js} +1 -1
  128. package/src/assets/web-panel/assets/{motion-B019-Q6h.js → motion-DGAffQ0Z.js} +1 -1
  129. package/src/assets/web-panel/assets/{move-D2XYj_gA.js → move-DFJ0-5IW.js} +1 -1
  130. package/src/assets/web-panel/assets/{omit-AIzzlguv.js → omit-AvrDghg1.js} +1 -1
  131. package/src/assets/web-panel/assets/{pickAttrs-CRkEQaLs.js → pickAttrs-D7csw9i1.js} +1 -1
  132. package/src/assets/web-panel/assets/{placementArrow-s4kAStH6.js → placementArrow-hZ6Lg6kG.js} +1 -1
  133. package/src/assets/web-panel/assets/{responsiveObserve-BCsWrTkb.js → responsiveObserve-DLLx5VvS.js} +1 -1
  134. package/src/assets/web-panel/assets/{slide-B_Hggtvv.js → slide-BaRIT3ev.js} +1 -1
  135. package/src/assets/web-panel/assets/{statusUtils-DnNf15VW.js → statusUtils-Cdjyuhrz.js} +1 -1
  136. package/src/assets/web-panel/assets/{styleChecker-CSQdy9SQ.js → styleChecker-CbrNybTt.js} +1 -1
  137. package/src/assets/web-panel/assets/useFlexGapSupport-B8gAhiRC.js +1 -0
  138. package/src/assets/web-panel/assets/{useFs-D78PlgeG.js → useFs-BZPy4ICP.js} +1 -1
  139. package/src/assets/web-panel/assets/{useMergedState-O7QXt4P5.js → useMergedState-WwedrFR0.js} +1 -1
  140. package/src/assets/web-panel/assets/{useRefs-0J6m8UWN.js → useRefs-Cdq8EWeF.js} +1 -1
  141. package/src/assets/web-panel/assets/{useState-CSzR8F8O.js → useState-DGS1NOyn.js} +1 -1
  142. package/src/assets/web-panel/assets/{vendor-M5lGV-wr.js → vendor-DhFY8mDK.js} +1 -1
  143. package/src/assets/web-panel/assets/{vnode-BTMmpsWu.js → vnode-6Y0NDMVv.js} +1 -1
  144. package/src/assets/web-panel/assets/{zoom-CwOTbvKc.js → zoom-DTbMGsSH.js} +1 -1
  145. package/src/assets/web-panel/index.html +3 -3
  146. package/src/commands/__tests__/hub-aichat.test.js +277 -0
  147. package/src/commands/__tests__/hub-wechat.test.js +243 -0
  148. package/src/commands/hub.js +881 -0
  149. package/src/commands/sync-providers.js +436 -0
  150. package/src/gateways/ws/personal-data-hub-protocol.js +68 -0
  151. package/src/index.js +6 -0
  152. package/src/lib/__tests__/personal-data-hub-aichat-wizard.test.js +209 -0
  153. package/src/lib/__tests__/sync-credentials.test.js +265 -0
  154. package/src/lib/__tests__/sync-engine-cli.test.js +293 -0
  155. package/src/lib/personal-data-hub-aichat-wizard.js +242 -0
  156. package/src/lib/personal-data-hub-wiring.js +189 -0
  157. package/src/lib/sync-cli-db.js +194 -0
  158. package/src/lib/sync-credentials.js +225 -0
  159. package/src/lib/sync-engine-cli.js +406 -0
  160. package/src/lib/sync-oss-client.js +273 -0
  161. package/src/lib/sync-webdav-client.js +194 -0
  162. package/src/assets/web-panel/assets/PersonalDataHub-BK7I0Rsb.css +0 -1
  163. package/src/assets/web-panel/assets/PersonalDataHub-ZbziiUr6.js +0 -1
  164. package/src/assets/web-panel/assets/index-BeA3spHc.js +0 -1
  165. package/src/assets/web-panel/assets/index-DoLRjAoc.js +0 -1
  166. package/src/assets/web-panel/assets/useFlexGapSupport-Bt-T27Pf.js +0 -1
@@ -0,0 +1,436 @@
1
+ /**
2
+ * cc sync webdav / cc sync oss subcommand groups — Phase 3c follow-up.
3
+ *
4
+ * v0.1 (Phase 1):configure / status / clear — 凭据落 ~/.chainlesschain/
5
+ * sync-credentials.enc (AES-256-GCM),与 desktop secure-config 同 shape。
6
+ *
7
+ * v0.2 (Phase 2):test (real connectivity probe) + run (本机 vault 同步)
8
+ * — 需 @aws-sdk/client-s3 + webdav npm dep + better-sqlite3 vault wiring,
9
+ * 工程更大;本 commit 不含。
10
+ *
11
+ * 命令树:
12
+ * cc sync webdav configure --url ... --username ... --password ... [--remote-path]
13
+ * cc sync webdav status 显示 mask 后凭据 + configured 标记
14
+ * cc sync webdav clear 擦除凭据 + 在 vault 内移除该 provider
15
+ * cc sync oss configure --endpoint --region --bucket --access-key-id
16
+ * --secret-access-key [--remote-path] [--force-path-style]
17
+ * cc sync oss status
18
+ * cc sync oss clear
19
+ *
20
+ * password / secretAccessKey 走 stdin 提示也支持(避免 shell history 留痕)—
21
+ * 留 v0.2 加 prompts;v0.1 仅 flag。
22
+ */
23
+
24
+ "use strict";
25
+
26
+ import chalk from "chalk";
27
+ import {
28
+ ALLOWED_PROVIDER_IDS,
29
+ getCredentials,
30
+ getCredentialsSanitized,
31
+ hasCredentials,
32
+ setCredentials,
33
+ clearCredentials,
34
+ } from "../lib/sync-credentials.js";
35
+ import { WebDAVClient } from "../lib/sync-webdav-client.js";
36
+ import { OSSClient } from "../lib/sync-oss-client.js";
37
+ import { runSync } from "../lib/sync-engine-cli.js";
38
+ import { openCliVault } from "../lib/sync-cli-db.js";
39
+
40
+ function _ensureValidProvider(name) {
41
+ if (!ALLOWED_PROVIDER_IDS.includes(name)) {
42
+ throw new Error(
43
+ `Unknown sync provider '${name}' (allowed: ${ALLOWED_PROVIDER_IDS.join(", ")})`,
44
+ );
45
+ }
46
+ }
47
+
48
+ function _printStatus(providerId) {
49
+ _ensureValidProvider(providerId);
50
+ const masked = getCredentialsSanitized(providerId);
51
+ const configured = hasCredentials(providerId);
52
+ console.log(
53
+ JSON.stringify(
54
+ {
55
+ provider: providerId,
56
+ configured,
57
+ credentials: masked,
58
+ notes: configured
59
+ ? [
60
+ "secrets are masked; raw values stored encrypted at ~/.chainlesschain/sync-credentials.enc",
61
+ ]
62
+ : ["not configured; run `cc sync <provider> configure --<flags>`"],
63
+ },
64
+ null,
65
+ 2,
66
+ ),
67
+ );
68
+ }
69
+
70
+ function _configureWebDAV(opts) {
71
+ const url = (opts.url || "").trim();
72
+ if (!url) throw new Error("--url required");
73
+ const username = (opts.username || "").trim();
74
+ const password = opts.password;
75
+ if (!password)
76
+ throw new Error("--password required (use stdin or env in v0.2)");
77
+ const remotePath = (opts.remotePath || "/").trim();
78
+ setCredentials("webdav", { url, username, password, remotePath });
79
+ console.log(chalk.green("✓ WebDAV credentials saved"));
80
+ console.log(chalk.dim(` url: ${url}`));
81
+ console.log(chalk.dim(` username: ${username}`));
82
+ console.log(chalk.dim(` password: ********`));
83
+ console.log(chalk.dim(` remotePath: ${remotePath}`));
84
+ }
85
+
86
+ function _configureOSS(opts) {
87
+ const endpoint = (opts.endpoint || "").trim();
88
+ if (!endpoint) throw new Error("--endpoint required");
89
+ const bucket = (opts.bucket || "").trim();
90
+ if (!bucket) throw new Error("--bucket required");
91
+ const accessKeyId = (opts.accessKeyId || "").trim();
92
+ if (!accessKeyId) throw new Error("--access-key-id required");
93
+ const secretAccessKey = opts.secretAccessKey;
94
+ if (!secretAccessKey) {
95
+ throw new Error("--secret-access-key required (use stdin or env in v0.2)");
96
+ }
97
+ const region = (opts.region || "auto").trim();
98
+ const remotePath = (opts.remotePath || "").trim();
99
+ const forcePathStyle = opts.forcePathStyle === true;
100
+ setCredentials("oss", {
101
+ endpoint,
102
+ region,
103
+ bucket,
104
+ accessKeyId,
105
+ secretAccessKey,
106
+ remotePath,
107
+ forcePathStyle,
108
+ });
109
+ console.log(chalk.green("✓ OSS / S3 credentials saved"));
110
+ console.log(chalk.dim(` endpoint: ${endpoint}`));
111
+ console.log(chalk.dim(` region: ${region}`));
112
+ console.log(chalk.dim(` bucket: ${bucket}`));
113
+ console.log(chalk.dim(` accessKeyId: ${accessKeyId}`));
114
+ console.log(chalk.dim(` secretAccessKey: ********`));
115
+ console.log(chalk.dim(` remotePath: ${remotePath}`));
116
+ console.log(chalk.dim(` forcePathStyle: ${forcePathStyle}`));
117
+ }
118
+
119
+ function _clearProvider(providerId) {
120
+ _ensureValidProvider(providerId);
121
+ if (!hasCredentials(providerId)) {
122
+ console.log(chalk.dim(`(${providerId} was already empty)`));
123
+ return;
124
+ }
125
+ clearCredentials(providerId);
126
+ console.log(chalk.green(`✓ ${providerId} credentials cleared`));
127
+ }
128
+
129
+ function _loadWebDAVCreds() {
130
+ const c = getCredentials("webdav");
131
+ if (!c.url || !c.password) return null;
132
+ return {
133
+ url: c.url,
134
+ username: c.username || "",
135
+ password: c.password,
136
+ remotePath: c.remotePath || "/",
137
+ };
138
+ }
139
+
140
+ function _loadOSSCreds() {
141
+ const c = getCredentials("oss");
142
+ if (!c.endpoint || !c.bucket || !c.accessKeyId || !c.secretAccessKey)
143
+ return null;
144
+ return {
145
+ endpoint: c.endpoint,
146
+ region: c.region || "auto",
147
+ bucket: c.bucket,
148
+ accessKeyId: c.accessKeyId,
149
+ secretAccessKey: c.secretAccessKey,
150
+ remotePath: c.remotePath || "",
151
+ forcePathStyle: c.forcePathStyle === true,
152
+ };
153
+ }
154
+
155
+ async function _testProvider(providerId) {
156
+ _ensureValidProvider(providerId);
157
+ const creds = providerId === "webdav" ? _loadWebDAVCreds() : _loadOSSCreds();
158
+ if (!creds) {
159
+ throw new Error(
160
+ `${providerId} 凭据未配置,先跑 \`cc sync ${providerId} configure --...\``,
161
+ );
162
+ }
163
+ const client =
164
+ providerId === "webdav" ? new WebDAVClient(creds) : new OSSClient(creds);
165
+ const res = await client.testConnection();
166
+ if (res.ok) {
167
+ console.log(chalk.green(`✓ ${providerId} 连接 OK`));
168
+ return;
169
+ }
170
+ console.error(
171
+ chalk.red(
172
+ `✗ ${providerId} 连接失败 (${res.status || "n/a"}): ${res.error}`,
173
+ ),
174
+ );
175
+ process.exitCode = 2;
176
+ }
177
+
178
+ async function _runProvider(providerId, opts = {}) {
179
+ _ensureValidProvider(providerId);
180
+ const creds = providerId === "webdav" ? _loadWebDAVCreds() : _loadOSSCreds();
181
+ if (!creds) {
182
+ throw new Error(
183
+ `${providerId} 凭据未配置,先跑 \`cc sync ${providerId} configure --...\``,
184
+ );
185
+ }
186
+
187
+ let vault;
188
+ try {
189
+ vault = await openCliVault();
190
+ } catch (err) {
191
+ if (err.code === "BETTER_SQLITE3_MISSING") {
192
+ console.error(chalk.red(`✗ ${err.message}`));
193
+ process.exitCode = 2;
194
+ return;
195
+ }
196
+ throw err;
197
+ }
198
+ const { dbManager, vaultPath } = vault;
199
+ if (opts.verbose) console.log(chalk.dim(`vault: ${vaultPath}`));
200
+
201
+ const client =
202
+ providerId === "webdav" ? new WebDAVClient(creds) : new OSSClient(creds);
203
+ let lastPrint = 0;
204
+ const onProgress = (e) => {
205
+ // Throttle stdout to avoid TTY thrash (engine already 5/500ms)
206
+ const now = Date.now();
207
+ if (
208
+ e.phase === "start" ||
209
+ ["success", "conflict", "failed"].includes(e.phase) ||
210
+ now - lastPrint >= 1000
211
+ ) {
212
+ lastPrint = now;
213
+ const parts = [`[${e.phase}]`];
214
+ if (e.totalPending != null) parts.push(`total=${e.totalPending}`);
215
+ parts.push(
216
+ `pushed=${e.pushed}`,
217
+ `skipped=${e.skipped}`,
218
+ `deleted=${e.deleted}`,
219
+ );
220
+ console.log(chalk.dim(parts.join(" ")));
221
+ }
222
+ };
223
+
224
+ try {
225
+ const result = await runSync({
226
+ dbManager,
227
+ client,
228
+ providerId,
229
+ accountKey: "",
230
+ onProgress,
231
+ });
232
+ if (result.success) {
233
+ console.log(
234
+ chalk.green(`✓ ${providerId} sync done (${result.status})`) +
235
+ ` — pushed=${result.pushed} skipped=${result.skipped} deleted=${result.deleted} duration=${result.durationMs}ms`,
236
+ );
237
+ } else {
238
+ console.error(
239
+ chalk.red(`✗ ${providerId} sync failed`) +
240
+ ` — pushed=${result.pushed} skipped=${result.skipped} deleted=${result.deleted}`,
241
+ );
242
+ if (result.error) console.error(chalk.red(` error: ${result.error}`));
243
+ process.exitCode = 2;
244
+ }
245
+ } finally {
246
+ try {
247
+ dbManager.close();
248
+ } catch (_e) {
249
+ /* cleanup */
250
+ }
251
+ }
252
+ }
253
+
254
+ /**
255
+ * Attach `cc sync webdav *` and `cc sync oss *` subcommands to the existing
256
+ * `cc sync` parent command. Caller passes the program; we find the sync
257
+ * parent and add children.
258
+ */
259
+ export function registerSyncProviderCommands(program) {
260
+ const parent = program.commands.find((c) => c.name() === "sync");
261
+ if (!parent) {
262
+ throw new Error(
263
+ "registerSyncProviderCommands: parent `sync` command not registered yet — call after registerSyncCommand",
264
+ );
265
+ }
266
+
267
+ // ── webdav subgroup ────────────────────────────────────────────
268
+ const webdav = parent
269
+ .command("webdav")
270
+ .description(
271
+ "WebDAV (Nextcloud / 坚果云 / 群晖) sync provider — credential management",
272
+ );
273
+
274
+ webdav
275
+ .command("configure")
276
+ .description(
277
+ "Save WebDAV credentials to ~/.chainlesschain/sync-credentials.enc",
278
+ )
279
+ .requiredOption("--url <url>", "WebDAV endpoint URL")
280
+ .option("--username <name>", "WebDAV username", "")
281
+ .requiredOption(
282
+ "--password <pw>",
283
+ "WebDAV password (use stdin in v0.2 — for now this WILL hit shell history)",
284
+ )
285
+ .option("--remote-path <p>", "remote directory path", "/")
286
+ .action(async (opts) => {
287
+ try {
288
+ _configureWebDAV(opts);
289
+ } catch (err) {
290
+ console.error(chalk.red(`✗ ${err?.message || err}`));
291
+ process.exitCode = 2;
292
+ }
293
+ });
294
+
295
+ webdav
296
+ .command("status")
297
+ .description("Show sanitized WebDAV credentials + configured flag")
298
+ .action(() => {
299
+ try {
300
+ _printStatus("webdav");
301
+ } catch (err) {
302
+ console.error(chalk.red(`✗ ${err?.message || err}`));
303
+ process.exitCode = 2;
304
+ }
305
+ });
306
+
307
+ webdav
308
+ .command("clear")
309
+ .description("Remove WebDAV credentials from vault")
310
+ .action(() => {
311
+ try {
312
+ _clearProvider("webdav");
313
+ } catch (err) {
314
+ console.error(chalk.red(`✗ ${err?.message || err}`));
315
+ process.exitCode = 2;
316
+ }
317
+ });
318
+
319
+ webdav
320
+ .command("test")
321
+ .description("Probe WebDAV connectivity (PROPFIND on remotePath)")
322
+ .action(async () => {
323
+ try {
324
+ await _testProvider("webdav");
325
+ } catch (err) {
326
+ console.error(chalk.red(`✗ ${err?.message || err}`));
327
+ process.exitCode = 2;
328
+ }
329
+ });
330
+
331
+ webdav
332
+ .command("run")
333
+ .description(
334
+ "Run one full WebDAV sync against ~/.chainlesschain/cli-vault.db",
335
+ )
336
+ .option("-v, --verbose", "show vault path + verbose progress", false)
337
+ .action(async (opts) => {
338
+ try {
339
+ await _runProvider("webdav", opts);
340
+ } catch (err) {
341
+ console.error(chalk.red(`✗ ${err?.message || err}`));
342
+ process.exitCode = 2;
343
+ }
344
+ });
345
+
346
+ // ── oss subgroup ───────────────────────────────────────────────
347
+ const oss = parent
348
+ .command("oss")
349
+ .description(
350
+ "S3 / OSS (AWS / 阿里云 / R2 / B2) sync provider — credential management",
351
+ );
352
+
353
+ oss
354
+ .command("configure")
355
+ .description(
356
+ "Save OSS credentials to ~/.chainlesschain/sync-credentials.enc",
357
+ )
358
+ .requiredOption(
359
+ "--endpoint <url>",
360
+ "S3-compat endpoint URL (e.g. https://oss-cn-hangzhou.aliyuncs.com)",
361
+ )
362
+ .option(
363
+ "--region <r>",
364
+ "region (default: auto for R2 / explicit for AWS+aliyun)",
365
+ "auto",
366
+ )
367
+ .requiredOption("--bucket <name>", "target bucket name")
368
+ .requiredOption("--access-key-id <id>", "access key id")
369
+ .requiredOption(
370
+ "--secret-access-key <secret>",
371
+ "secret access key (use stdin in v0.2 — hits shell history now)",
372
+ )
373
+ .option("--remote-path <p>", "object key prefix", "")
374
+ .option(
375
+ "--force-path-style",
376
+ "use path-style URLs (R2 / MinIO need true)",
377
+ false,
378
+ )
379
+ .action(async (opts) => {
380
+ try {
381
+ _configureOSS(opts);
382
+ } catch (err) {
383
+ console.error(chalk.red(`✗ ${err?.message || err}`));
384
+ process.exitCode = 2;
385
+ }
386
+ });
387
+
388
+ oss
389
+ .command("status")
390
+ .description("Show sanitized OSS credentials + configured flag")
391
+ .action(() => {
392
+ try {
393
+ _printStatus("oss");
394
+ } catch (err) {
395
+ console.error(chalk.red(`✗ ${err?.message || err}`));
396
+ process.exitCode = 2;
397
+ }
398
+ });
399
+
400
+ oss
401
+ .command("clear")
402
+ .description("Remove OSS credentials from vault")
403
+ .action(() => {
404
+ try {
405
+ _clearProvider("oss");
406
+ } catch (err) {
407
+ console.error(chalk.red(`✗ ${err?.message || err}`));
408
+ process.exitCode = 2;
409
+ }
410
+ });
411
+
412
+ oss
413
+ .command("test")
414
+ .description("Probe S3 / OSS connectivity (HeadBucket)")
415
+ .action(async () => {
416
+ try {
417
+ await _testProvider("oss");
418
+ } catch (err) {
419
+ console.error(chalk.red(`✗ ${err?.message || err}`));
420
+ process.exitCode = 2;
421
+ }
422
+ });
423
+
424
+ oss
425
+ .command("run")
426
+ .description("Run one full OSS sync against ~/.chainlesschain/cli-vault.db")
427
+ .option("-v, --verbose", "show vault path + verbose progress", false)
428
+ .action(async (opts) => {
429
+ try {
430
+ await _runProvider("oss", opts);
431
+ } catch (err) {
432
+ console.error(chalk.red(`✗ ${err?.message || err}`));
433
+ process.exitCode = 2;
434
+ }
435
+ });
436
+ }
@@ -21,6 +21,7 @@ import {
21
21
  getHub,
22
22
  close as closeHub,
23
23
  } from "../../lib/personal-data-hub-wiring.js";
24
+ import { getAIChatWizard } from "../../lib/personal-data-hub-aichat-wizard.js";
24
25
  import { existsSync, unlinkSync, readdirSync } from "node:fs";
25
26
  import { join } from "node:path";
26
27
 
@@ -212,6 +213,28 @@ export const PERSONAL_DATA_HUB_HANDLERS = {
212
213
  }),
213
214
  ),
214
215
 
216
+ // ─── Phase 12.6.8 — WeChat env-probe + register / unregister / list ──
217
+
218
+ "personal-data-hub.wechat-env-probe": async () =>
219
+ withHub(async (hub) => await hub.probeWechatEnv()),
220
+
221
+ "personal-data-hub.register-wechat": async (msg) =>
222
+ withHub(async (hub) =>
223
+ await hub.registerWechatAdapter({
224
+ account: msg.account,
225
+ dbPath: msg.dbPath,
226
+ wechatDataPath: msg.wechatDataPath,
227
+ fridaOpts: msg.fridaOpts,
228
+ keyProviderOverride: msg.keyProviderOverride,
229
+ }),
230
+ ),
231
+
232
+ "personal-data-hub.unregister-wechat": async (msg) =>
233
+ withHub(async (hub) => await hub.unregisterWechatAdapter(msg.uin)),
234
+
235
+ "personal-data-hub.list-wechat-accounts": async () =>
236
+ withHub((hub) => hub.listWechatAccounts()),
237
+
215
238
  // ─── Phase 8 — EntityResolver review / merge / unmerge ───────────────
216
239
 
217
240
  "personal-data-hub.review-queue-list": async (msg) =>
@@ -264,6 +287,51 @@ export const PERSONAL_DATA_HUB_HANDLERS = {
264
287
 
265
288
  "personal-data-hub.run-skill": async (msg) =>
266
289
  withHub(async (hub) => await hub.runSkill(msg.name, msg.options || {})),
290
+
291
+ // ─── Phase 10.3 — AIChat WebView 鉴权向导 (paste-mode on cc ui) ────────
292
+
293
+ "personal-data-hub.aichat-open-login": async (msg) =>
294
+ withHub(async (hub) => {
295
+ const wiz = getAIChatWizard({ hubDir: hub.hubDir });
296
+ return await wiz.openVendorLogin({
297
+ vendor: msg.vendor,
298
+ opts: msg.opts || {},
299
+ });
300
+ }),
301
+
302
+ "personal-data-hub.aichat-probe-cookies": async (msg) =>
303
+ withHub(async (hub) => {
304
+ const wiz = getAIChatWizard({ hubDir: hub.hubDir });
305
+ return await wiz.probeCookies({
306
+ vendor: msg.vendor,
307
+ cookieHeader: msg.cookieHeader,
308
+ });
309
+ }),
310
+
311
+ "personal-data-hub.aichat-register-vendor": async (msg) =>
312
+ withHub(async (hub) => {
313
+ const wiz = getAIChatWizard({ hubDir: hub.hubDir });
314
+ return await wiz.registerVendor({
315
+ vendor: msg.vendor,
316
+ cookies: msg.cookies,
317
+ opts: msg.opts || {},
318
+ });
319
+ }),
320
+
321
+ "personal-data-hub.aichat-rotate-login": async (msg) =>
322
+ withHub(async (hub) => {
323
+ const wiz = getAIChatWizard({ hubDir: hub.hubDir });
324
+ return await wiz.rotateLoginPartition({ vendor: msg.vendor });
325
+ }),
326
+
327
+ "personal-data-hub.list-aichat-accounts": async () =>
328
+ withHub(async (hub) => await hub.listAIChatAccounts()),
329
+
330
+ "personal-data-hub.unregister-aichat": async (msg) =>
331
+ withHub(async (hub) => await hub.unregisterAIChatVendor(msg.vendor)),
332
+
333
+ "personal-data-hub.aichat-health-check-once": async () =>
334
+ withHub(async (hub) => await hub.runAIChatHealthCheckOnce()),
267
335
  };
268
336
 
269
337
  /**
package/src/index.js CHANGED
@@ -15,6 +15,7 @@ import { registerNoteCommand } from "./commands/note.js";
15
15
  import { registerChatCommand } from "./commands/chat.js";
16
16
  import { registerAskCommand } from "./commands/ask.js";
17
17
  import { registerLlmCommand } from "./commands/llm.js";
18
+ import { registerHubCommand } from "./commands/hub.js";
18
19
  import {
19
20
  registerAgentCommand,
20
21
  registerSubAgentV2Command,
@@ -67,6 +68,7 @@ import { registerAuthCommand } from "./commands/auth.js";
67
68
  import { registerAuditCommand } from "./commands/audit.js";
68
69
  import { registerP2pCommand } from "./commands/p2p.js";
69
70
  import { registerSyncCommand } from "./commands/sync.js";
71
+ import { registerSyncProviderCommands } from "./commands/sync-providers.js";
70
72
  import { registerWalletCommand } from "./commands/wallet.js";
71
73
  import { registerOrgCommand } from "./commands/org.js";
72
74
  import { registerPluginCommand } from "./commands/plugin.js";
@@ -404,6 +406,7 @@ export function createProgram(opts = {}) {
404
406
  registerChatCommand(program);
405
407
  registerAskCommand(program);
406
408
  registerLlmCommand(program);
409
+ registerHubCommand(program);
407
410
  registerAgentCommand(program);
408
411
  registerSubAgentV2Command(program);
409
412
  registerExecBackendV2Command(program);
@@ -464,6 +467,9 @@ export function createProgram(opts = {}) {
464
467
  // Phase 5: P2P, blockchain & enterprise
465
468
  registerP2pCommand(program);
466
469
  registerSyncCommand(program);
470
+ // Phase 3c follow-up — cc sync webdav / cc sync oss subgroups (credential mgmt).
471
+ // Must come AFTER registerSyncCommand so the `sync` parent exists.
472
+ registerSyncProviderCommands(program);
467
473
  registerWalletCommand(program);
468
474
  registerOrgCommand(program);
469
475
  registerPluginCommand(program);