chainlesschain 0.162.20 → 0.162.26
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.
- package/package.json +2 -2
- package/src/assets/web-panel/.build-hash +1 -1
- package/src/assets/web-panel/assets/{AIOps-Buh_mYlF.js → AIOps-DEhhAYYj.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-Dc7c0bZf.js → ActionButton-DEyfUz5F.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-CR9TWfM-.js → Analytics-D1rjS61W.js} +1 -1
- package/src/assets/web-panel/assets/{AppLayout-DVfanUep.js → AppLayout-CptFJPy6.js} +2 -2
- package/src/assets/web-panel/assets/{Audit-BxojBqRe.js → Audit-BG6KQUHY.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-CGkreaK9.js → Backup-D2ikQT54.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-B-Q2ZGfz.js → BaseInput-BG_d8yMt.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-Dd_VC5Av.js → Chat-CcHmGkLY.js} +1 -1
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-B64kZfRH.js → ChatBubbleRenderer-DIXrOHbn.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-NYBD1rCW.js → Checkbox-Bx2h6vT3.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-B3Kqhgv1.js → Codegen-o14zzfuK.js} +1 -1
- package/src/assets/web-panel/assets/{Col-2A3Bg2GC.js → Col-HlZjxy7V.js} +1 -1
- package/src/assets/web-panel/assets/{Community-C84SkDEJ.js → Community-DXxMflr2.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-Crv3pyZJ.js → Compact-DbswbBjd.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-D4qasxoY.js → Compliance-C7Q4Da2p.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-Bfbvysw-.js → Cowork-BLImywOe.js} +1 -1
- package/src/assets/web-panel/assets/{Cron-Dkjyiekd.js → Cron-DpXu1G4m.js} +1 -1
- package/src/assets/web-panel/assets/{Crosschain-DbJm9Kjd.js → Crosschain-C4qokeJu.js} +1 -1
- package/src/assets/web-panel/assets/{DID-C2HI6acG.js → DID-C0BjPiij.js} +1 -1
- package/src/assets/web-panel/assets/{Dashboard-BXMY7QVP.js → Dashboard-CsfDXwPl.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-DcOykpfh.js → Dropdown-CiwMUKrx.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-Doo52F2M.js → EmailListRenderer-DX7xfm5a.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-cHubZT6U.js → Federation-CA4Ibsg0.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-B5OVlspi.js → FormItemContext-DvM0lU-7.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-OgA46PJq.js → GenericCardRenderer-REjsnTHA.js} +1 -1
- package/src/assets/web-panel/assets/{Git-_OKH_JOq.js → Git-ZhnSDQGH.js} +1 -1
- package/src/assets/web-panel/assets/{Governance-CTByBwSV.js → Governance-BL8iUV_g.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-C0nqgySA.js → Inference-BONrgLk-.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-CWW4ZIqH.js → KnowledgeGraph-q9SAz7h7.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-DrwqUltr.js → Logs-eHfEFnEZ.js} +1 -1
- package/src/assets/web-panel/assets/{Marketplace-LJMRx-dm.js → Marketplace-DzwuVedm.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-F_EjC8j3.js → McpTools-BRoLIeq5.js} +1 -1
- package/src/assets/web-panel/assets/{Memory-VonDem9-.js → Memory-DjvAa1Ce.js} +1 -1
- package/src/assets/web-panel/assets/{MobileBridge-CUWxIrfb.js → MobileBridge-CGTanjsT.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-CGOo70lk.js → MobileProjects-cTccXHwN.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-CqUquFbQ.js → Mtc-CNUe29wS.js} +1 -1
- package/src/assets/web-panel/assets/{MtcAudit-CRVusaip.js → MtcAudit-COk24mdH.js} +1 -1
- package/src/assets/web-panel/assets/{Multisig-B0o8Mv8T.js → Multisig-CFq2j0BU.js} +1 -1
- package/src/assets/web-panel/assets/{NLProgramming-CxQINUhu.js → NLProgramming-dfRr-FGW.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-B6Q_apFW.js → Notes-iM4aoXiw.js} +1 -1
- package/src/assets/web-panel/assets/{NotificationSettings-DO-lgp6x.js → NotificationSettings-CeVJ-942.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-DxoBoMtz.js → OrderTableRenderer-zQ5jvUZI.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-DqJ_KawH.js → Organization-CTSWyMGT.js} +1 -1
- package/src/assets/web-panel/assets/{Overflow-Cg4iKODM.js → Overflow---n60sAp.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-n5GPMrwC.js → P2P-BCQurpAB.js} +1 -1
- package/src/assets/web-panel/assets/{PdhVaultBrowser-BdZI0EJs.js → PdhVaultBrowser-C5L1qAc0.js} +2 -2
- package/src/assets/web-panel/assets/{Permissions-BjtwAIGb.js → Permissions-I8sgLLE5.js} +1 -1
- package/src/assets/web-panel/assets/PersonalDataHub-CEUfFRCj.js +2 -0
- package/src/assets/web-panel/assets/{PersonalDataHub-D0ncF92t.css → PersonalDataHub-CO9-IYDY.css} +1 -1
- package/src/assets/web-panel/assets/{Pipeline-BZe2-Flj.js → Pipeline-BTBjJaRd.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-OJqMon4c.js → Privacy-aCs44rpW.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-Dw-5SMG1.js → ProjectInit-DZ2iIlbN.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectSettings-DxqW44cV.js → ProjectSettings-oYUtNgHP.js} +1 -1
- package/src/assets/web-panel/assets/{Projects-CPOqs2ec.js → Projects-FonFg0ie.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-hBfwscEl.js → Providers-CRmOuabY.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-DA3WFFAr.js → QuickAsk-BHd6UZ1A.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-DMpz3URg.js → Recommend-BkzGGuq-.js} +1 -1
- package/src/assets/web-panel/assets/{Reputation-6-z56FwC.js → Reputation-Do7cPr9u.js} +1 -1
- package/src/assets/web-panel/assets/{Row-CL1Y6SfW.js → Row-D_sR3MmD.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-BIHU2bMf.js → RssFeed-pWSbZ06l.js} +1 -1
- package/src/assets/web-panel/assets/{Search-CRAfuEX-.js → Search-BTL71JSs.js} +1 -1
- package/src/assets/web-panel/assets/{Security-CVya3gvH.js → Security-8lbNoqY6.js} +1 -1
- package/src/assets/web-panel/assets/{Services-Cxv7_umF.js → Services-yr3QVduo.js} +1 -1
- package/src/assets/web-panel/assets/{Skeleton-D_GvsCtv.js → Skeleton-DdnY1ZTz.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-DyiEpcvf.js → Skills-fk24WY3D.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-wiglQzXV.js → Sla-bOXRT7wR.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-CLtovaa5.js → SpeechSettings-DjonFUbP.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-BOgVef1O.js → SyncSettings-C-7HTl6d.js} +1 -1
- package/src/assets/web-panel/assets/{Tasks-Ik8AX7-J.js → Tasks-DDohfzFT.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-CireiINW.js → Templates-C8PI_WTt.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-t7jF9NkQ.js → Tenant-CIvbeRkn.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-Btq_O951.js → Terminal-BuIPGugj.js} +1 -1
- package/src/assets/web-panel/assets/{TimelineRenderer-hC_Piiwy.js → TimelineRenderer-BefCbTxN.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-BTIqA2J1.js → Tokens-gGAeez46.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-Dzv2gJpK.js → Trigger-C_86E2v7.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-B13QpWOh.js → Trust-Beg23C1W.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-CFj3UF4G.js → UkeySign--sGSaISg.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-CGMOGTQb.js → VideoEditing-DIsnY6D_.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-BkCJ573Y.js → Wallet-a7ECYY0i.js} +1 -1
- package/src/assets/web-panel/assets/{WebAuthn-C8dCrmGH.js → WebAuthn-CsVpkUE8.js} +1 -1
- package/src/assets/web-panel/assets/{WorkflowEditor-CclfhxwH.js → WorkflowEditor-BOJ4WTgl.js} +1 -1
- package/src/assets/web-panel/assets/{chat-CW_X_A9l.js → chat-ezCR5ZZX.js} +1 -1
- package/src/assets/web-panel/assets/{colors-6GtheJb2.js → colors-DSUEQ7GR.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-tz7dJapw.js → compact-item-D4w3DGj_.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-CbiGcRCw.js → createContext-B_hvu-NR.js} +1 -1
- package/src/assets/web-panel/assets/{hasIn-bmNFD3PH.js → hasIn-FY775Vpc.js} +1 -1
- package/src/assets/web-panel/assets/{index-DxHmNJ8S.js → index-1ki6aTIz.js} +1 -1
- package/src/assets/web-panel/assets/{index-UId2JAY6.js → index-B3lbDu2b.js} +1 -1
- package/src/assets/web-panel/assets/{index-BM4slfDH.js → index-B9LXVosT.js} +1 -1
- package/src/assets/web-panel/assets/{index-b7sSMzkC.js → index-BGdchdRx.js} +1 -1
- package/src/assets/web-panel/assets/{index-KFdfLxVt.js → index-BGrm33US.js} +1 -1
- package/src/assets/web-panel/assets/{index-B9sJpsz3.js → index-BHPD-_s2.js} +1 -1
- package/src/assets/web-panel/assets/{index-B6GgMo1k.js → index-BMnGj-Ui.js} +1 -1
- package/src/assets/web-panel/assets/{index-B2P1c5yD.js → index-BSp1hSN8.js} +1 -1
- package/src/assets/web-panel/assets/{index-S9g45I5s.js → index-BaZmrJ6j.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cb33JbDx.js → index-BnvLdkR8.js} +1 -1
- package/src/assets/web-panel/assets/{index-CQ7aJ-8s.js → index-BzME19Nh.js} +1 -1
- package/src/assets/web-panel/assets/{index-DeoJYTHX.js → index-C0wDzrUK.js} +3 -3
- package/src/assets/web-panel/assets/{index-CBNnbQxM.js → index-CAa3LSKI.js} +1 -1
- package/src/assets/web-panel/assets/{index-CLk3xgD2.js → index-CE3vDzJj.js} +1 -1
- package/src/assets/web-panel/assets/{index-De0xvTEv.js → index-CLp4V3Tb.js} +1 -1
- package/src/assets/web-panel/assets/{index-CKP-AZD3.js → index-CNUQnJsg.js} +1 -1
- package/src/assets/web-panel/assets/{index-CzIQ0u4e.js → index-CSbCIyga.js} +1 -1
- package/src/assets/web-panel/assets/{index-UjxsY00y.js → index-CUNYcWEF.js} +1 -1
- package/src/assets/web-panel/assets/{index-CgLF_zD1.js → index-CV-F9a_X.js} +1 -1
- package/src/assets/web-panel/assets/{index-C5zlrlPd.js → index-CcvzscCg.js} +1 -1
- package/src/assets/web-panel/assets/{index-B3UH6whC.js → index-CdzLJsac.js} +1 -1
- package/src/assets/web-panel/assets/{index-CU0MeCwH.js → index-Cug_yoee.js} +1 -1
- package/src/assets/web-panel/assets/{index-DxdLksCx.js → index-CxMArAIk.js} +1 -1
- package/src/assets/web-panel/assets/index-CzkEIn_T.js +1 -0
- package/src/assets/web-panel/assets/index-D2PcvXPP.js +1 -0
- package/src/assets/web-panel/assets/{index-DMGJqZ-o.js → index-D6yJ0RMr.js} +1 -1
- package/src/assets/web-panel/assets/{index-DaYfMM7r.js → index-DM77-xyl.js} +1 -1
- package/src/assets/web-panel/assets/{index-CV9aPPYM.js → index-DfU6zsU8.js} +1 -1
- package/src/assets/web-panel/assets/{index-l2VM-W36.js → index-DqsQUPY7.js} +1 -1
- package/src/assets/web-panel/assets/{index-DK7ee5hC.js → index-DqxLCUYa.js} +1 -1
- package/src/assets/web-panel/assets/{index-DaK59dFw.js → index-DtztktoP.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cs5KWviO.js → index-Dz8-7APi.js} +1 -1
- package/src/assets/web-panel/assets/{index-Da2RUdcb.js → index-Enin7rzK.js} +1 -1
- package/src/assets/web-panel/assets/{index-CYIwY9zQ.js → index-S6A76pR1.js} +1 -1
- package/src/assets/web-panel/assets/{index-DvWXdCxl.js → index-ZGJo2fz1.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dj1N1idV.js → index-d0HXotWE.js} +1 -1
- package/src/assets/web-panel/assets/{index-CTnIkosg.js → index-gAtp_KkQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-zP_o4yKV.js → index-mlTTTHla.js} +1 -1
- package/src/assets/web-panel/assets/{index-BxCPkuTG.js → index-wWVM6ENX.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-BTGwT0NA.js → initDefaultProps-BoLcNBz9.js} +1 -1
- package/src/assets/web-panel/assets/{motion-BheHkG8e.js → motion-ouRvP3eO.js} +1 -1
- package/src/assets/web-panel/assets/{move-BkMMNkAw.js → move-BBITvaOV.js} +1 -1
- package/src/assets/web-panel/assets/{omit-B9zmSFf6.js → omit-D8Yxdvbb.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-CFNBcA5Z.js → pickAttrs-BIUy7mER.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-B4mvrUYw.js → placementArrow-CrNWpNSF.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-BJqsSjxJ.js → responsiveObserve-aHLPN464.js} +1 -1
- package/src/assets/web-panel/assets/{slide-Cj78MXSi.js → slide-2qNtePjk.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-Bk6ChXAV.js → statusUtils-FAF3iR3R.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-B_YDSNYf.js → styleChecker-BNFTkrbl.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-q90prOQL.js → useFlexGapSupport-BgdPlW7E.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-BtpFJ9kI.js → useFs-q1QvAh3f.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-C3qhf1sQ.js → usePersonalDataHub-DEZ6cY8C.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-Bz2j0JiG.js → vnode-vp6H-NL_.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-CzaEtel2.js → zoom-UatfJMw4.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/commands/__tests__/hub-bilibili-adb-sync.test.js +350 -0
- package/src/commands/__tests__/hub-douyin-adb-sync.test.js +199 -0
- package/src/commands/__tests__/hub-kuaishou-adb-sync.test.js +161 -0
- package/src/commands/__tests__/hub-toutiao-adb-sync.test.js +158 -0
- package/src/commands/__tests__/hub-weibo-adb-sync.test.js +163 -0
- package/src/commands/__tests__/hub-xhs-adb-sync.test.js +155 -0
- package/src/commands/hub.js +883 -0
- package/src/gateways/ws/personal-data-hub-protocol.js +84 -0
- package/src/lib/host-adb-bridge.js +77 -1
- package/src/lib/personal-data-hub-wiring.js +471 -12
- package/src/assets/web-panel/assets/PersonalDataHub-Bsf3Wh6n.js +0 -1
- package/src/assets/web-panel/assets/index-BFkZAdio.js +0 -1
- package/src/assets/web-panel/assets/index-BhgINPAH.js +0 -1
|
@@ -64,6 +64,12 @@ const {
|
|
|
64
64
|
JdAdapter,
|
|
65
65
|
MeituanAdapter,
|
|
66
66
|
PinduoduoAdapter,
|
|
67
|
+
Train12306Adapter,
|
|
68
|
+
TaobaoAdapter,
|
|
69
|
+
CtripAdapter,
|
|
70
|
+
AmapAdapter,
|
|
71
|
+
TelegramAdapter,
|
|
72
|
+
WhatsAppAdapter,
|
|
67
73
|
EntityResolver,
|
|
68
74
|
EntityResolverEmbeddingStage,
|
|
69
75
|
EntityResolverLLMStage,
|
|
@@ -147,6 +153,11 @@ export function resolveHubDir() {
|
|
|
147
153
|
}
|
|
148
154
|
|
|
149
155
|
async function initHub() {
|
|
156
|
+
// Phase 1c: hoisted so the hub-level `bilibiliAdbSync` method can reuse
|
|
157
|
+
// the same bridge instance the system-data-android adapter wires below.
|
|
158
|
+
// Single bridge per hub keeps `bilibili.cookies` extension state /
|
|
159
|
+
// adb path resolution / device picking consistent across callers.
|
|
160
|
+
let hostAdbBridge = null;
|
|
150
161
|
const hubDir = resolveHubDir();
|
|
151
162
|
mkdirSync(hubDir, { recursive: true });
|
|
152
163
|
mkdirSync(join(hubDir, "keys"), { recursive: true });
|
|
@@ -204,9 +215,20 @@ async function initHub() {
|
|
|
204
215
|
// and skip embedding+LLM stages entirely. Rule-stage still runs; the
|
|
205
216
|
// resolve_queue picks up enqueued pairs later if a host with Ollama is
|
|
206
217
|
// ever attached (e.g. desktop-side replay).
|
|
218
|
+
//
|
|
219
|
+
// 2026-05-25 — broadened the detection. The old startsWith("/data/data/
|
|
220
|
+
// com.chainlesschain.android") missed two cases:
|
|
221
|
+
// 1. /data/user/0/ — on Android 7+ (multi-user), context.filesDir
|
|
222
|
+
// resolves under /data/user/0/<pkg>/ instead of /data/data/<pkg>/,
|
|
223
|
+
// so the legacy startsWith never matched on real device.
|
|
224
|
+
// 2. Variant suffixes — com.chainlesschain.android.debug,
|
|
225
|
+
// .staging, etc. all have a separate package id but should share
|
|
226
|
+
// the in-APK skip behaviour.
|
|
227
|
+
// Match either path prefix + optional variant suffix in one regex; if
|
|
228
|
+
// the env override is set, honour it unconditionally.
|
|
207
229
|
const isInAppAndroidCc =
|
|
208
230
|
typeof process.env.PREFIX === "string" &&
|
|
209
|
-
process.env.PREFIX
|
|
231
|
+
/\/com\.chainlesschain\.android(\.[a-z]+)?\//.test(process.env.PREFIX);
|
|
210
232
|
const skipEmbeddings =
|
|
211
233
|
isInAppAndroidCc || process.env.CC_HUB_DISABLE_EMBEDDINGS === "1";
|
|
212
234
|
try {
|
|
@@ -290,7 +312,47 @@ async function initHub() {
|
|
|
290
312
|
// + caveats (Windows CRLF parse trap, 0/multi device, ENOENT).
|
|
291
313
|
try {
|
|
292
314
|
const { createHostAdbBridge } = await import("./host-adb-bridge.js");
|
|
293
|
-
|
|
315
|
+
// Phase 1b: register `bilibili.cookies` extension so the Phase 1c
|
|
316
|
+
// collector can pull WebView cookies from the user's Android Bilibili
|
|
317
|
+
// App. The factory is a pure function — no side effects until the
|
|
318
|
+
// handler is invoked, so cost of always-registering is zero.
|
|
319
|
+
const { createBilibiliCookiesExtension } =
|
|
320
|
+
await import("@chainlesschain/personal-data-hub/adapters/social-bilibili-adb");
|
|
321
|
+
// Phase 2a: register `douyin.pull-im-db` extension so the
|
|
322
|
+
// douyinAdbSync hub method can pull <uid>_im.db cohort from the
|
|
323
|
+
// user's Android Douyin App.
|
|
324
|
+
const { createDouyinDbExtension } =
|
|
325
|
+
await import("@chainlesschain/personal-data-hub/adapters/social-douyin-adb");
|
|
326
|
+
// Phase 3a: register `weibo.cookies` extension for the Weibo
|
|
327
|
+
// C-path collector (m.weibo.cn cookies + 4 HTTP endpoints).
|
|
328
|
+
const { createWeiboCookiesExtension } =
|
|
329
|
+
await import("@chainlesschain/personal-data-hub/adapters/social-weibo-adb");
|
|
330
|
+
// Phase 3c: register `xhs.cookies` extension for the Xhs C-path
|
|
331
|
+
// collector (xiaohongshu.com cookies + 4 endpoints with X-S sign).
|
|
332
|
+
const { createXhsCookiesExtension } =
|
|
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");
|
|
346
|
+
hostAdbBridge = createHostAdbBridge({
|
|
347
|
+
extensions: {
|
|
348
|
+
"bilibili.cookies": createBilibiliCookiesExtension(),
|
|
349
|
+
"douyin.pull-im-db": createDouyinDbExtension(),
|
|
350
|
+
"weibo.cookies": createWeiboCookiesExtension(),
|
|
351
|
+
"xhs.cookies": createXhsCookiesExtension(),
|
|
352
|
+
"toutiao.cookies": createToutiaoCookiesExtension(),
|
|
353
|
+
"kuaishou.cookies": createKuaishouCookiesExtension(),
|
|
354
|
+
},
|
|
355
|
+
});
|
|
294
356
|
sda._deps.bridgeProvider = () => hostAdbBridge;
|
|
295
357
|
} catch (_e) {
|
|
296
358
|
// Bridge module missing or failed to load — leave snapshot-only.
|
|
@@ -387,14 +449,21 @@ async function initHub() {
|
|
|
387
449
|
// reads it; no per-account credential needed at boot. Each wrapped in
|
|
388
450
|
// its own try so one broken ctor doesn't cascade.
|
|
389
451
|
//
|
|
390
|
-
// **
|
|
391
|
-
//
|
|
392
|
-
//
|
|
393
|
-
//
|
|
394
|
-
//
|
|
395
|
-
//
|
|
396
|
-
//
|
|
397
|
-
//
|
|
452
|
+
// **No more deferred adapters at boot** — 2026-05-25 final pass made all
|
|
453
|
+
// sqlite/device-pull adapters (Amap/Telegram/WhatsApp) ctor-optional:
|
|
454
|
+
// account.<x> dropped from required, inputPath alias added. The sqlite
|
|
455
|
+
// sync still requires the user to pre-extract the SQLite db (Telegram
|
|
456
|
+
// cache4.db unencrypted; WhatsApp msgstore.db needs WhatsApp Crypt key;
|
|
457
|
+
// Amap amap.db needs root ADB pull) — but the registry slot is now
|
|
458
|
+
// claimed so syncAdapter("<name>", path) routes correctly instead of
|
|
459
|
+
// "no adapter X" silent swallow. v0.2 followup: Android in-APK extractor
|
|
460
|
+
// for these 3 sqlite adapters (depends on root ADB / device-specific
|
|
461
|
+
// Crypt key recovery; previously blocked the whole code path before).
|
|
462
|
+
// Train12306Adapter moved out of deferred (v0.2 added snapshot mode —
|
|
463
|
+
// account.username OPTIONAL, see adapters/travel-12306/index.js:53-56);
|
|
464
|
+
// Android Kyfw12306LocalCollector ships snapshot JSON via
|
|
465
|
+
// ccRunner.syncAdapter("travel-12306", path) — must be registered here
|
|
466
|
+
// or cc returns "unknown adapter" + UI shows misleading "v0.2 补齐" hint.
|
|
398
467
|
// Earlier oversight: v5.0.3.84 wired Telegram + WhatsApp here, but their
|
|
399
468
|
// ctors throw without account args, so they were silently swallowed by
|
|
400
469
|
// try/catch and never actually registered. Removed to make the list
|
|
@@ -411,6 +480,12 @@ async function initHub() {
|
|
|
411
480
|
JdAdapter,
|
|
412
481
|
MeituanAdapter,
|
|
413
482
|
PinduoduoAdapter,
|
|
483
|
+
Train12306Adapter,
|
|
484
|
+
TaobaoAdapter,
|
|
485
|
+
CtripAdapter,
|
|
486
|
+
AmapAdapter,
|
|
487
|
+
TelegramAdapter,
|
|
488
|
+
WhatsAppAdapter,
|
|
414
489
|
]) {
|
|
415
490
|
try {
|
|
416
491
|
const adapter = new Cls();
|
|
@@ -420,6 +495,21 @@ async function initHub() {
|
|
|
420
495
|
}
|
|
421
496
|
}
|
|
422
497
|
|
|
498
|
+
// Phase 5.8 — email-imap snapshot mode (2026-05-25): Android
|
|
499
|
+
// EmailLocalCollector does Jakarta Mail IMAP fetch on-device + writes
|
|
500
|
+
// staging JSON; desktop EmailAdapter consumes it via snapshot path
|
|
501
|
+
// (no IMAP-account credential needed at boot). The user-driven
|
|
502
|
+
// `registerEmailAdapter` per-account flow still wires explicit IMAP
|
|
503
|
+
// sessions for desktop-direct IMAP fetch (different code path, both
|
|
504
|
+
// resolve `name === "email-imap"` — registry de-dups by name; the
|
|
505
|
+
// per-account flow wins when the user has registered an account).
|
|
506
|
+
try {
|
|
507
|
+
const emailSnapshot = new EmailAdapter({ snapshotMode: true });
|
|
508
|
+
if (!registry.has(emailSnapshot.name)) registry.register(emailSnapshot);
|
|
509
|
+
} catch (_err) {
|
|
510
|
+
// Continue boot even if snapshot ctor throws (shouldn't happen — no required opts)
|
|
511
|
+
}
|
|
512
|
+
|
|
423
513
|
// Phase 6: auto-register persisted Alipay accounts.
|
|
424
514
|
const alipayAccountsPath = join(hubDir, "alipay-accounts.json");
|
|
425
515
|
const alipayAccounts = loadAlipayAccounts(alipayAccountsPath);
|
|
@@ -529,8 +619,12 @@ async function initHub() {
|
|
|
529
619
|
if (!account || typeof account !== "object")
|
|
530
620
|
throw new Error("account required");
|
|
531
621
|
const adapter = new EmailAdapter({ account, ...opts });
|
|
622
|
+
// Phase 5.8 — if the boot-time snapshot stub claimed the "email-imap"
|
|
623
|
+
// slot, swap it out for this per-account IMAP adapter (user's explicit
|
|
624
|
+
// IMAP credentials should take priority over the Android-snapshot
|
|
625
|
+
// fallback). Both share `name === "email-imap"`.
|
|
532
626
|
if (registry.has(adapter.name)) {
|
|
533
|
-
|
|
627
|
+
registry.unregister(adapter.name);
|
|
534
628
|
}
|
|
535
629
|
registry.register(adapter);
|
|
536
630
|
const accounts = loadEmailAccounts(emailAccountsPath);
|
|
@@ -550,7 +644,16 @@ async function initHub() {
|
|
|
550
644
|
const target = accounts.find((c) => c.account.email === emailAddress);
|
|
551
645
|
const next = accounts.filter((c) => c.account.email !== emailAddress);
|
|
552
646
|
saveEmailAccounts(emailAccountsPath, next);
|
|
553
|
-
if (target)
|
|
647
|
+
if (target) {
|
|
648
|
+
registry.unregister("email-imap");
|
|
649
|
+
// Phase 5.8 — restore the snapshot stub so Android sync paths still
|
|
650
|
+
// work after the user unregisters their explicit IMAP account.
|
|
651
|
+
try {
|
|
652
|
+
registry.register(new EmailAdapter({ snapshotMode: true }));
|
|
653
|
+
} catch (_err) {
|
|
654
|
+
// Defensive — snapshot ctor has no required opts so this shouldn't fail
|
|
655
|
+
}
|
|
656
|
+
}
|
|
554
657
|
return { ok: true, removed: !!target };
|
|
555
658
|
},
|
|
556
659
|
|
|
@@ -735,6 +838,362 @@ async function initHub() {
|
|
|
735
838
|
lastSyncAt: row.lastSyncAt || null,
|
|
736
839
|
}));
|
|
737
840
|
},
|
|
841
|
+
|
|
842
|
+
// ─── Phase 1e — Bilibili C 路径 dry-run env probe ────────────────────
|
|
843
|
+
//
|
|
844
|
+
// "Doctor" mode mirrors `cc hub wechat doctor`: runs only the cookies-
|
|
845
|
+
// extraction half of the sync pipeline (no API calls, no vault writes)
|
|
846
|
+
// so the user can confirm root / Bilibili-installed / cookie-complete
|
|
847
|
+
// status before triggering a real sync. Same 9 typed reasons as
|
|
848
|
+
// bilibiliAdbSync — UI maps reasons to the same banners — but with
|
|
849
|
+
// an extra `cookieDiagnostic` payload on success so the doctor can
|
|
850
|
+
// print "found 5 of 5 cookies, no encrypted_value rows skipped, uid=N".
|
|
851
|
+
//
|
|
852
|
+
// Returns one of:
|
|
853
|
+
// {ok: true, uid, extractedAt, cookieDiagnostic: {cookieCount, hadEncrypted}}
|
|
854
|
+
// {ok: false, reason, message} — same reason taxonomy as
|
|
855
|
+
// bilibiliAdbSync; UI re-uses bilibiliReasonMessage()
|
|
856
|
+
async bilibiliAdbDoctor() {
|
|
857
|
+
if (!hostAdbBridge) {
|
|
858
|
+
return {
|
|
859
|
+
ok: false,
|
|
860
|
+
reason: "BRIDGE_UNAVAILABLE",
|
|
861
|
+
message:
|
|
862
|
+
"host-adb-bridge failed to initialize at hub boot — check `adb` is on PATH or set ADB_PATH env var",
|
|
863
|
+
};
|
|
864
|
+
}
|
|
865
|
+
try {
|
|
866
|
+
const result = await hostAdbBridge.invoke("bilibili.cookies");
|
|
867
|
+
return {
|
|
868
|
+
ok: true,
|
|
869
|
+
uid: result.uid,
|
|
870
|
+
extractedAt: result.extractedAt,
|
|
871
|
+
cookieDiagnostic: result.diagnostic || null,
|
|
872
|
+
};
|
|
873
|
+
} catch (err) {
|
|
874
|
+
const msg = err && err.message ? err.message : String(err);
|
|
875
|
+
const m = msg.match(/^(BILIBILI_[A-Z_]+)/);
|
|
876
|
+
return {
|
|
877
|
+
ok: false,
|
|
878
|
+
reason: m ? m[1] : "PROBE_FAILED",
|
|
879
|
+
message: msg,
|
|
880
|
+
};
|
|
881
|
+
}
|
|
882
|
+
},
|
|
883
|
+
|
|
884
|
+
// ─── Phase 1c — Bilibili C 路径 one-shot sync ────────────────────────
|
|
885
|
+
//
|
|
886
|
+
// Pulls cookies via the bilibili.cookies extension (P1a) → fetches
|
|
887
|
+
// history/favourite/dynamic/follow via BilibiliApiClient (P1b) → writes
|
|
888
|
+
// a snapshot JSON → calls registry.syncAdapter("social-bilibili") to
|
|
889
|
+
// ingest into the vault. Always cleans up the staging file even on
|
|
890
|
+
// error. Returns `{ok: true, report}` on success or
|
|
891
|
+
// `{ok: false, reason, message}` on failure with a stable typed reason
|
|
892
|
+
// string the UI can pattern-match (BILIBILI_NO_ROOT /
|
|
893
|
+
// BILIBILI_NOT_INSTALLED_OR_NEVER_LOGGED_IN / BILIBILI_COOKIES_INCOMPLETE
|
|
894
|
+
// / SYNC_FAILED / BRIDGE_UNAVAILABLE).
|
|
895
|
+
async bilibiliAdbSync(opts = {}) {
|
|
896
|
+
if (!hostAdbBridge) {
|
|
897
|
+
return {
|
|
898
|
+
ok: false,
|
|
899
|
+
reason: "BRIDGE_UNAVAILABLE",
|
|
900
|
+
message:
|
|
901
|
+
"host-adb-bridge failed to initialize at hub boot — check `adb` is on PATH or set ADB_PATH env var",
|
|
902
|
+
};
|
|
903
|
+
}
|
|
904
|
+
let collector;
|
|
905
|
+
try {
|
|
906
|
+
const mod =
|
|
907
|
+
await import("@chainlesschain/personal-data-hub/adapters/social-bilibili-adb");
|
|
908
|
+
collector = mod.default ? mod.default : mod;
|
|
909
|
+
} catch (err) {
|
|
910
|
+
return {
|
|
911
|
+
ok: false,
|
|
912
|
+
reason: "MODULE_LOAD_FAILED",
|
|
913
|
+
message: err && err.message ? err.message : String(err),
|
|
914
|
+
};
|
|
915
|
+
}
|
|
916
|
+
try {
|
|
917
|
+
const report = await collector.collectAndSync(
|
|
918
|
+
hostAdbBridge,
|
|
919
|
+
registry,
|
|
920
|
+
opts,
|
|
921
|
+
);
|
|
922
|
+
return { ok: true, report };
|
|
923
|
+
} catch (err) {
|
|
924
|
+
const msg = err && err.message ? err.message : String(err);
|
|
925
|
+
// Extract a typed reason prefix from the BILIBILI_* error codes
|
|
926
|
+
// the cookies-extension throws, falling back to SYNC_FAILED for
|
|
927
|
+
// anything from the API client / registry path.
|
|
928
|
+
const m = msg.match(/^(BILIBILI_[A-Z_]+)/);
|
|
929
|
+
return {
|
|
930
|
+
ok: false,
|
|
931
|
+
reason: m ? m[1] : "SYNC_FAILED",
|
|
932
|
+
message: msg,
|
|
933
|
+
};
|
|
934
|
+
}
|
|
935
|
+
},
|
|
936
|
+
|
|
937
|
+
// ─── Phase 2a — Douyin C 路径 one-shot sync ─────────────────────────
|
|
938
|
+
//
|
|
939
|
+
// Pulls <uid>_im.db cohort via the douyin.pull-im-db extension (P2a) →
|
|
940
|
+
// parses msg + SIMPLE_USER (abrignoni DFIR) → writes snapshot →
|
|
941
|
+
// syncAdapter("social-douyin") snapshot mode.
|
|
942
|
+
//
|
|
943
|
+
// 9 typed reason codes: BRIDGE_UNAVAILABLE / MODULE_LOAD_FAILED /
|
|
944
|
+
// DOUYIN_NO_ROOT / DOUYIN_NOT_INSTALLED / DOUYIN_NO_IM_DB /
|
|
945
|
+
// DOUYIN_MULTIPLE_USERS / DOUYIN_PULL_FAILED / DOUYIN_NOT_SQLITE /
|
|
946
|
+
// SYNC_FAILED.
|
|
947
|
+
async douyinAdbSync(opts = {}) {
|
|
948
|
+
if (!hostAdbBridge) {
|
|
949
|
+
return {
|
|
950
|
+
ok: false,
|
|
951
|
+
reason: "BRIDGE_UNAVAILABLE",
|
|
952
|
+
message:
|
|
953
|
+
"host-adb-bridge failed to initialize at hub boot — check `adb` is on PATH or set ADB_PATH env var",
|
|
954
|
+
};
|
|
955
|
+
}
|
|
956
|
+
let collector;
|
|
957
|
+
try {
|
|
958
|
+
const mod =
|
|
959
|
+
await import("@chainlesschain/personal-data-hub/adapters/social-douyin-adb");
|
|
960
|
+
collector = mod.default ? mod.default : mod;
|
|
961
|
+
} catch (err) {
|
|
962
|
+
return {
|
|
963
|
+
ok: false,
|
|
964
|
+
reason: "MODULE_LOAD_FAILED",
|
|
965
|
+
message: err && err.message ? err.message : String(err),
|
|
966
|
+
};
|
|
967
|
+
}
|
|
968
|
+
try {
|
|
969
|
+
const report = await collector.collectAndSync(
|
|
970
|
+
hostAdbBridge,
|
|
971
|
+
registry,
|
|
972
|
+
opts,
|
|
973
|
+
);
|
|
974
|
+
return { ok: true, report };
|
|
975
|
+
} catch (err) {
|
|
976
|
+
const msg = err && err.message ? err.message : String(err);
|
|
977
|
+
const m = msg.match(/^(DOUYIN_[A-Z_]+)/);
|
|
978
|
+
return {
|
|
979
|
+
ok: false,
|
|
980
|
+
reason: m ? m[1] : "SYNC_FAILED",
|
|
981
|
+
message: msg,
|
|
982
|
+
};
|
|
983
|
+
}
|
|
984
|
+
},
|
|
985
|
+
|
|
986
|
+
// ─── Phase 3a — Weibo C 路径 one-shot sync ──────────────────────────
|
|
987
|
+
//
|
|
988
|
+
// Pulls m.weibo.cn cookies via the weibo.cookies extension → fetchUid
|
|
989
|
+
// (/api/config — cookie has no inline UID) → 3 endpoints (posts /
|
|
990
|
+
// favourites / follows) → snapshot → syncAdapter("social-weibo")
|
|
991
|
+
// snapshot mode. **No WBI signing** (m.weibo.cn mobile API is
|
|
992
|
+
// sign-less).
|
|
993
|
+
//
|
|
994
|
+
// Typed reason codes: BRIDGE_UNAVAILABLE / MODULE_LOAD_FAILED /
|
|
995
|
+
// WEIBO_NO_ROOT / WEIBO_NOT_INSTALLED / WEIBO_COOKIES_EMPTY /
|
|
996
|
+
// WEIBO_COOKIES_TRUNCATED / WEIBO_NOT_SQLITE / WEIBO_COOKIES_INCOMPLETE /
|
|
997
|
+
// WEIBO_BASE64_PARSE / SYNC_FAILED.
|
|
998
|
+
async weiboAdbSync(opts = {}) {
|
|
999
|
+
if (!hostAdbBridge) {
|
|
1000
|
+
return {
|
|
1001
|
+
ok: false,
|
|
1002
|
+
reason: "BRIDGE_UNAVAILABLE",
|
|
1003
|
+
message:
|
|
1004
|
+
"host-adb-bridge failed to initialize at hub boot — check `adb` is on PATH or set ADB_PATH env var",
|
|
1005
|
+
};
|
|
1006
|
+
}
|
|
1007
|
+
let collector;
|
|
1008
|
+
try {
|
|
1009
|
+
const mod =
|
|
1010
|
+
await import("@chainlesschain/personal-data-hub/adapters/social-weibo-adb");
|
|
1011
|
+
collector = mod.default ? mod.default : mod;
|
|
1012
|
+
} catch (err) {
|
|
1013
|
+
return {
|
|
1014
|
+
ok: false,
|
|
1015
|
+
reason: "MODULE_LOAD_FAILED",
|
|
1016
|
+
message: err && err.message ? err.message : String(err),
|
|
1017
|
+
};
|
|
1018
|
+
}
|
|
1019
|
+
try {
|
|
1020
|
+
const report = await collector.collectAndSync(
|
|
1021
|
+
hostAdbBridge,
|
|
1022
|
+
registry,
|
|
1023
|
+
opts,
|
|
1024
|
+
);
|
|
1025
|
+
return { ok: true, report };
|
|
1026
|
+
} catch (err) {
|
|
1027
|
+
const msg = err && err.message ? err.message : String(err);
|
|
1028
|
+
const m = msg.match(/^(WEIBO_[A-Z_]+)/);
|
|
1029
|
+
return {
|
|
1030
|
+
ok: false,
|
|
1031
|
+
reason: m ? m[1] : "SYNC_FAILED",
|
|
1032
|
+
message: msg,
|
|
1033
|
+
};
|
|
1034
|
+
}
|
|
1035
|
+
},
|
|
1036
|
+
|
|
1037
|
+
// ─── Phase 3c — Xhs C 路径 one-shot sync ────────────────────────────
|
|
1038
|
+
//
|
|
1039
|
+
// Pulls xiaohongshu.com cookies via xhs.cookies extension → fetchMe
|
|
1040
|
+
// (/user/me — no X-S) → 3 endpoints (notes/liked/follows, X-S signed)
|
|
1041
|
+
// → snapshot → syncAdapter("social-xiaohongshu") snapshot mode.
|
|
1042
|
+
//
|
|
1043
|
+
// **X-S signing is best-effort** (~60% GET hit, <30% POST). Endpoint
|
|
1044
|
+
// failures tolerated as partial results — lastErrorCode surfaces the
|
|
1045
|
+
// 461 X-S rejection so UI can recommend "稍后重试".
|
|
1046
|
+
//
|
|
1047
|
+
// Typed reason codes: BRIDGE_UNAVAILABLE / MODULE_LOAD_FAILED /
|
|
1048
|
+
// XHS_NO_ROOT / XHS_NOT_INSTALLED / XHS_COOKIES_EMPTY /
|
|
1049
|
+
// XHS_COOKIES_TRUNCATED / XHS_NOT_SQLITE / XHS_COOKIES_INCOMPLETE /
|
|
1050
|
+
// XHS_BASE64_PARSE / SYNC_FAILED.
|
|
1051
|
+
async xhsAdbSync(opts = {}) {
|
|
1052
|
+
if (!hostAdbBridge) {
|
|
1053
|
+
return {
|
|
1054
|
+
ok: false,
|
|
1055
|
+
reason: "BRIDGE_UNAVAILABLE",
|
|
1056
|
+
message:
|
|
1057
|
+
"host-adb-bridge failed to initialize at hub boot — check `adb` is on PATH or set ADB_PATH env var",
|
|
1058
|
+
};
|
|
1059
|
+
}
|
|
1060
|
+
let collector;
|
|
1061
|
+
try {
|
|
1062
|
+
const mod =
|
|
1063
|
+
await import("@chainlesschain/personal-data-hub/adapters/social-xiaohongshu-adb");
|
|
1064
|
+
collector = mod.default ? mod.default : mod;
|
|
1065
|
+
} catch (err) {
|
|
1066
|
+
return {
|
|
1067
|
+
ok: false,
|
|
1068
|
+
reason: "MODULE_LOAD_FAILED",
|
|
1069
|
+
message: err && err.message ? err.message : String(err),
|
|
1070
|
+
};
|
|
1071
|
+
}
|
|
1072
|
+
try {
|
|
1073
|
+
const report = await collector.collectAndSync(
|
|
1074
|
+
hostAdbBridge,
|
|
1075
|
+
registry,
|
|
1076
|
+
opts,
|
|
1077
|
+
);
|
|
1078
|
+
return { ok: true, report };
|
|
1079
|
+
} catch (err) {
|
|
1080
|
+
const msg = err && err.message ? err.message : String(err);
|
|
1081
|
+
const m = msg.match(/^(XHS_[A-Z_]+)/);
|
|
1082
|
+
return {
|
|
1083
|
+
ok: false,
|
|
1084
|
+
reason: m ? m[1] : "SYNC_FAILED",
|
|
1085
|
+
message: msg,
|
|
1086
|
+
};
|
|
1087
|
+
}
|
|
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
|
+
},
|
|
738
1197
|
};
|
|
739
1198
|
}
|
|
740
1199
|
|