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
@@ -24,6 +24,7 @@ import { loadConfig } from "../lib/config-manager.js";
24
24
  import { isCloudHubConfigured } from "../lib/hub-llm-client.js";
25
25
  import { importPdh } from "../lib/pdh-load-error.js";
26
26
  import { getAIChatWizard } from "../lib/personal-data-hub-aichat-wizard.js";
27
+ import { runDedicatedBatchCollectors } from "../lib/pdh-dedicated-batch-collectors.js";
27
28
 
28
29
  function printJson(obj) {
29
30
  console.log(JSON.stringify(obj, null, 2));
@@ -37,9 +38,9 @@ function printJson(obj) {
37
38
  * + read commands are all-done after the report, no reason to keep idling.
38
39
  * Real-device repro on Xiaomi 24115RA8EC 2026-05-23.
39
40
  */
40
- function jsonAndExit(obj) {
41
+ function jsonAndExit(obj, exitCode = 0) {
41
42
  process.stdout.write(JSON.stringify(obj, null, 2) + "\n", () =>
42
- process.exit(0),
43
+ process.exit(exitCode),
43
44
  );
44
45
  }
45
46
 
@@ -57,6 +58,232 @@ function parsePositiveInt(raw) {
57
58
  return n;
58
59
  }
59
60
 
61
+ const SYNC_ENTITY_KEYS = ["events", "persons", "places", "items", "topics"];
62
+ const MAX_SYNC_COOKIE_BYTES = 64 * 1024;
63
+
64
+ function resolveSyncCookie(options = {}, env = process.env) {
65
+ if (options.cookie && options.cookieFile) {
66
+ throw new Error("Use either --cookie or --cookie-file, not both");
67
+ }
68
+ let raw = options.cookie || env.CC_PDH_COOKIE || null;
69
+ if (options.cookieFile) {
70
+ raw = readFileSync(String(options.cookieFile), "utf8");
71
+ if (Buffer.byteLength(raw, "utf8") > MAX_SYNC_COOKIE_BYTES) {
72
+ throw new Error(`Cookie file exceeds ${MAX_SYNC_COOKIE_BYTES} bytes`);
73
+ }
74
+ }
75
+ if (raw == null) return null;
76
+ const normalized = String(raw).trim();
77
+ if (Buffer.byteLength(normalized, "utf8") > MAX_SYNC_COOKIE_BYTES) {
78
+ throw new Error(`Cookie exceeds ${MAX_SYNC_COOKIE_BYTES} bytes`);
79
+ }
80
+ return normalized || null;
81
+ }
82
+
83
+ function syncCount(value) {
84
+ return Number.isFinite(value) && value > 0 ? value : 0;
85
+ }
86
+
87
+ function optionalSyncCount(value) {
88
+ return Number.isFinite(value) && value > 0 ? value : null;
89
+ }
90
+
91
+ function optionalNonNegativeSyncCount(value) {
92
+ return Number.isFinite(value) && value >= 0 ? value : null;
93
+ }
94
+
95
+ function syncEntityTotal(report) {
96
+ const counts = report?.entityCounts;
97
+ if (!counts || typeof counts !== "object") return 0;
98
+ return SYNC_ENTITY_KEYS.reduce(
99
+ (total, key) => total + syncCount(counts[key]),
100
+ 0,
101
+ );
102
+ }
103
+
104
+ function analyzeSyncReport(report) {
105
+ const valid = !!report && typeof report === "object";
106
+ const status =
107
+ valid && typeof report.status === "string" ? report.status : "invalid";
108
+ const total = syncEntityTotal(report);
109
+ const rawCount = syncCount(report?.rawCount);
110
+ const archivedRawCount = syncCount(report?.archivedRawCount);
111
+ const archiveFailureCount = syncCount(report?.archiveFailureCount);
112
+ const invalidCount = syncCount(report?.invalidCount);
113
+ const watermarkDeferred = report?.watermarkDeferred === true;
114
+ const checkpointCommitted =
115
+ typeof report?.checkpointCommitted === "boolean"
116
+ ? report.checkpointCommitted
117
+ : null;
118
+ const durability = {
119
+ archivedRawCount,
120
+ archiveFailureCount,
121
+ checkpointCommitted,
122
+ };
123
+ const pagination = {
124
+ pageBudget: optionalSyncCount(report?.pageBudget),
125
+ nextPageBudget: optionalSyncCount(report?.nextPageBudget),
126
+ scanDeferredCount: syncCount(report?.scanDeferredCount),
127
+ watermarkLookbackMs: syncCount(report?.watermarkLookbackMs),
128
+ collectionSinceWatermark:
129
+ typeof report?.collectionSinceWatermark === "string"
130
+ ? report.collectionSinceWatermark
131
+ : null,
132
+ };
133
+ const recovery = {
134
+ attemptCount: syncCount(report?.attemptCount),
135
+ retryCount: syncCount(report?.retryCount),
136
+ totalRetryDelayMs: syncCount(report?.totalRetryDelayMs),
137
+ retryExhausted: report?.retryExhausted === true,
138
+ retryAfterMs: optionalSyncCount(report?.retryAfterMs),
139
+ rateLimitReason:
140
+ typeof report?.rateLimitReason === "string"
141
+ ? report.rateLimitReason
142
+ : null,
143
+ rateLimitRemainingMinute: optionalNonNegativeSyncCount(
144
+ report?.rateLimitRemainingMinute,
145
+ ),
146
+ rateLimitRemainingDay: optionalNonNegativeSyncCount(
147
+ report?.rateLimitRemainingDay,
148
+ ),
149
+ sourceRequestCount: syncCount(report?.sourceRequestCount),
150
+ sourceRequestThrottleMs: syncCount(report?.sourceRequestThrottleMs),
151
+ sourceRequestRateLimitRemainingMinute: optionalNonNegativeSyncCount(
152
+ report?.sourceRequestRateLimitRemainingMinute,
153
+ ),
154
+ sourceRequestRateLimitRemainingDay: optionalNonNegativeSyncCount(
155
+ report?.sourceRequestRateLimitRemainingDay,
156
+ ),
157
+ };
158
+ if (valid && status === "skipped") {
159
+ return {
160
+ kind: "skipped",
161
+ ok: true,
162
+ total,
163
+ rawCount,
164
+ ...durability,
165
+ ...pagination,
166
+ ...recovery,
167
+ invalidCount,
168
+ error: null,
169
+ skipReason: report.skipReason || "NOT_READY",
170
+ skipMessage: report.skipMessage || "source is not ready",
171
+ };
172
+ }
173
+ if (!valid || status !== "ok") {
174
+ return {
175
+ kind: "failed",
176
+ ok: false,
177
+ total,
178
+ rawCount,
179
+ ...durability,
180
+ ...pagination,
181
+ ...recovery,
182
+ invalidCount,
183
+ error:
184
+ (valid && typeof report.error === "string" && report.error.trim()) ||
185
+ (status === "invalid" ? "invalid sync report" : `status=${status}`),
186
+ };
187
+ }
188
+ if (
189
+ watermarkDeferred ||
190
+ archiveFailureCount > 0 ||
191
+ checkpointCommitted === false ||
192
+ invalidCount > 0 ||
193
+ (rawCount > 0 && total === 0)
194
+ ) {
195
+ return {
196
+ kind: "partial",
197
+ ok: true,
198
+ total,
199
+ rawCount,
200
+ ...durability,
201
+ ...pagination,
202
+ ...recovery,
203
+ invalidCount,
204
+ watermarkDeferred,
205
+ error: null,
206
+ };
207
+ }
208
+ return {
209
+ kind: total === 0 ? "empty" : "success",
210
+ ok: true,
211
+ total,
212
+ rawCount,
213
+ ...durability,
214
+ ...pagination,
215
+ ...recovery,
216
+ invalidCount,
217
+ watermarkDeferred,
218
+ error: null,
219
+ };
220
+ }
221
+
222
+ function summarizeSyncReports(reports) {
223
+ const analyses = Array.isArray(reports)
224
+ ? reports.map(analyzeSyncReport)
225
+ : [analyzeSyncReport(null)];
226
+ return {
227
+ total: Array.isArray(reports) ? reports.length : 0,
228
+ success: analyses.filter((item) => item.kind === "success").length,
229
+ empty: analyses.filter((item) => item.kind === "empty").length,
230
+ partial: analyses.filter((item) => item.kind === "partial").length,
231
+ skipped: analyses.filter((item) => item.kind === "skipped").length,
232
+ failed: analyses.filter((item) => item.kind === "failed").length,
233
+ entities: analyses.reduce((total, item) => total + item.total, 0),
234
+ };
235
+ }
236
+
237
+ function formatSyncReportLine(report) {
238
+ const analysis = analyzeSyncReport(report);
239
+ const adapter = report?.adapter || "unknown";
240
+ return (
241
+ `${adapter} status=${report?.status || "invalid"} ` +
242
+ `raw=${analysis.rawCount} archived=${analysis.archivedRawCount} ` +
243
+ `archiveFailed=${analysis.archiveFailureCount} entities=${analysis.total} ` +
244
+ `invalid=${analysis.invalidCount} kgTriples=${syncCount(report?.kgTripleCount)} ` +
245
+ `ragDocs=${syncCount(report?.ragDocCount)} durationMs=${syncCount(report?.durationMs)}` +
246
+ (analysis.kind === "skipped"
247
+ ? ` skipReason=${analysis.skipReason} message=${analysis.skipMessage}`
248
+ : "") +
249
+ (analysis.watermarkDeferred ? " watermark=deferred" : "") +
250
+ (analysis.pageBudget !== null
251
+ ? ` pages=${analysis.pageBudget}` +
252
+ (analysis.nextPageBudget !== null ? `->${analysis.nextPageBudget}` : "")
253
+ : "") +
254
+ (analysis.scanDeferredCount > 0
255
+ ? ` deferredScans=${analysis.scanDeferredCount}`
256
+ : "") +
257
+ (analysis.retryCount > 0
258
+ ? ` attempts=${analysis.attemptCount} retries=${analysis.retryCount}` +
259
+ ` retryDelayMs=${analysis.totalRetryDelayMs}` +
260
+ (analysis.retryExhausted ? " retryExhausted=true" : "")
261
+ : "") +
262
+ (analysis.rateLimitReason
263
+ ? ` rateLimit=${analysis.rateLimitReason}` +
264
+ (analysis.retryAfterMs !== null
265
+ ? ` retryAfterMs=${analysis.retryAfterMs}`
266
+ : "") +
267
+ (analysis.rateLimitRemainingMinute !== null
268
+ ? ` remainingMinute=${analysis.rateLimitRemainingMinute}`
269
+ : "") +
270
+ (analysis.rateLimitRemainingDay !== null
271
+ ? ` remainingDay=${analysis.rateLimitRemainingDay}`
272
+ : "")
273
+ : "") +
274
+ (analysis.sourceRequestCount > 0
275
+ ? ` sourceRequests=${analysis.sourceRequestCount}` +
276
+ (analysis.sourceRequestThrottleMs > 0
277
+ ? ` sourceThrottleMs=${analysis.sourceRequestThrottleMs}`
278
+ : "")
279
+ : "") +
280
+ (analysis.checkpointCommitted === false
281
+ ? " checkpoint=not-committed"
282
+ : "") +
283
+ (analysis.error ? ` error=${analysis.error}` : "")
284
+ );
285
+ }
286
+
60
287
  function fail(spinner, err, asJson) {
61
288
  if (spinner) spinner.stop();
62
289
  const msg = err && err.message ? err.message : String(err);
@@ -150,11 +377,14 @@ async function cmdRepl(options = {}) {
150
377
  fail(boot, err, false);
151
378
  return;
152
379
  }
153
- boot.succeed("Hub loaded — vault open, engine warm. Type a question, or .exit to quit.");
380
+ boot.succeed(
381
+ "Hub loaded — vault open, engine warm. Type a question, or .exit to quit.",
382
+ );
154
383
 
155
384
  // Resolve cloud-egress consent ONCE (same precedence as cmdAsk).
156
385
  const envAllow =
157
- process.env.CC_HUB_ALLOW_NON_LOCAL === "1" || process.env.CC_HUB_ALLOW_NON_LOCAL === "true";
386
+ process.env.CC_HUB_ALLOW_NON_LOCAL === "1" ||
387
+ process.env.CC_HUB_ALLOW_NON_LOCAL === "true";
158
388
  let cfgCloudHub = false;
159
389
  try {
160
390
  cfgCloudHub = isCloudHubConfigured(loadConfig());
@@ -196,8 +426,12 @@ async function cmdRepl(options = {}) {
196
426
  logger.log(chalk.gray(`\n依据: ${result.citations.join(", ")}`));
197
427
  }
198
428
  if (result.llmName) {
199
- const tag = result.isLocal ? chalk.green("[local]") : chalk.yellow("[remote]");
200
- logger.log(chalk.gray(`-- ${result.llmName} ${tag} · ${Date.now() - t0}ms`));
429
+ const tag = result.isLocal
430
+ ? chalk.green("[local]")
431
+ : chalk.yellow("[remote]");
432
+ logger.log(
433
+ chalk.gray(`-- ${result.llmName} ${tag} · ${Date.now() - t0}ms`),
434
+ );
201
435
  }
202
436
  }
203
437
  } catch (err) {
@@ -210,7 +444,6 @@ async function cmdRepl(options = {}) {
210
444
  if (processing) return;
211
445
  processing = true;
212
446
  while (queue.length) {
213
- // eslint-disable-next-line no-await-in-loop
214
447
  await answerOne(queue.shift());
215
448
  }
216
449
  processing = false;
@@ -228,7 +461,9 @@ async function cmdRepl(options = {}) {
228
461
  if (!processing) rl.prompt();
229
462
  return;
230
463
  }
231
- if (["exit", "quit", ".exit", ".quit", "\\q"].includes(question.toLowerCase())) {
464
+ if (
465
+ ["exit", "quit", ".exit", ".quit", "\\q"].includes(question.toLowerCase())
466
+ ) {
232
467
  rl.close();
233
468
  return;
234
469
  }
@@ -519,7 +754,7 @@ async function cmdReadiness(options) {
519
754
  async function cmdSyncAdapter(name, options) {
520
755
  const spinner = options.json ? null : ora(`syncing ${name}...`).start();
521
756
  try {
522
- const hub = await getHub();
757
+ const hub = await (options._getHub || getHub)();
523
758
  const opts = {};
524
759
  if (options.since) opts.since = Number(options.since);
525
760
  if (options.until) opts.until = Number(options.until);
@@ -540,8 +775,18 @@ async function cmdSyncAdapter(name, options) {
540
775
  // QQ NT (qq-pc): the SQLCipher passphrase from qq-win-db-key (ASCII, e.g.
541
776
  // "5{sww#,6aq=)8=A@"). Routes qq-pc through the decrypt+parse sidecar.
542
777
  if (options.passphrase) opts.passphrase = String(options.passphrase);
543
- // Cookie-mode sources (weread): pass the login cookie through to the adapter.
544
- if (options.cookie) opts.cookie = String(options.cookie);
778
+ // Cookie-mode sources: a file/env path avoids exposing the secret in shell
779
+ // history and process listings. The value remains transient.
780
+ const runtimeCookie = resolveSyncCookie(options);
781
+ if (runtimeCookie) opts.cookie = runtimeCookie;
782
+ // Constructor-optional cookie collectors use a transient account identity
783
+ // to isolate watermarks without persisting the cookie or account id.
784
+ const runtimeAccountId = options.accountId || process.env.CC_PDH_ACCOUNT_ID;
785
+ if (runtimeAccountId) opts.accountId = String(runtimeAccountId);
786
+ // Alipay bill ZIP exports may be password protected. Environment fallback
787
+ // keeps the password out of shell history for automated collection.
788
+ const zipPassword = options.zipPassword || process.env.CC_PDH_ZIP_PASSWORD;
789
+ if (zipPassword) opts.zipPassword = String(zipPassword);
545
790
  // L1 local files (module 101): the local-files adapter walks directories
546
791
  // given via opts.roots (comma-separated dirs → array). Without this the
547
792
  // adapter falls back to its default user-data dirs.
@@ -552,7 +797,7 @@ async function cmdSyncAdapter(name, options) {
552
797
  .filter(Boolean);
553
798
  }
554
799
  const report = await hub.registry.syncAdapter(name, opts);
555
- if (spinner) spinner.succeed(`synced ${name}`);
800
+ const analysis = analyzeSyncReport(report);
556
801
  // 2026-05-24 in-APK Android exit + flush-race fix. Real-device repro on
557
802
  // Xiaomi 24115RA8EC:
558
803
  //
@@ -574,12 +819,32 @@ async function cmdSyncAdapter(name, options) {
574
819
  //
575
820
  // Fix: explicit drain-then-exit (jsonAndExit helper at top of file).
576
821
  if (options.json) {
577
- jsonAndExit(report);
822
+ jsonAndExit(report, analysis.ok ? 0 : 1);
578
823
  return;
579
824
  }
580
- logger.log(
581
- `ingested=${report.ingested} kgTriples=${report.kgTriples} ragDocs=${report.ragDocs} durationMs=${report.durationMs}`,
582
- );
825
+ if (!analysis.ok) {
826
+ if (spinner) spinner.fail(`sync ${name} failed`);
827
+ logger.error(chalk.red(`✗ ${formatSyncReportLine(report)}`));
828
+ process.exit(1);
829
+ return;
830
+ }
831
+ if (spinner) {
832
+ if (analysis.kind === "partial") {
833
+ spinner.warn(
834
+ analysis.watermarkDeferred
835
+ ? `synced ${name}; watermark deferred until the full page window is scanned` +
836
+ (analysis.nextPageBudget
837
+ ? ` (next page budget: ${analysis.nextPageBudget})`
838
+ : "")
839
+ : `synced ${name} with invalid data`,
840
+ );
841
+ } else if (analysis.kind === "empty") {
842
+ spinner.succeed(`synced ${name} (no new data)`);
843
+ } else {
844
+ spinner.succeed(`synced ${name}`);
845
+ }
846
+ }
847
+ logger.log(formatSyncReportLine(report));
583
848
  process.exit(0);
584
849
  } catch (err) {
585
850
  fail(spinner, err, options.json);
@@ -589,22 +854,47 @@ async function cmdSyncAdapter(name, options) {
589
854
  async function cmdSyncAll(options) {
590
855
  const spinner = options.json ? null : ora("syncing all...").start();
591
856
  try {
592
- const hub = await getHub();
593
- const opts = {};
857
+ const hub = await (options._getHub || getHub)();
858
+ const opts = { readyOnly: options.includeUnready !== true };
594
859
  if (options.since) opts.since = Number(options.since);
595
860
  if (options.until) opts.until = Number(options.until);
596
861
  if (options.limit) opts.limit = Number(options.limit);
597
- const reports = await hub.registry.syncAll(opts);
598
- if (spinner) spinner.succeed(`synced ${reports.length} adapters`);
862
+ const registryReports = await hub.registry.syncAll(opts);
863
+ const reports = await runDedicatedBatchCollectors(hub, registryReports);
864
+ const summary = summarizeSyncReports(reports);
865
+ if (spinner) {
866
+ if (summary.failed > 0 || summary.partial > 0) {
867
+ spinner.warn(
868
+ `sync completed: ${summary.success} success, ${summary.empty} empty, ` +
869
+ `${summary.partial} partial, ${summary.skipped} skipped, ` +
870
+ `${summary.failed} failed`,
871
+ );
872
+ } else if (summary.skipped > 0) {
873
+ spinner.info(
874
+ `sync completed: ${summary.success} success, ${summary.empty} empty, ` +
875
+ `${summary.skipped} skipped (${summary.entities} entities)`,
876
+ );
877
+ } else {
878
+ spinner.succeed(
879
+ `synced ${summary.total} adapters (${summary.entities} entities)`,
880
+ );
881
+ }
882
+ }
599
883
  if (options.json) {
600
884
  printJson(reports);
601
885
  } else {
602
886
  for (const r of reports) {
887
+ const line = formatSyncReportLine(r);
603
888
  logger.log(
604
- `${chalk.cyan(r.adapter)} ingested=${r.ingested} dur=${r.durationMs}ms`,
889
+ analyzeSyncReport(r).kind === "failed"
890
+ ? chalk.red(line)
891
+ : analyzeSyncReport(r).kind === "skipped"
892
+ ? chalk.gray(line)
893
+ : chalk.cyan(line),
605
894
  );
606
895
  }
607
896
  }
897
+ if (summary.failed > 0) process.exitCode = 1;
608
898
  } catch (err) {
609
899
  fail(spinner, err, options.json);
610
900
  }
@@ -1529,39 +1819,105 @@ async function cmdCollectWechat(options) {
1529
1819
  // p_skey cookie; this derives g_tk and pulls the owner's feeds. The cookie is
1530
1820
  // passed via --cookie or --cookie-file (kept out of argv/history when staged).
1531
1821
  async function cmdCollectQzone(options) {
1532
- const spinner = options.json ? null : ora("collect-qzone (API + ingest)...").start();
1822
+ const spinner = options.json
1823
+ ? null
1824
+ : ora("collect-qzone (API + ingest)...").start();
1533
1825
  try {
1534
1826
  const { createRequire } = await import("module");
1535
1827
  const require = createRequire(import.meta.url);
1536
1828
  const fs = require("fs");
1537
1829
  const qz = options._qzoneCore
1538
1830
  ? options._qzoneCore
1539
- : await importPdh("@chainlesschain/personal-data-hub/forensics/qzone-collect");
1831
+ : await importPdh(
1832
+ "@chainlesschain/personal-data-hub/forensics/qzone-collect",
1833
+ );
1540
1834
  let cookie = options.cookie;
1541
1835
  if (!cookie && options.cookieFile && fs.existsSync(options.cookieFile))
1542
1836
  cookie = fs.readFileSync(options.cookieFile, "utf8").trim();
1543
- if (!cookie) throw new Error("need --cookie \"<qzone cookie>\" or --cookie-file <path> (must contain uin + p_skey)");
1544
- const what = (options.what || "shuoshuo,msgb,album").split(",").map((s) => s.trim()).filter(Boolean);
1837
+ if (!cookie)
1838
+ throw new Error(
1839
+ 'need --cookie "<qzone cookie>" or --cookie-file <path> (must contain uin + p_skey)',
1840
+ );
1841
+ const what = (options.what || "shuoshuo,msgb,album")
1842
+ .split(",")
1843
+ .map((s) => s.trim())
1844
+ .filter(Boolean);
1545
1845
  const max = Number.isFinite(+options.max) ? +options.max : 1000;
1546
1846
 
1547
- const result = await qz.collectQzone({ uin: options.uin, cookie, what, max, fetchImpl: options._fetch });
1847
+ const result = await qz.collectQzone({
1848
+ uin: options.uin,
1849
+ cookie,
1850
+ what,
1851
+ max,
1852
+ fetchImpl: options._fetch,
1853
+ });
1548
1854
  if (!result.ok) {
1549
1855
  const report = { ok: false, reason: result.reason };
1550
- if (options.json) { jsonAndExit(report); return; }
1856
+ if (options.json) {
1857
+ jsonAndExit(report);
1858
+ return;
1859
+ }
1551
1860
  if (spinner) spinner.fail(`collect-qzone: ${result.reason}`);
1552
1861
  process.exit(2);
1553
1862
  }
1554
1863
 
1555
1864
  const hub = await (options._getHub || getHub)();
1556
1865
  const vault = hub.vault;
1557
- try { vault.putPerson({ type: "person", subtype: "contact", id: qz.SELF_ID, names: ["我(QQ空间)"], source: { adapter: "qzone", adapterVersion: "0.1.0", originalId: qz.SELF_ID, capturedAt: Date.now(), capturedBy: "api" }, ingestedAt: Date.now() }); } catch { /* dup */ }
1558
- for (const p of result.persons) { try { vault.putPerson(p); } catch { /* dup */ } }
1866
+ try {
1867
+ vault.putPerson({
1868
+ type: "person",
1869
+ subtype: "contact",
1870
+ id: qz.SELF_ID,
1871
+ names: ["我(QQ空间)"],
1872
+ source: {
1873
+ adapter: "qzone",
1874
+ adapterVersion: "0.1.0",
1875
+ originalId: qz.SELF_ID,
1876
+ capturedAt: Date.now(),
1877
+ capturedBy: "api",
1878
+ },
1879
+ ingestedAt: Date.now(),
1880
+ });
1881
+ } catch {
1882
+ /* dup */
1883
+ }
1884
+ for (const p of result.persons) {
1885
+ try {
1886
+ vault.putPerson(p);
1887
+ } catch {
1888
+ /* dup */
1889
+ }
1890
+ }
1559
1891
  let ingested = 0;
1560
- for (const ev of result.events) { try { vault.putEvent(ev); ingested++; } catch { /* dup */ } }
1892
+ for (const ev of result.events) {
1893
+ try {
1894
+ vault.putEvent(ev);
1895
+ ingested++;
1896
+ } catch {
1897
+ /* dup */
1898
+ }
1899
+ }
1561
1900
 
1562
- const report = { ok: true, uin: result.uin, counts: result.counts, events: result.events.length, persons: result.persons.length, ingested };
1563
- if (spinner) spinner.succeed(`collect-qzone: ${ingested} events → vault (${Object.entries(result.counts).map(([k, v]) => k + ":" + v).join(" ")})`);
1564
- if (options.json) { jsonAndExit(report); return; }
1901
+ const report = {
1902
+ ok: true,
1903
+ uin: result.uin,
1904
+ counts: result.counts,
1905
+ events: result.events.length,
1906
+ persons: result.persons.length,
1907
+ ingested,
1908
+ };
1909
+ if (spinner)
1910
+ spinner.succeed(
1911
+ `collect-qzone: ${ingested} events → vault (${Object.entries(
1912
+ result.counts,
1913
+ )
1914
+ .map(([k, v]) => k + ":" + v)
1915
+ .join(" ")})`,
1916
+ );
1917
+ if (options.json) {
1918
+ jsonAndExit(report);
1919
+ return;
1920
+ }
1565
1921
  logger.log(chalk.green("✓ Qzone collect succeeded"));
1566
1922
  logger.log(` counts: ${JSON.stringify(result.counts)}`);
1567
1923
  logger.log(` ingested: ${ingested}`);
@@ -1860,8 +2216,9 @@ async function cmdWechatList(options) {
1860
2216
  }
1861
2217
  logger.log(chalk.bold("Registered WeChat accounts:"));
1862
2218
  for (const row of rows) {
2219
+ const active = row.active ? chalk.green(" [active]") : "";
1863
2220
  logger.log(
1864
- ` • uin=${chalk.cyan(row.uin)} provider=${row.chosenKeyProvider || "?"} db=${row.dbPath || "(none)"} regAt=${row.registeredAt ? new Date(row.registeredAt).toISOString() : "?"}`,
2221
+ ` • uin=${chalk.cyan(row.uin)}${active} provider=${row.chosenKeyProvider || "?"} db=${row.dbPath || "(none)"} regAt=${row.registeredAt ? new Date(row.registeredAt).toISOString() : "?"}`,
1865
2222
  );
1866
2223
  }
1867
2224
  } catch (err) {
@@ -1869,6 +2226,35 @@ async function cmdWechatList(options) {
1869
2226
  }
1870
2227
  }
1871
2228
 
2229
+ async function cmdWechatActivate(uin, options) {
2230
+ try {
2231
+ if (!uin) throw new Error("uin argument required");
2232
+ const hub = await (options._getHub || getHub)();
2233
+ const r = await hub.activateWechatAdapter(uin, {
2234
+ keyProviderOverride: options.forceProvider || null,
2235
+ fridaOpts: options.fridaDeviceId
2236
+ ? { deviceId: options.fridaDeviceId }
2237
+ : null,
2238
+ });
2239
+ if (options.json) {
2240
+ printJson(r);
2241
+ return;
2242
+ }
2243
+ if (!r.ok) {
2244
+ logger.error(
2245
+ chalk.red(
2246
+ `activate failed: ${r.reason || "unknown"} ${r.message || ""}`,
2247
+ ),
2248
+ );
2249
+ process.exit(1);
2250
+ }
2251
+ logger.log(chalk.green(`WeChat account activated (uin=${uin})`));
2252
+ logger.log(` provider: ${chalk.cyan(r.chosenKeyProvider || "?")}`);
2253
+ } catch (err) {
2254
+ fail(null, err, options.json);
2255
+ }
2256
+ }
2257
+
1872
2258
  /**
1873
2259
  * Phase 1c — `cc hub bilibili-adb-sync`
1874
2260
  *
@@ -2935,7 +3321,10 @@ export function registerHubCommand(program) {
2935
3321
  "Allow non-local LLM (sends data off device — required when provider is not Ollama/vLLM)",
2936
3322
  )
2937
3323
  .option("--max-facts <n>", "Cap facts in prompt (default 80)")
2938
- .option("--max-query-limit <n>", "Cap vault queryEvents limit (default 200)")
3324
+ .option(
3325
+ "--max-query-limit <n>",
3326
+ "Cap vault queryEvents limit (default 200)",
3327
+ )
2939
3328
  .addHelpText(
2940
3329
  "after",
2941
3330
  "\nSame per-question semantics + cloud-egress gate as `cc hub ask`, but the\n" +
@@ -3039,7 +3428,19 @@ export function registerHubCommand(program) {
3039
3428
  )
3040
3429
  .option(
3041
3430
  "--cookie <cookie>",
3042
- "Login cookie for cookie-mode sources (e.g. weread)",
3431
+ "Login cookie for supported shopping, travel, and social collectors",
3432
+ )
3433
+ .option(
3434
+ "--cookie-file <path>",
3435
+ "Read the login cookie from a local file (preferred over putting it in shell history)",
3436
+ )
3437
+ .option(
3438
+ "--account-id <id>",
3439
+ "Platform account identity (for example a Zhihu url_token; stored only as a hashed scope)",
3440
+ )
3441
+ .option(
3442
+ "--zip-password <password>",
3443
+ "Password for an Alipay bill ZIP (or set CC_PDH_ZIP_PASSWORD to keep it out of shell history)",
3043
3444
  )
3044
3445
  .option("--json", "Output JSON")
3045
3446
  .action(cmdSyncAdapter);
@@ -3050,6 +3451,10 @@ export function registerHubCommand(program) {
3050
3451
  .option("--since <ms>", "Override watermark for all")
3051
3452
  .option("--until <ms>", "Stop at this unix-ms")
3052
3453
  .option("--limit <n>", "Cap each adapter")
3454
+ .option(
3455
+ "--include-unready",
3456
+ "Force every registered adapter to run instead of skipping sources that need setup",
3457
+ )
3053
3458
  .option("--json", "Output JSON")
3054
3459
  .action(cmdSyncAll);
3055
3460
 
@@ -3415,10 +3820,20 @@ export function registerHubCommand(program) {
3415
3820
  .description(
3416
3821
  "QQ空间 (Qzone): collect 说说/留言板/相册 via the Qzone CGI API. No local DB — needs the qzone-domain p_skey cookie (from the in-app WebView or a browser login to user.qzone.qq.com; base .qq.com skey is rejected). Derives g_tk from p_skey and ingests as post/message/media events.",
3417
3822
  )
3418
- .option("--cookie <cookie>", "Qzone cookie string (must contain uin + p_skey)")
3419
- .option("--cookie-file <path>", "File holding the cookie (preferred — keeps it out of argv)")
3823
+ .option(
3824
+ "--cookie <cookie>",
3825
+ "Qzone cookie string (must contain uin + p_skey)",
3826
+ )
3827
+ .option(
3828
+ "--cookie-file <path>",
3829
+ "File holding the cookie (preferred — keeps it out of argv)",
3830
+ )
3420
3831
  .option("--uin <uin>", "Account uin (else parsed from cookie)")
3421
- .option("--what <list>", "Comma list: shuoshuo,msgb,album (default all)", "shuoshuo,msgb,album")
3832
+ .option(
3833
+ "--what <list>",
3834
+ "Comma list: shuoshuo,msgb,album (default all)",
3835
+ "shuoshuo,msgb,album",
3836
+ )
3422
3837
  .option("--max <n>", "Max items per source", "1000")
3423
3838
  .option("--json", "Output JSON")
3424
3839
  .action(cmdCollectQzone);
@@ -3543,6 +3958,17 @@ export function registerHubCommand(program) {
3543
3958
  .option("--json", "Output JSON")
3544
3959
  .action(cmdWechatList);
3545
3960
 
3961
+ wechat
3962
+ .command("activate <uin>")
3963
+ .description("Activate a saved WeChat account without registering it again")
3964
+ .option("--force-provider <md5|frida>", "Override the saved key provider")
3965
+ .option(
3966
+ "--frida-device-id <id>",
3967
+ "Frida device id (defaults to first USB device)",
3968
+ )
3969
+ .option("--json", "Output JSON")
3970
+ .action(cmdWechatActivate);
3971
+
3546
3972
  wechat
3547
3973
  .command("unregister <uin>")
3548
3974
  .description(
@@ -3574,6 +4000,13 @@ export const _internal = {
3574
4000
  cmdQueryEvents,
3575
4001
  cmdEventDetail,
3576
4002
  parsePositiveInt,
4003
+ syncEntityTotal,
4004
+ analyzeSyncReport,
4005
+ summarizeSyncReports,
4006
+ formatSyncReportLine,
4007
+ resolveSyncCookie,
4008
+ cmdSyncAdapter,
4009
+ cmdSyncAll,
3577
4010
  cmdAIChatList,
3578
4011
  cmdAIChatLogin,
3579
4012
  cmdAIChatProbe,
@@ -3583,6 +4016,7 @@ export const _internal = {
3583
4016
  cmdWechatEnvProbe,
3584
4017
  cmdWechatRegister,
3585
4018
  cmdWechatList,
4019
+ cmdWechatActivate,
3586
4020
  cmdWechatUnregister,
3587
4021
  cmdWechatDoctor,
3588
4022
  cmdBilibiliAdbSync,