chainlesschain 0.162.12 → 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-C3TDNq29.js → AIOps-Bq_zxhCr.js} +1 -1
  5. package/src/assets/web-panel/assets/{ActionButton-C9fE18pE.js → ActionButton-CaevDm9t.js} +1 -1
  6. package/src/assets/web-panel/assets/{Analytics-wnZF602C.js → Analytics-B0gOmwPw.js} +1 -1
  7. package/src/assets/web-panel/assets/{AppLayout-BjgTMK7O.js → AppLayout-DWhZiV0Q.js} +2 -2
  8. package/src/assets/web-panel/assets/{Audit-BBL0BW5_.js → Audit-ZuZJBCxo.js} +1 -1
  9. package/src/assets/web-panel/assets/{Backup-BKLqYCWU.js → Backup-CX7jhH5l.js} +1 -1
  10. package/src/assets/web-panel/assets/{BaseInput-BGSzMCZs.js → BaseInput-CVLx7HVq.js} +1 -1
  11. package/src/assets/web-panel/assets/{Chat-CQWzZWEY.js → Chat-C6yL5tRD.js} +1 -1
  12. package/src/assets/web-panel/assets/{Checkbox-BkTri12Q.js → Checkbox-BePhbqVq.js} +1 -1
  13. package/src/assets/web-panel/assets/{Codegen-BH1m09EO.js → Codegen-B5E4x1Lm.js} +1 -1
  14. package/src/assets/web-panel/assets/{Col-BXnBuqIa.js → Col-CWhNU6A7.js} +1 -1
  15. package/src/assets/web-panel/assets/{Community-C_Nr4XCx.js → Community-mSEAuJhp.js} +1 -1
  16. package/src/assets/web-panel/assets/{Compact-Du6GwLrj.js → Compact-DSudHzX3.js} +1 -1
  17. package/src/assets/web-panel/assets/{Compliance-66M0oi1Q.js → Compliance-CxJLYjyn.js} +1 -1
  18. package/src/assets/web-panel/assets/{Cowork-DQrkZRNd.js → Cowork-C-trppQj.js} +1 -1
  19. package/src/assets/web-panel/assets/{Cron-CwdIFH_v.js → Cron-_Ij4v5fY.js} +1 -1
  20. package/src/assets/web-panel/assets/{Crosschain-DqlcrQ9L.js → Crosschain-eLHXzp5T.js} +1 -1
  21. package/src/assets/web-panel/assets/{DID-OmPLKf7L.js → DID-BP04AUUB.js} +1 -1
  22. package/src/assets/web-panel/assets/{Dashboard-D_dampTL.js → Dashboard-CzEeQv62.js} +2 -2
  23. package/src/assets/web-panel/assets/{Dropdown-CA1W7jAn.js → Dropdown-C_SGOB22.js} +1 -1
  24. package/src/assets/web-panel/assets/{Federation-Chlk9a7s.js → Federation-BgaP4BOv.js} +1 -1
  25. package/src/assets/web-panel/assets/{FormItemContext-t0UqYFLq.js → FormItemContext-BxGLLt9r.js} +1 -1
  26. package/src/assets/web-panel/assets/{Git-CEq0raYm.js → Git-Bt_uM_Gw.js} +2 -2
  27. package/src/assets/web-panel/assets/{Governance-C06CX7Ge.js → Governance-N2-0RG_o.js} +1 -1
  28. package/src/assets/web-panel/assets/{Inference-6VIFHxIP.js → Inference-eS3g-CzP.js} +1 -1
  29. package/src/assets/web-panel/assets/{KnowledgeGraph-BCJPjMBQ.js → KnowledgeGraph-CUuvNVah.js} +1 -1
  30. package/src/assets/web-panel/assets/{Logs-BBpOYFct.js → Logs-wPbwEt2r.js} +1 -1
  31. package/src/assets/web-panel/assets/{Marketplace-BFH6jMWt.js → Marketplace-DH91kTwo.js} +1 -1
  32. package/src/assets/web-panel/assets/{McpTools-uCFvRqGs.js → McpTools-D-GyyBrI.js} +1 -1
  33. package/src/assets/web-panel/assets/{Memory-B0Kux_KT.js → Memory-BOtUy-tw.js} +1 -1
  34. package/src/assets/web-panel/assets/{MobileBridge-DHow2jiK.js → MobileBridge-DIP__XQd.js} +1 -1
  35. package/src/assets/web-panel/assets/{MobileProjects-BFo9YQZp.js → MobileProjects-1nqr1UsU.js} +1 -1
  36. package/src/assets/web-panel/assets/{Mtc-riOh1G_F.js → Mtc-CCE0x7h2.js} +1 -1
  37. package/src/assets/web-panel/assets/{MtcAudit-Bm-hE2SP.js → MtcAudit-BBkz0XUO.js} +1 -1
  38. package/src/assets/web-panel/assets/{Multisig-DfUQxh5a.js → Multisig-CIKSJvTY.js} +2 -2
  39. package/src/assets/web-panel/assets/{NLProgramming-DuNvLBEq.js → NLProgramming-BDkgeFcq.js} +1 -1
  40. package/src/assets/web-panel/assets/{Notes-DB20wd3c.js → Notes-ONiUxfN1.js} +1 -1
  41. package/src/assets/web-panel/assets/{NotificationSettings-CB-GkOWR.js → NotificationSettings-CGcyKEIe.js} +1 -1
  42. package/src/assets/web-panel/assets/{Organization-3bU7PZuG.js → Organization-BZtMYBJt.js} +4 -4
  43. package/src/assets/web-panel/assets/{Overflow-BGCPP_0Y.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-BHgAe1oC.js → P2P-D71Cpk-m.js} +1 -1
  46. package/src/assets/web-panel/assets/{Permissions-BuOD4xwc.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-DBS5U4LB.js → Pipeline-BOyp0_Qo.js} +1 -1
  50. package/src/assets/web-panel/assets/{Privacy-UNjIc5El.js → Privacy-a_AcphvF.js} +1 -1
  51. package/src/assets/web-panel/assets/{ProjectInit-CicqCJGy.js → ProjectInit-CFu1grYt.js} +1 -1
  52. package/src/assets/web-panel/assets/{ProjectSettings-CIxAbt4Y.js → ProjectSettings-p54Eivhh.js} +1 -1
  53. package/src/assets/web-panel/assets/{Projects-BJycZScO.js → Projects-DkB88XAu.js} +1 -1
  54. package/src/assets/web-panel/assets/{Providers-DxXvprme.js → Providers-EK7f8DEd.js} +1 -1
  55. package/src/assets/web-panel/assets/{QuickAsk-rrqjU8_Y.js → QuickAsk-CpO0w3iP.js} +1 -1
  56. package/src/assets/web-panel/assets/{Recommend-BEwHMhI7.js → Recommend-BUJVQdv9.js} +1 -1
  57. package/src/assets/web-panel/assets/{Reputation-DoVKCCMn.js → Reputation-kU2fOuZt.js} +1 -1
  58. package/src/assets/web-panel/assets/{Row-F5XcDhHr.js → Row-oGWRbk6g.js} +1 -1
  59. package/src/assets/web-panel/assets/{RssFeed-cZrRG7k8.js → RssFeed-saC_46Yo.js} +1 -1
  60. package/src/assets/web-panel/assets/{Search-B9ctZjqx.js → Search-CjtRqFUu.js} +1 -1
  61. package/src/assets/web-panel/assets/{Security-Z62hl1mc.js → Security-BX0NBVfQ.js} +1 -1
  62. package/src/assets/web-panel/assets/{Services-CQf5XqgZ.js → Services-Bgxsnei_.js} +1 -1
  63. package/src/assets/web-panel/assets/{Skeleton-DuCKw2Eh.js → Skeleton-CwBb3k2a.js} +1 -1
  64. package/src/assets/web-panel/assets/{Skills-qVkhva0s.js → Skills-CZCMYH6Z.js} +1 -1
  65. package/src/assets/web-panel/assets/{Sla-BQbatr7s.js → Sla-Djy1uHnZ.js} +1 -1
  66. package/src/assets/web-panel/assets/{SpeechSettings-DLFBzAgD.js → SpeechSettings-CGUI_Uyh.js} +1 -1
  67. package/src/assets/web-panel/assets/{SyncSettings-CrzETZMW.js → SyncSettings-DK2CKHRD.js} +1 -1
  68. package/src/assets/web-panel/assets/{Tasks-D_EQ1nJ7.js → Tasks-BKiOzeIO.js} +1 -1
  69. package/src/assets/web-panel/assets/{Templates-D4y-dGRc.js → Templates-CnQpleXj.js} +1 -1
  70. package/src/assets/web-panel/assets/{Tenant-2XI0jkPn.js → Tenant-DwKz0cjm.js} +1 -1
  71. package/src/assets/web-panel/assets/{Terminal-fUi5V2Z9.js → Terminal-A7t_wsR8.js} +1 -1
  72. package/src/assets/web-panel/assets/{Tokens-BuUNB2mg.js → Tokens-BqYY9l44.js} +1 -1
  73. package/src/assets/web-panel/assets/{Trigger-7DqLLuej.js → Trigger-BI4bXFmi.js} +1 -1
  74. package/src/assets/web-panel/assets/{Trust-CeACvTYx.js → Trust-yMynKTRG.js} +1 -1
  75. package/src/assets/web-panel/assets/{UkeySign-mDP9EXHq.js → UkeySign-Br4IScM6.js} +1 -1
  76. package/src/assets/web-panel/assets/{VideoEditing-veWlKclv.js → VideoEditing-CWcThGsP.js} +1 -1
  77. package/src/assets/web-panel/assets/{Wallet-Cd2Hheb8.js → Wallet-CZcAtjxj.js} +1 -1
  78. package/src/assets/web-panel/assets/{WebAuthn-DyL7ZiHX.js → WebAuthn-BnTZFMA0.js} +3 -3
  79. package/src/assets/web-panel/assets/{WorkflowEditor-C7-7LJH9.js → WorkflowEditor-N7gGz3_n.js} +1 -1
  80. package/src/assets/web-panel/assets/{chat-DXomZMuo.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-DlU92QNs.js → colors-LKhZyttv.js} +1 -1
  83. package/src/assets/web-panel/assets/{compact-item-sBiTL8mX.js → compact-item-CsJSebxT.js} +1 -1
  84. package/src/assets/web-panel/assets/{createContext-DZXEnzum.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-CpCHBZ2M.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-ClN_JuFa.js → index-6qPbrYF7.js} +1 -1
  89. package/src/assets/web-panel/assets/{index-CDyzZ8_O.js → index-B7UYymse.js} +1 -1
  90. package/src/assets/web-panel/assets/{index-C52udT0_.js → index-BDSZDDb2.js} +4 -4
  91. package/src/assets/web-panel/assets/{index-s8tvk-fF.js → index-BEDFHKO3.js} +1 -1
  92. package/src/assets/web-panel/assets/{index-D_IgY63-.js → index-BMvdoiFr.js} +1 -1
  93. package/src/assets/web-panel/assets/{index-Dyg6ikIL.js → index-BNVLVzN5.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-B0Qbxr57.js → index-BSNibAqz.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-DeGnHcp5.js → index-BV-__mlC.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-B_-RETt0.js → index-BXH9ujMW.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-XI6772AD.js → index-BZluCuTH.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-BqnhEJls.js → index-BhiZDGg7.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-BK2AFy44.js → index-BjOrt4vw.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-Dn8m1d1f.js → index-BmJdof_c.js} +2 -2
  101. package/src/assets/web-panel/assets/{index-C6SDf50u.js → index-BsirlkJ0.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-CD3iljXs.js → index-BvF2tC6C.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-CJ7XYa5K.js → index-C2HBKw07.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-_zyXBoS7.js → index-CKjBAdm0.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-X48zYgZ6.js → index-CRGNuUIM.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-Dj9Nvz6S.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-C59FgSkU.js → index-CyHdYUeZ.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-B23tuoo9.js → index-D401L3yx.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-DKe9jmKG.js → index-D5IZCkZG.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-F9cBucYf.js → index-D7ZcBI5s.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-CjXSvceY.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-Dq5Rn5VS.js → index-DJVkBmSc.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-ibFHnqHz.js → index-DM3uBEWD.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-ChahjdYE.js → index-DOO73rHE.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-CivbS-57.js → index-DXp1jVsK.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-B3k9UPHc.js → index-Dd7dICwB.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-Di1_EQ-X.js → index-Dm-3kvtD.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-DygNvCeR.js → index-DnPt5OdD.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-D_MzScPM.js → index-E7t1hAnk.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-CUe5t5Aa.js → index-JTX9A7w0.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-CwbWZubA.js → index-Kn-Of5ew.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-DUlPMzoM.js → index-R1cFADfk.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-TwQZkVGh.js → index-RIO4JKMP.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-ThrAiEF9.js → index-uTEVWPYA.js} +1 -1
  127. package/src/assets/web-panel/assets/{initDefaultProps-DEi92ZnZ.js → initDefaultProps-CBW0okek.js} +1 -1
  128. package/src/assets/web-panel/assets/{motion-BtYKzpOc.js → motion-DGAffQ0Z.js} +1 -1
  129. package/src/assets/web-panel/assets/{move-Cb3A1-v-.js → move-DFJ0-5IW.js} +1 -1
  130. package/src/assets/web-panel/assets/{omit-B6qPDdOf.js → omit-AvrDghg1.js} +1 -1
  131. package/src/assets/web-panel/assets/{pickAttrs-DDyeQMUc.js → pickAttrs-D7csw9i1.js} +1 -1
  132. package/src/assets/web-panel/assets/{placementArrow-BPV6VO47.js → placementArrow-hZ6Lg6kG.js} +1 -1
  133. package/src/assets/web-panel/assets/{responsiveObserve-DJ1ra4dT.js → responsiveObserve-DLLx5VvS.js} +1 -1
  134. package/src/assets/web-panel/assets/{slide-D6v8tHvB.js → slide-BaRIT3ev.js} +1 -1
  135. package/src/assets/web-panel/assets/{statusUtils-DulKcQLZ.js → statusUtils-Cdjyuhrz.js} +1 -1
  136. package/src/assets/web-panel/assets/{styleChecker-Bne7zwMt.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-CR-iLa4Z.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-yL9axxBy.js → vnode-6Y0NDMVv.js} +1 -1
  144. package/src/assets/web-panel/assets/{zoom-B-VCMXSD.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 +417 -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 +4 -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--WA-aZAJ.js +0 -1
  163. package/src/assets/web-panel/assets/PersonalDataHub-BK7I0Rsb.css +0 -1
  164. package/src/assets/web-panel/assets/index-CcRX6BlT.js +0 -1
  165. package/src/assets/web-panel/assets/index-z6h6tqP3.js +0 -1
  166. package/src/assets/web-panel/assets/useFlexGapSupport-C1miTomM.js +0 -1
@@ -19,6 +19,7 @@ import chalk from "chalk";
19
19
  import ora from "ora";
20
20
  import { logger } from "../lib/logger.js";
21
21
  import { getHub } from "../lib/personal-data-hub-wiring.js";
22
+ import { getAIChatWizard } from "../lib/personal-data-hub-aichat-wizard.js";
22
23
 
23
24
  function printJson(obj) {
24
25
  console.log(JSON.stringify(obj, null, 2));
@@ -356,6 +357,316 @@ async function cmdRunSkill(name, options) {
356
357
  }
357
358
  }
358
359
 
360
+ // ─── Phase 10.3 — cc hub aichat <verb> wizard subcommand surface ─────
361
+ //
362
+ // Mirrors the WS topics (personal-data-hub.aichat-*) so scripts and the
363
+ // Android in-app terminal can drive the AIChat WebView wizard without a
364
+ // UI. cc ui defaults to fallbackMode:"paste" — these subcommands inherit
365
+ // that, so the user-facing path is always: login (print loginUrl) →
366
+ // fetch cookies in external browser → register --cookies <string>.
367
+
368
+ async function cmdAIChatList(options) {
369
+ try {
370
+ const wiz =
371
+ options._wizard ||
372
+ getAIChatWizard({ hubDir: (await (options._getHub || getHub)()).hubDir });
373
+ // Probe each known vendor for current health
374
+ const items = [];
375
+ for (const vendor of options._knownVendors || _defaultKnownVendors()) {
376
+ const opened = await wiz.openVendorLogin({ vendor });
377
+ items.push({
378
+ vendor,
379
+ displayName: opened.notes ? opened.notes.split(";")[0] : vendor,
380
+ loginUrl: opened.loginUrl,
381
+ fallbackMode: opened.fallbackMode,
382
+ requiredCookies: opened.requiredCookies || [],
383
+ });
384
+ }
385
+ if (options.json) {
386
+ printJson({ vendors: items });
387
+ } else {
388
+ logger.log(chalk.bold("可注册 vendor 列表:"));
389
+ for (const v of items) {
390
+ logger.log(` • ${chalk.cyan(v.vendor)} ${chalk.gray(v.loginUrl)}`);
391
+ }
392
+ }
393
+ } catch (err) {
394
+ fail(null, err, options.json);
395
+ }
396
+ }
397
+
398
+ async function cmdAIChatLogin(vendor, options) {
399
+ try {
400
+ const wiz =
401
+ options._wizard ||
402
+ getAIChatWizard({ hubDir: (await (options._getHub || getHub)()).hubDir });
403
+ const r = await wiz.openVendorLogin({ vendor });
404
+ if (options.json) {
405
+ printJson(r);
406
+ return;
407
+ }
408
+ if (!r.ok) {
409
+ logger.error(chalk.red(`✗ ${r.reason || "open failed"}`));
410
+ process.exit(1);
411
+ }
412
+ logger.log(chalk.bold(`vendor: ${vendor}`));
413
+ logger.log(` loginUrl: ${chalk.cyan(r.loginUrl)}`);
414
+ if (r.helpText) logger.log(` ${chalk.gray(r.helpText)}`);
415
+ if (r.requiredCookies && r.requiredCookies.length) {
416
+ logger.log(
417
+ chalk.gray(
418
+ ` required: ${r.requiredCookies.join(", ")} (至少识别 1 个)`,
419
+ ),
420
+ );
421
+ }
422
+ logger.log(
423
+ chalk.gray(
424
+ "\n登录完成后从浏览器 DevTools 复制 cookie,再跑:\n cc hub aichat register " +
425
+ vendor +
426
+ ' --cookies "<paste>"',
427
+ ),
428
+ );
429
+ } catch (err) {
430
+ fail(null, err, options.json);
431
+ }
432
+ }
433
+
434
+ async function cmdAIChatProbe(vendor, options) {
435
+ try {
436
+ const wiz =
437
+ options._wizard ||
438
+ getAIChatWizard({ hubDir: (await (options._getHub || getHub)()).hubDir });
439
+ if (!options.cookies) {
440
+ throw new Error('--cookies <string> required (e.g. "a=1; b=2")');
441
+ }
442
+ const r = await wiz.probeCookies({ vendor, cookieHeader: options.cookies });
443
+ if (options.json) {
444
+ printJson(r);
445
+ return;
446
+ }
447
+ if (!r.ok) {
448
+ logger.error(
449
+ chalk.red(
450
+ `✗ ${r.reason || "incomplete"} — missing: ${(r.missingRequired || []).join(", ") || "(none)"}`,
451
+ ),
452
+ );
453
+ process.exit(1);
454
+ }
455
+ logger.log(chalk.green(`✓ ${vendor} cookies look valid`));
456
+ logger.log(` found: ${(r.foundRequired || []).join(", ")}`);
457
+ if (r.foundOptional && r.foundOptional.length) {
458
+ logger.log(` +opt: ${r.foundOptional.join(", ")}`);
459
+ }
460
+ } catch (err) {
461
+ fail(null, err, options.json);
462
+ }
463
+ }
464
+
465
+ async function cmdAIChatRegister(vendor, options) {
466
+ try {
467
+ if (!options.cookies) {
468
+ throw new Error("--cookies <string> required");
469
+ }
470
+ const wiz =
471
+ options._wizard ||
472
+ getAIChatWizard({ hubDir: (await (options._getHub || getHub)()).hubDir });
473
+ const r = await wiz.registerVendor({ vendor, cookies: options.cookies });
474
+ if (options.json) {
475
+ printJson(r);
476
+ return;
477
+ }
478
+ if (!r.ok) {
479
+ logger.error(chalk.red(`✗ ${r.reason || "register failed"}`));
480
+ if (r.missingRequired && r.missingRequired.length) {
481
+ logger.error(chalk.gray(` missing: ${r.missingRequired.join(", ")}`));
482
+ }
483
+ process.exit(1);
484
+ }
485
+ logger.log(chalk.green(`✓ registered ${vendor} (${r.accountId})`));
486
+ } catch (err) {
487
+ fail(null, err, options.json);
488
+ }
489
+ }
490
+
491
+ async function cmdAIChatHealth(options) {
492
+ // One-shot health-checker pass (does NOT start the periodic loop —
493
+ // that's owned by long-running processes like the cc ui server). This
494
+ // is the manual/scripted equivalent.
495
+ try {
496
+ const factoryDeps = options._factoryDeps || {};
497
+ const hubDir =
498
+ factoryDeps.hubDir || (await (options._getHub || getHub)()).hubDir;
499
+ const { createAIChatHealthChecker } =
500
+ await import("@chainlesschain/personal-data-hub/adapters/ai-chat-history/health-checker");
501
+ const { createAccountsStore, createVendorAdapterBridge } =
502
+ await import("../lib/personal-data-hub-aichat-wizard.js");
503
+ const accountsStore =
504
+ factoryDeps.accountsStore || createAccountsStore({ hubDir });
505
+ const vendorAdapter =
506
+ factoryDeps.vendorAdapter || createVendorAdapterBridge();
507
+ const hc = createAIChatHealthChecker({
508
+ accountsStore,
509
+ vendorAdapter,
510
+ _deps: factoryDeps.timerDeps,
511
+ });
512
+ const r = await hc.runOnce();
513
+ if (options.json) {
514
+ printJson(r);
515
+ return;
516
+ }
517
+ logger.log(
518
+ `checked=${r.checked} ${chalk.green("ok=" + r.ok)} ${chalk.red("failed=" + r.failed)} ${chalk.yellow("mismatch=" + r.mismatch)}`,
519
+ );
520
+ } catch (err) {
521
+ fail(null, err, options.json);
522
+ }
523
+ }
524
+
525
+ async function cmdAIChatUnregister(vendor, options) {
526
+ try {
527
+ const factoryDeps = options._factoryDeps || {};
528
+ const hubDir =
529
+ factoryDeps.hubDir || (await (options._getHub || getHub)()).hubDir;
530
+ const { createAccountsStore } =
531
+ await import("../lib/personal-data-hub-aichat-wizard.js");
532
+ const accountsStore =
533
+ factoryDeps.accountsStore || createAccountsStore({ hubDir });
534
+ const existing = await accountsStore.get(vendor);
535
+ if (!existing) {
536
+ const result = { ok: false, reason: "NOT_REGISTERED", vendor };
537
+ if (options.json) printJson(result);
538
+ else logger.error(chalk.red(`✗ ${vendor} is not registered`));
539
+ process.exit(1);
540
+ }
541
+ await accountsStore.delete(vendor);
542
+ if (options.json) {
543
+ printJson({ ok: true, vendor, removed: true });
544
+ } else {
545
+ logger.log(chalk.green(`✓ removed ${vendor} from aichat-accounts.json`));
546
+ }
547
+ } catch (err) {
548
+ fail(null, err, options.json);
549
+ }
550
+ }
551
+
552
+ // ─── Phase 12.6.9 — cc hub wechat <verb> subcommand surface ─────────
553
+ //
554
+ // Mirrors the WS topics (personal-data-hub.wechat-env-probe /
555
+ // register-wechat / unregister-wechat / list-wechat-accounts). Useful
556
+ // for headless / scripted setup on a rooted Android attached to a Mac
557
+ // where the user doesn't want to bring up the Vue page just to wire
558
+ // the adapter (cf. cc hub aichat).
559
+
560
+ async function cmdWechatEnvProbe(options) {
561
+ try {
562
+ const hub = await (options._getHub || getHub)();
563
+ const probe = await hub.probeWechatEnv();
564
+ if (options.json) {
565
+ printJson(probe);
566
+ return;
567
+ }
568
+ logger.log(chalk.bold("WeChat env-probe:"));
569
+ logger.log(` ${probe.ok ? chalk.green("✓") : chalk.red("✗")} suggested: ${chalk.cyan(probe.suggestedKeyProvider)}`);
570
+ logger.log(` device: ${probe.device.reachable ? chalk.green("reachable") : chalk.red("unreachable")}${probe.device.serial ? " (" + probe.device.serial + ")" : ""} abi=${probe.device.abi || "?"}`);
571
+ logger.log(` root: ${probe.root.detected ? chalk.green("yes") : chalk.gray("no")} magisk=${probe.root.magiskInstalled ? "yes" : "no"}`);
572
+ logger.log(` frida-server: ${probe.frida.serverRunning ? chalk.green("running") : chalk.gray("not running")}${probe.frida.port ? " :" + probe.frida.port : ""}`);
573
+ logger.log(` wechat: ${probe.wechat.installed ? chalk.green(probe.wechat.versionName) : chalk.gray("not installed")}`);
574
+ for (const reason of probe.reasons || []) logger.log(` · ${chalk.gray(reason)}`);
575
+ for (const w of probe.warnings || []) logger.log(` ${chalk.yellow("!")} ${chalk.yellow(w)}`);
576
+ } catch (err) {
577
+ fail(null, err, options.json);
578
+ }
579
+ }
580
+
581
+ async function cmdWechatRegister(options) {
582
+ try {
583
+ if (!options.uin) {
584
+ throw new Error("--uin <wxid-or-uin> required");
585
+ }
586
+ const hub = await (options._getHub || getHub)();
587
+ const r = await hub.registerWechatAdapter({
588
+ account: { uin: options.uin },
589
+ dbPath: options.db || null,
590
+ wechatDataPath: options.wechatDataPath || null,
591
+ keyProviderOverride: options.forceProvider || null,
592
+ fridaOpts: options.fridaDeviceId ? { deviceId: options.fridaDeviceId } : null,
593
+ });
594
+ if (options.json) {
595
+ printJson(r);
596
+ return;
597
+ }
598
+ if (!r.ok) {
599
+ logger.error(chalk.red(`✗ ${r.reason || "register failed"}: ${r.message || ""}`));
600
+ if (r.probe) {
601
+ for (const reason of r.probe.reasons || []) logger.error(chalk.gray(" · " + reason));
602
+ }
603
+ process.exit(1);
604
+ }
605
+ logger.log(chalk.green(`✓ wechat registered (uin=${options.uin})`));
606
+ logger.log(` provider: ${chalk.cyan(r.chosenKeyProvider)}`);
607
+ logger.log(` sensitivity: ${r.sensitivity}`);
608
+ } catch (err) {
609
+ fail(null, err, options.json);
610
+ }
611
+ }
612
+
613
+ async function cmdWechatList(options) {
614
+ try {
615
+ const hub = await (options._getHub || getHub)();
616
+ const rows = hub.listWechatAccounts();
617
+ if (options.json) {
618
+ printJson({ accounts: rows });
619
+ return;
620
+ }
621
+ if (rows.length === 0) {
622
+ logger.log(chalk.gray("(no registered WeChat accounts)"));
623
+ return;
624
+ }
625
+ logger.log(chalk.bold("Registered WeChat accounts:"));
626
+ for (const row of rows) {
627
+ logger.log(` • uin=${chalk.cyan(row.uin)} provider=${row.chosenKeyProvider || "?"} db=${row.dbPath || "(none)"} regAt=${row.registeredAt ? new Date(row.registeredAt).toISOString() : "?"}`);
628
+ }
629
+ } catch (err) {
630
+ fail(null, err, options.json);
631
+ }
632
+ }
633
+
634
+ async function cmdWechatUnregister(uin, options) {
635
+ try {
636
+ if (!uin) throw new Error("uin argument required");
637
+ const hub = await (options._getHub || getHub)();
638
+ const r = await hub.unregisterWechatAdapter(uin);
639
+ if (options.json) {
640
+ printJson(r);
641
+ return;
642
+ }
643
+ if (!r.ok) {
644
+ logger.error(chalk.red(`✗ ${r.reason || "unregister failed"}`));
645
+ process.exit(1);
646
+ }
647
+ if (r.removed) logger.log(chalk.green(`✓ removed wechat account (uin=${uin})`));
648
+ else logger.log(chalk.gray(`(uin=${uin} was not registered — nothing removed)`));
649
+ } catch (err) {
650
+ fail(null, err, options.json);
651
+ }
652
+ }
653
+
654
+ function _defaultKnownVendors() {
655
+ // Match KNOWN_VENDORS in the hub package — kept inline so this file
656
+ // doesn't have to dynamic-import that module on the hot path.
657
+ return [
658
+ "deepseek",
659
+ "kimi",
660
+ "tongyi",
661
+ "zhipu",
662
+ "hunyuan",
663
+ "qianfan",
664
+ "coze",
665
+ "dreamina",
666
+ "doubao",
667
+ ];
668
+ }
669
+
359
670
  // ─── Commander wire-up ───────────────────────────────────────────────
360
671
 
361
672
  export function registerHubCommand(program) {
@@ -461,4 +772,110 @@ export function registerHubCommand(program) {
461
772
  .option("--confirm", "Required to proceed")
462
773
  .option("--json", "Output JSON")
463
774
  .action(cmdDestroy);
775
+
776
+ // Phase 10.3 — AIChat WebView wizard CLI surface (paste-mode on cc ui).
777
+ const aichat = hub
778
+ .command("aichat")
779
+ .description(
780
+ "AIChat WebView 鉴权向导 — list / login / probe / register / health / unregister 9 家国产 AI",
781
+ );
782
+
783
+ aichat
784
+ .command("list")
785
+ .description("List the 9 known AIChat vendors with their login URLs")
786
+ .option("--json", "Output JSON")
787
+ .action(cmdAIChatList);
788
+
789
+ aichat
790
+ .command("login <vendor>")
791
+ .description("Print the vendor's login URL + paste-fallback help text")
792
+ .option("--json", "Output JSON")
793
+ .action(cmdAIChatLogin);
794
+
795
+ aichat
796
+ .command("probe <vendor>")
797
+ .description(
798
+ "Classify a pasted cookie string against the vendor spec (dry-run)",
799
+ )
800
+ .option("--cookies <string>", 'Raw cookie header (e.g. "a=1; b=2")')
801
+ .option("--json", "Output JSON")
802
+ .action(cmdAIChatProbe);
803
+
804
+ aichat
805
+ .command("register <vendor>")
806
+ .description(
807
+ "Register the vendor — runs validateCookie + persists aichat-accounts.json",
808
+ )
809
+ .option("--cookies <string>", "Raw cookie header from the browser")
810
+ .option("--json", "Output JSON")
811
+ .action(cmdAIChatRegister);
812
+
813
+ aichat
814
+ .command("health")
815
+ .description("Run one HealthChecker pass over registered AIChat vendors")
816
+ .option("--json", "Output JSON")
817
+ .action(cmdAIChatHealth);
818
+
819
+ aichat
820
+ .command("unregister <vendor>")
821
+ .description(
822
+ "Remove a registered AIChat vendor entry (does not touch vault data)",
823
+ )
824
+ .option("--json", "Output JSON")
825
+ .action(cmdAIChatUnregister);
826
+
827
+ // Phase 12.6.9 — cc hub wechat <verb> mirror of WS topics.
828
+ const wechat = hub
829
+ .command("wechat")
830
+ .description(
831
+ "WeChat adapter — env-probe / register / list / unregister (rooted Android required for 8.0+)",
832
+ );
833
+
834
+ wechat
835
+ .command("env-probe")
836
+ .description("Probe attached Android device for adb / root / frida-server / WeChat version")
837
+ .option("--json", "Output JSON")
838
+ .action(cmdWechatEnvProbe);
839
+
840
+ wechat
841
+ .command("register")
842
+ .description(
843
+ "Bootstrap a WeChat adapter (chooses md5 or frida path per env-probe) and persist wechat-accounts.json",
844
+ )
845
+ .requiredOption("--uin <id>", "WeChat numeric UIN (≤ 8.0) or wxid (8.0+)")
846
+ .option("--db <path>", "Local path to the already-pulled EnMicroMsg.db")
847
+ .option("--wechat-data-path <dir>", "Local pulled /data/data/com.tencent.mm/ tree (required for md5 path)")
848
+ .option("--force-provider <md5|frida>", "Override env-probe suggestion")
849
+ .option("--frida-device-id <id>", "Frida device id (defaults to first USB device)")
850
+ .option("--json", "Output JSON")
851
+ .action(cmdWechatRegister);
852
+
853
+ wechat
854
+ .command("list")
855
+ .description("List registered WeChat accounts (scrubbed)")
856
+ .option("--json", "Output JSON")
857
+ .action(cmdWechatList);
858
+
859
+ wechat
860
+ .command("unregister <uin>")
861
+ .description("Remove a registered WeChat account (does not touch vault data)")
862
+ .option("--json", "Output JSON")
863
+ .action(cmdWechatUnregister);
464
864
  }
865
+
866
+ // exported for tests — handler functions can be invoked directly with
867
+ // `_wizard` / `_factoryDeps` / `_knownVendors` injected, bypassing the
868
+ // real `getHub()` call. The commander wiring above is the runtime path.
869
+ export const _internal = {
870
+ cmdAIChatList,
871
+ cmdAIChatLogin,
872
+ cmdAIChatProbe,
873
+ cmdAIChatRegister,
874
+ cmdAIChatHealth,
875
+ cmdAIChatUnregister,
876
+ cmdWechatEnvProbe,
877
+ cmdWechatRegister,
878
+ cmdWechatList,
879
+ cmdWechatUnregister,
880
+ _defaultKnownVendors,
881
+ };