chainlesschain 0.162.176 → 0.162.178

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 (260) hide show
  1. package/README.md +10 -0
  2. package/package.json +1 -1
  3. package/src/assets/web-panel/.build-hash +1 -1
  4. package/src/assets/web-panel/assets/{AIOps-BDLu5Elz.js → AIOps-DRftcSue.js} +1 -1
  5. package/src/assets/web-panel/assets/{ActionButton-DH5us-CK.js → ActionButton-BFvUaMKR.js} +1 -1
  6. package/src/assets/web-panel/assets/{Analytics-BZ0u8IFG.js → Analytics-C0-Rru4P.js} +3 -3
  7. package/src/assets/web-panel/assets/AppLayout-bx-BCljj.js +9 -0
  8. package/src/assets/web-panel/assets/{Artifacts-Br2YBbh_.js → Artifacts-DAJ8B3Un.js} +1 -1
  9. package/src/assets/web-panel/assets/{Audit-C3C6a482.js → Audit-hOk4L1lr.js} +1 -1
  10. package/src/assets/web-panel/assets/{BackgroundAgents-CzHvebcj.js → BackgroundAgents-3pbDpM9z.js} +1 -1
  11. package/src/assets/web-panel/assets/{Backup-DZNHYDFd.js → Backup-BtziGDn9.js} +1 -1
  12. package/src/assets/web-panel/assets/{BaseInput-VRiC4fIx.js → BaseInput-kmshphJ3.js} +1 -1
  13. package/src/assets/web-panel/assets/{Chat-Cm08WWAD.js → Chat-d7tGSosA.js} +5 -5
  14. package/src/assets/web-panel/assets/{ChatBubbleRenderer-CGHYrugQ.js → ChatBubbleRenderer-p-_PBpX_.js} +1 -1
  15. package/src/assets/web-panel/assets/{Checkbox-DtByk7d7.js → Checkbox-C4Eh4Tz5.js} +1 -1
  16. package/src/assets/web-panel/assets/{Codegen-CphXXOfD.js → Codegen-r7gmhZyA.js} +1 -1
  17. package/src/assets/web-panel/assets/{Col-Hz86TnLR.js → Col-U7mDaGlL.js} +1 -1
  18. package/src/assets/web-panel/assets/{Community-HP03ltpD.js → Community-Bpu8aH1T.js} +1 -1
  19. package/src/assets/web-panel/assets/{Compact-B_N1mqQz.js → Compact-CHb2XBJe.js} +1 -1
  20. package/src/assets/web-panel/assets/{Compliance-CVztRpi8.js → Compliance-Cn_r4dey.js} +1 -1
  21. package/src/assets/web-panel/assets/{Cowork-wUVOyZih.js → Cowork-CdMWfDcz.js} +4 -4
  22. package/src/assets/web-panel/assets/{Cron-DW5TLJKw.js → Cron-BtnREHWy.js} +2 -2
  23. package/src/assets/web-panel/assets/{Crosschain-CrAFGhWH.js → Crosschain-BKI9TSzr.js} +1 -1
  24. package/src/assets/web-panel/assets/{DID-pA-oD8ke.js → DID-pkNubzzJ.js} +2 -2
  25. package/src/assets/web-panel/assets/Dashboard-1rrz1snN.js +3 -0
  26. package/src/assets/web-panel/assets/{Dropdown-EweJcsek.js → Dropdown-DLyFVxDc.js} +1 -1
  27. package/src/assets/web-panel/assets/{EmailListRenderer-C9xVLPG4.js → EmailListRenderer-CtUWfYVq.js} +1 -1
  28. package/src/assets/web-panel/assets/{FamilyGuardDashboard-CDcEEqlu.js → FamilyGuardDashboard-B8eX2Qe4.js} +1 -1
  29. package/src/assets/web-panel/assets/{Federation-DtZda9A_.js → Federation-D8lsDGus.js} +1 -1
  30. package/src/assets/web-panel/assets/{FormItemContext-CiYdcVz3.js → FormItemContext-CRYt_aIw.js} +1 -1
  31. package/src/assets/web-panel/assets/{GenericCardRenderer-DA13uwA0.js → GenericCardRenderer-ClKzY8_N.js} +1 -1
  32. package/src/assets/web-panel/assets/{Git-DzRhZD1O.js → Git-BXj5Dney.js} +2 -2
  33. package/src/assets/web-panel/assets/{Governance-D5RMgOSb.js → Governance-Cm-I8RMz.js} +1 -1
  34. package/src/assets/web-panel/assets/{Inference-BgrPfSNk.js → Inference-CPvbhvgt.js} +1 -1
  35. package/src/assets/web-panel/assets/{KnowledgeGraph-DzjnD571.js → KnowledgeGraph-sYNDZaoi.js} +1 -1
  36. package/src/assets/web-panel/assets/{Logs-BhWzVDtN.js → Logs-BZY_3CRZ.js} +2 -2
  37. package/src/assets/web-panel/assets/{MarkdownRenderer-BDape9cx.js → MarkdownRenderer-up0BW6pv.js} +1 -1
  38. package/src/assets/web-panel/assets/{Marketplace-DJtL5GV7.js → Marketplace-C5MEJ2Qe.js} +1 -1
  39. package/src/assets/web-panel/assets/{McpTools-CZcQygI7.js → McpTools-ihdrn43I.js} +5 -5
  40. package/src/assets/web-panel/assets/{Memory-DUWSDUUu.js → Memory-Br8bPMlh.js} +2 -2
  41. package/src/assets/web-panel/assets/{MobileBridge-BTwq2WKY.js → MobileBridge-BNntgrYW.js} +1 -1
  42. package/src/assets/web-panel/assets/MobileProjects-BdV915mw.js +1 -0
  43. package/src/assets/web-panel/assets/{Mtc-BiGugEQm.js → Mtc-A3wDmlqL.js} +5 -5
  44. package/src/assets/web-panel/assets/{MtcAudit-DY7a6gUe.js → MtcAudit-CF-mBLWM.js} +2 -2
  45. package/src/assets/web-panel/assets/{Multisig-BQbDu_w7.js → Multisig-Iy2k_MSo.js} +3 -3
  46. package/src/assets/web-panel/assets/{NLProgramming-CM2wXTLv.js → NLProgramming-kk0W7HUb.js} +1 -1
  47. package/src/assets/web-panel/assets/{Notes-DI6gGs1v.js → Notes-B5u5t_4S.js} +3 -3
  48. package/src/assets/web-panel/assets/{NotificationSettings-BsZOLWAB.js → NotificationSettings-BN0POf6_.js} +1 -1
  49. package/src/assets/web-panel/assets/OrderTableRenderer-CHkSUrXB.js +1 -0
  50. package/src/assets/web-panel/assets/{Organization-Cds0_tXr.js → Organization-DwWQESuN.js} +4 -4
  51. package/src/assets/web-panel/assets/{Overflow-WunYMD87.js → Overflow-DG6klrcC.js} +1 -1
  52. package/src/assets/web-panel/assets/{P2P-Bo6j4DDv.js → P2P-BwJcKkgZ.js} +2 -2
  53. package/src/assets/web-panel/assets/{PdhVaultBrowser-Bh2XPD5f.js → PdhVaultBrowser-BwOHG0in.js} +5 -5
  54. package/src/assets/web-panel/assets/{Permissions-EMvMMC8N.js → Permissions-CGMXe4TX.js} +4 -4
  55. package/src/assets/web-panel/assets/PersonalDataHub-ziYqg7-A.js +8 -0
  56. package/src/assets/web-panel/assets/{Pipeline-BOx8HOgL.js → Pipeline-BzJfeoGt.js} +1 -1
  57. package/src/assets/web-panel/assets/{Privacy-tBeTVQVM.js → Privacy-DLh3Bblx.js} +1 -1
  58. package/src/assets/web-panel/assets/{ProjectInit-CVYg1W4M.js → ProjectInit-USVWW36c.js} +2 -2
  59. package/src/assets/web-panel/assets/{ProjectSettings-Dvt5I7y1.js → ProjectSettings-CiiOn62h.js} +2 -2
  60. package/src/assets/web-panel/assets/Projects-6V-PNmcA.js +1 -0
  61. package/src/assets/web-panel/assets/{Providers-Ct8xqY-E.js → Providers-CBPWWzpu.js} +1 -1
  62. package/src/assets/web-panel/assets/{QrScannerModal-Cni8Ooja.js → QrScannerModal-QVwoRUq3.js} +1 -1
  63. package/src/assets/web-panel/assets/{QuickAsk-BJVLKdxr.js → QuickAsk-CXnR-2Vn.js} +1 -1
  64. package/src/assets/web-panel/assets/{Recommend-DPG8Rbbm.js → Recommend-ClaNzjmF.js} +1 -1
  65. package/src/assets/web-panel/assets/{RemoteSession-DsdR7dCt.js → RemoteSession-C3rGw8vJ.js} +2 -2
  66. package/src/assets/web-panel/assets/{Reputation-Csg1YM-b.js → Reputation-Ci-OWAoP.js} +1 -1
  67. package/src/assets/web-panel/assets/{Row-D9DoFoEf.js → Row-DRhAwXOS.js} +1 -1
  68. package/src/assets/web-panel/assets/{RssFeed-BsvKrXMS.js → RssFeed-BQLJQ2_y.js} +3 -3
  69. package/src/assets/web-panel/assets/{Search-DFUStfgQ.js → Search-QQUpkfFd.js} +1 -1
  70. package/src/assets/web-panel/assets/{Security-ILg1zxdK.js → Security-DdXKzuKT.js} +4 -4
  71. package/src/assets/web-panel/assets/{Services-Dd41PCaY.js → Services-x2Zh62Qd.js} +2 -2
  72. package/src/assets/web-panel/assets/{Skeleton-Bzo1cN80.js → Skeleton-GdY4KwRz.js} +1 -1
  73. package/src/assets/web-panel/assets/{Skills-BDHh17P0.js → Skills-Bv4tY1Fd.js} +1 -1
  74. package/src/assets/web-panel/assets/{Sla-jl7UTiRY.js → Sla-C3QnM-11.js} +1 -1
  75. package/src/assets/web-panel/assets/{SpeechSettings-BePa-RF6.js → SpeechSettings-Bl3ytvmI.js} +1 -1
  76. package/src/assets/web-panel/assets/{SyncSettings-DiqqDKGZ.js → SyncSettings-Wp9IwTsP.js} +2 -2
  77. package/src/assets/web-panel/assets/{Tasks-DYQ_6lxj.js → Tasks-CF3rIrDe.js} +1 -1
  78. package/src/assets/web-panel/assets/{Templates-JiDeI06L.js → Templates-CGfvVVM9.js} +1 -1
  79. package/src/assets/web-panel/assets/{Tenant-hhgI6zwS.js → Tenant-CVXmwQ3U.js} +1 -1
  80. package/src/assets/web-panel/assets/Terminal-bvwrt03E.js +3 -0
  81. package/src/assets/web-panel/assets/{TimelineRenderer-B8uB5Llk.js → TimelineRenderer-D0g74KhH.js} +1 -1
  82. package/src/assets/web-panel/assets/{Tokens-C3b_6r2z.js → Tokens-BH4IwzlT.js} +1 -1
  83. package/src/assets/web-panel/assets/{Trigger-tIP7HKVe.js → Trigger-DJOpM533.js} +1 -1
  84. package/src/assets/web-panel/assets/{Trust-vjoc11vJ.js → Trust-B43EPRLr.js} +1 -1
  85. package/src/assets/web-panel/assets/{UkeySign-DUPBnGuH.js → UkeySign-BmBFG-em.js} +1 -1
  86. package/src/assets/web-panel/assets/{VideoEditing-CBvhUY5T.js → VideoEditing-n9oJwB8k.js} +1 -1
  87. package/src/assets/web-panel/assets/{Wallet-DUaQ0uA5.js → Wallet-D5QeivHp.js} +4 -4
  88. package/src/assets/web-panel/assets/{WebAuthn-DllSivjE.js → WebAuthn-DcNy7igO.js} +5 -5
  89. package/src/assets/web-panel/assets/{WorkflowEditor-xc8D3uO6.js → WorkflowEditor-BVjc7-5-.js} +1 -1
  90. package/src/assets/web-panel/assets/{chat-BVicU7oA.js → chat-Dy5Tfj3m.js} +1 -1
  91. package/src/assets/web-panel/assets/{colors-DJzLmhLm.js → colors-C4c2CNZU.js} +1 -1
  92. package/src/assets/web-panel/assets/{compact-item-BvYRfThE.js → compact-item-DPa3O5vN.js} +1 -1
  93. package/src/assets/web-panel/assets/{createContext-DGXxCBKR.js → createContext-TLcfNA6_.js} +1 -1
  94. package/src/assets/web-panel/assets/devWarning-BAwdDA_5.js +1 -0
  95. package/src/assets/web-panel/assets/{hasIn-SBDJB1y4.js → hasIn-D41LVFkp.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-D7HimK0M.js → index-0oevYjfT.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-DCdRAgjy.js → index-388pLGJ1.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-BO1itZaY.js → index-B8nLBZbv.js} +3 -3
  99. package/src/assets/web-panel/assets/{index-DvUTDYXX.js → index-BPTGAjee.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-hxTODbM1.js → index-BPtrOBmW.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-wcCL-miV.js → index-BQiIxHBy.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-CKyEivf8.js → index-BSM1cHVK.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-BJZf9DhV.js → index-BYPr9fkz.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-DHVLJ8q0.js → index-BsQ7Ev6i.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-Cs2rmLFt.js → index-Btk9qLL2.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-z1ZylsLq.js → index-BvmziZSG.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-Cf-O_g_8.js → index-BvopLC_T.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-DMarmfrv.js → index-C7xhTVyP.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-CoJAO1Lm.js → index-CNk_ZooP.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-9gdI7uUW.js → index-CQrEHoOG.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-Bf-ctERC.js → index-CSxex23J.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-MjC4G09d.js → index-CVjgm992.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-e4fXH_WO.js → index-CWK4zOPe.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-xfluRkCT.js → index-CX0VsoP4.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-DRfiXB_p.js → index-CXl0YPNG.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-d5BVd-cL.js → index-Cip7LWml.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-Dm_77jgR.js → index-Cq_hlWNt.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-YJkzy8ZF.js → index-CzZ49YZL.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-CtwqO5qo.js → index-D2Nkivlm.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-BYqz4Wrr.js → index-DBUgRs4D.js} +1 -1
  121. package/src/assets/web-panel/assets/index-DEjVkdzq.js +1 -0
  122. package/src/assets/web-panel/assets/{index-CdGY9P8a.js → index-DNsBj2Ob.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-DonCnfMr.js → index-Di4X8cfI.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-1SdDS6lR.js → index-DljFsVGI.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-DnjPdvR6.js → index-Korc3QIe.js} +1 -1
  126. package/src/assets/web-panel/assets/index-LMOc5xrS.js +1 -0
  127. package/src/assets/web-panel/assets/{index-VMfwIH5G.js → index-MKZDje0H.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-DKrvvWm4.js → index-OHAfRu_3.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-FxZzRyE1.js → index-WEJr8PL5.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-Crk5NTb0.js → index-WinCp6du.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-DCqRS6da.js → index-Yjr6cqSK.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-BTrBGBJs.js → index-iQ6gtFih.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-lpaGoTH3.js → index-pt3s7yvV.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-CloCgBUR.js → index-tQ3igERQ.js} +1 -1
  135. package/src/assets/web-panel/assets/{initDefaultProps-C1zO1KnY.js → initDefaultProps-BFZu87WZ.js} +1 -1
  136. package/src/assets/web-panel/assets/{motion-CWLtEGmC.js → motion-DJIo7qvt.js} +1 -1
  137. package/src/assets/web-panel/assets/{move-DzD_C3Vm.js → move-Cfr5qknL.js} +1 -1
  138. package/src/assets/web-panel/assets/{mtc-parser-D880PYJl.js → mtc-parser-Bgc-OadH.js} +1 -1
  139. package/src/assets/web-panel/assets/{omit-CFR_z2ov.js → omit-X3WI-TNp.js} +1 -1
  140. package/src/assets/web-panel/assets/{pickAttrs-srIhgrSC.js → pickAttrs-pJhU9IxK.js} +1 -1
  141. package/src/assets/web-panel/assets/{placementArrow-C1rXpibP.js → placementArrow-BNg_Vj3T.js} +1 -1
  142. package/src/assets/web-panel/assets/{responsiveObserve-C30gRcSS.js → responsiveObserve-TeSEGQ5-.js} +1 -1
  143. package/src/assets/web-panel/assets/{slide-CvtKiMfV.js → slide-D_t_P0bv.js} +1 -1
  144. package/src/assets/web-panel/assets/{statusUtils-DNHO7ITG.js → statusUtils-DrrIMwAT.js} +1 -1
  145. package/src/assets/web-panel/assets/{styleChecker-Dt_Sl-g4.js → styleChecker-BjZCuFRm.js} +1 -1
  146. package/src/assets/web-panel/assets/{useFlexGapSupport-Cjev42Gh.js → useFlexGapSupport-rTFdlqdQ.js} +1 -1
  147. package/src/assets/web-panel/assets/{useFs-Baxglj2V.js → useFs-BidCpfLX.js} +1 -1
  148. package/src/assets/web-panel/assets/usePersonalDataHub-C5mHttA9.js +1 -0
  149. package/src/assets/web-panel/assets/{vnode-mIRkdT7o.js → vnode-BrbcRiHZ.js} +1 -1
  150. package/src/assets/web-panel/assets/{zoom-HzI5DlH_.js → zoom-PISX7AkR.js} +1 -1
  151. package/src/assets/web-panel/index.html +1 -1
  152. package/src/commands/__tests__/hub-wechat.test.js +45 -0
  153. package/src/commands/agenda.js +22 -6
  154. package/src/commands/agent.js +3 -3
  155. package/src/commands/background-session.js +16 -6
  156. package/src/commands/batch.js +79 -27
  157. package/src/commands/changelog.js +15 -4
  158. package/src/commands/context.js +33 -1
  159. package/src/commands/eval.js +21 -6
  160. package/src/commands/hook.js +2 -2
  161. package/src/commands/hub.js +473 -39
  162. package/src/commands/init.js +212 -110
  163. package/src/commands/llm.js +22 -6
  164. package/src/commands/loop.js +9 -2
  165. package/src/commands/skill.js +13 -1
  166. package/src/commands/statusline.js +3 -3
  167. package/src/data/changelog.json +53 -5
  168. package/src/gateways/ws/personal-data-hub-protocol.js +22 -2
  169. package/src/harness/background-task-manager.js +18 -6
  170. package/src/harness/background-task-worker.js +11 -18
  171. package/src/harness/golden-transcript.js +3 -0
  172. package/src/harness/mcp-client.js +9 -15
  173. package/src/harness/worktree-isolator.js +18 -21
  174. package/src/index.js +18 -7
  175. package/src/lib/agent-core.js +5 -0
  176. package/src/lib/agent-ipc-bus.js +12 -3
  177. package/src/lib/agent-team/team-worktree.js +28 -6
  178. package/src/lib/agent-worktree.js +20 -19
  179. package/src/lib/approval-authority-store.js +891 -0
  180. package/src/lib/async-hook-supervisor.cjs +134 -24
  181. package/src/lib/async-hook-supervisor.js +47 -0
  182. package/src/lib/background-agent-supervisor.js +35 -12
  183. package/src/lib/background-interaction-resolver.js +399 -54
  184. package/src/lib/background-session-transport.js +3 -1
  185. package/src/lib/background-task-manager.js +5 -1
  186. package/src/lib/changelog.js +57 -0
  187. package/src/lib/chrome-connector.js +6 -2
  188. package/src/lib/claude-code-bridge.js +24 -8
  189. package/src/lib/cli-anything-bridge.js +82 -25
  190. package/src/lib/context-breakdown.js +82 -3
  191. package/src/lib/doctor-checkup.js +18 -6
  192. package/src/lib/eval/tasks.js +25 -31
  193. package/src/lib/event-runtime-host.js +225 -0
  194. package/src/lib/event-runtime-store.js +102 -21
  195. package/src/lib/event-runtime-worker.js +70 -2
  196. package/src/lib/hook-runner.cjs +71 -36
  197. package/src/lib/hook-runner.js +55 -0
  198. package/src/lib/hooks-v2-producers.js +33 -8
  199. package/src/lib/hooks-v2-runtime.js +360 -40
  200. package/src/lib/host-adb-bridge.js +18 -3
  201. package/src/lib/interaction-adapter.js +66 -0
  202. package/src/lib/lsp/__tests__/benchmark.test.js +61 -0
  203. package/src/lib/lsp/__tests__/lsp-client.test.js +6 -1
  204. package/src/lib/lsp/benchmark.js +20 -4
  205. package/src/lib/lsp/lsp-client.js +6 -4
  206. package/src/lib/lsp/lsp-server-registry.js +0 -2
  207. package/src/lib/operation-fingerprint.js +107 -2
  208. package/src/lib/orchestrator.js +8 -2
  209. package/src/lib/packer/pack-update-applier.js +14 -2
  210. package/src/lib/packer/smoke-runner.js +18 -5
  211. package/src/lib/paths.js +1 -1
  212. package/src/lib/pdh-dedicated-batch-collectors.js +124 -0
  213. package/src/lib/personal-data-hub-wiring.js +327 -52
  214. package/src/lib/plugin-monitor-supervisor.js +20 -13
  215. package/src/lib/plugin-runtime/install.js +10 -3
  216. package/src/lib/process-execution-broker/credential-agent.js +954 -111
  217. package/src/lib/process-execution-broker/index.js +369 -85
  218. package/src/lib/process-execution-broker/platform-sandbox.js +320 -140
  219. package/src/lib/provider-http-error.js +94 -0
  220. package/src/lib/remote-approval-bridge.js +222 -26
  221. package/src/lib/repl-bang-memorize.js +10 -2
  222. package/src/lib/repl-goal.js +19 -2
  223. package/src/lib/settings-hook-events.cjs +13 -8
  224. package/src/lib/settings-hook-events.js +20 -0
  225. package/src/lib/side-effect-ledger-store.js +65 -14
  226. package/src/lib/skill-loader.js +215 -12
  227. package/src/lib/skill-packs/generator.js +18 -9
  228. package/src/lib/skill-process-broker.js +85 -0
  229. package/src/lib/slash-commands.js +10 -2
  230. package/src/lib/status-line.cjs +28 -7
  231. package/src/lib/status-line.js +33 -0
  232. package/src/lib/sub-agent-context.js +42 -0
  233. package/src/lib/turn-binding-store.js +64 -15
  234. package/src/lib/turn-binding.js +85 -16
  235. package/src/repl/agent-repl.js +88 -49
  236. package/src/repl/remote-approval.js +13 -13
  237. package/src/repl/repl-turn-binding.js +46 -16
  238. package/src/runtime/agent-core.js +419 -84
  239. package/src/runtime/coding-agent-contract-shared.cjs +16 -0
  240. package/src/runtime/headless-runner.js +172 -44
  241. package/src/runtime/headless-stream.js +221 -11
  242. package/src/runtime/session-slash-commands.js +506 -0
  243. package/src/skills/video-editing/extractors/audio-extractor.js +13 -5
  244. package/src/skills/video-editing/extractors/video-extractor.js +13 -3
  245. package/src/skills/video-editing/media-process.js +20 -0
  246. package/src/skills/video-editing/render/audio-mix.js +13 -3
  247. package/src/skills/video-editing/render/ffmpeg-concat.js +7 -2
  248. package/src/skills/video-editing/render/ffmpeg-extract.js +7 -2
  249. package/src/workers/background-agent-worker.js +76 -40
  250. package/src/assets/web-panel/assets/AppLayout-Duu8xR14.js +0 -9
  251. package/src/assets/web-panel/assets/Dashboard-CXrd5gAw.js +0 -3
  252. package/src/assets/web-panel/assets/MobileProjects-NZvvfDME.js +0 -1
  253. package/src/assets/web-panel/assets/OrderTableRenderer-C48mu09U.js +0 -1
  254. package/src/assets/web-panel/assets/PersonalDataHub-AX3ypUDV.js +0 -9
  255. package/src/assets/web-panel/assets/Projects-Cc7FC9-e.js +0 -1
  256. package/src/assets/web-panel/assets/Terminal-CjTZPa37.js +0 -3
  257. package/src/assets/web-panel/assets/devWarning-BT46Y_QI.js +0 -1
  258. package/src/assets/web-panel/assets/index-B7nuIywP.js +0 -1
  259. package/src/assets/web-panel/assets/index-ycwAfC-i.js +0 -1
  260. package/src/assets/web-panel/assets/usePersonalDataHub-B4NkcLaP.js +0 -1
@@ -32,6 +32,22 @@ import { buildCliHubLLM } from "./hub-llm-client.js";
32
32
  // Test seam (mirrors _atomicWriteJson600): re-exported so the existing
33
33
  // pdh-wiring-load-error suite can keep importing it from here.
34
34
  export { rewritePdhLoadError as _rewritePdhLoadError } from "./pdh-load-error.js";
35
+
36
+ export function finalizeOneClickSyncReport(report) {
37
+ if (report && report.status === "ok") {
38
+ return { ok: true, report };
39
+ }
40
+ const status =
41
+ report && typeof report.status === "string" ? report.status : "invalid";
42
+ return {
43
+ ok: false,
44
+ reason: "SYNC_FAILED",
45
+ message:
46
+ (report && typeof report.error === "string" && report.error.trim()) ||
47
+ `registry sync returned status=${status}`,
48
+ report: report || null,
49
+ };
50
+ }
35
51
  // Hub package is CJS; in ESM we default-import then destructure (Node 22
36
52
  // won't let us name-import a CJS module unless it ships a separate ESM
37
53
  // shim, which we don't).
@@ -136,6 +152,7 @@ let LocalVault,
136
152
  AmapAdapter,
137
153
  TelegramAdapter,
138
154
  WhatsAppAdapter,
155
+ createJsonSourceFetch,
139
156
  AIChatHistoryAdapter,
140
157
  EntityResolver,
141
158
  EntityResolverEmbeddingStage,
@@ -260,6 +277,7 @@ function ensurePdhLoaded() {
260
277
  AmapAdapter,
261
278
  TelegramAdapter,
262
279
  WhatsAppAdapter,
280
+ createJsonSourceFetch,
263
281
  AIChatHistoryAdapter,
264
282
  EntityResolver,
265
283
  EntityResolverEmbeddingStage,
@@ -468,8 +486,8 @@ async function initHub() {
468
486
  }
469
487
 
470
488
  // ADB one-click readiness for the social platforms (B站/微博/抖音/小红书/
471
- // 头条/快手): each has a *AdbSync hub method that pulls from a rooted phone
472
- // over USB. The probe runs one `adb devices` so readiness() can show
489
+ // 头条/快手) plus Android system data. The probe runs one `adb devices`
490
+ // so readiness() can show
473
491
  // "已连接手机,点一键采集" vs "请插上 root 手机" instead of the misleading
474
492
  // snapshot guidance. Best-effort — never throws into the readiness probe.
475
493
  const ADB_ONE_CLICK_NAMES = new Set([
@@ -479,6 +497,7 @@ async function initHub() {
479
497
  "social-xiaohongshu",
480
498
  "social-toutiao",
481
499
  "social-kuaishou",
500
+ "system-data-android",
482
501
  ]);
483
502
  const adbReadinessProbe = async () => {
484
503
  try {
@@ -530,17 +549,15 @@ async function initHub() {
530
549
  // Phase 5.6: auto-register persisted email accounts.
531
550
  const emailAccountsPath = join(hubDir, "email-accounts.json");
532
551
  const emailAccounts = loadEmailAccounts(emailAccountsPath);
533
- for (const cfg of emailAccounts) {
534
- try {
535
- const adapter = new EmailAdapter({
552
+ registerNewestValidAccount({
553
+ registry,
554
+ accounts: emailAccounts,
555
+ createAdapter: (cfg) =>
556
+ new EmailAdapter({
536
557
  account: cfg.account,
537
558
  ...(cfg.opts || {}),
538
- });
539
- registry.register(adapter);
540
- } catch (_err) {
541
- // Continue boot even if one config is corrupt
542
- }
543
- }
559
+ }),
560
+ });
544
561
 
545
562
  // Plan A v0.1 — Android on-device system-data adapter. Stateless: the UI
546
563
  // produces a snapshot JSON via ContentResolver/PackageManager and passes
@@ -548,14 +565,13 @@ async function initHub() {
548
565
  // one-shot wire here. Safe to register on every host (no-op until a sync
549
566
  // call provides inputPath); future hosts may filter by platform if useful.
550
567
  try {
551
- const sda = new SystemDataAndroidAdapter();
552
568
  // Auto-engage host-side ADB bridge: when the UI clicks 同步 with no
553
569
  // inputPath, the adapter falls back to bridge mode and pulls
554
570
  // contacts + app.list via `adb shell` against the
555
- // developer-mode-attached phone. The adapter's constructor hardcodes
556
- // `_deps.bridgeProvider = () => null`, so we mutate after construction.
571
+ // developer-mode-attached phone.
557
572
  // See packages/cli/src/lib/host-adb-bridge.js for the bridge surface
558
573
  // + caveats (Windows CRLF parse trap, 0/multi device, ENOENT).
574
+ let bridgeProvider = () => null;
559
575
  try {
560
576
  const { createHostAdbBridge } = await import("./host-adb-bridge.js");
561
577
  // Phase 1b: register `bilibili.cookies` extension so the Phase 1c
@@ -604,10 +620,11 @@ async function initHub() {
604
620
  "whatsapp.backup": createWhatsAppBackupExtension(),
605
621
  },
606
622
  });
607
- sda._deps.bridgeProvider = () => hostAdbBridge;
623
+ bridgeProvider = () => hostAdbBridge;
608
624
  } catch (_e) {
609
625
  // Bridge module missing or failed to load — leave snapshot-only.
610
626
  }
627
+ const sda = new SystemDataAndroidAdapter({ bridgeProvider });
611
628
  if (!registry.has(sda.name)) registry.register(sda);
612
629
  } catch (_err) {
613
630
  // Boot must continue even if the adapter fails to register; cc hub will
@@ -731,6 +748,19 @@ async function initHub() {
731
748
  // ctors throw without account args, so they were silently swallowed by
732
749
  // try/catch and never actually registered. Removed to make the list
733
750
  // accurate.
751
+ const runtimeCookieAdapterClasses = new Set([
752
+ TaobaoAdapter,
753
+ JdAdapter,
754
+ MeituanAdapter,
755
+ ElemeAdapter,
756
+ PinduoduoAdapter,
757
+ DianpingAdapter,
758
+ XianyuAdapter,
759
+ VipshopAdapter,
760
+ Train12306Adapter,
761
+ ZhihuAdapter,
762
+ ]);
763
+ const sourceJsonFetch = createJsonSourceFetch();
734
764
  for (const Cls of [
735
765
  WeiboAdapter,
736
766
  ZhihuAdapter,
@@ -801,9 +831,12 @@ async function initHub() {
801
831
  WhatsAppAdapter,
802
832
  ]) {
803
833
  try {
804
- const adapter = Cls === WhatsAppAdapter
805
- ? new Cls({ bridgeProvider: () => hostAdbBridge })
806
- : new Cls();
834
+ const adapter =
835
+ Cls === WhatsAppAdapter
836
+ ? new Cls({ bridgeProvider: () => hostAdbBridge })
837
+ : runtimeCookieAdapterClasses.has(Cls)
838
+ ? new Cls({ fetchFn: sourceJsonFetch })
839
+ : new Cls();
807
840
  if (!registry.has(adapter.name)) registry.register(adapter);
808
841
  } catch (_err) {
809
842
  // Continue boot even if one adapter ctor throws
@@ -828,17 +861,15 @@ async function initHub() {
828
861
  // Phase 6: auto-register persisted Alipay accounts.
829
862
  const alipayAccountsPath = join(hubDir, "alipay-accounts.json");
830
863
  const alipayAccounts = loadAlipayAccounts(alipayAccountsPath);
831
- for (const cfg of alipayAccounts) {
832
- try {
833
- const adapter = new AlipayBillAdapter({
864
+ registerNewestValidAccount({
865
+ registry,
866
+ accounts: alipayAccounts,
867
+ createAdapter: (cfg) =>
868
+ new AlipayBillAdapter({
834
869
  account: cfg.account,
835
870
  ...(cfg.opts || {}),
836
- });
837
- if (!registry.has(adapter.name)) registry.register(adapter);
838
- } catch (_err) {
839
- // Continue boot even if one config is corrupt
840
- }
841
- }
871
+ }),
872
+ });
842
873
 
843
874
  // Phase 10.3.5 — AIChat HealthChecker (mirror of desktop wiring). cc ui
844
875
  // typically only runs while the user has the web-shell open, but the
@@ -960,7 +991,10 @@ async function initHub() {
960
991
  }
961
992
  registry.register(adapter);
962
993
  const accounts = loadEmailAccounts(emailAccountsPath);
963
- const next = accounts.filter((c) => c.account.email !== account.email);
994
+ const next = accounts.filter(
995
+ (c) =>
996
+ !sameAccountIdentity(c.account && c.account.email, account.email),
997
+ );
964
998
  next.push({ account, opts, registeredAt: Date.now() });
965
999
  saveEmailAccounts(emailAccountsPath, next);
966
1000
  return {
@@ -971,30 +1005,87 @@ async function initHub() {
971
1005
  };
972
1006
  },
973
1007
 
1008
+ async activateEmailAdapter(emailAddress) {
1009
+ if (!emailAddress || typeof emailAddress !== "string") {
1010
+ throw new Error("email required");
1011
+ }
1012
+ const activated = activatePersistedAdapter({
1013
+ registry,
1014
+ accounts: loadEmailAccounts(emailAccountsPath),
1015
+ identity: emailAddress,
1016
+ identityOf: (cfg) => cfg.account && cfg.account.email,
1017
+ createAdapter: (cfg) =>
1018
+ new EmailAdapter({
1019
+ account: cfg.account,
1020
+ ...(cfg.opts || {}),
1021
+ }),
1022
+ });
1023
+ if (!activated) {
1024
+ throw new Error("Saved email account not found");
1025
+ }
1026
+ const { adapter } = activated;
1027
+ return {
1028
+ name: adapter.name,
1029
+ version: adapter.version,
1030
+ capabilities: adapter.capabilities,
1031
+ sensitivity: adapter.dataDisclosure.sensitivity,
1032
+ active: true,
1033
+ };
1034
+ },
1035
+
974
1036
  async unregisterEmailAdapter(emailAddress) {
975
1037
  const accounts = loadEmailAccounts(emailAccountsPath);
976
- const target = accounts.find((c) => c.account.email === emailAddress);
977
- const next = accounts.filter((c) => c.account.email !== emailAddress);
1038
+ const target = accounts.find((c) =>
1039
+ sameAccountIdentity(c.account && c.account.email, emailAddress),
1040
+ );
1041
+ const next = accounts.filter(
1042
+ (c) => !sameAccountIdentity(c.account && c.account.email, emailAddress),
1043
+ );
1044
+ const active = registry.get("email-imap");
1045
+ const removingActive =
1046
+ !!target &&
1047
+ !!active &&
1048
+ !active._snapshotMode &&
1049
+ sameAccountIdentity(
1050
+ active.account && active.account.email,
1051
+ emailAddress,
1052
+ );
978
1053
  saveEmailAccounts(emailAccountsPath, next);
979
- if (target) {
1054
+ if (removingActive) {
980
1055
  registry.unregister("email-imap");
981
- // Phase 5.8 — restore the snapshot stub so Android sync paths still
982
- // work after the user unregisters their explicit IMAP account.
983
- try {
984
- registry.register(new EmailAdapter({ snapshotMode: true }));
985
- } catch (_err) {
986
- // Defensive — snapshot ctor has no required opts so this shouldn't fail
1056
+ const fallback = registerNewestValidAccount({
1057
+ registry,
1058
+ accounts: next,
1059
+ createAdapter: (cfg) =>
1060
+ new EmailAdapter({
1061
+ account: cfg.account,
1062
+ ...(cfg.opts || {}),
1063
+ }),
1064
+ });
1065
+ if (!fallback) {
1066
+ // Restore the snapshot stub only when no configured account remains.
1067
+ try {
1068
+ registry.register(new EmailAdapter({ snapshotMode: true }));
1069
+ } catch (_err) {
1070
+ // Defensive — snapshot ctor has no required opts.
1071
+ }
987
1072
  }
988
1073
  }
989
1074
  return { ok: true, removed: !!target };
990
1075
  },
991
1076
 
992
1077
  listEmailAccounts() {
1078
+ const active = registry.get("email-imap");
1079
+ const activeEmail =
1080
+ active && !active._snapshotMode && active.account
1081
+ ? active.account.email
1082
+ : null;
993
1083
  return loadEmailAccounts(emailAccountsPath).map((c) => ({
994
1084
  email: c.account.email,
995
1085
  provider: c.account.provider,
996
1086
  folders: c.account.folders || null,
997
1087
  registeredAt: c.registeredAt || null,
1088
+ active: sameAccountIdentity(c.account.email, activeEmail),
998
1089
  pdfPasswordHints:
999
1090
  c.opts && c.opts.pdfPasswordHints
1000
1091
  ? Object.keys(c.opts.pdfPasswordHints)
@@ -1031,7 +1122,10 @@ async function initHub() {
1031
1122
  if (registry.has(adapter.name)) registry.unregister(adapter.name);
1032
1123
  registry.register(adapter);
1033
1124
  const accounts = loadAlipayAccounts(alipayAccountsPath);
1034
- const next = accounts.filter((c) => c.account.email !== account.email);
1125
+ const next = accounts.filter(
1126
+ (c) =>
1127
+ !sameAccountIdentity(c.account && c.account.email, account.email),
1128
+ );
1035
1129
  next.push({ account, opts, registeredAt: Date.now() });
1036
1130
  saveAlipayAccounts(alipayAccountsPath, next);
1037
1131
  return {
@@ -1042,16 +1136,67 @@ async function initHub() {
1042
1136
  };
1043
1137
  },
1044
1138
 
1139
+ async activateAlipayAdapter(email) {
1140
+ if (!email || typeof email !== "string") {
1141
+ throw new Error("email required");
1142
+ }
1143
+ const activated = activatePersistedAdapter({
1144
+ registry,
1145
+ accounts: loadAlipayAccounts(alipayAccountsPath),
1146
+ identity: email,
1147
+ identityOf: (cfg) => cfg.account && cfg.account.email,
1148
+ createAdapter: (cfg) =>
1149
+ new AlipayBillAdapter({
1150
+ account: cfg.account,
1151
+ ...(cfg.opts || {}),
1152
+ }),
1153
+ });
1154
+ if (!activated) {
1155
+ throw new Error("Saved Alipay account not found");
1156
+ }
1157
+ const { adapter } = activated;
1158
+ return {
1159
+ name: adapter.name,
1160
+ version: adapter.version,
1161
+ capabilities: adapter.capabilities,
1162
+ sensitivity: adapter.dataDisclosure.sensitivity,
1163
+ active: true,
1164
+ };
1165
+ },
1166
+
1045
1167
  async unregisterAlipayAdapter(email) {
1046
1168
  const accounts = loadAlipayAccounts(alipayAccountsPath);
1047
- const target = accounts.find((c) => c.account.email === email);
1048
- const next = accounts.filter((c) => c.account.email !== email);
1169
+ const target = accounts.find((c) =>
1170
+ sameAccountIdentity(c.account && c.account.email, email),
1171
+ );
1172
+ const next = accounts.filter(
1173
+ (c) => !sameAccountIdentity(c.account && c.account.email, email),
1174
+ );
1175
+ const active = registry.get("alipay-bill");
1176
+ const removingActive =
1177
+ !!target &&
1178
+ !!active &&
1179
+ sameAccountIdentity(active.account && active.account.email, email);
1049
1180
  saveAlipayAccounts(alipayAccountsPath, next);
1050
- if (target) registry.unregister("alipay-bill");
1181
+ if (removingActive) {
1182
+ registry.unregister("alipay-bill");
1183
+ registerNewestValidAccount({
1184
+ registry,
1185
+ accounts: next,
1186
+ createAdapter: (cfg) =>
1187
+ new AlipayBillAdapter({
1188
+ account: cfg.account,
1189
+ ...(cfg.opts || {}),
1190
+ }),
1191
+ });
1192
+ }
1051
1193
  return { ok: true, removed: !!target };
1052
1194
  },
1053
1195
 
1054
1196
  listAlipayAccounts() {
1197
+ const active = registry.get("alipay-bill");
1198
+ const activeEmail =
1199
+ active && active.account ? active.account.email : null;
1055
1200
  return loadAlipayAccounts(alipayAccountsPath).map((c) => ({
1056
1201
  email: c.account.email,
1057
1202
  hasZipPassword: !!(
@@ -1059,6 +1204,7 @@ async function initHub() {
1059
1204
  (c.opts && c.opts.zipPassword)
1060
1205
  ),
1061
1206
  registeredAt: c.registeredAt || null,
1207
+ active: sameAccountIdentity(c.account.email, activeEmail),
1062
1208
  }));
1063
1209
  },
1064
1210
 
@@ -1119,7 +1265,8 @@ async function initHub() {
1119
1265
  const wechatAccountsPath = join(hubDir, "wechat-accounts.json");
1120
1266
  const accounts = loadWechatAccounts(wechatAccountsPath);
1121
1267
  const next = accounts.filter(
1122
- (c) => !(c.account && c.account.uin === opts.account.uin),
1268
+ (c) =>
1269
+ !sameAccountIdentity(c.account && c.account.uin, opts.account.uin),
1123
1270
  );
1124
1271
  next.push({
1125
1272
  account: { uin: opts.account.uin },
@@ -1144,23 +1291,85 @@ async function initHub() {
1144
1291
  };
1145
1292
  },
1146
1293
 
1294
+ async activateWechatAdapter(uin, opts = {}) {
1295
+ if (!uin || typeof uin !== "string") {
1296
+ return { ok: false, reason: "UIN_REQUIRED" };
1297
+ }
1298
+ const wechatAccountsPath = join(hubDir, "wechat-accounts.json");
1299
+ const accounts = loadWechatAccounts(wechatAccountsPath);
1300
+ const config = accounts.find((row) =>
1301
+ sameAccountIdentity(row.account && row.account.uin, uin),
1302
+ );
1303
+ if (!config) {
1304
+ return {
1305
+ ok: false,
1306
+ reason: "ACCOUNT_NOT_FOUND",
1307
+ message: "Saved WeChat account not found",
1308
+ };
1309
+ }
1310
+
1311
+ let r;
1312
+ try {
1313
+ r = await bootstrapWechatAdapter({
1314
+ account: config.account,
1315
+ dbPath: config.dbPath || null,
1316
+ wechatDataPath: config.wechatDataPath || null,
1317
+ fridaOpts: opts.fridaOpts || null,
1318
+ keyProviderOverride:
1319
+ opts.keyProviderOverride || config.chosenKeyProvider || null,
1320
+ exec: opts.exec,
1321
+ _probe: opts._probe,
1322
+ });
1323
+ } catch (err) {
1324
+ return {
1325
+ ok: false,
1326
+ reason: "BOOTSTRAP_THREW",
1327
+ message: err && err.message ? err.message : String(err),
1328
+ };
1329
+ }
1330
+ if (!r.ok) return r;
1331
+
1332
+ if (registry.has(r.adapter.name)) registry.unregister(r.adapter.name);
1333
+ registry.register(r.adapter);
1334
+ return {
1335
+ ok: true,
1336
+ name: r.adapter.name,
1337
+ version: r.adapter.version,
1338
+ capabilities: r.adapter.capabilities,
1339
+ sensitivity: r.adapter.dataDisclosure.sensitivity,
1340
+ chosenKeyProvider: r.keyProvider && r.keyProvider.name,
1341
+ probe: r.probe,
1342
+ registeredAt: config.registeredAt || null,
1343
+ active: true,
1344
+ };
1345
+ },
1346
+
1147
1347
  async unregisterWechatAdapter(uin) {
1148
1348
  if (!uin || typeof uin !== "string") {
1149
1349
  return { ok: false, reason: "UIN_REQUIRED" };
1150
1350
  }
1151
1351
  const wechatAccountsPath = join(hubDir, "wechat-accounts.json");
1152
1352
  const accounts = loadWechatAccounts(wechatAccountsPath);
1153
- const target = accounts.find((c) => c.account && c.account.uin === uin);
1353
+ const target = accounts.find((c) =>
1354
+ sameAccountIdentity(c.account && c.account.uin, uin),
1355
+ );
1154
1356
  const next = accounts.filter(
1155
- (c) => !(c.account && c.account.uin === uin),
1357
+ (c) => !sameAccountIdentity(c.account && c.account.uin, uin),
1156
1358
  );
1359
+ const active = registry.get("wechat");
1360
+ const removingActive =
1361
+ !!target &&
1362
+ !!active &&
1363
+ sameAccountIdentity(active.account && active.account.uin, uin);
1157
1364
  saveWechatAccounts(wechatAccountsPath, next);
1158
- if (target && registry.has("wechat")) registry.unregister("wechat");
1365
+ if (removingActive) registry.unregister("wechat");
1159
1366
  return { ok: true, removed: !!target, uin };
1160
1367
  },
1161
1368
 
1162
1369
  listWechatAccounts() {
1163
1370
  const wechatAccountsPath = join(hubDir, "wechat-accounts.json");
1371
+ const active = registry.get("wechat");
1372
+ const activeUin = active && active.account ? active.account.uin : null;
1164
1373
  return loadWechatAccounts(wechatAccountsPath).map((row) => ({
1165
1374
  uin: row.account ? row.account.uin : null,
1166
1375
  dbPath: row.dbPath || null,
@@ -1168,6 +1377,7 @@ async function initHub() {
1168
1377
  chosenKeyProvider: row.chosenKeyProvider || null,
1169
1378
  registeredAt: row.registeredAt || null,
1170
1379
  lastSyncAt: row.lastSyncAt || null,
1380
+ active: sameAccountIdentity(row.account && row.account.uin, activeUin),
1171
1381
  }));
1172
1382
  },
1173
1383
 
@@ -1251,7 +1461,7 @@ async function initHub() {
1251
1461
  registry,
1252
1462
  opts,
1253
1463
  );
1254
- return { ok: true, report };
1464
+ return finalizeOneClickSyncReport(report);
1255
1465
  } catch (err) {
1256
1466
  const msg = err && err.message ? err.message : String(err);
1257
1467
  // Extract a typed reason prefix from the BILIBILI_* error codes
@@ -1303,7 +1513,7 @@ async function initHub() {
1303
1513
  registry,
1304
1514
  opts,
1305
1515
  );
1306
- return { ok: true, report };
1516
+ return finalizeOneClickSyncReport(report);
1307
1517
  } catch (err) {
1308
1518
  const msg = err && err.message ? err.message : String(err);
1309
1519
  const m = msg.match(/^(DOUYIN_[A-Z_]+)/);
@@ -1347,7 +1557,7 @@ async function initHub() {
1347
1557
  registry,
1348
1558
  opts,
1349
1559
  );
1350
- return { ok: true, report };
1560
+ return finalizeOneClickSyncReport(report);
1351
1561
  } catch (err) {
1352
1562
  const msg = err && err.message ? err.message : String(err);
1353
1563
  const m = msg.match(/^(DOUYIN_[A-Z_]+)/);
@@ -1394,7 +1604,7 @@ async function initHub() {
1394
1604
  registry,
1395
1605
  opts,
1396
1606
  );
1397
- return { ok: true, report };
1607
+ return finalizeOneClickSyncReport(report);
1398
1608
  } catch (err) {
1399
1609
  const msg = err && err.message ? err.message : String(err);
1400
1610
  const m = msg.match(/^(WEIBO_[A-Z_]+)/);
@@ -1447,7 +1657,7 @@ async function initHub() {
1447
1657
  registry,
1448
1658
  opts,
1449
1659
  );
1450
- return { ok: true, report };
1660
+ return finalizeOneClickSyncReport(report);
1451
1661
  } catch (err) {
1452
1662
  const msg = err && err.message ? err.message : String(err);
1453
1663
  const m = msg.match(/^(XHS_[A-Z_]+)/);
@@ -1500,7 +1710,7 @@ async function initHub() {
1500
1710
  registry,
1501
1711
  opts,
1502
1712
  );
1503
- return { ok: true, report };
1713
+ return finalizeOneClickSyncReport(report);
1504
1714
  } catch (err) {
1505
1715
  const msg = err && err.message ? err.message : String(err);
1506
1716
  const m = msg.match(/^(TOUTIAO_[A-Z_]+)/);
@@ -1555,7 +1765,7 @@ async function initHub() {
1555
1765
  registry,
1556
1766
  opts,
1557
1767
  );
1558
- return { ok: true, report };
1768
+ return finalizeOneClickSyncReport(report);
1559
1769
  } catch (err) {
1560
1770
  const msg = err && err.message ? err.message : String(err);
1561
1771
  const m = msg.match(/^(KUAISHOU_[A-Z_]+)/);
@@ -1646,6 +1856,71 @@ function saveAlipayAccounts(filePath, accounts) {
1646
1856
  _atomicWriteJson600(filePath, accounts);
1647
1857
  }
1648
1858
 
1859
+ export function sameAccountIdentity(left, right) {
1860
+ if (left == null || right == null) return false;
1861
+ return (
1862
+ String(left).normalize("NFKC").trim().toLowerCase() ===
1863
+ String(right).normalize("NFKC").trim().toLowerCase()
1864
+ );
1865
+ }
1866
+
1867
+ export function accountRowsNewestFirst(accounts) {
1868
+ if (!Array.isArray(accounts)) return [];
1869
+ return accounts
1870
+ .map((row, index) => ({
1871
+ row,
1872
+ index,
1873
+ registeredAt: Number.isFinite(Number(row && row.registeredAt))
1874
+ ? Number(row.registeredAt)
1875
+ : 0,
1876
+ }))
1877
+ .sort(
1878
+ (left, right) =>
1879
+ right.registeredAt - left.registeredAt || right.index - left.index,
1880
+ )
1881
+ .map(({ row }) => row);
1882
+ }
1883
+
1884
+ function registerNewestValidAccount({ registry, accounts, createAdapter }) {
1885
+ for (const cfg of accountRowsNewestFirst(accounts)) {
1886
+ try {
1887
+ const adapter = createAdapter(cfg);
1888
+ registry.register(adapter);
1889
+ return adapter;
1890
+ } catch (_err) {
1891
+ // Corrupt persisted rows are skipped so the next valid account can boot.
1892
+ }
1893
+ }
1894
+ return null;
1895
+ }
1896
+
1897
+ export function activatePersistedAdapter({
1898
+ registry,
1899
+ accounts,
1900
+ identity,
1901
+ identityOf,
1902
+ createAdapter,
1903
+ }) {
1904
+ const config = (Array.isArray(accounts) ? accounts : []).find((row) =>
1905
+ sameAccountIdentity(identityOf(row), identity),
1906
+ );
1907
+ if (!config) return null;
1908
+
1909
+ // Construct first so an invalid persisted row cannot evict the currently
1910
+ // active adapter. The registry slot is replaced only after construction.
1911
+ const adapter = createAdapter(config);
1912
+ const previous =
1913
+ typeof registry.get === "function" ? registry.get(adapter.name) : null;
1914
+ if (registry.has(adapter.name)) registry.unregister(adapter.name);
1915
+ try {
1916
+ registry.register(adapter);
1917
+ } catch (err) {
1918
+ if (previous) registry.register(previous);
1919
+ throw err;
1920
+ }
1921
+ return { adapter, config };
1922
+ }
1923
+
1649
1924
  export async function getHub() {
1650
1925
  if (_hub) return _hub;
1651
1926
  if (!_initPromise) {
@@ -21,13 +21,14 @@
21
21
  * real processes.
22
22
  */
23
23
 
24
- import { spawn } from "node:child_process";
25
24
  import { executionBroker } from "./process-execution-broker/index.js";
26
25
  import { EventRuntimeProducer } from "./event-runtime-producer.js";
27
26
  import { EventRuntimeStore } from "./event-runtime-store.js";
28
27
  import { monitorEventId } from "./monitor-event.js";
29
28
 
30
- export const _deps = { spawn };
29
+ export const _deps = {
30
+ spawn: (...args) => executionBroker.spawn(...args),
31
+ };
31
32
 
32
33
  const DEFAULT_INTERVAL_MS = 60_000;
33
34
  const DEFAULT_TIMEOUT_MS = 30_000;
@@ -40,8 +41,7 @@ export class PluginMonitorSupervisor {
40
41
  this.defaultIntervalMs = opts.defaultIntervalMs || DEFAULT_INTERVAL_MS;
41
42
  this.timeoutMs = opts.timeoutMs || DEFAULT_TIMEOUT_MS;
42
43
  this._spawn = opts.spawn || _deps.spawn;
43
- this._brokerSpawn =
44
- opts.brokerSpawn || executionBroker.spawn.bind(executionBroker);
44
+ this._pluginSpawn = opts.brokerSpawn || this._spawn;
45
45
  const eventRuntimeStore =
46
46
  opts.eventRuntimeStore ||
47
47
  (process.env.CC_EVENT_RUNTIME_DURABLE === "1" ? new EventRuntimeStore() : null);
@@ -210,17 +210,24 @@ export class PluginMonitorSupervisor {
210
210
  }
211
211
 
212
212
  _spawnForDescriptor(desc, options) {
213
- if (desc?.origin === "plugin:monitor") {
214
- return this._brokerSpawn(desc.command, desc.args, {
213
+ const isPlugin = desc?.origin === "plugin:monitor";
214
+ return (isPlugin ? this._pluginSpawn : this._spawn)(
215
+ desc.command,
216
+ desc.args,
217
+ {
215
218
  ...options,
216
- origin: desc.origin,
219
+ origin: isPlugin ? desc.origin : "plugin-monitor:process",
217
220
  policy: "allow",
218
- pluginId: desc.pluginId,
219
- pluginVersion: desc.pluginVersion,
220
- pluginSource: desc.pluginSource,
221
- });
222
- }
223
- return this._spawn(desc.command, desc.args, options);
221
+ scope: "plugin-monitor",
222
+ ...(isPlugin
223
+ ? {
224
+ pluginId: desc.pluginId,
225
+ pluginVersion: desc.pluginVersion,
226
+ pluginSource: desc.pluginSource,
227
+ }
228
+ : {}),
229
+ },
230
+ );
224
231
  }
225
232
 
226
233
  /**