chainlesschain 0.162.25 → 0.162.27

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 (157) hide show
  1. package/package.json +2 -2
  2. package/src/assets/web-panel/.build-hash +1 -1
  3. package/src/assets/web-panel/assets/{AIOps-CAdsXHkz.js → AIOps-D67bnWOm.js} +1 -1
  4. package/src/assets/web-panel/assets/{ActionButton-JsLRBlBP.js → ActionButton-z7o1N942.js} +1 -1
  5. package/src/assets/web-panel/assets/{Analytics-DeM96q71.js → Analytics-ygwetD7a.js} +1 -1
  6. package/src/assets/web-panel/assets/{AppLayout-eb_6mT6V.js → AppLayout-DKIKC0vr.js} +2 -2
  7. package/src/assets/web-panel/assets/{Audit-BEOY-CQE.js → Audit-RfvwANd0.js} +1 -1
  8. package/src/assets/web-panel/assets/{Backup-irFD_DBa.js → Backup-CLC0Npju.js} +1 -1
  9. package/src/assets/web-panel/assets/{BaseInput-Dq7wtv_k.js → BaseInput-Cy955ldQ.js} +1 -1
  10. package/src/assets/web-panel/assets/{Chat-CstRKWdu.js → Chat-Di1G3WpZ.js} +1 -1
  11. package/src/assets/web-panel/assets/{ChatBubbleRenderer-3BBqk317.js → ChatBubbleRenderer-D2CwVV3N.js} +1 -1
  12. package/src/assets/web-panel/assets/{Checkbox-A8D25IT5.js → Checkbox-mM6T49x7.js} +1 -1
  13. package/src/assets/web-panel/assets/{Codegen-1EfMWeRA.js → Codegen-CFRknQ28.js} +1 -1
  14. package/src/assets/web-panel/assets/{Col-Bc08LzOn.js → Col-Md7VPq32.js} +1 -1
  15. package/src/assets/web-panel/assets/{Community-BNnNv7xp.js → Community-B75271cm.js} +1 -1
  16. package/src/assets/web-panel/assets/{Compact-nFjLneHM.js → Compact-BOrAa1JM.js} +1 -1
  17. package/src/assets/web-panel/assets/{Compliance-CZpaaHND.js → Compliance-CqgTFpLC.js} +1 -1
  18. package/src/assets/web-panel/assets/{Cowork-DzHugH3j.js → Cowork-Bvdzx2lF.js} +1 -1
  19. package/src/assets/web-panel/assets/{Cron-C7YRyiN-.js → Cron-BP3ZLMIx.js} +1 -1
  20. package/src/assets/web-panel/assets/{Crosschain-er2h0L0q.js → Crosschain-Dy8IWecD.js} +1 -1
  21. package/src/assets/web-panel/assets/{DID-DaMdE0A7.js → DID-DxnpBszy.js} +1 -1
  22. package/src/assets/web-panel/assets/{Dashboard-1z2K_E1B.js → Dashboard-h8TY-9dT.js} +2 -2
  23. package/src/assets/web-panel/assets/{Dropdown-B9NIqAXf.js → Dropdown-CfIh_9pn.js} +1 -1
  24. package/src/assets/web-panel/assets/{EmailListRenderer-CBHLFokz.js → EmailListRenderer-egkHFDB9.js} +1 -1
  25. package/src/assets/web-panel/assets/{Federation-D2fEJEki.js → Federation-iXsC9ljf.js} +1 -1
  26. package/src/assets/web-panel/assets/{FormItemContext-tmsd70yG.js → FormItemContext-D16LYrK1.js} +1 -1
  27. package/src/assets/web-panel/assets/{GenericCardRenderer-DW4Lnrsr.js → GenericCardRenderer-B2l7qvIp.js} +1 -1
  28. package/src/assets/web-panel/assets/{Git-D8aBagAp.js → Git-DshuXpeI.js} +1 -1
  29. package/src/assets/web-panel/assets/{Governance-CKDAHamy.js → Governance-BzgoQvxX.js} +1 -1
  30. package/src/assets/web-panel/assets/{Inference-BLLp118j.js → Inference-CMikYc6i.js} +1 -1
  31. package/src/assets/web-panel/assets/{KnowledgeGraph-Cawx-yfu.js → KnowledgeGraph-DAP_uKkx.js} +1 -1
  32. package/src/assets/web-panel/assets/{Logs-sWSzp5PY.js → Logs-Zax7aDPt.js} +1 -1
  33. package/src/assets/web-panel/assets/{Marketplace-BQMX3dSy.js → Marketplace-DC8_c3hX.js} +1 -1
  34. package/src/assets/web-panel/assets/{McpTools-DjlFST3o.js → McpTools-CvpCNH6E.js} +1 -1
  35. package/src/assets/web-panel/assets/{Memory-LZE1wG7m.js → Memory-BVgvCyNB.js} +1 -1
  36. package/src/assets/web-panel/assets/{MobileBridge-BWG47jQ6.js → MobileBridge-BvffJp-I.js} +1 -1
  37. package/src/assets/web-panel/assets/{MobileProjects-DHVv0tYo.js → MobileProjects-BBEmZ56X.js} +1 -1
  38. package/src/assets/web-panel/assets/{Mtc-Di1hrhM3.js → Mtc-D4Lg-E10.js} +1 -1
  39. package/src/assets/web-panel/assets/{MtcAudit-BowOCi-O.js → MtcAudit-BpuX4w67.js} +1 -1
  40. package/src/assets/web-panel/assets/{Multisig-CgpR0s8E.js → Multisig-CclH6FTt.js} +1 -1
  41. package/src/assets/web-panel/assets/{NLProgramming-O4U3Plxd.js → NLProgramming-DPBSg0ot.js} +1 -1
  42. package/src/assets/web-panel/assets/{Notes-Ce_5C6XT.js → Notes-CapzFL8Y.js} +1 -1
  43. package/src/assets/web-panel/assets/{NotificationSettings-BVVopkxj.js → NotificationSettings-Fxts3vW8.js} +1 -1
  44. package/src/assets/web-panel/assets/{OrderTableRenderer-XW2G50wt.js → OrderTableRenderer-DexmnSf8.js} +1 -1
  45. package/src/assets/web-panel/assets/{Organization-DaW54kdP.js → Organization-Cx9wnh2C.js} +1 -1
  46. package/src/assets/web-panel/assets/{Overflow-CVTGMUVt.js → Overflow-uNU3Jy_O.js} +1 -1
  47. package/src/assets/web-panel/assets/{P2P-CpEwrhBx.js → P2P-DZqGX3zP.js} +1 -1
  48. package/src/assets/web-panel/assets/{PdhVaultBrowser-CDqun-Z9.js → PdhVaultBrowser-BbXlJUmU.js} +2 -2
  49. package/src/assets/web-panel/assets/{Permissions-BsSU3MaL.js → Permissions-tSlqIXRk.js} +1 -1
  50. package/src/assets/web-panel/assets/{PersonalDataHub-DmUc89_0.css → PersonalDataHub-CO9-IYDY.css} +1 -1
  51. package/src/assets/web-panel/assets/PersonalDataHub-DdPngiX0.js +2 -0
  52. package/src/assets/web-panel/assets/{Pipeline-CPCDpDyd.js → Pipeline-G-YXvU25.js} +1 -1
  53. package/src/assets/web-panel/assets/{Privacy-oZEQvVWA.js → Privacy-BIDsJhkC.js} +1 -1
  54. package/src/assets/web-panel/assets/{ProjectInit-CRu5bDNW.js → ProjectInit-DTGzvgQ9.js} +1 -1
  55. package/src/assets/web-panel/assets/{ProjectSettings-ComIZ7gQ.js → ProjectSettings-8QjihLTL.js} +1 -1
  56. package/src/assets/web-panel/assets/{Projects-Djr10qFp.js → Projects-D7S7x7R1.js} +1 -1
  57. package/src/assets/web-panel/assets/Providers-BNI-WkmA.css +1 -0
  58. package/src/assets/web-panel/assets/Providers-DpTXneeZ.js +1 -0
  59. package/src/assets/web-panel/assets/{QuickAsk-C21t1JEf.js → QuickAsk-C83JwW8d.js} +1 -1
  60. package/src/assets/web-panel/assets/{Recommend-BjJForJo.js → Recommend-PO0TXid1.js} +1 -1
  61. package/src/assets/web-panel/assets/{Reputation-Cp8Ym-Hk.js → Reputation-pwXhN9Lv.js} +1 -1
  62. package/src/assets/web-panel/assets/{Row-n8ruyEoT.js → Row-829tJQ3D.js} +1 -1
  63. package/src/assets/web-panel/assets/{RssFeed-CosaiHvS.js → RssFeed-Btnw67Mk.js} +1 -1
  64. package/src/assets/web-panel/assets/{Search-DUNSNFJZ.js → Search-olQ94qFA.js} +1 -1
  65. package/src/assets/web-panel/assets/{Security-Z3WyX_MB.js → Security-C_Vfuu0K.js} +1 -1
  66. package/src/assets/web-panel/assets/{Services-U0m9Oj8V.js → Services-ByfhJMDp.js} +1 -1
  67. package/src/assets/web-panel/assets/{Skeleton-B_M5sv2W.js → Skeleton-CWxck8Jk.js} +1 -1
  68. package/src/assets/web-panel/assets/{Skills-NKU9c6LT.js → Skills-yady6VUJ.js} +1 -1
  69. package/src/assets/web-panel/assets/{Sla-DscfpqF8.js → Sla-Dc_HEsj7.js} +1 -1
  70. package/src/assets/web-panel/assets/{SpeechSettings-DP0O84ej.js → SpeechSettings--vhH3ORV.js} +1 -1
  71. package/src/assets/web-panel/assets/{SyncSettings-P_WEyoH3.js → SyncSettings-GUPyaG2O.js} +1 -1
  72. package/src/assets/web-panel/assets/{Tasks-C8YAncnj.js → Tasks-Sj1OYuDS.js} +1 -1
  73. package/src/assets/web-panel/assets/{Templates-F12-SRc3.js → Templates-rdiV_eFo.js} +1 -1
  74. package/src/assets/web-panel/assets/{Tenant-CULHbrwu.js → Tenant-N76bdElE.js} +1 -1
  75. package/src/assets/web-panel/assets/{Terminal-DdYrQ0n3.js → Terminal-KZ1H0ObH.js} +1 -1
  76. package/src/assets/web-panel/assets/{TimelineRenderer-C12_BYAe.js → TimelineRenderer-D7nI-o49.js} +1 -1
  77. package/src/assets/web-panel/assets/{Tokens-8MVLlc0s.js → Tokens-c2LL4v7q.js} +1 -1
  78. package/src/assets/web-panel/assets/{Trigger-Bl6QmvKw.js → Trigger-B57LuN-B.js} +1 -1
  79. package/src/assets/web-panel/assets/{Trust-BH_aEsWy.js → Trust-BMmdOSoP.js} +1 -1
  80. package/src/assets/web-panel/assets/{UkeySign-DsX2CeE4.js → UkeySign-CtGUfuxi.js} +1 -1
  81. package/src/assets/web-panel/assets/{VideoEditing-DaRdn6e9.js → VideoEditing-CzrCzzLF.js} +1 -1
  82. package/src/assets/web-panel/assets/{Wallet-DO89dzlU.js → Wallet-Ciiwlppn.js} +1 -1
  83. package/src/assets/web-panel/assets/{WebAuthn-KUKNjImY.js → WebAuthn-BPFoLjnF.js} +1 -1
  84. package/src/assets/web-panel/assets/{WorkflowEditor-CnSoP-Z9.js → WorkflowEditor-Bf8UZPRx.js} +1 -1
  85. package/src/assets/web-panel/assets/{chat-Jp0M9E52.js → chat-aoVkknKT.js} +1 -1
  86. package/src/assets/web-panel/assets/{colors-Bkq4q91x.js → colors-CKv2MZMK.js} +1 -1
  87. package/src/assets/web-panel/assets/{compact-item-CCt1byem.js → compact-item-1FPS5mTP.js} +1 -1
  88. package/src/assets/web-panel/assets/{createContext-DwRLi0Uq.js → createContext-o2GXZ1sO.js} +1 -1
  89. package/src/assets/web-panel/assets/{hasIn-CTVm-2lw.js → hasIn-CMm7HgH-.js} +1 -1
  90. package/src/assets/web-panel/assets/{index-TqiVFiUf.js → index-866hrngI.js} +1 -1
  91. package/src/assets/web-panel/assets/{index-B9q3wKEr.js → index-8AzFTShP.js} +1 -1
  92. package/src/assets/web-panel/assets/index-BHtt98Qo.js +1 -0
  93. package/src/assets/web-panel/assets/{index-Cvrka2TD.js → index-BQcTgRAZ.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-DJegJP2N.js → index-BSqFVnSI.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-CIBi-rGt.js → index-BUWd4FFK.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-DRwUdk7I.js → index-Bb7YRgoc.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-hpRtUCjU.js → index-BbJDxap_.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-DC-8E2CG.js → index-BwA5hOgO.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-CPnSymMN.js → index-CFgWbJuM.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-CDbgmmSF.js → index-CXDN0kh7.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-BhSbNePw.js → index-CXHs9New.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-DXDSJwDk.js → index-CalorQK0.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-BziGa10S.js → index-CcfXX0ID.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-B3irAeY8.js → index-CdDX6sEY.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-DWQ9NRWg.js → index-Ch-sPaT4.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-MdArO-BF.js → index-Chh-oVTw.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-zwGGcR7I.js → index-Cr1ZwF59.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-BtzUDs1M.js → index-Cr2EOK21.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-B2pkXVOU.js → index-Crp4UcP-.js} +1 -1
  110. package/src/assets/web-panel/assets/index-Cul_OH-A.js +1 -0
  111. package/src/assets/web-panel/assets/{index-TL3iHPdE.js → index-D1QEfzq_.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-BjGcDwb2.js → index-D3aMAQEQ.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-B_U_xDvh.js → index-D3bKIme7.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-CjJWQqPG.js → index-DCxs8O-B.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-Db3R-khd.js → index-DDP25Jlo.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-DFcr_PT2.js → index-DT76REiB.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-D-UAtktg.js → index-DZ747YY7.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-C2ovimhG.js → index-De4hAcPZ.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-CdlVwys1.js → index-DoVMBKvC.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-BD2U0Ciz.js → index-JP5LGd1K.js} +3 -3
  121. package/src/assets/web-panel/assets/{index-BJmiHI2z.js → index-OiF8vib7.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-C3ZzMEg0.js → index-Y_UOzu30.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-CFh73FRz.js → index-bJ5UBvQQ.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-eyVkd-kF.js → index-dXE5uCaT.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-CLjugrcu.js → index-fyC4Vx7E.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-DRkGL2HJ.js → index-g4LWpdR7.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-6OmglXey.js → index-u3FjYN52.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-CJWYdgmz.js → index-yhq2Pttf.js} +1 -1
  129. package/src/assets/web-panel/assets/{initDefaultProps-9iSe4Eid.js → initDefaultProps-Co0jgVso.js} +1 -1
  130. package/src/assets/web-panel/assets/{motion-CcUz2pq7.js → motion-Zw-nUuCZ.js} +1 -1
  131. package/src/assets/web-panel/assets/{move-3Po9fM71.js → move-O_Pya0SD.js} +1 -1
  132. package/src/assets/web-panel/assets/{omit-BBcRnciw.js → omit-bqQYnuYR.js} +1 -1
  133. package/src/assets/web-panel/assets/parsers-UEvh_ShA.js +4 -0
  134. package/src/assets/web-panel/assets/{pickAttrs-UCqcWwOy.js → pickAttrs-PeesUh3N.js} +1 -1
  135. package/src/assets/web-panel/assets/{placementArrow-boVtHxA4.js → placementArrow-DoUJMHry.js} +1 -1
  136. package/src/assets/web-panel/assets/{responsiveObserve-V0qPHZOl.js → responsiveObserve-QHPYy6hK.js} +1 -1
  137. package/src/assets/web-panel/assets/{slide-CZyysA_q.js → slide-H_RDRwbZ.js} +1 -1
  138. package/src/assets/web-panel/assets/{statusUtils-BLyCU5L3.js → statusUtils-RuUT_noY.js} +1 -1
  139. package/src/assets/web-panel/assets/{styleChecker-BfXrPW7h.js → styleChecker-DuWlOmft.js} +1 -1
  140. package/src/assets/web-panel/assets/{useFlexGapSupport-Be2wILDi.js → useFlexGapSupport-CJmU3crw.js} +1 -1
  141. package/src/assets/web-panel/assets/{useFs-CzJYoHOI.js → useFs-CBYaEAuH.js} +1 -1
  142. package/src/assets/web-panel/assets/{usePersonalDataHub-__HEfTF9.js → usePersonalDataHub-B0x06BwX.js} +1 -1
  143. package/src/assets/web-panel/assets/{vnode-C0XE0aCE.js → vnode-B2BMGDRL.js} +1 -1
  144. package/src/assets/web-panel/assets/{zoom-CphwCBhl.js → zoom-D_OEfpnp.js} +1 -1
  145. package/src/assets/web-panel/index.html +1 -1
  146. package/src/commands/__tests__/hub-ask.test.js +104 -1
  147. package/src/commands/__tests__/hub-kuaishou-adb-sync.test.js +161 -0
  148. package/src/commands/__tests__/hub-toutiao-adb-sync.test.js +158 -0
  149. package/src/commands/hub.js +353 -1
  150. package/src/gateways/ws/personal-data-hub-protocol.js +34 -0
  151. package/src/lib/personal-data-hub-wiring.js +218 -0
  152. package/src/assets/web-panel/assets/PersonalDataHub-BafcAH5d.js +0 -1
  153. package/src/assets/web-panel/assets/Providers-BEakqcO5.css +0 -1
  154. package/src/assets/web-panel/assets/Providers-CltNzV7e.js +0 -2
  155. package/src/assets/web-panel/assets/index-CR2wmKfw.js +0 -1
  156. package/src/assets/web-panel/assets/index-iXk8Oeci.js +0 -1
  157. package/src/assets/web-panel/assets/parsers-DftYMnlk.js +0 -3
@@ -331,12 +331,26 @@ async function initHub() {
331
331
  // collector (xiaohongshu.com cookies + 4 endpoints with X-S sign).
332
332
  const { createXhsCookiesExtension } =
333
333
  await import("@chainlesschain/personal-data-hub/adapters/social-xiaohongshu-adb");
334
+ // Phase 6c: register `toutiao.cookies` extension for the Toutiao
335
+ // C-path collector (www.toutiao.com cookies + 4 endpoints, 3 of
336
+ // which need _signature signing — CLI context falls back to -99
337
+ // short-circuit, desktop wiring upgrades via ToutiaoSignBridge).
338
+ const { createToutiaoCookiesExtension } =
339
+ await import("@chainlesschain/personal-data-hub/adapters/social-toutiao-adb");
340
+ // Phase 6d: register `kuaishou.cookies` extension. Profile from
341
+ // cookie's api_ph payload (no HTTP); 3 GraphQL POST endpoints need
342
+ // __NS_sig3 + kpf/kpn — CLI short-circuits, desktop upgrades via
343
+ // KuaishouSignBridge.
344
+ const { createKuaishouCookiesExtension } =
345
+ await import("@chainlesschain/personal-data-hub/adapters/social-kuaishou-adb");
334
346
  hostAdbBridge = createHostAdbBridge({
335
347
  extensions: {
336
348
  "bilibili.cookies": createBilibiliCookiesExtension(),
337
349
  "douyin.pull-im-db": createDouyinDbExtension(),
338
350
  "weibo.cookies": createWeiboCookiesExtension(),
339
351
  "xhs.cookies": createXhsCookiesExtension(),
352
+ "toutiao.cookies": createToutiaoCookiesExtension(),
353
+ "kuaishou.cookies": createKuaishouCookiesExtension(),
340
354
  },
341
355
  });
342
356
  sda._deps.bridgeProvider = () => hostAdbBridge;
@@ -1072,6 +1086,114 @@ async function initHub() {
1072
1086
  };
1073
1087
  }
1074
1088
  },
1089
+
1090
+ // ─── Phase 6c — Toutiao C 路径 one-shot sync ────────────────────────
1091
+ //
1092
+ // Pulls www.toutiao.com cookies via toutiao.cookies extension →
1093
+ // fetchProfile (/passport/account/info/v2 — no _sig) → 3 endpoints
1094
+ // (feed/collection/search, _signature required).
1095
+ //
1096
+ // **CLI context has NO sign bridge** — the 3 _signature endpoints
1097
+ // short-circuit with lastErrorCode=-99 (no HTTP traffic). Profile is
1098
+ // still fetched. Desktop wiring upgrades via ToutiaoSignBridge.
1099
+ //
1100
+ // Typed reason codes: BRIDGE_UNAVAILABLE / MODULE_LOAD_FAILED /
1101
+ // TOUTIAO_NO_ROOT / TOUTIAO_NOT_INSTALLED / TOUTIAO_COOKIES_EMPTY /
1102
+ // TOUTIAO_COOKIES_TRUNCATED / TOUTIAO_NOT_SQLITE /
1103
+ // TOUTIAO_COOKIES_INCOMPLETE / TOUTIAO_BASE64_PARSE / SYNC_FAILED.
1104
+ async toutiaoAdbSync(opts = {}) {
1105
+ if (!hostAdbBridge) {
1106
+ return {
1107
+ ok: false,
1108
+ reason: "BRIDGE_UNAVAILABLE",
1109
+ message:
1110
+ "host-adb-bridge failed to initialize at hub boot — check `adb` is on PATH or set ADB_PATH env var",
1111
+ };
1112
+ }
1113
+ let collector;
1114
+ try {
1115
+ const mod =
1116
+ await import("@chainlesschain/personal-data-hub/adapters/social-toutiao-adb");
1117
+ collector = mod.default ? mod.default : mod;
1118
+ } catch (err) {
1119
+ return {
1120
+ ok: false,
1121
+ reason: "MODULE_LOAD_FAILED",
1122
+ message: err && err.message ? err.message : String(err),
1123
+ };
1124
+ }
1125
+ try {
1126
+ const report = await collector.collectAndSync(
1127
+ hostAdbBridge,
1128
+ registry,
1129
+ opts,
1130
+ );
1131
+ return { ok: true, report };
1132
+ } catch (err) {
1133
+ const msg = err && err.message ? err.message : String(err);
1134
+ const m = msg.match(/^(TOUTIAO_[A-Z_]+)/);
1135
+ return {
1136
+ ok: false,
1137
+ reason: m ? m[1] : "SYNC_FAILED",
1138
+ message: msg,
1139
+ };
1140
+ }
1141
+ },
1142
+
1143
+ // ─── Phase 6d — Kuaishou C 路径 one-shot sync ───────────────────────
1144
+ //
1145
+ // Pulls www.kuaishou.com cookies via kuaishou.cookies extension →
1146
+ // fetchProfile (PURE COOKIE PARSE — reads api_ph payload, no HTTP)
1147
+ // → 3 signed GraphQL POST endpoints (visionFeedRecommend /
1148
+ // visionProfilePhotoList / visionSearchPhoto, __NS_sig3 + kpf/kpn).
1149
+ //
1150
+ // **CLI context has NO sign bridge** — 3 signed endpoints short-
1151
+ // circuit with lastErrorCode=-99 (no HTTP traffic). Profile + uid
1152
+ // still emit from cookie payload. Desktop wiring upgrades via
1153
+ // KuaishouSignBridge.
1154
+ //
1155
+ // Typed reason codes: BRIDGE_UNAVAILABLE / MODULE_LOAD_FAILED /
1156
+ // KUAISHOU_NO_ROOT / KUAISHOU_NOT_INSTALLED / KUAISHOU_COOKIES_EMPTY /
1157
+ // KUAISHOU_COOKIES_TRUNCATED / KUAISHOU_NOT_SQLITE /
1158
+ // KUAISHOU_COOKIES_INCOMPLETE / KUAISHOU_BASE64_PARSE / SYNC_FAILED.
1159
+ async kuaishouAdbSync(opts = {}) {
1160
+ if (!hostAdbBridge) {
1161
+ return {
1162
+ ok: false,
1163
+ reason: "BRIDGE_UNAVAILABLE",
1164
+ message:
1165
+ "host-adb-bridge failed to initialize at hub boot — check `adb` is on PATH or set ADB_PATH env var",
1166
+ };
1167
+ }
1168
+ let collector;
1169
+ try {
1170
+ const mod =
1171
+ await import("@chainlesschain/personal-data-hub/adapters/social-kuaishou-adb");
1172
+ collector = mod.default ? mod.default : mod;
1173
+ } catch (err) {
1174
+ return {
1175
+ ok: false,
1176
+ reason: "MODULE_LOAD_FAILED",
1177
+ message: err && err.message ? err.message : String(err),
1178
+ };
1179
+ }
1180
+ try {
1181
+ const report = await collector.collectAndSync(
1182
+ hostAdbBridge,
1183
+ registry,
1184
+ opts,
1185
+ );
1186
+ return { ok: true, report };
1187
+ } catch (err) {
1188
+ const msg = err && err.message ? err.message : String(err);
1189
+ const m = msg.match(/^(KUAISHOU_[A-Z_]+)/);
1190
+ return {
1191
+ ok: false,
1192
+ reason: m ? m[1] : "SYNC_FAILED",
1193
+ message: msg,
1194
+ };
1195
+ }
1196
+ },
1075
1197
  };
1076
1198
  }
1077
1199
 
@@ -1151,6 +1273,95 @@ export async function getHub() {
1151
1273
  return _initPromise;
1152
1274
  }
1153
1275
 
1276
+ // ─── Minimal hub bootstrap for read-only / LLM-free commands ────────────
1277
+ //
1278
+ // 2026-05-27 — `cc hub retrieve-context` cold-start was 90s+ on Android
1279
+ // because initHub() wires 50+ adapters + KG sink + RAG sink + EntityResolver
1280
+ // + email accounts auto-load + 6 ADB extension imports — none of which
1281
+ // retrieveContext actually needs. AnalysisEngine.retrieveContext only
1282
+ // touches: vault.queryEvents / queryPersons / queryItems / stats / audit /
1283
+ // searchEvents / searchPersons. No adapters. No LLM call. Skipping the
1284
+ // heavy wiring should cut cold-start from ~90s to <5s in-APK.
1285
+ //
1286
+ // Singleton-cached separately from full hub — if the user later runs a
1287
+ // `cc hub sync-adapter` in the same process, getHub() lazy-builds the
1288
+ // full hub on demand. The minimal hub's vault is closed when full hub
1289
+ // boots to avoid double-open contention (SQLCipher allows single writer).
1290
+ //
1291
+ // Returns the same shape as getHub() for the keys retrieveContext needs:
1292
+ // { hubDir, vault, engine, llm, kgSink:null, ragSink:null, registry:null }.
1293
+
1294
+ let _hubMinimal = null;
1295
+ let _hubMinimalInitPromise = null;
1296
+
1297
+ async function initHubMinimal() {
1298
+ const hubDir = resolveHubDir();
1299
+ mkdirSync(hubDir, { recursive: true });
1300
+ mkdirSync(join(hubDir, "keys"), { recursive: true });
1301
+
1302
+ const keyProvider = new FileKeyProvider(join(hubDir, "keys"));
1303
+ const KEY_NAME = "vault:default";
1304
+ let key = await keyProvider.get(KEY_NAME);
1305
+ if (!key) {
1306
+ key = generateKeyHex();
1307
+ await keyProvider.set(KEY_NAME, key);
1308
+ }
1309
+
1310
+ const vault = new LocalVault({ path: join(hubDir, "vault.db"), key });
1311
+ vault.open();
1312
+
1313
+ // No LLM: retrieveContext is LLM-free. AnalysisEngine constructor still
1314
+ // requires a `llm` arg with chat() + isLocal — pass a sentinel that
1315
+ // throws if anyone actually calls it (defense against future code
1316
+ // accidentally invoking ask() via this minimal hub).
1317
+ const sentinelLlm = {
1318
+ isLocal: true,
1319
+ name: "minimal-hub-sentinel",
1320
+ chat: () => {
1321
+ throw new Error(
1322
+ "minimal hub: LLM unavailable — use getHub() for ask() / chat paths",
1323
+ );
1324
+ },
1325
+ };
1326
+
1327
+ const engine = new AnalysisEngine({
1328
+ vault,
1329
+ llm: sentinelLlm,
1330
+ // No ragRetriever — BM25 sink is part of full hub init, skip here.
1331
+ });
1332
+
1333
+ return {
1334
+ hubDir,
1335
+ vault,
1336
+ engine,
1337
+ llm: null,
1338
+ kgSink: null,
1339
+ ragSink: null,
1340
+ registry: null,
1341
+ minimal: true,
1342
+ };
1343
+ }
1344
+
1345
+ export async function getHubMinimal() {
1346
+ if (_hubMinimal) return _hubMinimal;
1347
+ // If full hub is already initialized, reuse its vault + engine — opening
1348
+ // a second LocalVault against the same SQLCipher DB would fight for the
1349
+ // file lock.
1350
+ if (_hub) return _hub;
1351
+ if (!_hubMinimalInitPromise) {
1352
+ _hubMinimalInitPromise = initHubMinimal()
1353
+ .then((h) => {
1354
+ _hubMinimal = h;
1355
+ return h;
1356
+ })
1357
+ .catch((err) => {
1358
+ _hubMinimalInitPromise = null;
1359
+ throw err;
1360
+ });
1361
+ }
1362
+ return _hubMinimalInitPromise;
1363
+ }
1364
+
1154
1365
  export function close() {
1155
1366
  if (_hub && _hub.aichatHealthChecker) {
1156
1367
  try {
@@ -1162,8 +1373,15 @@ export function close() {
1162
1373
  _hub.vault.close();
1163
1374
  } catch (_e) {}
1164
1375
  }
1376
+ if (_hubMinimal && _hubMinimal.vault && _hubMinimal !== _hub) {
1377
+ try {
1378
+ _hubMinimal.vault.close();
1379
+ } catch (_e) {}
1380
+ }
1165
1381
  _hub = null;
1166
1382
  _initPromise = null;
1383
+ _hubMinimal = null;
1384
+ _hubMinimalInitPromise = null;
1167
1385
  _bm25 = null;
1168
1386
  _kgMod = null;
1169
1387
  _bm25Mod = null;
@@ -1 +0,0 @@
1
- import{w as et,L as n,Q as g,N as t,c as o,M as y,R as d,F as ee,Y as re,Z as tt,P as r,O as l,S as p,a1 as at,f as ue,r as S,K as c,a as se,a4 as Bt,o as Rt,u as X,a0 as Tt,$ as Ht}from"./vendor-DhFY8mDK.js";import{u as Me}from"./usePersonalDataHub-__HEfTF9.js";import{_ as Le,d as k}from"./index-BD2U0Ciz.js";import{R as je,aB as zt,O as Ft,al as Wt,h as qt,aC as Kt,Q as Vt,aD as Qt,aE as Gt,y as Yt,q as Xt,aF as jt,a3 as Jt,ad as Zt,aG as ea,m as ta,e as Je}from"./icons-AILO5ZcK.js";const aa={key:0},oa={class:"vendor-head"},la={class:"hint"},na={class:"hint",style:{"margin-top":"4px"}},sa={key:0,class:"hint",style:{"margin-top":"4px",color:"#ff4d4f"}},ia={key:1},ra={class:"hint"},ua=["href"],da={class:"howto"},pa=["href"],ca={key:3,style:{"margin-top":"8px"}},fa={key:2,class:"kv",style:{"margin-top":"4px"}},va={key:3,class:"kv",style:{"margin-top":"4px",color:"#ff4d4f"}},ma={key:2},ya={__name:"AIChatWizard",props:{open:{type:Boolean,default:!1},existingAccounts:{type:Array,default:()=>[]}},emits:["update:open","registered"],setup(me,{emit:_e}){const w=me,L=_e,Q=[{vendor:"deepseek",displayName:"DeepSeek",notes:"手机号 + 验证码登录",requiredCookies:["userToken"],cookieMaxAgeHintDays:30},{vendor:"kimi",displayName:"Kimi",notes:"手机号验证码登录",requiredCookies:["access_token"],cookieMaxAgeHintDays:30},{vendor:"tongyi",displayName:"通义千问",notes:"阿里云账号 SSO(过期较快)",requiredCookies:["login_aliyunid"],cookieMaxAgeHintDays:7},{vendor:"zhipu",displayName:"智谱清言",notes:"手机号 + 验证码",requiredCookies:["chatglm_token"],cookieMaxAgeHintDays:30},{vendor:"hunyuan",displayName:"腾讯混元",notes:"QQ / 微信 / 手机号",requiredCookies:["hy_token"],cookieMaxAgeHintDays:14},{vendor:"qianfan",displayName:"百度文心",notes:"百度账号",requiredCookies:["BDUSS"],cookieMaxAgeHintDays:7},{vendor:"coze",displayName:"字节扣子 Coze",notes:"字节统一 passport",requiredCookies:["sessionid"],cookieMaxAgeHintDays:14},{vendor:"dreamina",displayName:"即梦 Dreamina",notes:"字节图像生成",requiredCookies:["sessionid"],cookieMaxAgeHintDays:14},{vendor:"doubao",displayName:"豆包 Doubao",notes:"字节文本 AI",requiredCookies:["sessionid"],cookieMaxAgeHintDays:14}],h=Me(),m=S(1),b=S(null),U=S(""),O=S(null),B=S(null),V=S(null),M=se({open:!1,probe:!1,register:!1}),ie=ue(()=>Q.find(_=>_.vendor===b.value)||{}),de=ue(()=>m.value===1?"选择一家 AI 服务商":m.value===2?O.value?.fallbackMode==="paste"?"在外部浏览器登录,把 cookie 粘贴到下面":"在内嵌浏览器登录,主进程自动读取 cookie":"校验并写入本地加密 vault"),j=ue(()=>{const _=B.value;return _?_.reason==="UNKNOWN_VENDOR"?"未知厂商 — 请刷新页面或重选":_.reason==="PASTE_REQUIRED"?"请先粘贴 cookie 字符串":_.missingRequired?.length?`缺关键 cookie: ${_.missingRequired.join(", ")}`:_.reason||"cookie 校验失败":""}),R=ue(()=>{const _=V.value;return _?_.reason==="REQUIRED_COOKIES_MISSING"?`缺关键 cookie: ${(_.missingRequired||[]).join(", ")}`:_.reason==="VALIDATE_COOKIE_FAILED"?"厂商拒绝该 cookie(可能已过期或被风控)":_.reason==="ADAPTER_THREW"?`Adapter 抛错: ${_.error||"网络错误"}`:_.reason==="UNKNOWN_VENDOR"?"未知厂商":_.reason||"注册失败":"未知错误"});function v(_){return w.existingAccounts.some(i=>i&&i.vendor===_)}function le(_){return w.existingAccounts.find(i=>i&&i.vendor===_)||null}function q(_){const i=le(_);return i?i.lastHealth?i.lastHealth.ok?"ok":i.lastHealth.reason==="SPEC_VERSION_MISMATCH"?"mismatch":"fail":"unknown":null}function te(_){const i=le(_);if(!i||!i.lastHealth||i.lastHealth.ok)return"";const z=i.lastHealth.reason;return z?z==="SPEC_VERSION_MISMATCH"?"cookie 规格已升级,请重新登录":z==="ADAPTER_THREW"?"上次校验抛错,建议稍后重试":z==="COOKIE_EXPIRED"?"Cookie 已过期,请重新登录":z:"Cookie 校验失败,建议重新登录"}async function J(_){try{(await h.unregisterAichat(_))?.ok&&L("registered",{vendor:_,accountId:null,unregistered:!0})}catch(i){V.value={ok:!1,reason:i?.message||"UNREGISTER_FAILED"}}}function A(_){b.value=_}async function W(){if(b.value){M.open=!0,O.value=null,B.value=null,U.value="";try{if(O.value=await h.openAichatLogin(b.value),!O.value?.ok)return;m.value=2}catch(_){O.value={ok:!1,reason:_?.message||"OPEN_FAILED"}}finally{M.open=!1}}}async function ae(){M.probe=!0,B.value=null;try{const _=U.value.trim(),i=_||void 0;B.value=await h.probeAichatCookies(b.value,i)}catch(_){B.value={ok:!1,reason:_?.message||"PROBE_FAILED"}}finally{M.probe=!1}}async function I(){if(B.value?.ok){M.register=!0;try{V.value=await h.registerAichatVendor(b.value,B.value.cookies),m.value=3,V.value?.ok&&L("registered",{vendor:b.value,accountId:V.value.accountId})}catch(_){V.value={ok:!1,reason:_?.message||"REGISTER_FAILED"},m.value=3}finally{M.register=!1}}}function K(){m.value=1,b.value=null,U.value="",O.value=null,B.value=null,V.value=null}function pe(){K(),L("update:open",!1)}return et(()=>w.open,_=>{_&&K()}),(_,i)=>{const z=c("a-alert"),D=c("a-tag"),G=c("a-button"),Ee=c("a-popconfirm"),ke=c("a-card"),Se=c("a-col"),ye=c("a-row"),T=c("a-collapse-panel"),H=c("a-collapse"),C=c("a-textarea"),f=c("a-form-item"),we=c("a-form"),Ce=c("a-result"),xe=c("a-space"),he=c("a-drawer");return n(),g(he,{open:me.open,title:"添加 AI 对话账号",placement:"right",width:640,"destroy-on-close":!0,"onUpdate:open":i[4]||(i[4]=N=>L("update:open",N)),onClose:pe},{footer:t(()=>[o(xe,{style:{float:"right"}},{default:t(()=>[m.value>1&&m.value<3?(n(),g(G,{key:0,onClick:i[3]||(i[3]=N=>m.value=m.value-1)},{default:t(()=>[...i[22]||(i[22]=[l("上一步",-1)])]),_:1})):p("",!0),o(G,{onClick:pe},{default:t(()=>[...i[23]||(i[23]=[l("取消",-1)])]),_:1}),m.value===1?(n(),g(G,{key:1,type:"primary",disabled:!b.value,loading:M.open,onClick:W},{default:t(()=>[...i[24]||(i[24]=[l(" 下一步 ",-1)])]),_:1},8,["disabled","loading"])):p("",!0),m.value===2&&O.value?.fallbackMode==="paste"?(n(),g(G,{key:2,loading:M.probe,disabled:!U.value.trim(),onClick:ae},{default:t(()=>[...i[25]||(i[25]=[l(" 检测 cookie ",-1)])]),_:1},8,["loading","disabled"])):p("",!0),m.value===2&&O.value?.fallbackMode!=="paste"?(n(),g(G,{key:3,loading:M.probe,onClick:ae},{default:t(()=>[...i[26]||(i[26]=[l(" 检测 cookie ",-1)])]),_:1},8,["loading"])):p("",!0),m.value===2?(n(),g(G,{key:4,type:"primary",loading:M.register,disabled:!B.value?.ok,onClick:I},{default:t(()=>[...i[27]||(i[27]=[l(" 注册 ",-1)])]),_:1},8,["loading","disabled"])):p("",!0)]),_:1})]),default:t(()=>[o(z,{message:`第 ${m.value} / 3 步`,description:de.value,type:"info","show-icon":"",style:{"margin-bottom":"16px"}},null,8,["message","description"]),m.value===1?(n(),y("div",aa,[i[10]||(i[10]=d("p",{class:"hint"}," 选择要接入的 AI 服务商。登录后将本地读取 cookie 同步对话历史;cookie 仅落本机加密文件,不上传任何云端。 ",-1)),o(ye,{gutter:[12,12]},{default:t(()=>[(n(),y(ee,null,re(Q,N=>o(Se,{xs:24,sm:12,md:8,key:N.vendor},{default:t(()=>[o(ke,{size:"small",hoverable:"",class:tt(["vendor-card",{selected:b.value===N.vendor}]),onClick:Pe=>A(N.vendor)},{default:t(()=>[d("div",oa,[d("strong",null,r(N.displayName),1),q(N.vendor)==="fail"?(n(),g(D,{key:0,color:"red"},{default:t(()=>[...i[5]||(i[5]=[l("🔴 重新登录",-1)])]),_:1})):q(N.vendor)==="mismatch"?(n(),g(D,{key:1,color:"orange"},{default:t(()=>[...i[6]||(i[6]=[l("⚠ 规格升级",-1)])]),_:1})):q(N.vendor)==="unknown"?(n(),g(D,{key:2,color:"blue"},{default:t(()=>[...i[7]||(i[7]=[l("已接入·待巡检",-1)])]),_:1})):q(N.vendor)==="ok"?(n(),g(D,{key:3,color:"green"},{default:t(()=>[...i[8]||(i[8]=[l("✓ 已接入",-1)])]),_:1})):p("",!0)]),d("div",la,r(N.notes),1),d("div",na,[o(D,{color:"default"},{default:t(()=>[l(r(N.requiredCookies.length)+" 必需 cookie",1)]),_:2},1024),o(D,{color:"default"},{default:t(()=>[l("过期约 "+r(N.cookieMaxAgeHintDays)+" 天",1)]),_:2},1024)]),v(N.vendor)&&te(N.vendor)?(n(),y("div",sa,r(te(N.vendor)),1)):p("",!0),v(N.vendor)?(n(),y("div",{key:1,class:"vendor-actions",onClick:i[0]||(i[0]=at(()=>{},["stop"]))},[o(Ee,{title:"注销该 AI 对话来源?历史事件仍可在 vault 中查询。","ok-text":"注销","cancel-text":"取消",onConfirm:Pe=>J(N.vendor)},{default:t(()=>[o(G,{size:"small",type:"text",danger:""},{default:t(()=>[...i[9]||(i[9]=[l("注销",-1)])]),_:1})]),_:1},8,["onConfirm"])])):p("",!0)]),_:2},1032,["class","onClick"])]),_:2},1024)),64))]),_:1})])):p("",!0),m.value===2&&O.value?(n(),y("div",ia,[d("p",ra,[d("strong",null,r(ie.value.displayName),1),i[11]||(i[11]=l(" · ",-1)),d("a",{href:O.value.loginUrl,target:"_blank",rel:"noopener noreferrer"},r(O.value.loginUrl),9,ua)]),O.value.fallbackMode==="paste"?(n(),g(z,{key:0,message:O.value.helpText||"请在外部浏览器登录后从开发者工具复制全部 cookie 字符串粘贴到下方。",type:"warning","show-icon":"",style:{"margin-bottom":"12px"}},null,8,["message"])):(n(),g(z,{key:1,message:"桌面端:请在弹出的内嵌浏览器窗口登录后点击 “检测 cookie”。",type:"info","show-icon":"",style:{"margin-bottom":"12px"}})),O.value.fallbackMode==="paste"?(n(),g(H,{key:2,bordered:!1,style:{"margin-bottom":"12px"}},{default:t(()=>[o(T,{key:"howto",header:"如何获取 cookie 字符串?"},{default:t(()=>[d("ol",da,[d("li",null,[i[12]||(i[12]=l("用 Chrome / Edge 打开 ",-1)),d("a",{href:O.value.loginUrl,target:"_blank"},r(O.value.loginUrl),9,pa)]),i[13]||(i[13]=d("li",null,"完成登录,进入对话页",-1)),i[14]||(i[14]=d("li",null,[l("按 "),d("kbd",null,"F12"),l(" 打开开发者工具 → "),d("strong",null,"Application"),l(" → "),d("strong",null,"Cookies")],-1)),i[15]||(i[15]=d("li",null,"选中域名 → 全选所有 cookie 行 → 用扩展(如 EditThisCookie)导出 “name=value; …” 串",-1)),i[16]||(i[16]=d("li",null,[l("或在 Console 执行 "),d("code",null,"document.cookie"),l(" 复制结果(注意:HTTP-Only cookie 取不到,仍需 Application 面板)")],-1)),i[17]||(i[17]=d("li",null,"粘贴到下方文本框,点 “检测 cookie”",-1))])]),_:1})]),_:1})):p("",!0),o(we,{layout:"vertical"},{default:t(()=>[o(f,{label:"Cookie 字符串"},{default:t(()=>[o(C,{value:U.value,"onUpdate:value":i[1]||(i[1]=N=>U.value=N),rows:6,placeholder:"name1=value1; name2=value2; name3=value3 …",autocomplete:"off"},null,8,["value"])]),_:1})]),_:1}),B.value?(n(),y("div",ca,[B.value.ok?(n(),g(z,{key:0,type:"success","show-icon":"",message:`已识别 ${B.value.foundRequired.length} 个必需 cookie + ${B.value.foundOptional.length} 个可选 cookie`},null,8,["message"])):(n(),g(z,{key:1,type:"error","show-icon":"",message:j.value},null,8,["message"])),B.value.foundRequired?.length?(n(),y("div",fa," ✓ "+r(B.value.foundRequired.join(", ")),1)):p("",!0),B.value.missingRequired?.length?(n(),y("div",va," 缺失: "+r(B.value.missingRequired.join(", ")),1)):p("",!0)])):p("",!0)])):p("",!0),m.value===3?(n(),y("div",ma,[V.value?.ok?(n(),g(Ce,{key:0,status:"success",title:`${ie.value.displayName} 已接入`,"sub-title":`accountId: ${V.value.accountId} · userId: ${V.value.validation?.userId||"匿名"}`},{extra:t(()=>[o(G,{type:"primary",onClick:pe},{default:t(()=>[...i[18]||(i[18]=[l("完成",-1)])]),_:1}),o(G,{onClick:K},{default:t(()=>[...i[19]||(i[19]=[l("再加一家",-1)])]),_:1})]),_:1},8,["title","sub-title"])):(n(),g(Ce,{key:1,status:"error",title:"接入失败","sub-title":R.value},{extra:t(()=>[o(G,{type:"primary",onClick:i[2]||(i[2]=N=>m.value=2)},{default:t(()=>[...i[20]||(i[20]=[l("返回粘贴 cookie",-1)])]),_:1}),o(G,{onClick:K},{default:t(()=>[...i[21]||(i[21]=[l("选其他厂商",-1)])]),_:1})]),_:1},8,["sub-title"]))])):p("",!0)]),_:1},8,["open"])}}},ga=Le(ya,[["__scopeId","data-v-a608230c"]]),_a={key:0},ka={key:0,class:"probe-result"},ba={key:0,class:"kv"},Aa={key:0,class:"kv"},wa={key:1},Ca={key:2},Ia={key:2,style:{"margin-top":"12px"}},Da={__name:"WechatWizard",props:{open:{type:Boolean,default:!1}},emits:["update:open","registered"],setup(me,{emit:_e}){const w=me,L=_e,Q=Me(),h=S(1),m=S(null),b=se({uin:"",dbPath:"",wechatDataPath:"",forceProvider:null}),U=S(null),O=se({probe:!1,register:!1}),B=ue(()=>h.value===1?"探测设备 + WeChat 版本,确认可用的 keyProvider":h.value===2?"填 UIN 与已 adb-pull 的本地路径":"bootstrap 注册 + 持久化 wechat-accounts.json"),V=ue(()=>{const R=U.value;return R?R.reason==="ENV_UNSUPPORTED"?R.message||"env-probe 拒绝 — 请回到第 1 步看 reasons":R.reason==="MD5_NEEDS_WECHAT_DATA_PATH"?"MD5 路径需要 wechatDataPath":R.reason==="FRIDA_NEEDS_WXID"?"Frida 路径需要 account.uin / wxid":R.reason==="ADAPTER_CTOR_FAILED"?`Adapter ctor 抛错: ${R.message||""}`:R.reason==="BOOTSTRAP_THREW"?`Bootstrap 抛错: ${R.message||""}`:R.reason==="UIN_REQUIRED"?"UIN 不能为空":R.message||R.reason||"注册失败":"未知错误"});async function M(){O.probe=!0;try{m.value=await Q.probeWechatEnv()}catch(R){m.value={ok:!1,suggestedKeyProvider:"unsupported",reasons:[R?.message||"probe failed"],device:{reachable:!1},root:{detected:!1,magiskInstalled:!1},frida:{serverRunning:!1,port:null},wechat:{installed:!1,versionName:null,majorVersion:null},warnings:[]}}finally{O.probe=!1}}async function ie(){O.register=!0;try{U.value=await Q.registerWechat({account:{uin:b.uin},dbPath:b.dbPath||null,wechatDataPath:b.wechatDataPath||null,keyProviderOverride:b.forceProvider}),h.value=3,U.value?.ok&&L("registered",{uin:b.uin,chosenKeyProvider:U.value.chosenKeyProvider})}catch(R){U.value={ok:!1,reason:"BOOTSTRAP_THREW",message:R?.message||"RPC failed"},h.value=3}finally{O.register=!1}}function de(){h.value=1,m.value=null,b.uin="",b.dbPath="",b.wechatDataPath="",b.forceProvider=null,U.value=null}function j(){de(),L("update:open",!1)}return et(()=>w.open,R=>{R&&de()}),(R,v)=>{const le=c("a-alert"),q=c("a-button"),te=c("a-tag"),J=c("a-descriptions-item"),A=c("a-descriptions"),W=c("a-input"),ae=c("a-form-item"),I=c("a-radio"),K=c("a-radio-group"),pe=c("a-form"),_=c("a-result"),i=c("a-space"),z=c("a-drawer");return n(),g(z,{open:me.open,title:"添加 WeChat 账号",placement:"right",width:640,"destroy-on-close":!0,"onUpdate:open":v[8]||(v[8]=D=>L("update:open",D)),onClose:j},{footer:t(()=>[o(i,{style:{float:"right"}},{default:t(()=>[h.value>1&&h.value<3?(n(),g(q,{key:0,onClick:v[6]||(v[6]=D=>h.value=h.value-1)},{default:t(()=>[...v[21]||(v[21]=[l("上一步",-1)])]),_:1})):p("",!0),o(q,{onClick:j},{default:t(()=>[...v[22]||(v[22]=[l("取消",-1)])]),_:1}),h.value===1?(n(),g(q,{key:1,type:"primary",disabled:!m.value||m.value.suggestedKeyProvider==="unsupported",onClick:v[7]||(v[7]=D=>h.value=2)},{default:t(()=>[...v[23]||(v[23]=[l(" 下一步 ",-1)])]),_:1},8,["disabled"])):p("",!0),h.value===2?(n(),g(q,{key:2,type:"primary",loading:O.register,disabled:!b.uin||m.value?.suggestedKeyProvider==="md5"&&!b.wechatDataPath,onClick:ie},{default:t(()=>[...v[24]||(v[24]=[l(" 注册 ",-1)])]),_:1},8,["loading","disabled"])):p("",!0)]),_:1})]),default:t(()=>[o(le,{message:`第 ${h.value} / 3 步`,description:B.value,type:"info","show-icon":"",style:{"margin-bottom":"16px"}},null,8,["message","description"]),h.value===1?(n(),y("div",_a,[v[11]||(v[11]=d("p",{class:"hint"},[l(" 请用 USB 连接 Android 设备(开启 USB 调试)。WeChat ≥ 8.0 需要 root + frida-server。 探测仅读取 "),d("code",null,"adb shell"),l(" 命令输出,不写入任何东西。 ")],-1)),o(q,{type:"primary",loading:O.probe,onClick:M,style:{"margin-bottom":"12px"}},{default:t(()=>[...v[9]||(v[9]=[l(" 🔍 探测环境 ",-1)])]),_:1},8,["loading"]),m.value?(n(),y("div",ka,[o(A,{column:1,size:"small",bordered:""},{default:t(()=>[o(J,{label:"suggestedKeyProvider"},{default:t(()=>[o(te,{color:m.value.suggestedKeyProvider==="unsupported"?"red":"green"},{default:t(()=>[l(r(m.value.suggestedKeyProvider),1)]),_:1},8,["color"])]),_:1}),o(J,{label:"adb 设备"},{default:t(()=>[o(te,{color:m.value.device.reachable?"green":"red"},{default:t(()=>[l(r(m.value.device.reachable?"已连接":"未连接"),1)]),_:1},8,["color"]),m.value.device.serial?(n(),y("span",ba,r(m.value.device.serial)+" · abi="+r(m.value.device.abi||"?"),1)):p("",!0)]),_:1}),o(J,{label:"root"},{default:t(()=>[o(te,{color:m.value.root.detected?"green":"default"},{default:t(()=>[l(r(m.value.root.detected?"已 root":"未 root"),1)]),_:1},8,["color"]),m.value.root.magiskInstalled?(n(),g(te,{key:0,color:"blue"},{default:t(()=>[...v[10]||(v[10]=[l("Magisk",-1)])]),_:1})):p("",!0)]),_:1}),o(J,{label:"frida-server"},{default:t(()=>[o(te,{color:m.value.frida.serverRunning?"green":"default"},{default:t(()=>[l(r(m.value.frida.serverRunning?"运行中":"未运行"),1)]),_:1},8,["color"]),m.value.frida.port?(n(),y("span",Aa," :"+r(m.value.frida.port),1)):p("",!0)]),_:1}),o(J,{label:"WeChat"},{default:t(()=>[o(te,{color:m.value.wechat.installed?"green":"red"},{default:t(()=>[l(r(m.value.wechat.installed?m.value.wechat.versionName:"未安装"),1)]),_:1},8,["color"])]),_:1})]),_:1}),(n(!0),y(ee,null,re(m.value.reasons||[],D=>(n(),g(le,{key:D,message:D,type:"info","show-icon":"",style:{"margin-top":"8px"}},null,8,["message"]))),128)),(n(!0),y(ee,null,re(m.value.warnings||[],D=>(n(),g(le,{key:D,message:D,type:"warning","show-icon":"",style:{"margin-top":"8px"}},null,8,["message"]))),128))])):p("",!0)])):p("",!0),h.value===2?(n(),y("div",wa,[v[16]||(v[16]=d("p",{class:"hint"},[l(" 填写从 adb pull 拉下来的本地路径。MD5 路径(7.x)需要 "),d("code",null,"wechatDataPath"),l("; Frida 路径(8.0+)需要设备运行 frida-server。 ")],-1)),o(pe,{layout:"vertical"},{default:t(()=>[o(ae,{label:"UIN / wxid",required:""},{default:t(()=>[o(W,{value:b.uin,"onUpdate:value":v[0]||(v[0]=D=>b.uin=D),placeholder:"WeChat 数字 UIN 或 wxid"},null,8,["value"])]),_:1}),o(ae,{label:"dbPath(已拉下的 EnMicroMsg.db 本地路径)"},{default:t(()=>[o(W,{value:b.dbPath,"onUpdate:value":v[1]||(v[1]=D=>b.dbPath=D),placeholder:"C:\\\\users\\\\me\\\\pull\\\\EnMicroMsg.db"},null,8,["value"])]),_:1}),o(ae,{label:"wechatDataPath(已拉下的 /data/data/com.tencent.mm/ 目录)"},{default:t(()=>[o(W,{value:b.wechatDataPath,"onUpdate:value":v[2]||(v[2]=D=>b.wechatDataPath=D),placeholder:"C:\\\\users\\\\me\\\\pull\\\\com.tencent.mm"},null,8,["value"]),v[12]||(v[12]=d("div",{class:"hint"},"MD5 路径必填;Frida 路径可空",-1))]),_:1}),o(ae,{label:"强制 keyProvider(覆盖 env-probe 建议)"},{default:t(()=>[o(K,{value:b.forceProvider,"onUpdate:value":v[3]||(v[3]=D=>b.forceProvider=D)},{default:t(()=>[o(I,{value:null},{default:t(()=>[...v[13]||(v[13]=[l("自动(推荐)",-1)])]),_:1}),o(I,{value:"md5"},{default:t(()=>[...v[14]||(v[14]=[l("md5",-1)])]),_:1}),o(I,{value:"frida"},{default:t(()=>[...v[15]||(v[15]=[l("frida",-1)])]),_:1})]),_:1},8,["value"])]),_:1})]),_:1})])):p("",!0),h.value===3?(n(),y("div",Ca,[U.value?.ok?(n(),g(_,{key:0,status:"success",title:`WeChat 已接入 (uin=${b.uin})`,"sub-title":`provider=${U.value.chosenKeyProvider} · sensitivity=${U.value.sensitivity}`},{extra:t(()=>[o(q,{type:"primary",onClick:j},{default:t(()=>[...v[17]||(v[17]=[l("完成",-1)])]),_:1}),o(q,{onClick:de},{default:t(()=>[...v[18]||(v[18]=[l("再加一个",-1)])]),_:1})]),_:1},8,["title","sub-title"])):(n(),g(_,{key:1,status:"error",title:"接入失败","sub-title":V.value},Bt({_:2},[U.value?.probe?.reasons?.length?{name:"extra",fn:t(()=>[o(q,{onClick:v[4]||(v[4]=D=>h.value=1)},{default:t(()=>[...v[19]||(v[19]=[l("返回检查环境",-1)])]),_:1}),o(q,{onClick:v[5]||(v[5]=D=>h.value=2)},{default:t(()=>[...v[20]||(v[20]=[l("返回修改路径",-1)])]),_:1})]),key:"0"}:void 0]),1032,["sub-title"])),U.value?.probe?.reasons?.length?(n(),y("div",Ia,[(n(!0),y(ee,null,re(U.value.probe.reasons,D=>(n(),g(le,{key:D,message:D,type:"warning","show-icon":"",style:{"margin-bottom":"4px"}},null,8,["message"]))),128))])):p("",!0)])):p("",!0)]),_:1},8,["open"])}}},Ea=Le(Da,[["__scopeId","data-v-c7327e24"]]),Sa={class:"pdh-page"},xa={class:"pdh-header"},ha={class:"kv"},Pa={key:0,class:"kv"},Oa={key:1,class:"kv"},$a={class:"kv"},Ma={key:0,class:"kv hint"},La={style:{"margin-top":"12px",display:"flex","justify-content":"space-between","align-items":"center"}},Ua={key:0,style:{"margin-top":"12px"}},Na={key:1,style:{"margin-top":"12px"}},Ba={class:"answer"},Ra={style:{"margin-top":"8px","font-size":"12px",color:"var(--text-color-secondary, #888)"}},Ta={key:2,style:{"margin-top":"8px"}},Ha={style:{display:"flex","align-items":"center",gap:"8px"}},za={class:"hint",style:{"margin-top":"4px"}},Fa={key:0,style:{"margin-top":"16px"}},Wa={class:"json-pre",style:{"max-height":"300px",overflow:"auto"}},qa={key:0,style:{"margin-top":"8px"}},Ka={style:{"min-width":"220px"}},Va={style:{color:"#999","font-size":"12px","margin-left":"4px"}},Qa={key:2,style:{"margin-top":"12px"}},Ga={class:"kv",style:{"margin-bottom":"4px"}},Ya={key:0,style:{color:"#faad14"}},Xa={key:2,class:"kv hint"},ja={key:3,class:"kv hint",style:{color:"#ff4d4f"}},Ja={key:3,style:{"margin-top":"12px"}},Za={key:2,style:{"margin-top":"8px"}},eo={key:1},to={style:{"margin-left":"8px"}},ao={key:3,class:"json-pre"},oo={style:{"margin-left":"6px"}},lo={key:0,style:{"margin-left":"6px"}},no={key:0,class:"hint",style:{"margin-top":"4px"}},so={key:0,style:{"margin-top":"8px"}},io={style:{"margin-bottom":"12px"}},ro={class:"hint"},uo={class:"kv"},po={class:"kv",style:{"margin-top":"4px"}},co={class:"kv"},fo={key:0,class:"hint",style:{"margin-top":"4px"}},vo={key:1,style:{"font-size":"11px"}},Ze="pdh.syncIncludeOptions.v1",mo={__name:"PersonalDataHub",setup(me,{expose:_e}){const w=Me(),L=S(null),Q=S(null),h=S([]),m=S(""),b=S(null),U=S(""),O=S(!1),B=S(!1),V=S([]),M=S(null),ie={"system-data-android":{contacts:!0,apps:!0,sms:!0,calls:!0}};function de(){try{const a=localStorage.getItem(Ze);if(!a)return JSON.parse(JSON.stringify(ie));const e=JSON.parse(a);return{"system-data-android":{...ie["system-data-android"],...e["system-data-android"]||{}}}}catch{return JSON.parse(JSON.stringify(ie))}}const j=se(de());function R(){try{localStorage.setItem(Ze,JSON.stringify(j)),console.log("[PDH-include] persisted:",JSON.stringify(j))}catch(a){console.warn("[PDH-include] persist failed:",a&&a.message)}}const v=S({}),le={"system-data-android":[{key:"contacts",label:"联系人",hint:"~767 条"},{key:"apps",label:"已安装应用",hint:"~176 个"},{key:"sms",label:"短信内容",hint:"~2400 条 · 高敏感",sensitive:!0},{key:"calls",label:"通话记录",hint:"~18000 条 · 包含号码",sensitive:!0}]};function q(a){return Object.prototype.hasOwnProperty.call(le,a)}function te(a,e,u){const E=u&&u.target?!!u.target.checked:!!u;console.log("[PDH-include] toggle",a,e,"=>",E),j[a]||(j[a]={}),j[a][e]=E,R()}const J=S(!1),A=se({provider:"qq",email:"",authCode:"",host:"",port:993,pdfPasswordHints:{idCardLast6:"",phoneLast6:"",cardLast6:""}}),W=S(null),ae=S(!1),I=S(null),K=S(null),pe=[{name:"analysis.spending",label:"消费分析",icon:Kt,description:"总支出 / 商家排行 / 月度趋势"},{name:"analysis.relations",label:"人际关系",icon:Vt,description:"与每个人的互动频率 / 主动比例"},{name:"analysis.footprint",label:"足迹",icon:Qt,description:"常去地点 / 出行模式"},{name:"analysis.interests",label:"兴趣画像",icon:Gt,description:"从购买 / 浏览 / 收藏抽兴趣"},{name:"analysis.timeline",label:"时间线",icon:Yt,description:"跨源事件串成故事"}],_=S(!1),i=S([]),z=se({queue:{pending:0},mergeGroups:0,reviewQueue:0}),D=S(!1),G=S([]);function Ee(a){a?.unregistered?k.success(`已注销 ${a.vendor}`):k.success(`已接入 ${a.vendor}`),Y()}const ke=S(!1);function Se(a){k.success(`WeChat 已接入 (uin=${a.uin}, provider=${a.chosenKeyProvider})`),Y()}const ye=S(!1),T=se({email:"",zipPassword:"",filePath:""}),H=S(null),C=se({active:!1,adapter:"",phase:"",mailbox:"",current:0,total:0,attempt:1,errorMessage:""}),f=se({refresh:!1,ask:!1,addMock:!1,syncAll:!1,sync:{},audit:!1,testEmail:!1,saveEmail:!1,eventDetail:!1,importAlipay:!1,reviewQueue:!1,resolverDrain:!1,skill:!1,bilibiliAdbSync:!1,bilibiliAdbDoctor:!1,douyinAdbSync:!1,weiboAdbSync:!1,xhsAdbSync:!1});function we(a){switch(a){case"BRIDGE_UNAVAILABLE":return"adb 未安装或不在 PATH — 请安装 Android Platform Tools 或设置 ADB_PATH 环境变量";case"MODULE_LOAD_FAILED":return"PDH adapter 模块缺失 — 请重装 cc";case"BILIBILI_NO_ROOT":return"手机未 root — Bilibili 正式版 APK 不是 debuggable,需 Magisk root 才能读 Cookies DB";case"BILIBILI_NOT_INSTALLED_OR_NEVER_LOGGED_IN":return"请在手机上安装 Bilibili App 并登录一次,然后重试";case"BILIBILI_COOKIES_INCOMPLETE":return"Cookie 缺关键字段 — 请在手机 Bilibili App 上重新登录";case"BILIBILI_COOKIES_TRUNCATED":return"ADB 流被截断 — 拔插 USB 重试,或检查 `adb logcat` 是否有 MIUI ROM 干扰";case"BILIBILI_NOT_SQLITE":return"ADB 拉回的文件不是 sqlite — 可能 base64 stream 被 MIUI/HyperOS 干扰,拔插 USB 重试";case"BILIBILI_INVALID_UID":return"Cookie 中 DedeUserID 不是正整数 — 请重新登录";default:return"同步失败 — 详见 message 字段"}}function Ce(a){switch(a){case"BRIDGE_UNAVAILABLE":return"adb 未安装或不在 PATH — 请安装 Android Platform Tools 或设置 ADB_PATH 环境变量";case"MODULE_LOAD_FAILED":return"PDH adapter 模块缺失 — 请重装 cc";case"DOUYIN_NO_ROOT":return"手机未 root — 抖音正式版 APK 不是 debuggable,需 Magisk root 才能读 IM 数据库";case"DOUYIN_NOT_INSTALLED":return"请在手机上安装抖音 App,然后重试";case"DOUYIN_NO_IM_DB":return"抖音 App 已装但未生成 IM 数据库 — 请登录抖音并打开任一聊天会话后重试";case"DOUYIN_MULTIPLE_USERS":return"此手机登录了多个抖音账号 — 请加 --uid <19位数字> 选一个";case"DOUYIN_UID_NOT_FOUND":return"指定的 uid 不在设备上的抖音账号列表里";case"DOUYIN_PULL_FAILED":return"ADB 流传输失败 — 拔插 USB 重试,或检查 `adb logcat` 是否有 MIUI ROM 干扰";case"DOUYIN_NOT_SQLITE":return"拉回的文件不是 sqlite — 可能 base64 stream 被 MIUI/HyperOS 干扰,拔插 USB 重试";default:return"同步失败 — 详见 message 字段"}}function xe(a){switch(a){case"BRIDGE_UNAVAILABLE":return"adb 未安装或不在 PATH — 请安装 Android Platform Tools 或设置 ADB_PATH 环境变量";case"MODULE_LOAD_FAILED":return"PDH adapter 模块缺失 — 请重装 cc";case"WEIBO_NO_ROOT":return"手机未 root — 微博正式版 APK 不是 debuggable,需 Magisk root 才能读 Cookies DB";case"WEIBO_NOT_INSTALLED":return"请在手机上安装微博 App 并登录一次,然后重试 (或微博使用了非默认 WebView 数据目录)";case"WEIBO_COOKIES_EMPTY":return"ADB 流返 0 字节 — MIUI/HyperOS silent 失败?拔插 USB 重试";case"WEIBO_COOKIES_TRUNCATED":return"ADB 流被截断 — 拔插 USB 重试,或检查 `adb logcat` 是否有 MIUI ROM 干扰";case"WEIBO_NOT_SQLITE":return"拉回的文件不是 sqlite — 可能 base64 stream 被 MIUI 干扰,拔插 USB 重试";case"WEIBO_BASE64_PARSE":return"base64 解码失败 — adb 终端编码问题,请检查 `chcp 65001`";case"WEIBO_COOKIES_INCOMPLETE":return"SUB cookie 缺失 — 请在手机微博 App 上重新登录";default:return"同步失败 — 详见 message 字段"}}function he(a){switch(a){case"BRIDGE_UNAVAILABLE":return"adb 未安装或不在 PATH — 请安装 Android Platform Tools 或设置 ADB_PATH 环境变量";case"MODULE_LOAD_FAILED":return"PDH adapter 模块缺失 — 请重装 cc";case"XHS_NO_ROOT":return"手机未 root — 小红书正式版 APK 不是 debuggable,需 Magisk root 才能读 Cookies DB";case"XHS_NOT_INSTALLED":return"请在手机上安装小红书 App 并登录一次,然后重试";case"XHS_COOKIES_EMPTY":return"ADB 流返 0 字节 — MIUI/HyperOS silent 失败?拔插 USB 重试";case"XHS_COOKIES_TRUNCATED":return"ADB 流被截断 — 拔插 USB 重试,或检查 `adb logcat` 是否有 MIUI ROM 干扰";case"XHS_NOT_SQLITE":return"拉回的文件不是 sqlite — 可能 base64 stream 被 MIUI 干扰,拔插 USB 重试";case"XHS_BASE64_PARSE":return"base64 解码失败 — adb 终端编码问题,请检查 `chcp 65001`";case"XHS_COOKIES_INCOMPLETE":return"a1 或 web_session cookie 缺失 — 请在手机小红书 App 上重新登录 (X-S 签名需要 a1 字段)";default:return"同步失败 — 详见 message 字段"}}async function N(){if(!f.xhsAdbSync){f.xhsAdbSync=!0;try{const a=await w.xhsAdbSync({});if(!a||!a.ok){const P=a&&a.reason||"SYNC_FAILED",$=he(P),F=a&&a.message||"";k.error({content:`Xhs ADB 同步失败:${$}`,description:F,duration:8});return}const e=a.report||{},u=e.xhs||{},E=u.eventCounts||{};u.meFetchFailed?k.warning({content:"Xhs 同步未拉到 user_id — /user/me 返空 data",description:`lastErrorCode=${u.lastErrorCode}, ${u.lastErrorMessage||""}。可能 cookie 已过期或 web_session 缺失,请在手机重新登录。`,duration:10}):u.lastErrorCode===461?k.warning({content:"Xhs X-S 签名被拒 (461) — 部分接口未抓到",description:`命中 ${E.total||0} events。我们的 X-S 算法 best-effort (~60% GET / <30% POST hit),461 在 POST 较常见。稍后重试 (X-S 算法可能 4-8 周 rotate)。`,duration:10}):u.lastErrorCode?k.warning({content:`Xhs 同步部分完成 (${E.total||0} events)`,description:`lastErrorCode=${u.lastErrorCode}, ${u.lastErrorMessage||""}`,duration:8}):k.success(`Xhs 同步成功:notes=${E.note||0} / liked=${E.liked||0} / follow=${E.follow||0} (total=${E.total||0})${u.nickname?" ["+u.nickname+"]":""}`),M.value=e,Y()}catch(a){k.error({content:"Xhs ADB 同步异常",description:a&&a.message?a.message:String(a),duration:8})}finally{f.xhsAdbSync=!1}}}async function Pe(){if(!f.weiboAdbSync){f.weiboAdbSync=!0;try{const a=await w.weiboAdbSync({});if(!a||!a.ok){const P=a&&a.reason||"SYNC_FAILED",$=xe(P),F=a&&a.message||"";k.error({content:`Weibo ADB 同步失败:${$}`,description:F,duration:8});return}const e=a.report||{},u=e.weibo||{},E=u.eventCounts||{};u.uidFetchFailed?k.warning({content:"Weibo 同步未拉到 UID — /api/config 返 login=false",description:`lastErrorCode=${u.lastErrorCode}, ${u.lastErrorMessage||""}。可能 cookie 已过期 (请在手机重新登录) 或微博触发 anti-bot redirect。事件数 0,未入 vault。`,duration:10}):u.lastErrorCode?k.warning({content:`Weibo 同步部分完成 (${E.total||0} events)`,description:`lastErrorCode=${u.lastErrorCode}, ${u.lastErrorMessage||""} — 部分接口受反爬限制,稍后重试可补齐`,duration:8}):k.success(`Weibo 同步成功:posts=${E.post||0} / fav=${E.favourite||0} / follow=${E.follow||0} (total=${E.total||0})`),M.value=e,Y()}catch(a){k.error({content:"Weibo ADB 同步异常",description:a&&a.message?a.message:String(a),duration:8})}finally{f.weiboAdbSync=!1}}}async function ot(){if(!f.douyinAdbSync){f.douyinAdbSync=!0;try{const a=await w.douyinAdbSync({});if(!a||!a.ok){const $=a&&a.reason||"SYNC_FAILED",F=Ce($),ce=a&&a.message||"";k.error({content:`Douyin ADB 同步失败:${F}`,description:ce,duration:8});return}const e=a.report||{},u=e.douyin||{},E=u.eventCounts||{},P=u.parserDiagnostic||{};if(!P.hadMsgTable&&!P.hadSimpleUserTable)k.warning({content:"Douyin 同步完成但 0 events",description:"msg 和 SIMPLE_USER 表都未在 IM 数据库中找到 — 抖音 App 版本可能用了不同 schema",duration:10});else if(!P.hadMsgTable||!P.hadSimpleUserTable){const $=[];P.hadMsgTable||$.push("msg (私信)"),P.hadSimpleUserTable||$.push("SIMPLE_USER (联系人)"),k.warning({content:`Douyin 部分同步:msg=${E.message||0} contacts=${E.contact||0}`,description:`${$.join("、")} 表未找到,未入库部分数据`,duration:8})}else k.success(`Douyin 同步成功:messages=${E.message||0} contacts=${E.contact||0} (total=${E.total||0})`);M.value=e,Y()}catch(a){k.error({content:"Douyin ADB 同步异常",description:a&&a.message?a.message:String(a),duration:8})}finally{f.douyinAdbSync=!1}}}async function lt(){if(!f.bilibiliAdbDoctor){f.bilibiliAdbDoctor=!0;try{const a=await w.bilibiliAdbDoctor();if(!a||!a.ok){const u=a&&a.reason||"PROBE_FAILED",E=we(u),P=a&&a.message||"";k.error({content:`Bilibili 诊断失败:${E}`,description:P,duration:8});return}const e=a.cookieDiagnostic||{};e.hadEncrypted?k.warning({content:`Bilibili 环境就绪 (uid=${a.uid}) — 但发现 Keystore 加密 cookie`,description:`cookies 数=${e.cookieCount||"?"}; 部分行使用 Android Keystore 加密 (跳过)。可能是较新 Bilibili App + Android 14+。可继续同步,但可能数据不全。`,duration:10}):k.success(`Bilibili 环境就绪 — uid=${a.uid}, 找到 ${e.cookieCount||"?"} 个 cookie,可以同步`)}catch(a){k.error({content:"Bilibili 诊断异常",description:a&&a.message?a.message:String(a),duration:8})}finally{f.bilibiliAdbDoctor=!1}}}async function nt(){if(!f.bilibiliAdbSync){f.bilibiliAdbSync=!0;try{const a=await w.bilibiliAdbSync({});if(!a||!a.ok){const P=a&&a.reason||"SYNC_FAILED",$=we(P),F=a&&a.message||"";k.error({content:`Bilibili ADB 同步失败:${$}`,description:F,duration:8});return}const e=a.report||{},u=e.bilibili||{},E=u.eventCounts||{};u.lastErrorCode?k.warning({content:`Bilibili 同步部分完成 (${E.total||0} events)`,description:`lastErrorCode=${u.lastErrorCode}, ${u.lastErrorMessage||""} — 部分接口受反爬限制,稍后重试可补齐`,duration:8}):k.success(`Bilibili 同步成功:history=${E.history||0} / fav=${E.favourite||0} / dyn=${E.dynamic||0} / follow=${E.follow||0} (total=${E.total||0})`),M.value=e,Y()}catch(a){k.error({content:"Bilibili ADB 同步异常",description:a&&a.message?a.message:String(a),duration:8})}finally{f.bilibiliAdbSync=!1}}}const st=[{title:"名称",dataIndex:"name",key:"name",width:140},{title:"版本",dataIndex:"version",key:"version",width:80},{title:"能力",key:"capabilities"},{title:"敏感度",key:"sensitivity",width:140},{title:"操作",key:"actions",width:160,align:"right"}],it=[{title:"时间",key:"at",dataIndex:"at",width:170},{title:"动作",dataIndex:"action",key:"action",width:200},{title:"详情",key:"details"}],rt=[{title:"日期",key:"occurredAt",width:100},{title:"描述",dataIndex:"description",key:"description"},{title:"金额",key:"amount",width:140,align:"right"}];function ut(a){return a==="high"?"red":a==="medium"?"orange":"default"}function dt(a){if(!a)return"";const e=a.entityCounts||{},u=`events=${e.events??0} persons=${e.persons??0} | raw=${a.rawCount??0} invalid=${a.invalidCount??0} | KG triples=${a.kgTripleCount??0} RAG docs=${a.ragDocCount??0} | ${a.durationMs??0}ms`;return a.error?`${u} · 错误: ${a.error}`:u}async function Y(){f.refresh=!0;try{L.value=await w.health(),Q.value=await w.stats(),h.value=await w.listAdapters();try{G.value=await w.listAichatAccounts()}catch{}}catch(a){k.error("刷新失败: "+a.message)}finally{f.refresh=!1}}async function Ue(){if(m.value.trim()){f.ask=!0,U.value="",b.value=null;try{b.value=await w.ask(m.value.trim(),{acceptNonLocal:O.value})}catch(a){U.value=a.message}finally{f.ask=!1}}}async function pt(){f.addMock=!0;try{await w.registerMock({count:30,seed:Date.now()%1e3}),await Y(),k.success("MockAdapter 已注册(30 条 mock 数据 ready 同步)")}catch(a){k.error("注册失败: "+a.message)}finally{f.addMock=!1}}function Ne(a=""){C.active=!0,C.adapter=a,C.phase="starting",C.mailbox="",C.current=0,C.total=0,C.attempt=1,C.errorMessage=""}function Be(a){a&&(a.adapter&&(C.adapter=a.adapter),a.phase&&(C.phase=a.phase),typeof a.current=="number"&&(C.current=a.current),typeof a.total=="number"&&(C.total=a.total),typeof a.attempt=="number"&&(C.attempt=a.attempt),a.mailbox&&(C.mailbox=a.mailbox),a.phase==="error"&&(C.errorMessage=a.message||"sync error"))}async function ct(a){f.sync[a]=!0,Ne(a);try{const e=j[a],u=e?{include:{...e}}:{};typeof w.syncAdapterStream=="function"?M.value=await w.syncAdapterStream(a,u,Be):M.value=await w.syncAdapter(a,u),await Y()}catch(e){k.error(`同步 ${a} 失败: ${e.message}`)}finally{f.sync[a]=!1,C.active=!1}}async function ft(){f.syncAll=!0,Ne("(all)");try{const a=typeof w.syncAllStream=="function"?await w.syncAllStream({},Be):await w.syncAll();M.value=a?.[a.length-1]||null,await Y(),k.success(`已同步 ${a?.length||0} 个 adapter`)}catch(a){k.error("同步失败: "+a.message)}finally{f.syncAll=!1,C.active=!1}}async function vt(a){try{await w.unregister(a),await Y()}catch(e){k.error("移除失败: "+e.message)}}async function mt(a){if(a){f.audit=!0;try{V.value=await w.recentAudit({limit:200})}catch(e){k.error("审计日志加载失败: "+e.message)}finally{f.audit=!1}}}const Ie=ue(()=>!(!A.email||!A.email.includes("@")||!A.authCode||A.authCode.length<4||A.provider==="custom"&&!A.host));function yt(a){return{qq:"QQ: 邮箱 → 设置 → 账户 → IMAP/SMTP → 开启 → 生成授权码",163:"163: 邮箱 → 设置 → POP3/SMTP/IMAP → 开启 IMAP/SMTP 服务 → 授权密码",189:"189: 设置 → 第三方客户端授权码",outlook:"Outlook: account.microsoft.com/security → App password",gmail:"Gmail: myaccount.google.com/apppasswords (需开启 2FA)",custom:"联系你的邮箱管理员获取 IMAP 端点 + app-password"}[a]||"请输入服务商授权码(不是登录密码)"}function Re(){A.provider="qq",A.email="",A.authCode="",A.host="",A.port=993,A.pdfPasswordHints={idCardLast6:"",phoneLast6:"",cardLast6:""},W.value=null}function Te(){const a={provider:A.provider,email:A.email.trim(),authCode:A.authCode};return A.provider==="custom"&&(a.host=A.host.trim(),a.port=A.port||993,a.secure=!0),a}function gt(){const a={};for(const e of Object.keys(A.pdfPasswordHints)){const u=A.pdfPasswordHints[e];typeof u=="string"&&u.trim().length>0&&(a[e]=u.trim())}return Object.keys(a).length>0?a:null}async function _t(){if(Ie.value){f.testEmail=!0,W.value=null;try{W.value=await w.testEmailAuth(Te())}catch(a){W.value={ok:!1,error:a.message}}finally{f.testEmail=!1}}}async function kt(){if(!(!Ie.value||!W.value?.ok)){f.saveEmail=!0;try{const a={},e=gt();e&&(a.pdfPasswordHints=e),await w.registerEmail(Te(),a),k.success("邮箱账号已注册"),J.value=!1,Re(),await Y()}catch(a){k.error("保存失败: "+a.message)}finally{f.saveEmail=!1}}}const He=ue(()=>!(!T.email||!T.email.includes("@")||!T.filePath||T.filePath.length<3));function bt(){T.email="",T.zipPassword="",T.filePath="",H.value=null}async function At(){if(He.value){f.importAlipay=!0,H.value=null;try{await w.registerAlipay({email:T.email.trim(),zipPassword:T.zipPassword||void 0});const e=/\.zip$/i.test(T.filePath)?{zipPath:T.filePath,zipPassword:T.zipPassword||void 0}:{csvPath:T.filePath};H.value=await w.importAlipayBill(e),H.value?.status==="ok"?(k.success(`导入成功 — ${H.value.entityCounts?.events||0} 笔交易`),await Y()):k.error("导入失败: "+(H.value?.error||H.value?.status))}catch(a){H.value={status:"error",error:a.message},k.error("导入失败: "+a.message)}finally{f.importAlipay=!1}}}async function ze(a){if(a){f.eventDetail=!0,ae.value=!0;try{I.value=await w.eventDetail(a)}catch(e){I.value=null,k.error("事件详情加载失败: "+e.message)}finally{f.eventDetail=!1}}}_e({showEventDetail:ze});async function wt(a){f.skill=!0,K.value=null;try{K.value=await w.runSkill(a,{})}catch(e){k.error(`${a} 失败: ${e.message}`)}finally{f.skill=!1}}async function De(){f.reviewQueue=!0;try{i.value=await w.reviewQueueList(50);const a=await w.resolverStats();Object.assign(z,a)}catch(a){k.error("待消歧加载失败: "+a.message)}finally{f.reviewQueue=!1}}async function Ct(){_.value=!0,await De()}async function Oe(a,e){try{await w.reviewDecision(a,e),k.success(`已记录决策: ${e}`),await De()}catch(u){k.error("决策失败: "+u.message)}}async function It(){f.resolverDrain=!0;try{const a=await w.resolverDrain(20);k.success(`drain 完成 — same=${a.same} different=${a.different} review=${a.review}`),await De()}catch(a){k.error("drain 失败: "+a.message)}finally{f.resolverDrain=!1}}async function Dt(){try{const a=await w.resolverStats();Object.assign(z,a)}catch{}}return Rt(()=>{Y(),Dt()}),(a,e)=>{const u=c("a-button"),E=c("a-badge"),P=c("a-space"),$=c("a-tag"),F=c("a-card"),ce=c("a-col"),Fe=c("a-row"),Et=c("a-textarea"),We=c("a-checkbox"),ne=c("a-alert"),fe=c("a-divider"),St=c("a-spin"),xt=c("a-popover"),ht=c("a-popconfirm"),$e=c("a-table"),qe=c("a-empty"),Ke=c("a-progress"),ge=c("a-select-option"),Pt=c("a-select"),oe=c("a-form-item"),ve=c("a-input"),Ve=c("a-tooltip"),Qe=c("a-input-password"),Ot=c("a-input-number"),Ge=c("a-form"),be=c("a-drawer"),Ae=c("a-descriptions-item"),$t=c("a-descriptions"),Mt=c("a-list-item-meta"),Ye=c("a-list-item"),Xe=c("a-list"),Lt=c("a-collapse-panel"),Ut=c("a-collapse");return n(),y("div",Sa,[d("div",xa,[e[30]||(e[30]=d("div",null,[d("h2",{class:"page-title"},"个人数据中台"),d("p",{class:"page-sub"}," 让数据回归个人 — 各 app 数据本地加密落盘,本地 LLM 跨源分析,零云端外传。 ")],-1)),o(P,null,{default:t(()=>[o(u,{loading:f.refresh,onClick:Y},{icon:t(()=>[o(X(je))]),default:t(()=>[e[27]||(e[27]=l(" 刷新 ",-1))]),_:1},8,["loading"]),o(E,{count:z.reviewQueue,offset:[0,0]},{default:t(()=>[o(u,{type:"primary",ghost:"",onClick:Ct},{icon:t(()=>[o(X(zt))]),default:t(()=>[e[28]||(e[28]=l(" 待消歧 ",-1))]),_:1})]),_:1},8,["count"]),o(u,{type:"primary",ghost:"",onClick:e[0]||(e[0]=s=>B.value=!0)},{icon:t(()=>[o(X(Ft))]),default:t(()=>[e[29]||(e[29]=l(" 审计日志 ",-1))]),_:1})]),_:1})]),o(Fe,{gutter:16,style:{"margin-bottom":"16px"}},{default:t(()=>[o(ce,{xs:24,sm:12,md:6},{default:t(()=>[o(F,{size:"small",title:"Vault"},{extra:t(()=>[o($,{color:L.value?.vault?.ok?"green":"red"},{default:t(()=>[l(r(L.value?.vault?.ok?"正常":"未就绪"),1)]),_:1},8,["color"])]),default:t(()=>[d("div",ha,"schema v"+r(L.value?.vault?.schemaVersion??"?"),1),Q.value?.vault?(n(),y("div",Pa," 事件 "+r(Q.value.vault.events)+" · 联系人 "+r(Q.value.vault.persons),1)):p("",!0),Q.value?.vault?(n(),y("div",Oa," 地点 "+r(Q.value.vault.places)+" · 商品 "+r(Q.value.vault.items)+" · 主题 "+r(Q.value.vault.topics),1)):p("",!0)]),_:1})]),_:1}),o(ce,{xs:24,sm:12,md:6},{default:t(()=>[o(F,{size:"small",title:"本地 LLM"},{extra:t(()=>[o($,{color:L.value?.llm?.ok?L.value.llm.isLocal?"green":"orange":"red"},{default:t(()=>[l(r(L.value?.llm?.ok?L.value.llm.isLocal?"本地":"非本地":"未就绪"),1)]),_:1},8,["color"])]),default:t(()=>[d("div",$a,r(L.value?.llm?.name||"—"),1),L.value?.llm?.ok&&!L.value.llm.isLocal?(n(),y("div",Ma," ⚠️ 非本地 — ask 会被隐私 gate 拒绝,除非显式 acceptNonLocal ")):p("",!0)]),_:1})]),_:1}),o(ce,{xs:24,sm:12,md:6},{default:t(()=>[o(F,{size:"small",title:"KG 索引"},{extra:t(()=>[o($,{color:L.value?.kgSink?.ok?"green":"default"},{default:t(()=>[l(r(L.value?.kgSink?.ok?"已连接":"不可用"),1)]),_:1},8,["color"])]),default:t(()=>[e[31]||(e[31]=d("div",{class:"kv"},"events / persons → cc knowledge-graph 实体 + 关系",-1))]),_:1})]),_:1}),o(ce,{xs:24,sm:12,md:6},{default:t(()=>[o(F,{size:"small",title:"RAG 索引"},{extra:t(()=>[o($,{color:L.value?.ragSink?.ok?"green":"default"},{default:t(()=>[l(r(L.value?.ragSink?.ok?"已连接":"不可用"),1)]),_:1},8,["color"])]),default:t(()=>[e[32]||(e[32]=d("div",{class:"kv"},"文本 → BM25(vector 留待后续 phase)",-1))]),_:1})]),_:1})]),_:1}),o(F,{style:{"margin-bottom":"16px"}},{title:t(()=>[o(P,null,{default:t(()=>[o(X(qt)),e[33]||(e[33]=d("span",null,"问我数据",-1))]),_:1})]),default:t(()=>[o(Et,{value:m.value,"onUpdate:value":e[1]||(e[1]=s=>m.value=s),rows:2,placeholder:"例:上个月在淘宝总共花了多少?/我妈生日那周买了啥送哪儿?",onKeydown:Tt(at(Ue,["exact","prevent"]),["enter"])},null,8,["value","onKeydown"]),d("div",La,[o(We,{checked:O.value,"onUpdate:checked":e[2]||(e[2]=s=>O.value=s)},{default:t(()=>[...e[34]||(e[34]=[l("允许非本地 LLM (volcengine / anthropic 等)",-1)])]),_:1},8,["checked"]),o(u,{type:"primary",loading:f.ask,disabled:!m.value.trim(),onClick:Ue},{icon:t(()=>[o(X(Wt))]),default:t(()=>[e[35]||(e[35]=l(" 提问 ",-1))]),_:1},8,["loading","disabled"])]),U.value?(n(),y("div",Ua,[o(ne,{type:"error","show-icon":"",message:U.value},null,8,["message"])])):p("",!0),b.value?(n(),y("div",Na,[b.value.warning==="no-facts"?(n(),g(ne,{key:0,type:"warning","show-icon":"",message:"vault 里没找到匹配的事件('no-facts')—— 先同步几个 adapter 让数据进 vault",style:{"margin-bottom":"12px"}})):b.value.warning==="hallucinated-citations"?(n(),g(ne,{key:1,type:"warning","show-icon":"",message:`LLM 引用了 ${b.value.hallucinatedCitations?.length||0} 个不存在的 event id —— 模型在编造`,style:{"margin-bottom":"12px"}},null,8,["message"])):p("",!0),d("div",Ba,r(b.value.answer),1),d("div",Ra," 引用 "+r(b.value.citations?.length||0)+" 条事实 · "+r(b.value.facts?.length||0)+" facts 入 prompt · "+r(b.value.durationMs)+"ms · "+r(b.value.model),1),b.value.citations?.length?(n(),y("div",Ta,[e[36]||(e[36]=d("span",{style:{"font-size":"12px",color:"var(--text-color-secondary, #888)"}},"事件链接(点击查看明细 / PDF 解密结果):",-1)),o(P,{style:{"margin-top":"4px"},wrap:""},{default:t(()=>[(n(!0),y(ee,null,re(b.value.citations,s=>(n(),g($,{key:s,color:"blue",style:{cursor:"pointer"},onClick:x=>ze(s)},{default:t(()=>[l(r(s),1)]),_:2},1032,["onClick"]))),128))]),_:1})])):p("",!0)])):p("",!0)]),_:1}),o(F,{style:{"margin-bottom":"16px"}},{title:t(()=>[o(P,null,{default:t(()=>[o(X(Xt)),e[37]||(e[37]=d("span",null,"分析 skill (Phase 11)",-1))]),_:1})]),extra:t(()=>[o($,{color:"purple"},{default:t(()=>[...e[38]||(e[38]=[l("5 内置",-1)])]),_:1})]),default:t(()=>[o(Fe,{gutter:[12,12]},{default:t(()=>[(n(),y(ee,null,re(pe,s=>o(ce,{xs:24,sm:12,md:8,key:s.name},{default:t(()=>[o(F,{size:"small",hoverable:"",onClick:x=>wt(s.name)},{default:t(()=>[d("div",Ha,[(n(),g(Ht(s.icon),{style:{"font-size":"18px",color:"#722ed1"}})),d("strong",null,r(s.label),1)]),d("div",za,r(s.description),1)]),_:2},1032,["onClick"])]),_:2},1024)),64))]),_:1}),K.value?(n(),y("div",Fa,[o(fe,{plain:"",orientation:"left"},{default:t(()=>[l(r(K.value.skill)+" 结果",1)]),_:1}),o(St,{spinning:f.skill},{default:t(()=>[d("pre",Wa,r(JSON.stringify(K.value,null,2)),1),K.value.llm_commentary||K.value.llm_narrative?(n(),y("div",qa,[o(ne,{type:"info",message:K.value.llm_commentary||K.value.llm_narrative},null,8,["message"])])):p("",!0)]),_:1},8,["spinning"])])):p("",!0)]),_:1}),o(F,{style:{"margin-bottom":"16px"}},{title:t(()=>[o(P,null,{default:t(()=>[o(X(ta)),e[39]||(e[39]=d("span",null,"Adapters",-1))]),_:1})]),extra:t(()=>[o(P,null,{default:t(()=>[o(u,{onClick:e[3]||(e[3]=s=>J.value=!0)},{icon:t(()=>[o(X(jt))]),default:t(()=>[e[40]||(e[40]=l(" 添加邮箱账号 ",-1))]),_:1}),o(u,{onClick:e[4]||(e[4]=s=>ye.value=!0)},{icon:t(()=>[o(X(Jt))]),default:t(()=>[e[41]||(e[41]=l(" 导入支付宝账单 ",-1))]),_:1}),o(u,{onClick:e[5]||(e[5]=s=>D.value=!0)},{icon:t(()=>[o(X(Zt))]),default:t(()=>[e[42]||(e[42]=l(" 添加 AI 对话账号 ",-1))]),_:1}),o(u,{onClick:e[6]||(e[6]=s=>ke.value=!0)},{icon:t(()=>[o(X(ea))]),default:t(()=>[e[43]||(e[43]=l(" 添加 WeChat ",-1))]),_:1}),o(u,{onClick:lt,loading:f.bilibiliAdbDoctor},{default:t(()=>[...e[44]||(e[44]=[l(" 诊断 Bilibili ADB ",-1)])]),_:1},8,["loading"]),o(u,{onClick:nt,loading:f.bilibiliAdbSync},{default:t(()=>[...e[45]||(e[45]=[l(" 通过 PC ADB 同步 Bilibili ",-1)])]),_:1},8,["loading"]),o(u,{onClick:Pe,loading:f.weiboAdbSync},{default:t(()=>[...e[46]||(e[46]=[l(" 通过 PC ADB 同步 Weibo ",-1)])]),_:1},8,["loading"]),o(u,{onClick:N,loading:f.xhsAdbSync},{default:t(()=>[...e[47]||(e[47]=[l(" 通过 PC ADB 同步 Xhs ",-1)])]),_:1},8,["loading"]),o(u,{onClick:ot,loading:f.douyinAdbSync},{default:t(()=>[...e[48]||(e[48]=[l(" 通过 PC ADB 同步 Douyin ",-1)])]),_:1},8,["loading"]),o(u,{onClick:pt,loading:f.addMock},{default:t(()=>[...e[49]||(e[49]=[l(" 注册 MockAdapter(开发) ",-1)])]),_:1},8,["loading"]),o(u,{type:"primary",onClick:ft,loading:f.syncAll,disabled:!h.value.length},{default:t(()=>[...e[50]||(e[50]=[l(" 同步全部 ",-1)])]),_:1},8,["loading","disabled"])]),_:1})]),default:t(()=>[h.value.length?(n(),g($e,{key:0,columns:st,"data-source":h.value,pagination:!1,"row-key":s=>s.name,size:"middle"},{bodyCell:t(({column:s,record:x})=>[s.key==="sensitivity"?(n(),y(ee,{key:0},[o($,{color:ut(x.sensitivity)},{default:t(()=>[l(r(x.sensitivity),1)]),_:2},1032,["color"]),x.legalGate?(n(),g($,{key:0,color:"red",style:{"margin-left":"4px"}},{default:t(()=>[...e[51]||(e[51]=[l("需法律确认",-1)])]),_:1})):p("",!0)],64)):s.key==="capabilities"?(n(!0),y(ee,{key:1},re(x.capabilities,Z=>(n(),g($,{key:Z,style:{"margin-right":"4px"}},{default:t(()=>[l(r(Z),1)]),_:2},1024))),128)):s.key==="actions"?(n(),g(P,{key:2},{default:t(()=>[o(u,{size:"small",loading:f.sync[x.name],onClick:Z=>ct(x.name)},{default:t(()=>[...e[52]||(e[52]=[l(" 同步 ",-1)])]),_:1},8,["loading","onClick"]),q(x.name)?(n(),g(xt,{key:0,open:v.value[x.name],"onUpdate:open":Z=>v.value[x.name]=Z,trigger:"click",placement:"left",title:`${x.name} 采集范围`},{content:t(()=>[d("div",Ka,[(n(!0),y(ee,null,re(le[x.name],Z=>(n(),y("div",{key:Z.key,style:{margin:"6px 0"}},[o(We,{checked:j[x.name][Z.key]!==!1,onChange:Nt=>te(x.name,Z.key,Nt)},{default:t(()=>[l(r(Z.label)+" ",1),d("span",Va,r(Z.hint),1),Z.sensitive?(n(),g($,{key:0,color:"orange",size:"small",style:{"margin-left":"4px"}},{default:t(()=>[...e[53]||(e[53]=[l("敏感",-1)])]),_:1})):p("",!0)]),_:2},1032,["checked","onChange"])]))),128)),e[54]||(e[54]=d("div",{style:{"margin-top":"8px","font-size":"11px",color:"#999"}}," 取消勾选的数据本次同步不会拉取入库 ",-1))])]),default:t(()=>[o(u,{size:"small",title:"选择采集范围"},{default:t(()=>[...e[55]||(e[55]=[l("⚙",-1)])]),_:1})]),_:2},1032,["open","onUpdate:open","title"])):p("",!0),o(ht,{title:`从注册表移除 ${x.name}?(vault 数据不会删除)`,onConfirm:Z=>vt(x.name)},{default:t(()=>[o(u,{size:"small",danger:""},{default:t(()=>[...e[56]||(e[56]=[l("移除",-1)])]),_:1})]),_:1},8,["title","onConfirm"])]),_:2},1024)):p("",!0)]),_:1},8,["data-source","row-key"])):(n(),g(qe,{key:1,description:"无已注册 adapter — 点上方按钮注册 MockAdapter 看效果"})),C.active?(n(),y("div",Qa,[o(F,{size:"small",bordered:!0},{default:t(()=>[d("div",Ga,[e[57]||(e[57]=d("strong",null,"同步进行中",-1)),l(" · "+r(C.adapter)+" · "+r(C.phase||"...")+" ",1),C.attempt&&C.attempt>1?(n(),y("span",Ya," (重试 #"+r(C.attempt)+") ",1)):p("",!0)]),C.total>0?(n(),g(Ke,{key:0,percent:Math.round(C.current/C.total*100),status:C.errorMessage?"exception":"active",size:"small"},null,8,["percent","status"])):(n(),g(Ke,{key:1,percent:0,status:"active",size:"small"})),C.mailbox?(n(),y("div",Xa," 邮箱 "+r(C.mailbox)+" · "+r(C.current)+" / "+r(C.total),1)):p("",!0),C.errorMessage?(n(),y("div",ja,r(C.errorMessage),1)):p("",!0)]),_:1})])):p("",!0),M.value?(n(),y("div",Ja,[o(ne,{type:M.value.status==="ok"?"success":"error","show-icon":"",message:`同步 ${M.value.adapter}: ${M.value.status}`,description:dt(M.value)},null,8,["type","message","description"])])):p("",!0)]),_:1}),o(be,{open:J.value,"onUpdate:open":e[16]||(e[16]=s=>J.value=s),title:"添加邮箱账号",placement:"right",width:"560","destroy-on-close":!0,onClose:Re},{footer:t(()=>[o(P,null,{default:t(()=>[o(u,{onClick:e[15]||(e[15]=s=>J.value=!1)},{default:t(()=>[...e[67]||(e[67]=[l("取消",-1)])]),_:1}),o(u,{loading:f.testEmail,disabled:!Ie.value,onClick:_t},{default:t(()=>[...e[68]||(e[68]=[l(" 测试连接 ",-1)])]),_:1},8,["loading","disabled"]),o(u,{type:"primary",loading:f.saveEmail,disabled:!Ie.value||!W.value?.ok,onClick:kt},{default:t(()=>[...e[69]||(e[69]=[l(" 保存并注册 ",-1)])]),_:1},8,["loading","disabled"])]),_:1})]),default:t(()=>[o(ne,{message:"数据回归个人 — 凭证落本地加密文件(与 vault 主密钥同目录),同步动作 100% 本地。",type:"info","show-icon":"",style:{"margin-bottom":"16px"}}),o(Ge,{layout:"vertical",model:A},{default:t(()=>[o(oe,{label:"邮箱服务商",required:""},{default:t(()=>[o(Pt,{value:A.provider,"onUpdate:value":e[7]||(e[7]=s=>A.provider=s),placeholder:"选择服务商"},{default:t(()=>[o(ge,{value:"qq"},{default:t(()=>[...e[58]||(e[58]=[l("QQ 邮箱 (imap.qq.com)",-1)])]),_:1}),o(ge,{value:"163"},{default:t(()=>[...e[59]||(e[59]=[l("网易邮箱 163/126",-1)])]),_:1}),o(ge,{value:"189"},{default:t(()=>[...e[60]||(e[60]=[l("189 邮箱",-1)])]),_:1}),o(ge,{value:"outlook"},{default:t(()=>[...e[61]||(e[61]=[l("Outlook / Hotmail",-1)])]),_:1}),o(ge,{value:"gmail"},{default:t(()=>[...e[62]||(e[62]=[l("Gmail",-1)])]),_:1}),o(ge,{value:"custom"},{default:t(()=>[...e[63]||(e[63]=[l("自定义 IMAP",-1)])]),_:1})]),_:1},8,["value"])]),_:1}),o(oe,{label:"邮箱地址",required:""},{default:t(()=>[o(ve,{value:A.email,"onUpdate:value":e[8]||(e[8]=s=>A.email=s),placeholder:"you@qq.com",autocomplete:"off"},null,8,["value"])]),_:1}),o(oe,{required:""},{label:t(()=>[o(P,null,{default:t(()=>[e[64]||(e[64]=d("span",null,"授权码(非登录密码)",-1)),o(Ve,{title:yt(A.provider)},{default:t(()=>[o(X(Je),{style:{color:"#888"}})]),_:1},8,["title"])]),_:1})]),default:t(()=>[o(Qe,{value:A.authCode,"onUpdate:value":e[9]||(e[9]=s=>A.authCode=s),placeholder:"例:QQ 邮箱 设置 → 账户 → 开启 IMAP/SMTP → 生成的授权码",autocomplete:"off"},null,8,["value"])]),_:1}),A.provider==="custom"?(n(),g(oe,{key:0,label:"IMAP host"},{default:t(()=>[o(ve,{value:A.host,"onUpdate:value":e[10]||(e[10]=s=>A.host=s),placeholder:"mail.example.com"},null,8,["value"])]),_:1})):p("",!0),A.provider==="custom"?(n(),g(oe,{key:1,label:"端口"},{default:t(()=>[o(Ot,{value:A.port,"onUpdate:value":e[11]||(e[11]=s=>A.port=s),min:1,max:65535,"default-value":993},null,8,["value"])]),_:1})):p("",!0),o(fe,{orientation:"left",plain:""},{default:t(()=>[...e[65]||(e[65]=[l("PDF 账单解密提示(可选)",-1)])]),_:1}),e[66]||(e[66]=d("p",{class:"hint"},"银行 PDF 月结大多加密;提供几个常用候选项让 Phase 5.5 自动解锁:",-1)),o(oe,{label:"身份证后 6 位"},{default:t(()=>[o(ve,{value:A.pdfPasswordHints.idCardLast6,"onUpdate:value":e[12]||(e[12]=s=>A.pdfPasswordHints.idCardLast6=s),placeholder:"123456",autocomplete:"off"},null,8,["value"])]),_:1}),o(oe,{label:"手机后 6 位"},{default:t(()=>[o(ve,{value:A.pdfPasswordHints.phoneLast6,"onUpdate:value":e[13]||(e[13]=s=>A.pdfPasswordHints.phoneLast6=s),placeholder:"123456",autocomplete:"off"},null,8,["value"])]),_:1}),o(oe,{label:"信用卡尾 6 位"},{default:t(()=>[o(ve,{value:A.pdfPasswordHints.cardLast6,"onUpdate:value":e[14]||(e[14]=s=>A.pdfPasswordHints.cardLast6=s),placeholder:"123456",autocomplete:"off"},null,8,["value"])]),_:1}),W.value?(n(),y("div",Za,[o(ne,{type:W.value.ok?"success":"error","show-icon":"",message:W.value.ok?"凭证有效 — 可以保存":`认证失败: ${W.value.reason||W.value.error}`},null,8,["type","message"])])):p("",!0)]),_:1},8,["model"])]),_:1},8,["open"]),o(be,{open:ae.value,"onUpdate:open":e[17]||(e[17]=s=>ae.value=s),title:I.value?`事件 ${I.value.event.id}`:"加载中...",placement:"right",width:"640","destroy-on-close":!0},{default:t(()=>[I.value?(n(),y(ee,{key:0},[o($t,{column:1,size:"small",bordered:""},{default:t(()=>[o(Ae,{label:"类型"},{default:t(()=>[l(r(I.value.event.subtype),1)]),_:1}),o(Ae,{label:"发生于"},{default:t(()=>[l(r(new Date(I.value.event.occurredAt).toLocaleString()),1)]),_:1}),o(Ae,{label:"actor"},{default:t(()=>[l(r(I.value.event.actor),1)]),_:1}),I.value.event.content?.title?(n(),g(Ae,{key:0,label:"标题"},{default:t(()=>[l(r(I.value.event.content.title),1)]),_:1})):p("",!0),I.value.event.source?.adapter?(n(),g(Ae,{key:1,label:"来源 adapter"},{default:t(()=>[l(r(I.value.event.source.adapter)+" @ v"+r(I.value.event.source.adapterVersion),1)]),_:1})):p("",!0)]),_:1}),I.value.classification?(n(),g(fe,{key:0,orientation:"left",plain:""},{default:t(()=>[...e[70]||(e[70]=[l("分类",-1)])]),_:1})):p("",!0),I.value.classification?(n(),y("div",eo,[o($,{color:"blue"},{default:t(()=>[l(r(I.value.classification.category),1)]),_:1}),o($,null,{default:t(()=>[l(r(I.value.classification.layer),1)]),_:1}),d("span",to,"置信 "+r(Math.round((I.value.classification.confidence||0)*100))+"%",1)])):p("",!0),I.value.extraction?(n(),g(fe,{key:2,orientation:"left",plain:""},{default:t(()=>[l("结构化字段("+r(I.value.extraction.template)+")",1)]),_:1})):p("",!0),I.value.extraction?(n(),y("pre",ao,r(JSON.stringify(I.value.extraction.fields,null,2)),1)):p("",!0),I.value.extraction?.pdfExtraction?(n(),g(fe,{key:4,orientation:"left",plain:""},{default:t(()=>[...e[71]||(e[71]=[l("PDF 解密 / 解析",-1)])]),_:1})):p("",!0),I.value.extraction?.pdfExtraction?(n(),g(Xe,{key:5,"data-source":I.value.extraction.pdfExtraction,size:"small"},{renderItem:t(({item:s})=>[o(Ye,null,{default:t(()=>[o(Mt,{title:s.filename},{description:t(()=>[d("div",null,[o($,{color:s.decrypted?"green":"red"},{default:t(()=>[l(r(s.decrypted?"已解密":"解密失败"),1)]),_:2},1032,["color"]),d("span",oo,"尝试 "+r(s.attempted)+" 次",1),s.transactionsExtracted!=null?(n(),y("span",lo," · 提取 "+r(s.transactionsExtracted)+" 条交易 ",1)):p("",!0)]),s.error?(n(),y("div",no,r(s.error),1)):p("",!0)]),_:2},1032,["title"])]),_:2},1024)]),_:1},8,["data-source"])):p("",!0),I.value.extraction?.fields?.transactions?.length?(n(),y(ee,{key:6},[o(fe,{orientation:"left",plain:""},{default:t(()=>[...e[72]||(e[72]=[l("交易明细",-1)])]),_:1}),o($e,{columns:rt,"data-source":I.value.extraction.fields.transactions,pagination:{pageSize:10,size:"small"},"row-key":(s,x)=>x,size:"small"},{bodyCell:t(({column:s,record:x})=>[s.key==="occurredAt"?(n(),y(ee,{key:0},[l(r(new Date(x.occurredAtMs).toLocaleDateString()),1)],64)):s.key==="amount"?(n(),y("span",{key:1,class:tt(x.amount.direction==="in"?"amount-in":"amount-out")},r(x.amount.direction==="in"?"+":"-")+r(x.amount.value.toFixed(2))+" "+r(x.amount.currency),3)):p("",!0)]),_:1},8,["data-source","row-key"])],64)):p("",!0)],64)):(n(),g(qe,{key:1,description:"无事件数据"}))]),_:1},8,["open","title"]),o(be,{open:ye.value,"onUpdate:open":e[22]||(e[22]=s=>ye.value=s),title:"导入支付宝账单",placement:"right",width:"560","destroy-on-close":!0,onClose:bt},{footer:t(()=>[o(P,null,{default:t(()=>[o(u,{onClick:e[21]||(e[21]=s=>ye.value=!1)},{default:t(()=>[...e[78]||(e[78]=[l("关闭",-1)])]),_:1}),o(u,{type:"primary",loading:f.importAlipay,disabled:!He.value,onClick:At},{default:t(()=>[...e[79]||(e[79]=[l(" 注册账户 + 导入 ",-1)])]),_:1},8,["loading","disabled"])]),_:1})]),default:t(()=>[o(ne,{message:"支付宝官方导出 CSV — 服务器侧全量、稳定无风控。3 分钟拿到 12 个月流水。",type:"info","show-icon":"",style:{"margin-bottom":"16px"}}),o(Ut,{bordered:!1,style:{"margin-bottom":"12px"}},{default:t(()=>[o(Lt,{header:"如何导出账单(首次必看)"},{default:t(()=>[...e[73]||(e[73]=[d("ol",{style:{"padding-left":"18px","font-size":"13px"}},[d("li",null,"支付宝 app → 我的 → 账单 → 右上角 ⋯"),d("li",null,'点 "开具交易流水证明"'),d("li",null,"选月份范围(最长 12 个月)"),d("li",null,'用途选 "个人对账"'),d("li",null,"发送到你的绑定邮箱"),d("li",null,[l("从邮箱下载 "),d("code",null,"alipay_record_*.zip")]),d("li",null,"解压密码 = 你的身份证后 6 位")],-1)])]),_:1})]),_:1}),o(Ge,{layout:"vertical",model:T},{default:t(()=>[o(oe,{label:"支付宝绑定邮箱(账户标识)",required:""},{default:t(()=>[o(ve,{value:T.email,"onUpdate:value":e[18]||(e[18]=s=>T.email=s),placeholder:"alipay-bound@example.com",autocomplete:"off"},null,8,["value"])]),_:1}),o(oe,null,{label:t(()=>[o(P,null,{default:t(()=>[e[74]||(e[74]=d("span",null,"ZIP 密码(身份证后 6 位)",-1)),o(Ve,{title:"支付宝 ZIP 默认密码 = 身份证号后 6 位。也支持自定义密码。"},{default:t(()=>[o(X(Je),{style:{color:"#888"}})]),_:1})]),_:1})]),default:t(()=>[o(Qe,{value:T.zipPassword,"onUpdate:value":e[19]||(e[19]=s=>T.zipPassword=s),placeholder:"例:123456",autocomplete:"off"},null,8,["value"]),e[75]||(e[75]=d("div",{class:"hint",style:{"margin-top":"4px"}}," 空白则解析时再问,或导入的 ZIP 未加密。 ",-1))]),_:1}),o(fe,{orientation:"left",plain:""},{default:t(()=>[...e[76]||(e[76]=[l("选择文件",-1)])]),_:1}),o(oe,{label:"ZIP 或 CSV 文件路径"},{default:t(()=>[o(ve,{value:T.filePath,"onUpdate:value":e[20]||(e[20]=s=>T.filePath=s),placeholder:"C:\\\\Users\\\\you\\\\Downloads\\\\alipay_record_xxx.zip","allow-clear":""},null,8,["value"]),e[77]||(e[77]=d("div",{class:"hint",style:{"margin-top":"4px"}}," 桌面版可通过 Electron 文件选择器自动填充;web-shell 复制完整路径。 ",-1))]),_:1}),H.value?(n(),y("div",so,[o(ne,{type:H.value.status==="ok"?"success":"error","show-icon":"",message:H.value.status==="ok"?`导入成功 — ${H.value.entityCounts?.events||0} 笔交易`:`导入失败: ${H.value.error||H.value.status}`,description:H.value.status==="ok"?`${H.value.entityCounts?.persons||0} 个交易对方 · ${H.value.kgTripleCount||0} KG triples · ${H.value.durationMs||0}ms`:null},null,8,["type","message","description"])])):p("",!0)]),_:1},8,["model"])]),_:1},8,["open"]),o(be,{open:_.value,"onUpdate:open":e[23]||(e[23]=s=>_.value=s),title:"待消歧(EntityResolver 模糊判定)",placement:"right",width:"640","destroy-on-close":!0},{default:t(()=>[i.value.length===0&&!f.reviewQueue?(n(),g(ne,{key:0,type:"success","show-icon":"",message:"无待消歧 pair — 所有跨源 Person 已确定。",style:{"margin-bottom":"12px"}})):p("",!0),d("div",io,[o(P,null,{default:t(()=>[o(u,{loading:f.reviewQueue,onClick:De},{icon:t(()=>[o(X(je))]),default:t(()=>[e[80]||(e[80]=l(" 刷新 ",-1))]),_:1},8,["loading"]),o(u,{loading:f.resolverDrain,onClick:It},{default:t(()=>[...e[81]||(e[81]=[l(" 手动 drain 队列 ",-1)])]),_:1},8,["loading"]),d("span",ro," queue: "+r(z.queue?.pending||0)+" pending · "+r(z.mergeGroups||0)+" groups ",1)]),_:1})]),o(Xe,{"data-source":i.value,pagination:{pageSize:5,size:"small"},size:"small"},{renderItem:t(({item:s})=>[o(Ye,null,{default:t(()=>[o(F,{size:"small",style:{width:"100%"}},{default:t(()=>[d("div",uo,[d("strong",null,"Pair #"+r(s.id),1),s.embed_sim?(n(),g($,{key:0,color:"blue",style:{"margin-left":"8px"}},{default:t(()=>[l(" sim "+r(Number(s.embed_sim).toFixed(2)),1)]),_:2},1024)):p("",!0),s.llm_verdict?(n(),g($,{key:1,color:s.llm_verdict==="yes"?"green":s.llm_verdict==="no"?"red":"orange",style:{"margin-left":"4px"}},{default:t(()=>[l(" LLM: "+r(s.llm_verdict),1)]),_:2},1032,["color"])):p("",!0)]),d("div",po,"A: "+r(s.a_person_id),1),d("div",co,"B: "+r(s.b_person_id),1),s.llm_reason?(n(),y("div",fo," LLM 理由: "+r(s.llm_reason),1)):p("",!0),o(P,{style:{"margin-top":"8px"}},{default:t(()=>[o(u,{size:"small",type:"primary",onClick:x=>Oe(s.id,"same")},{default:t(()=>[...e[82]||(e[82]=[l("同一人",-1)])]),_:1},8,["onClick"]),o(u,{size:"small",danger:"",onClick:x=>Oe(s.id,"different")},{default:t(()=>[...e[83]||(e[83]=[l("不同人",-1)])]),_:1},8,["onClick"]),o(u,{size:"small",onClick:x=>Oe(s.id,"skip")},{default:t(()=>[...e[84]||(e[84]=[l("跳过",-1)])]),_:1},8,["onClick"])]),_:2},1024)]),_:2},1024)]),_:2},1024)]),_:1},8,["data-source"])]),_:1},8,["open"]),o(be,{open:B.value,"onUpdate:open":e[24]||(e[24]=s=>B.value=s),title:"审计日志(数据 lineage)",placement:"right",width:"600",onAfterOpenChange:mt},{default:t(()=>[o($e,{columns:it,"data-source":V.value,pagination:{pageSize:20,size:"small"},"row-key":s=>s.id,size:"small"},{bodyCell:t(({column:s,record:x})=>[s.key==="at"?(n(),y(ee,{key:0},[l(r(new Date(x.at).toLocaleString()),1)],64)):s.key==="details"?(n(),y("code",vo,r(x.details||"—"),1)):p("",!0)]),_:1},8,["data-source","row-key"])]),_:1},8,["open"]),o(ga,{open:D.value,"onUpdate:open":e[25]||(e[25]=s=>D.value=s),"existing-accounts":G.value,onRegistered:Ee},null,8,["open","existing-accounts"]),o(Ea,{open:ke.value,"onUpdate:open":e[26]||(e[26]=s=>ke.value=s),onRegistered:Se},null,8,["open"])])}}},bo=Le(mo,[["__scopeId","data-v-3b29f69d"]]);export{bo as default};
@@ -1 +0,0 @@
1
- .providers-grid[data-v-38d68389]{display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:12px}.provider-card[data-v-38d68389]{border:1px solid var(--border-color)!important;transition:border-color .2s}.provider-card[data-v-38d68389]:hover{border-color:var(--text-muted)!important}.provider-card.active[data-v-38d68389]{border-color:#52c41a!important;background:#29a27014!important}.section-title[data-v-38d68389]{color:var(--text-primary, #ccc);font-size:16px;font-weight:500;margin:0}.config-card[data-v-38d68389]{border-radius:8px}.config-card[data-v-38d68389] .ant-card-body{padding:24px}.config-form[data-v-38d68389] .ant-form-item-label>label{color:var(--text-secondary, #aaa);font-size:13px}.config-form[data-v-38d68389] .ant-input,.config-form[data-v-38d68389] .ant-input-password input,.config-form[data-v-38d68389] .ant-input-number,.config-form[data-v-38d68389] .ant-select-selector{background:var(--bg-card-hover, #1a1a1a)!important;border-color:var(--border-color, #333)!important;color:var(--text-primary, #e0e0e0)!important}.config-form[data-v-38d68389] .ant-input::placeholder,.config-form[data-v-38d68389] .ant-input-password input::placeholder{color:var(--text-muted, #555)!important}.config-form[data-v-38d68389] .ant-input-number-input,.config-form[data-v-38d68389] .ant-select-selection-item{color:var(--text-primary, #e0e0e0)!important}.config-form[data-v-38d68389] .ant-select-arrow{color:var(--text-muted, #555)}.config-form[data-v-38d68389] .ant-slider-rail{background:var(--border-color, #333)}.config-form[data-v-38d68389] .ant-slider-track{background:#1890ff}.config-form[data-v-38d68389] .ant-slider-handle{border-color:#1890ff}.config-form[data-v-38d68389] .ant-input-password-icon{color:var(--text-muted, #555)}.config-grid[data-v-38d68389]{display:grid;grid-template-columns:repeat(2,1fr);gap:0 24px}@media(max-width:640px){.config-grid[data-v-38d68389]{grid-template-columns:1fr}}
@@ -1,2 +0,0 @@
1
- import{E as Z,r as P,o as H,M as N,R as n,c as s,N as l,u as g,Q as K,S as B,F as X,Y as ee,K as u,a as te,L as y,O as x,P as M,Z as oe}from"./vendor-DhFY8mDK.js";import{u as A,_ as ae,d as _}from"./index-BD2U0Ciz.js";import{a as se,b as le}from"./parsers-DftYMnlk.js";import{R as q}from"./icons-AILO5ZcK.js";const re=Z("providers",()=>{const O=P(!1),i=P(null),m=P([]),T=P([]),c=P(null);async function t(){const v=A();O.value=!0;try{const{output:k}=await v.execute("llm providers",15e3);m.value=se(k);const b=m.value.find(C=>C.active);b&&(c.value=b.name);const{output:w}=await v.execute("llm models",15e3);T.value=le(w)}catch(k){console.error("Failed to load providers:",k)}finally{O.value=!1}}async function d(v){await A().execute(`llm switch ${v}`,1e4),m.value.forEach(b=>b.active=b.name===v),c.value=v}async function F(v){const k=A();i.value=v;try{const{output:b,exitCode:w}=await k.execute("llm test",3e4),C=m.value.find(S=>S.name===v);return C&&(C.status=w===0?"ok":"error"),w===0}catch{const b=m.value.find(w=>w.name===v);return b&&(b.status="error"),!1}finally{i.value=null}}return{loading:O,testing:i,providers:m,localModels:T,activeProvider:c,loadProviders:t,switchProvider:d,testProvider:F}}),ne={style:{display:"flex","align-items":"center","justify-content":"space-between","margin-bottom":"24px"}},ie={key:1,style:{"text-align":"center",padding:"60px"}},de={key:2},ue={class:"providers-grid"},ce={style:{display:"flex","align-items":"center",gap:"12px","margin-bottom":"12px"}},pe={style:{"font-size":"24px"}},me={style:{flex:"1"}},ve={style:{color:"#e0e0e0","font-weight":"500"}},fe={style:{color:"var(--text-secondary)","font-size":"11px","font-family":"monospace"}},ge={style:{display:"flex",gap:"8px","justify-content":"flex-end"}},ye={key:0,style:{"margin-top":"24px"}},be={style:{color:"#ccc","font-family":"monospace","font-size":"13px"}},xe={style:{display:"flex","align-items":"center","justify-content":"space-between","margin-bottom":"16px"}},_e={class:"config-grid"},ke={style:{display:"flex","align-items":"center",gap:"12px"}},we={style:{display:"flex",gap:"12px","justify-content":"flex-end","margin-top":"16px"}},he={__name:"Providers",setup(O){const i=re(),m=A(),T=P(!1),c=P(!1),t=te({provider:void 0,model:"",apiKey:"",baseUrl:"",temperature:.7,maxTokens:4096});let d={};const F=["ollama","openai","anthropic","volcengine","deepseek","gemini","groq","mistral","custom","zhipu"],v={ollama:"Ollama(本地)",openai:"OpenAI",anthropic:"Anthropic",volcengine:"火山引擎(豆包)",deepseek:"DeepSeek",gemini:"Google Gemini",groq:"Groq",mistral:"Mistral",custom:"Custom(自定义)",zhipu:"智谱 AI"},k=F.map(a=>({value:a,label:v[a]||a}));async function b(a){try{await i.switchProvider(a),_.success(`已切换到 ${a}`)}catch(e){_.error(`切换失败: ${e.message}`)}}async function w(a){await i.testProvider(a)?_.success(`${a} 连接正常`):_.warning(`${a} 连接失败,请检查配置`)}function C(a){const e={};if(!a)return e;try{const U=JSON.parse(a.trim()),p=U.llm||U;return p.provider&&(e.provider=p.provider),p.model&&(e.model=p.model),p.apiKey&&(e.apiKey=p.apiKey),p.baseUrl&&(e.baseUrl=p.baseUrl),p.temperature!==void 0&&(e.temperature=Number(p.temperature)),p.maxTokens!==void 0&&(e.maxTokens=Number(p.maxTokens)),e}catch{}const r=a.split(`
2
- `);for(const U of r){const z=U.trim().match(/^(?:llm\.)?(\w+)\s*[=:]\s*(.+)$/i);if(!z)continue;const[,I,j]=z,f=j.trim(),h=I.toLowerCase();if(h==="provider"&&f)e.provider=f;else if(h==="model"&&f)e.model=f;else if(h==="apikey"&&f)f.includes("***")||(e.apiKey=f);else if(h==="baseurl")e.baseUrl=f;else if(h==="temperature"){const $=parseFloat(f);isNaN($)||(e.temperature=$)}else if(h==="maxtokens"){const $=parseInt(f,10);isNaN($)||(e.maxTokens=$)}}return e}async function S(){T.value=!0;try{const{output:a}=await m.execute("config list",15e3),e=C(a);e.provider&&(t.provider=e.provider),e.model&&(t.model=e.model),e.apiKey&&(t.apiKey=e.apiKey),e.baseUrl&&(t.baseUrl=e.baseUrl),e.temperature!==void 0&&(t.temperature=e.temperature),e.maxTokens!==void 0&&(t.maxTokens=e.maxTokens),d={...t},_.success("配置已加载")}catch(a){_.error(`加载配置失败: ${a.message}`)}finally{T.value=!1}}async function E(){c.value=!0;const a=[],e=[];try{if(t.provider&&t.provider!==d.provider)try{await m.execute(`config set llm.provider ${t.provider}`,1e4),e.push("provider")}catch(r){a.push(`provider: ${r.message}`)}if(t.model&&t.model!==d.model)try{await m.execute(`config set llm.model ${t.model}`,1e4),e.push("model")}catch(r){a.push(`model: ${r.message}`)}if(t.apiKey&&t.apiKey!==d.apiKey)try{await m.execute(`config set llm.apiKey ${t.apiKey}`,1e4),e.push("apiKey")}catch(r){a.push(`apiKey: ${r.message}`)}if(t.baseUrl!==void 0&&t.baseUrl!==d.baseUrl)try{await m.execute(`config set llm.baseUrl ${t.baseUrl}`,1e4),e.push("baseUrl")}catch(r){a.push(`baseUrl: ${r.message}`)}if(t.temperature!==d.temperature)try{await m.execute(`config set llm.temperature ${t.temperature}`,1e4),e.push("temperature")}catch(r){a.push(`temperature: ${r.message}`)}if(t.maxTokens!==d.maxTokens)try{await m.execute(`config set llm.maxTokens ${t.maxTokens}`,1e4),e.push("maxTokens")}catch(r){a.push(`maxTokens: ${r.message}`)}a.length>0?_.warning(`部分配置保存失败: ${a.join("; ")}`):e.length>0?(_.success(`已保存 ${e.length} 项配置`),d={...t},e.includes("provider")&&i.loadProviders()):_.info("没有检测到配置变更")}catch(r){_.error(`保存配置失败: ${r.message}`)}finally{c.value=!1}}function G(){t.provider=d.provider||void 0,t.model=d.model||"",t.apiKey=d.apiKey||"",t.baseUrl=d.baseUrl||"",t.temperature=d.temperature??.7,t.maxTokens=d.maxTokens??4096}return H(()=>{i.loadProviders(),S()}),(a,e)=>{const r=u("a-button"),U=u("a-alert"),p=u("a-spin"),z=u("a-tag"),I=u("a-badge"),j=u("a-card"),f=u("a-list-item"),h=u("a-list"),$=u("a-divider"),D=u("a-select"),L=u("a-form-item"),R=u("a-input"),J=u("a-input-password"),Q=u("a-slider"),V=u("a-input-number"),W=u("a-form");return y(),N("div",null,[n("div",ne,[e[9]||(e[9]=n("div",null,[n("h2",{class:"page-title"},"LLM 配置"),n("p",{class:"page-sub"},"管理 AI 服务提供商")],-1)),s(r,{type:"primary",ghost:"",loading:g(i).loading,onClick:e[0]||(e[0]=o=>g(i).loadProviders())},{icon:l(()=>[s(g(q))]),default:l(()=>[e[8]||(e[8]=x(" 刷新 ",-1))]),_:1},8,["loading"])]),g(i).activeProvider?(y(),K(U,{key:0,type:"success",style:{"margin-bottom":"20px",background:"rgba(41,162,112,.08)","border-color":"rgba(41,162,112,.3)"},"show-icon":""},{message:l(()=>[n("span",null,[e[10]||(e[10]=x("当前激活:",-1)),n("strong",null,M(g(i).activeProvider),1)])]),_:1})):B("",!0),g(i).loading?(y(),N("div",ie,[s(p,{size:"large"}),e[11]||(e[11]=n("div",{style:{color:"var(--text-muted)","margin-top":"12px"}},"加载 LLM 信息中...",-1))])):(y(),N("div",de,[n("div",ue,[(y(!0),N(X,null,ee(g(i).providers,o=>(y(),K(j,{key:o.name,class:oe(["provider-card",{active:o.active}]),style:{background:"var(--bg-card)"},size:"small"},{default:l(()=>[n("div",ce,[n("span",pe,M(o.icon),1),n("div",me,[n("div",ve,M(o.label),1),n("div",fe,M(o.name),1)]),n("div",null,[o.active?(y(),K(z,{key:0,color:"green"},{default:l(()=>[...e[12]||(e[12]=[x("活跃",-1)])]),_:1})):o.status==="ok"?(y(),K(I,{key:1,status:"success",text:""})):o.status==="error"?(y(),K(I,{key:2,status:"error",text:""})):B("",!0)])]),n("div",ge,[s(r,{size:"small",style:{background:"var(--bg-card-hover)","border-color":"var(--border-color)"},loading:g(i).testing===o.name,onClick:Y=>w(o.name)},{default:l(()=>[...e[13]||(e[13]=[x(" 测试 ",-1)])]),_:1},8,["loading","onClick"]),o.active?(y(),K(z,{key:1,color:"green",style:{margin:"0","line-height":"24px"}},{default:l(()=>[...e[15]||(e[15]=[x("当前",-1)])]),_:1})):(y(),K(r,{key:0,size:"small",type:"primary",ghost:"",onClick:Y=>b(o.name)},{default:l(()=>[...e[14]||(e[14]=[x(" 切换 ",-1)])]),_:1},8,["onClick"]))])]),_:2},1032,["class"]))),128))]),g(i).localModels.length?(y(),N("div",ye,[e[16]||(e[16]=n("h3",{style:{color:"#ccc","font-size":"15px","margin-bottom":"12px"}}," 本地模型(Ollama) ",-1)),s(h,{"data-source":g(i).localModels,size:"small",style:{background:"var(--bg-card)","border-radius":"8px",border:"1px solid var(--border-color)"}},{renderItem:l(({item:o})=>[s(f,{style:{padding:"10px 16px","border-color":"#252525"}},{actions:l(()=>[s(z,{color:"cyan",style:{"font-size":"10px"}},{default:l(()=>[x(M(o.size||"local"),1)]),_:2},1024)]),default:l(()=>[n("span",be,M(o.name),1)]),_:2},1024)]),_:1},8,["data-source"])])):B("",!0),s($,{style:{"border-color":"var(--border-color)",margin:"32px 0 24px"}}),n("div",xe,[e[18]||(e[18]=n("h3",{class:"section-title"},"LLM 参数设置",-1)),s(r,{size:"small",loading:T.value,onClick:S,style:{background:"var(--bg-card-hover)","border-color":"var(--border-color)"}},{icon:l(()=>[s(g(q))]),default:l(()=>[e[17]||(e[17]=x(" 加载配置 ",-1))]),_:1},8,["loading"])]),s(j,{class:"config-card",style:{background:"var(--bg-card)","border-color":"var(--border-color)"}},{default:l(()=>[s(W,{model:t,layout:"vertical",class:"config-form"},{default:l(()=>[n("div",_e,[s(L,{label:"Provider(提供商)"},{default:l(()=>[s(D,{value:t.provider,"onUpdate:value":e[1]||(e[1]=o=>t.provider=o),placeholder:"选择 LLM 提供商",options:g(k),style:{width:"100%"},disabled:c.value},null,8,["value","options","disabled"])]),_:1}),s(L,{label:"Model(模型名称)"},{default:l(()=>[s(R,{value:t.model,"onUpdate:value":e[2]||(e[2]=o=>t.model=o),placeholder:"例如 doubao-seed-1-6-251015","allow-clear":"",disabled:c.value},null,8,["value","disabled"])]),_:1}),s(L,{label:"API Key"},{default:l(()=>[s(J,{value:t.apiKey,"onUpdate:value":e[3]||(e[3]=o=>t.apiKey=o),placeholder:"输入 API Key",disabled:c.value},null,8,["value","disabled"])]),_:1}),s(L,{label:"Base URL"},{default:l(()=>[s(R,{value:t.baseUrl,"onUpdate:value":e[4]||(e[4]=o=>t.baseUrl=o),placeholder:"例如 https://ark.cn-beijing.volces.com/api/v3","allow-clear":"",disabled:c.value},null,8,["value","disabled"])]),_:1}),s(L,{label:"Temperature(温度)"},{default:l(()=>[n("div",ke,[s(Q,{value:t.temperature,"onUpdate:value":e[5]||(e[5]=o=>t.temperature=o),min:0,max:2,step:.1,style:{flex:"1"},disabled:c.value},null,8,["value","disabled"]),s(V,{value:t.temperature,"onUpdate:value":e[6]||(e[6]=o=>t.temperature=o),min:0,max:2,step:.1,precision:1,style:{width:"80px"},disabled:c.value},null,8,["value","disabled"])])]),_:1}),s(L,{label:"Max Tokens(最大输出长度)"},{default:l(()=>[s(V,{value:t.maxTokens,"onUpdate:value":e[7]||(e[7]=o=>t.maxTokens=o),min:256,max:128e3,step:256,style:{width:"100%"},placeholder:"4096",disabled:c.value},null,8,["value","disabled"])]),_:1})]),n("div",we,[s(r,{onClick:G,disabled:c.value,style:{background:"var(--bg-card-hover)","border-color":"var(--border-color)"}},{default:l(()=>[...e[19]||(e[19]=[x(" 重置 ",-1)])]),_:1},8,["disabled"]),s(r,{type:"primary",loading:c.value,onClick:E},{default:l(()=>[...e[20]||(e[20]=[x(" 保存配置 ",-1)])]),_:1},8,["loading"])])]),_:1},8,["model"])]),_:1})]))])}}},Te=ae(he,[["__scopeId","data-v-38d68389"]]);export{Te as default};
@@ -1 +0,0 @@
1
- import{A as o}from"./Row-n8ruyEoT.js";import{S as t}from"./index-BD2U0Ciz.js";import"./responsiveObserve-V0qPHZOl.js";import"./vendor-DhFY8mDK.js";import"./useFlexGapSupport-Be2wILDi.js";import"./styleChecker-BfXrPW7h.js";import"./index-CFh73FRz.js";import"./icons-AILO5ZcK.js";const l=t(o);export{l as default};
@@ -1 +0,0 @@
1
- import{C as o}from"./Col-Bc08LzOn.js";import{S as t}from"./index-BD2U0Ciz.js";import"./index-CFh73FRz.js";import"./vendor-DhFY8mDK.js";import"./icons-AILO5ZcK.js";const s=t(o);export{s as default};
@@ -1,3 +0,0 @@
1
- function p(a){const e=a.split(`
2
- `),n=[];let i="built-in";for(const l of e){const t=l.trim();if(!t||t.startsWith("─")||t.startsWith("="))continue;const r=t.match(/^([a-z][a-z0-9-]+)\s+\(\d+\)$/);if(r){i=r[1];continue}const s=t.match(/^[●•]\s+([a-z][a-z0-9-]+)\s+(.+)$/);if(s){let c=s[2].trim();const m=c.match(/\s+\[(bundled|project|managed|workspace|marketplace)\]$/);m&&(c=c.slice(0,-m[0].length).trim());const u=i.includes("agent")?"agent":i.includes("llm")?"llm-query":i==="cli-direct"||i.includes("cli")?"cli-direct":"built-in";n.push({name:s[1],description:c,category:i,executionMode:u});continue}const o=t.match(/^([a-z][a-z0-9-]+)\s+[-–]\s+(.+)/)||t.match(/^([a-z][a-z0-9-]+)\s{2,}(.+)/);o&&n.push({name:o[1],description:o[2],category:i,executionMode:i.includes("agent")?"agent":i.includes("llm")?"llm-query":i.includes("cli")?"cli-direct":"built-in"})}return n}const d=[{name:"anthropic",label:"Anthropic (Claude)",icon:"🤖"},{name:"openai",label:"OpenAI (GPT)",icon:"🧠"},{name:"ollama",label:"Ollama (本地)",icon:"🦙"},{name:"deepseek",label:"DeepSeek",icon:"🔍"},{name:"gemini",label:"Google Gemini",icon:"✨"},{name:"volcengine",label:"火山引擎 (豆包)",icon:"🌋"},{name:"dashscope",label:"通义千问 (DashScope)",icon:"🌊"},{name:"kimi",label:"Kimi (月之暗面)",icon:"🌙"},{name:"minimax",label:"MiniMax (海螺AI)",icon:"🐚"},{name:"mistral",label:"Mistral AI",icon:"💨"}];function h(a){const e=[];for(const n of d)e.push({...n,configured:a.toLowerCase().includes(n.name),active:a.match(new RegExp(`\\*\\s*${n.name}`,"i"))!==null,status:"unknown"});if(!e.find(n=>n.active)){const n=a.match(/active[:\s]+(\w+)/i);if(n){const i=e.find(l=>l.name===n[1].toLowerCase());i&&(i.active=!0)}}return e}function f(a){return a.split(`
3
- `).map(e=>e.trim()).filter(e=>e&&!e.startsWith("#")&&!e.startsWith("─")&&e.includes(":")).map(e=>({name:e,size:""})).slice(0,20)}export{h as a,f as b,p};