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.
Files changed (156) 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-Buh_mYlF.js → AIOps-DEhhAYYj.js} +1 -1
  4. package/src/assets/web-panel/assets/{ActionButton-Dc7c0bZf.js → ActionButton-DEyfUz5F.js} +1 -1
  5. package/src/assets/web-panel/assets/{Analytics-CR9TWfM-.js → Analytics-D1rjS61W.js} +1 -1
  6. package/src/assets/web-panel/assets/{AppLayout-DVfanUep.js → AppLayout-CptFJPy6.js} +2 -2
  7. package/src/assets/web-panel/assets/{Audit-BxojBqRe.js → Audit-BG6KQUHY.js} +1 -1
  8. package/src/assets/web-panel/assets/{Backup-CGkreaK9.js → Backup-D2ikQT54.js} +1 -1
  9. package/src/assets/web-panel/assets/{BaseInput-B-Q2ZGfz.js → BaseInput-BG_d8yMt.js} +1 -1
  10. package/src/assets/web-panel/assets/{Chat-Dd_VC5Av.js → Chat-CcHmGkLY.js} +1 -1
  11. package/src/assets/web-panel/assets/{ChatBubbleRenderer-B64kZfRH.js → ChatBubbleRenderer-DIXrOHbn.js} +1 -1
  12. package/src/assets/web-panel/assets/{Checkbox-NYBD1rCW.js → Checkbox-Bx2h6vT3.js} +1 -1
  13. package/src/assets/web-panel/assets/{Codegen-B3Kqhgv1.js → Codegen-o14zzfuK.js} +1 -1
  14. package/src/assets/web-panel/assets/{Col-2A3Bg2GC.js → Col-HlZjxy7V.js} +1 -1
  15. package/src/assets/web-panel/assets/{Community-C84SkDEJ.js → Community-DXxMflr2.js} +1 -1
  16. package/src/assets/web-panel/assets/{Compact-Crv3pyZJ.js → Compact-DbswbBjd.js} +1 -1
  17. package/src/assets/web-panel/assets/{Compliance-D4qasxoY.js → Compliance-C7Q4Da2p.js} +1 -1
  18. package/src/assets/web-panel/assets/{Cowork-Bfbvysw-.js → Cowork-BLImywOe.js} +1 -1
  19. package/src/assets/web-panel/assets/{Cron-Dkjyiekd.js → Cron-DpXu1G4m.js} +1 -1
  20. package/src/assets/web-panel/assets/{Crosschain-DbJm9Kjd.js → Crosschain-C4qokeJu.js} +1 -1
  21. package/src/assets/web-panel/assets/{DID-C2HI6acG.js → DID-C0BjPiij.js} +1 -1
  22. package/src/assets/web-panel/assets/{Dashboard-BXMY7QVP.js → Dashboard-CsfDXwPl.js} +2 -2
  23. package/src/assets/web-panel/assets/{Dropdown-DcOykpfh.js → Dropdown-CiwMUKrx.js} +1 -1
  24. package/src/assets/web-panel/assets/{EmailListRenderer-Doo52F2M.js → EmailListRenderer-DX7xfm5a.js} +1 -1
  25. package/src/assets/web-panel/assets/{Federation-cHubZT6U.js → Federation-CA4Ibsg0.js} +1 -1
  26. package/src/assets/web-panel/assets/{FormItemContext-B5OVlspi.js → FormItemContext-DvM0lU-7.js} +1 -1
  27. package/src/assets/web-panel/assets/{GenericCardRenderer-OgA46PJq.js → GenericCardRenderer-REjsnTHA.js} +1 -1
  28. package/src/assets/web-panel/assets/{Git-_OKH_JOq.js → Git-ZhnSDQGH.js} +1 -1
  29. package/src/assets/web-panel/assets/{Governance-CTByBwSV.js → Governance-BL8iUV_g.js} +1 -1
  30. package/src/assets/web-panel/assets/{Inference-C0nqgySA.js → Inference-BONrgLk-.js} +1 -1
  31. package/src/assets/web-panel/assets/{KnowledgeGraph-CWW4ZIqH.js → KnowledgeGraph-q9SAz7h7.js} +1 -1
  32. package/src/assets/web-panel/assets/{Logs-DrwqUltr.js → Logs-eHfEFnEZ.js} +1 -1
  33. package/src/assets/web-panel/assets/{Marketplace-LJMRx-dm.js → Marketplace-DzwuVedm.js} +1 -1
  34. package/src/assets/web-panel/assets/{McpTools-F_EjC8j3.js → McpTools-BRoLIeq5.js} +1 -1
  35. package/src/assets/web-panel/assets/{Memory-VonDem9-.js → Memory-DjvAa1Ce.js} +1 -1
  36. package/src/assets/web-panel/assets/{MobileBridge-CUWxIrfb.js → MobileBridge-CGTanjsT.js} +1 -1
  37. package/src/assets/web-panel/assets/{MobileProjects-CGOo70lk.js → MobileProjects-cTccXHwN.js} +1 -1
  38. package/src/assets/web-panel/assets/{Mtc-CqUquFbQ.js → Mtc-CNUe29wS.js} +1 -1
  39. package/src/assets/web-panel/assets/{MtcAudit-CRVusaip.js → MtcAudit-COk24mdH.js} +1 -1
  40. package/src/assets/web-panel/assets/{Multisig-B0o8Mv8T.js → Multisig-CFq2j0BU.js} +1 -1
  41. package/src/assets/web-panel/assets/{NLProgramming-CxQINUhu.js → NLProgramming-dfRr-FGW.js} +1 -1
  42. package/src/assets/web-panel/assets/{Notes-B6Q_apFW.js → Notes-iM4aoXiw.js} +1 -1
  43. package/src/assets/web-panel/assets/{NotificationSettings-DO-lgp6x.js → NotificationSettings-CeVJ-942.js} +1 -1
  44. package/src/assets/web-panel/assets/{OrderTableRenderer-DxoBoMtz.js → OrderTableRenderer-zQ5jvUZI.js} +1 -1
  45. package/src/assets/web-panel/assets/{Organization-DqJ_KawH.js → Organization-CTSWyMGT.js} +1 -1
  46. package/src/assets/web-panel/assets/{Overflow-Cg4iKODM.js → Overflow---n60sAp.js} +1 -1
  47. package/src/assets/web-panel/assets/{P2P-n5GPMrwC.js → P2P-BCQurpAB.js} +1 -1
  48. package/src/assets/web-panel/assets/{PdhVaultBrowser-BdZI0EJs.js → PdhVaultBrowser-C5L1qAc0.js} +2 -2
  49. package/src/assets/web-panel/assets/{Permissions-BjtwAIGb.js → Permissions-I8sgLLE5.js} +1 -1
  50. package/src/assets/web-panel/assets/PersonalDataHub-CEUfFRCj.js +2 -0
  51. package/src/assets/web-panel/assets/{PersonalDataHub-D0ncF92t.css → PersonalDataHub-CO9-IYDY.css} +1 -1
  52. package/src/assets/web-panel/assets/{Pipeline-BZe2-Flj.js → Pipeline-BTBjJaRd.js} +1 -1
  53. package/src/assets/web-panel/assets/{Privacy-OJqMon4c.js → Privacy-aCs44rpW.js} +1 -1
  54. package/src/assets/web-panel/assets/{ProjectInit-Dw-5SMG1.js → ProjectInit-DZ2iIlbN.js} +1 -1
  55. package/src/assets/web-panel/assets/{ProjectSettings-DxqW44cV.js → ProjectSettings-oYUtNgHP.js} +1 -1
  56. package/src/assets/web-panel/assets/{Projects-CPOqs2ec.js → Projects-FonFg0ie.js} +1 -1
  57. package/src/assets/web-panel/assets/{Providers-hBfwscEl.js → Providers-CRmOuabY.js} +1 -1
  58. package/src/assets/web-panel/assets/{QuickAsk-DA3WFFAr.js → QuickAsk-BHd6UZ1A.js} +1 -1
  59. package/src/assets/web-panel/assets/{Recommend-DMpz3URg.js → Recommend-BkzGGuq-.js} +1 -1
  60. package/src/assets/web-panel/assets/{Reputation-6-z56FwC.js → Reputation-Do7cPr9u.js} +1 -1
  61. package/src/assets/web-panel/assets/{Row-CL1Y6SfW.js → Row-D_sR3MmD.js} +1 -1
  62. package/src/assets/web-panel/assets/{RssFeed-BIHU2bMf.js → RssFeed-pWSbZ06l.js} +1 -1
  63. package/src/assets/web-panel/assets/{Search-CRAfuEX-.js → Search-BTL71JSs.js} +1 -1
  64. package/src/assets/web-panel/assets/{Security-CVya3gvH.js → Security-8lbNoqY6.js} +1 -1
  65. package/src/assets/web-panel/assets/{Services-Cxv7_umF.js → Services-yr3QVduo.js} +1 -1
  66. package/src/assets/web-panel/assets/{Skeleton-D_GvsCtv.js → Skeleton-DdnY1ZTz.js} +1 -1
  67. package/src/assets/web-panel/assets/{Skills-DyiEpcvf.js → Skills-fk24WY3D.js} +1 -1
  68. package/src/assets/web-panel/assets/{Sla-wiglQzXV.js → Sla-bOXRT7wR.js} +1 -1
  69. package/src/assets/web-panel/assets/{SpeechSettings-CLtovaa5.js → SpeechSettings-DjonFUbP.js} +1 -1
  70. package/src/assets/web-panel/assets/{SyncSettings-BOgVef1O.js → SyncSettings-C-7HTl6d.js} +1 -1
  71. package/src/assets/web-panel/assets/{Tasks-Ik8AX7-J.js → Tasks-DDohfzFT.js} +1 -1
  72. package/src/assets/web-panel/assets/{Templates-CireiINW.js → Templates-C8PI_WTt.js} +1 -1
  73. package/src/assets/web-panel/assets/{Tenant-t7jF9NkQ.js → Tenant-CIvbeRkn.js} +1 -1
  74. package/src/assets/web-panel/assets/{Terminal-Btq_O951.js → Terminal-BuIPGugj.js} +1 -1
  75. package/src/assets/web-panel/assets/{TimelineRenderer-hC_Piiwy.js → TimelineRenderer-BefCbTxN.js} +1 -1
  76. package/src/assets/web-panel/assets/{Tokens-BTIqA2J1.js → Tokens-gGAeez46.js} +1 -1
  77. package/src/assets/web-panel/assets/{Trigger-Dzv2gJpK.js → Trigger-C_86E2v7.js} +1 -1
  78. package/src/assets/web-panel/assets/{Trust-B13QpWOh.js → Trust-Beg23C1W.js} +1 -1
  79. package/src/assets/web-panel/assets/{UkeySign-CFj3UF4G.js → UkeySign--sGSaISg.js} +1 -1
  80. package/src/assets/web-panel/assets/{VideoEditing-CGMOGTQb.js → VideoEditing-DIsnY6D_.js} +1 -1
  81. package/src/assets/web-panel/assets/{Wallet-BkCJ573Y.js → Wallet-a7ECYY0i.js} +1 -1
  82. package/src/assets/web-panel/assets/{WebAuthn-C8dCrmGH.js → WebAuthn-CsVpkUE8.js} +1 -1
  83. package/src/assets/web-panel/assets/{WorkflowEditor-CclfhxwH.js → WorkflowEditor-BOJ4WTgl.js} +1 -1
  84. package/src/assets/web-panel/assets/{chat-CW_X_A9l.js → chat-ezCR5ZZX.js} +1 -1
  85. package/src/assets/web-panel/assets/{colors-6GtheJb2.js → colors-DSUEQ7GR.js} +1 -1
  86. package/src/assets/web-panel/assets/{compact-item-tz7dJapw.js → compact-item-D4w3DGj_.js} +1 -1
  87. package/src/assets/web-panel/assets/{createContext-CbiGcRCw.js → createContext-B_hvu-NR.js} +1 -1
  88. package/src/assets/web-panel/assets/{hasIn-bmNFD3PH.js → hasIn-FY775Vpc.js} +1 -1
  89. package/src/assets/web-panel/assets/{index-DxHmNJ8S.js → index-1ki6aTIz.js} +1 -1
  90. package/src/assets/web-panel/assets/{index-UId2JAY6.js → index-B3lbDu2b.js} +1 -1
  91. package/src/assets/web-panel/assets/{index-BM4slfDH.js → index-B9LXVosT.js} +1 -1
  92. package/src/assets/web-panel/assets/{index-b7sSMzkC.js → index-BGdchdRx.js} +1 -1
  93. package/src/assets/web-panel/assets/{index-KFdfLxVt.js → index-BGrm33US.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-B9sJpsz3.js → index-BHPD-_s2.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-B6GgMo1k.js → index-BMnGj-Ui.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-B2P1c5yD.js → index-BSp1hSN8.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-S9g45I5s.js → index-BaZmrJ6j.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-Cb33JbDx.js → index-BnvLdkR8.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-CQ7aJ-8s.js → index-BzME19Nh.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-DeoJYTHX.js → index-C0wDzrUK.js} +3 -3
  101. package/src/assets/web-panel/assets/{index-CBNnbQxM.js → index-CAa3LSKI.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-CLk3xgD2.js → index-CE3vDzJj.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-De0xvTEv.js → index-CLp4V3Tb.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-CKP-AZD3.js → index-CNUQnJsg.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-CzIQ0u4e.js → index-CSbCIyga.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-UjxsY00y.js → index-CUNYcWEF.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-CgLF_zD1.js → index-CV-F9a_X.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-C5zlrlPd.js → index-CcvzscCg.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-B3UH6whC.js → index-CdzLJsac.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-CU0MeCwH.js → index-Cug_yoee.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-DxdLksCx.js → index-CxMArAIk.js} +1 -1
  112. package/src/assets/web-panel/assets/index-CzkEIn_T.js +1 -0
  113. package/src/assets/web-panel/assets/index-D2PcvXPP.js +1 -0
  114. package/src/assets/web-panel/assets/{index-DMGJqZ-o.js → index-D6yJ0RMr.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-DaYfMM7r.js → index-DM77-xyl.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-CV9aPPYM.js → index-DfU6zsU8.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-l2VM-W36.js → index-DqsQUPY7.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-DK7ee5hC.js → index-DqxLCUYa.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-DaK59dFw.js → index-DtztktoP.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-Cs5KWviO.js → index-Dz8-7APi.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-Da2RUdcb.js → index-Enin7rzK.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-CYIwY9zQ.js → index-S6A76pR1.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-DvWXdCxl.js → index-ZGJo2fz1.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-Dj1N1idV.js → index-d0HXotWE.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-CTnIkosg.js → index-gAtp_KkQ.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-zP_o4yKV.js → index-mlTTTHla.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-BxCPkuTG.js → index-wWVM6ENX.js} +1 -1
  128. package/src/assets/web-panel/assets/{initDefaultProps-BTGwT0NA.js → initDefaultProps-BoLcNBz9.js} +1 -1
  129. package/src/assets/web-panel/assets/{motion-BheHkG8e.js → motion-ouRvP3eO.js} +1 -1
  130. package/src/assets/web-panel/assets/{move-BkMMNkAw.js → move-BBITvaOV.js} +1 -1
  131. package/src/assets/web-panel/assets/{omit-B9zmSFf6.js → omit-D8Yxdvbb.js} +1 -1
  132. package/src/assets/web-panel/assets/{pickAttrs-CFNBcA5Z.js → pickAttrs-BIUy7mER.js} +1 -1
  133. package/src/assets/web-panel/assets/{placementArrow-B4mvrUYw.js → placementArrow-CrNWpNSF.js} +1 -1
  134. package/src/assets/web-panel/assets/{responsiveObserve-BJqsSjxJ.js → responsiveObserve-aHLPN464.js} +1 -1
  135. package/src/assets/web-panel/assets/{slide-Cj78MXSi.js → slide-2qNtePjk.js} +1 -1
  136. package/src/assets/web-panel/assets/{statusUtils-Bk6ChXAV.js → statusUtils-FAF3iR3R.js} +1 -1
  137. package/src/assets/web-panel/assets/{styleChecker-B_YDSNYf.js → styleChecker-BNFTkrbl.js} +1 -1
  138. package/src/assets/web-panel/assets/{useFlexGapSupport-q90prOQL.js → useFlexGapSupport-BgdPlW7E.js} +1 -1
  139. package/src/assets/web-panel/assets/{useFs-BtpFJ9kI.js → useFs-q1QvAh3f.js} +1 -1
  140. package/src/assets/web-panel/assets/{usePersonalDataHub-C3qhf1sQ.js → usePersonalDataHub-DEZ6cY8C.js} +1 -1
  141. package/src/assets/web-panel/assets/{vnode-Bz2j0JiG.js → vnode-vp6H-NL_.js} +1 -1
  142. package/src/assets/web-panel/assets/{zoom-CzaEtel2.js → zoom-UatfJMw4.js} +1 -1
  143. package/src/assets/web-panel/index.html +1 -1
  144. package/src/commands/__tests__/hub-bilibili-adb-sync.test.js +350 -0
  145. package/src/commands/__tests__/hub-douyin-adb-sync.test.js +199 -0
  146. package/src/commands/__tests__/hub-kuaishou-adb-sync.test.js +161 -0
  147. package/src/commands/__tests__/hub-toutiao-adb-sync.test.js +158 -0
  148. package/src/commands/__tests__/hub-weibo-adb-sync.test.js +163 -0
  149. package/src/commands/__tests__/hub-xhs-adb-sync.test.js +155 -0
  150. package/src/commands/hub.js +883 -0
  151. package/src/gateways/ws/personal-data-hub-protocol.js +84 -0
  152. package/src/lib/host-adb-bridge.js +77 -1
  153. package/src/lib/personal-data-hub-wiring.js +471 -12
  154. package/src/assets/web-panel/assets/PersonalDataHub-Bsf3Wh6n.js +0 -1
  155. package/src/assets/web-panel/assets/index-BFkZAdio.js +0 -1
  156. package/src/assets/web-panel/assets/index-BhgINPAH.js +0 -1
@@ -392,6 +392,90 @@ export const PERSONAL_DATA_HUB_HANDLERS = {
392
392
  "personal-data-hub.list-wechat-accounts": async () =>
393
393
  withHub((hub) => hub.listWechatAccounts()),
394
394
 
395
+ // ─── Phase 1c — Bilibili C 路径 one-shot sync ─────────────────────────
396
+ //
397
+ // Pulls cookies from the user's Android Bilibili App via ADB, fetches 4
398
+ // endpoints, ingests as a snapshot. Returns the standard
399
+ // `{ok, report?, reason?, message?}` shape — see hub.bilibiliAdbSync for
400
+ // the full reason taxonomy. UI maps reasons to banner strings.
401
+ "personal-data-hub.bilibili-adb-sync": async (msg) =>
402
+ withHub((hub) =>
403
+ hub.bilibiliAdbSync({
404
+ limits: msg && msg.limits,
405
+ stagingDir: msg && msg.stagingDir,
406
+ displayName: msg && msg.displayName,
407
+ }),
408
+ ),
409
+
410
+ // Phase 1e — dry-run env probe (cookies path only, no API calls / vault writes)
411
+ "personal-data-hub.bilibili-adb-doctor": async () =>
412
+ withHub((hub) => hub.bilibiliAdbDoctor()),
413
+
414
+ // Phase 2a — Douyin C 路径 one-shot sync (db extraction)
415
+ "personal-data-hub.douyin-adb-sync": async (msg) =>
416
+ withHub((hub) =>
417
+ hub.douyinAdbSync({
418
+ uid: msg && msg.uid,
419
+ limits: msg && msg.limits,
420
+ stagingDir: msg && msg.stagingDir,
421
+ displayName: msg && msg.displayName,
422
+ }),
423
+ ),
424
+
425
+ // Phase 3a — Weibo C 路径 one-shot sync (m.weibo.cn cookies + 4 endpoints)
426
+ "personal-data-hub.weibo-adb-sync": async (msg) =>
427
+ withHub((hub) =>
428
+ hub.weiboAdbSync({
429
+ limits: msg && msg.limits,
430
+ stagingDir: msg && msg.stagingDir,
431
+ displayName: msg && msg.displayName,
432
+ }),
433
+ ),
434
+
435
+ // Phase 3c — Xhs C 路径 one-shot sync (xiaohongshu.com cookies + 4 endpoints X-S signed)
436
+ "personal-data-hub.xhs-adb-sync": async (msg) =>
437
+ withHub((hub) =>
438
+ hub.xhsAdbSync({
439
+ limits: msg && msg.limits,
440
+ stagingDir: msg && msg.stagingDir,
441
+ displayName: msg && msg.displayName,
442
+ }),
443
+ ),
444
+
445
+ // Phase 6c — Toutiao C 路径 one-shot sync (www.toutiao.com cookies +
446
+ // passport profile + 3 _signature endpoints). CLI/web context with no
447
+ // desktop bridge: 3 signed endpoints short-circuit (no HTTP). Desktop
448
+ // wiring uses ToutiaoSignBridge → ~100% hit.
449
+ "personal-data-hub.toutiao-adb-sync": async (msg) =>
450
+ withHub((hub) =>
451
+ hub.toutiaoAdbSync({
452
+ limits: msg && msg.limits,
453
+ stagingDir: msg && msg.stagingDir,
454
+ displayName: msg && msg.displayName,
455
+ }),
456
+ ),
457
+
458
+ // Phase 6d — Kuaishou C 路径 one-shot sync (www.kuaishou.com cookies +
459
+ // profile from api_ph payload + 3 GraphQL endpoints with __NS_sig3 +
460
+ // kpf/kpn). CLI/web context: signed endpoints short-circuit (no HTTP).
461
+ // Desktop wiring uses KuaishouSignBridge → ~100% hit.
462
+ "personal-data-hub.kuaishou-adb-sync": async (msg) =>
463
+ withHub((hub) =>
464
+ hub.kuaishouAdbSync({
465
+ limits: msg && msg.limits,
466
+ stagingDir: msg && msg.stagingDir,
467
+ displayName: msg && msg.displayName,
468
+ }),
469
+ ),
470
+
471
+ // Phase 6e — Bridge dry-run doctor. Spins up Xhs / Toutiao / Kuaishou
472
+ // sign bridges with empty cookie, probes for candidate signing globals,
473
+ // times each phase. No phone needed. Detects SDK rotation BEFORE the
474
+ // user starts a real sync. Desktop-only — CLI/web-shell-no-desktop
475
+ // returns MODULE_LOAD_FAILED.
476
+ "personal-data-hub.bridge-doctor": async () =>
477
+ withHub((hub) => hub.bridgeDoctor()),
478
+
395
479
  // ─── Phase 8 — EntityResolver review / merge / unmerge ───────────────
396
480
 
397
481
  "personal-data-hub.review-queue-list": async (msg) =>
@@ -381,7 +381,71 @@ async function readSnapshot(params, opts) {
381
381
  return stdout;
382
382
  }
383
383
 
384
+ /**
385
+ * Phase B0 — plugin point for platform-specific ADB methods.
386
+ *
387
+ * `opts.extensions` is an optional `{ [methodName]: handler }` map. Each
388
+ * handler is called as `handler(params, ctx)` where `ctx` exposes the
389
+ * shared ADB primitives so platform extensions don't re-implement
390
+ * device-picking or row-parsing:
391
+ *
392
+ * ctx = {
393
+ * adb, // (args, opts) => Promise<stdout>
394
+ * pickDevice, // (opts) => Promise<serial>
395
+ * parseContentQueryRows, // (stdout) => Array<{key:value}>
396
+ * }
397
+ *
398
+ * Resolution order in `invoke(method, params)`:
399
+ * 1. Built-in method (the switch below)
400
+ * 2. Extension method from opts.extensions
401
+ * 3. Throw HostAdbBridgeUnavailableError
402
+ *
403
+ * Built-ins always win — extensions cannot shadow them. This guarantees
404
+ * the multipath plan's Phase 1+ per-platform extensions can't break the
405
+ * already-shipping system-data-android consumer.
406
+ *
407
+ * Example (Phase 1 will land for real):
408
+ * const bridge = createHostAdbBridge({
409
+ * extensions: {
410
+ * "douyin.snapshot": async (params, { adb, pickDevice }) => {
411
+ * const serial = await pickDevice();
412
+ * const uid = params.uid;
413
+ * const out = await adb(
414
+ * ["shell", "su", "-c", `base64 /data/data/com.ss.android.ugc.aweme/databases/${uid}_im.db`],
415
+ * { serial, timeoutMs: 60_000 },
416
+ * );
417
+ * return { snapshotBase64: out };
418
+ * },
419
+ * },
420
+ * });
421
+ * await bridge.invoke("douyin.snapshot", { uid: "1234567890" });
422
+ */
423
+ const BUILTIN_METHODS = new Set([
424
+ "contacts.query",
425
+ "app.list",
426
+ "sms.query",
427
+ "call.query",
428
+ "media.list",
429
+ "snapshot.list",
430
+ "snapshot.read",
431
+ ]);
432
+
384
433
  export function createHostAdbBridge(opts = {}) {
434
+ const extensions = opts.extensions || {};
435
+ // Defense: warn (but allow) when an extension tries to shadow a
436
+ // built-in. Built-ins always win in dispatch — Phase B0 keeps this
437
+ // a soft warning so it surfaces in tests; we can upgrade to a hard
438
+ // throw in Phase 1 if any extension author actually attempts it.
439
+ for (const k of Object.keys(extensions)) {
440
+ if (BUILTIN_METHODS.has(k)) {
441
+ // eslint-disable-next-line no-console
442
+ console.warn(
443
+ `host-adb-bridge: extension "${k}" shadows a built-in method and will be ignored at dispatch`,
444
+ );
445
+ }
446
+ }
447
+ const ctx = { adb, pickDevice, parseContentQueryRows };
448
+
385
449
  return {
386
450
  /**
387
451
  * SystemDataAndroidAdapter._bridgeAvailable() reads this; must be
@@ -393,6 +457,13 @@ export function createHostAdbBridge(opts = {}) {
393
457
  caps() {
394
458
  return { available: true };
395
459
  },
460
+ /**
461
+ * Diagnostic only — reflects extension method names registered for
462
+ * this bridge instance. Useful for `cc doctor`-style introspection.
463
+ */
464
+ extensionMethods() {
465
+ return Object.keys(extensions).filter((k) => !BUILTIN_METHODS.has(k));
466
+ },
396
467
  async invoke(method, params = {}) {
397
468
  switch (method) {
398
469
  case "contacts.query":
@@ -409,10 +480,15 @@ export function createHostAdbBridge(opts = {}) {
409
480
  return await listSnapshots(params, opts);
410
481
  case "snapshot.read":
411
482
  return await readSnapshot(params, opts);
412
- default:
483
+ default: {
484
+ const ext = extensions[method];
485
+ if (typeof ext === "function") {
486
+ return await ext(params, ctx);
487
+ }
413
488
  throw new HostAdbBridgeUnavailableError(
414
489
  `method "${method}" not implemented by host-adb-bridge`,
415
490
  );
491
+ }
416
492
  }
417
493
  },
418
494
  };